From 06afc3984d8e30e1c64db65373aa8e1378d44c16 Mon Sep 17 00:00:00 2001 From: Denys Dmytriyenko Date: Sat, 28 Sep 2013 15:54:37 -0400 Subject: linux-omap-2.6.39: remove old beagleboard-specific and not supported kernel Beagleboard is supported by newer 3.x kernel recipes. Signed-off-by: Denys Dmytriyenko Acked-by: Franklin Cooper Jr. --- ...e-add-support-for-beagleboard-xM-revision.patch | 117 - ...P3-beagle-add-support-for-expansionboards.patch | 359 - .../0003-OMAP3-beagle-add-MADC-support.patch | 36 - ...eagle-add-regulators-for-camera-interface.patch | 88 - .../0005-OMAP3-beagle-HACK-add-in-1GHz-OPP.patch | 31 - .../beagle/0006-OMAP3-BEAGLE-fix-RTC.patch | 27 - ...mc-Adjust-dto-to-eliminate-timeout-errors.patch | 33 - ...ap3-beagle-Use-GPTIMERi-1-for-clockevents.patch | 42 - .../linux-omap-2.6.39/beagleboard/configs/stock | 3490 ------ .../linux/linux-omap-2.6.39/beagleboard/defconfig | 3517 ------ ...d-driver-for-Aptina-Micron-mt9p031-sensor.patch | 859 -- .../0002-v4l-Add-mt9v032-sensor-driver.patch | 853 -- ...-for-mt9p031-LI-5M03-module-in-Beagleboar.patch | 162 - ...ap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch | 67 - ...-omap_usbhs_alloc_children-error-handling.patch | 50 - ...003-mfd-Add-omap-usbhs-runtime-PM-support.patch | 245 - ...b-ehci-and-ohci-hwmod-structures-for-omap.patch | 406 - ...005-arm-omap-usb-register-hwmods-of-usbhs.patch | 160 - ...b-device-name-change-for-the-clk-names-of.patch | 123 - ...Suspend-and-resume-support-of-ehci-and-oh.patch | 165 - ...-Correct-the-warning-print-during-script-.patch | 36 - ...-Modifying-the-macro-name-Main_Ref-to-all.patch | 61 - ...FD-TWL4030-power-scripts-for-OMAP3-boards.patch | 705 -- .../0011-MFD-TWL4030-TWL-version-checking.patch | 164 - ...TWL4030-workaround-changes-for-Erratum-27.patch | 341 - ...TWL4030-optimizing-resource-configuration.patch | 184 - ...-Enable-DMA-mode1-RX-for-USB-Mass-Storage.patch | 121 - ...-NFS-Revert-NFSROOT-default-mount-options.patch | 13 - .../0001-OMAP2-cpufreq-free-up-table-on-exit.patch | 38 - ...MAP2-cpufreq-handle-invalid-cpufreq-table.patch | 44 - .../0003-OMAP2-cpufreq-minor-comment-cleanup.patch | 33 - ...eq-use-clk_init_cpufreq_table-if-OPPs-not.patch | 48 - ...pufreq-use-cpufreq_frequency_table_target.patch | 78 - .../0006-OMAP2-cpufreq-fix-freq_table-leak.patch | 100 - ...q-helpers-for-walking-the-frequency-table.patch | 134 - .../0002-cpufreq-introduce-hotplug-governor.patch | 879 -- ...q-ensure-driver-initializes-after-cpufreq.patch | 27 - ...PUfreq-ensure-policy-is-fully-initialized.patch | 31 - .../0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch | 263 - ...AP-PM-CPUFREQ-Fix-conditional-compilation.patch | 32 - ...-cpufreq-fixup-after-new-OPP-layer-merged.patch | 33 - ...q-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch | 669 -- ...cpufreq-Add-SMP-support-to-cater-OMAP4430.patch | 170 - ...pufreq-Fix-typo-when-attempting-to-set-mp.patch | 29 - ...-clockdomain-Add-an-api-to-read-idle-mode.patch | 77 - ...kdomain-Add-SoC-support-for-clkdm_is_idle.patch | 86 - ...itialise-sleep_switch-to-a-non-valid-valu.patch | 35 - ...P2-PM-idle-clkdms-only-if-already-in-idle.patch | 50 - ...hwmod-Follow-the-recomended-PRCM-sequence.patch | 46 - ...6-OMAP-Serial-Check-wk_st-only-if-present.patch | 33 - ...age-remove-spurious-pr_notice-for-debugfs.patch | 30 - ...OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch | 41 - ...reflex-fix-sr_late_init-error-path-in-pro.patch | 30 - ...AP3-smartreflex-request-the-memory-region.patch | 36 - ...artreflex-fix-ioremap-leak-on-probe-error.patch | 66 - ...reflex-delete-instance-from-sr_list-on-pr.patch | 29 - ...reflex-delete-debugfs-entries-on-probe-er.patch | 48 - ...uidle-remove-useless-SDP-specific-timings.patch | 57 - ...OMAP3-SR-make-notify-independent-of-class.patch | 48 - ...010-OMAP3-SR-disable-interrupt-by-default.patch | 37 - ...1-OMAP3-SR-enable-disable-SR-only-on-need.patch | 41 - .../0012-OMAP3-SR-fix-cosmetic-indentation.patch | 49 - ...01-OMAP-DSS2-DSI-fix-use_sys_clk-highfreq.patch | 33 - .../0002-OMAP-DSS2-DSI-fix-dsi_dump_clocks.patch | 49 - ...SS2-Fix-Return-correct-lcd-clock-source-f.patch | 43 - .../0004-OMAP-DSS-DSI-Fix-DSI-PLL-power-bug.patch | 64 - ...-OMAP-DSS2-fix-panel-Kconfig-dependencies.patch | 61 - ...dd-bootarg-for-selecting-svideo-or-compos.patch | 75 - .../sakoman/0007-video-add-timings-for-hd720.patch | 27 - ...-smsc911x-return-ENODEV-if-device-is-not-.patch | 29 - ...ut-touchscreen-ads7846-return-ENODEV-if-d.patch | 47 - ...10-Revert-omap2_mcspi-Flush-posted-writes.patch | 25 - ...p_hsmmc-improve-interrupt-synchronisation.patch | 482 - ...SDIO-cards-off-to-save-power.-Doing-so-wi.patch | 51 - ...13-Enable-the-use-of-SDIO-card-interrupts.patch | 288 - ...Enable-audio-capture-by-default-for-twl40.patch | 27 - ...odecs-twl4030-Turn-on-mic-bias-by-default.patch | 25 - ...C-add-support-for-backup-battery-recharge.patch | 55 - ...mc-twl4030-move-clock-input-selection-pri.patch | 39 - ...wer-off-support-for-the-TWL4030-companion.patch | 103 - ...RM-OMAP-Add-twl4030-madc-support-to-Overo.patch | 33 - ...20-Enabling-Hwmon-driver-for-twl4030-madc.patch | 46 - .../0021-mfd-twl-core-enable-madc-clock.patch | 54 - ...0022-rtc-twl-Switch-to-using-threaded-irq.patch | 25 - ...tomatically-set-musb-mode-in-platform-dat.patch | 49 - ...mc-Adjust-dto-to-eliminate-timeout-errors.patch | 28 - .../0025-omap-Fix-mtd-subpage-read-alignment.patch | 95 - ...ap2-Force-all-buffer-reads-to-u32-alignme.patch | 35 - ...-nand-fix-subpage-ecc-issue-with-prefetch.patch | 63 - .../0028-OMAP-Overo-Add-support-for-spidev.patch | 46 - ...029-unionfs-Add-support-for-unionfs-2.5.9.patch | 11494 ------------------- ...-omap_device-activate-latency-messages-fr.patch | 34 - .../sakoman/0031-omap-overo-Add-opp-init.patch | 105 - ...2-omap3-Add-basic-support-for-720MHz-part.patch | 202 - recipes-kernel/linux/linux-omap_2.6.39.bb | 123 - 95 files changed, 29857 deletions(-) delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagle/0001-OMAP3-beagle-add-support-for-beagleboard-xM-revision.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagle/0002-OMAP3-beagle-add-support-for-expansionboards.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagle/0003-OMAP3-beagle-add-MADC-support.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagle/0004-OMAP3-beagle-add-regulators-for-camera-interface.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagle/0005-OMAP3-beagle-HACK-add-in-1GHz-OPP.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagle/0006-OMAP3-BEAGLE-fix-RTC.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagle/0007-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagle/0007-omap3-beagle-Use-GPTIMERi-1-for-clockevents.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagleboard/configs/stock delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/beagleboard/defconfig delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/camera/0001-Add-driver-for-Aptina-Micron-mt9p031-sensor.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/camera/0002-v4l-Add-mt9v032-sensor-driver.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/camera/0003-Add-support-for-mt9p031-LI-5M03-module-in-Beagleboar.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0001-mfd-Fix-omap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0002-mfd-Fix-omap_usbhs_alloc_children-error-handling.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0003-mfd-Add-omap-usbhs-runtime-PM-support.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0004-arm-omap-usb-ehci-and-ohci-hwmod-structures-for-omap.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0005-arm-omap-usb-register-hwmods-of-usbhs.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0006-arm-omap-usb-device-name-change-for-the-clk-names-of.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0008-MFD-TWL4030-Correct-the-warning-print-during-script-.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0009-MFD-TWL4030-Modifying-the-macro-name-Main_Ref-to-all.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0010-MFD-TWL4030-power-scripts-for-OMAP3-boards.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0011-MFD-TWL4030-TWL-version-checking.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0012-MFD-TWL4030-workaround-changes-for-Erratum-27.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/mfd/0013-MFD-TWL4030-optimizing-resource-configuration.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/musb/0001-usb-musb-Enable-DMA-mode1-RX-for-USB-Mass-Storage.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/net/0001-NFS-Revert-NFSROOT-default-mount-options.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0001-OMAP2-cpufreq-free-up-table-on-exit.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0002-OMAP2-cpufreq-handle-invalid-cpufreq-table.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0003-OMAP2-cpufreq-minor-comment-cleanup.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0004-OMAP2-cpufreq-use-clk_init_cpufreq_table-if-OPPs-not.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0005-OMAP2-cpufreq-use-cpufreq_frequency_table_target.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0002-cpufreq-introduce-hotplug-governor.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0001-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0002-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0004-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0005-cpufreq-fixup-after-new-OPP-layer-merged.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0006-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0008-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0001-OMAP2-clockdomain-Add-an-api-to-read-idle-mode.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0002-OMAP2-clockdomain-Add-SoC-support-for-clkdm_is_idle.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0003-OMAP2-PM-Initialise-sleep_switch-to-a-non-valid-valu.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0004-OMAP2-PM-idle-clkdms-only-if-already-in-idle.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0005-OMAP2-hwmod-Follow-the-recomended-PRCM-sequence.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0006-OMAP-Serial-Check-wk_st-only-if-present.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0001-OMAP3-voltage-remove-spurious-pr_notice-for-debugfs.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0002-OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0003-OMAP3-smartreflex-fix-sr_late_init-error-path-in-pro.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0004-OMAP3-smartreflex-request-the-memory-region.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0005-OMAP3-smartreflex-fix-ioremap-leak-on-probe-error.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0006-OMAP3-smartreflex-delete-instance-from-sr_list-on-pr.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0007-OMAP3-smartreflex-delete-debugfs-entries-on-probe-er.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0008-OMAP3-cpuidle-remove-useless-SDP-specific-timings.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0009-OMAP3-SR-make-notify-independent-of-class.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0010-OMAP3-SR-disable-interrupt-by-default.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0011-OMAP3-SR-enable-disable-SR-only-on-need.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0012-OMAP3-SR-fix-cosmetic-indentation.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0001-OMAP-DSS2-DSI-fix-use_sys_clk-highfreq.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0002-OMAP-DSS2-DSI-fix-dsi_dump_clocks.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0003-OMAP2PLUS-DSS2-Fix-Return-correct-lcd-clock-source-f.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0004-OMAP-DSS-DSI-Fix-DSI-PLL-power-bug.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0005-OMAP-DSS2-fix-panel-Kconfig-dependencies.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0006-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0007-video-add-timings-for-hd720.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0008-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0009-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0010-Revert-omap2_mcspi-Flush-posted-writes.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0011-Revert-omap_hsmmc-improve-interrupt-synchronisation.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0012-Don-t-turn-SDIO-cards-off-to-save-power.-Doing-so-wi.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0014-soc-codecs-Enable-audio-capture-by-default-for-twl40.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0015-soc-codecs-twl4030-Turn-on-mic-bias-by-default.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0016-RTC-add-support-for-backup-battery-recharge.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0017-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0018-Add-power-off-support-for-the-TWL4030-companion.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0020-Enabling-Hwmon-driver-for-twl4030-madc.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0021-mfd-twl-core-enable-madc-clock.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0022-rtc-twl-Switch-to-using-threaded-irq.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0023-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0024-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0025-omap-Fix-mtd-subpage-read-alignment.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0026-mtd-nand-omap2-Force-all-buffer-reads-to-u32-alignme.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0027-omap-nand-fix-subpage-ecc-issue-with-prefetch.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0028-OMAP-Overo-Add-support-for-spidev.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0029-unionfs-Add-support-for-unionfs-2.5.9.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0030-omap-Change-omap_device-activate-latency-messages-fr.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0031-omap-overo-Add-opp-init.patch delete mode 100644 recipes-kernel/linux/linux-omap-2.6.39/sakoman/0032-omap3-Add-basic-support-for-720MHz-part.patch delete mode 100644 recipes-kernel/linux/linux-omap_2.6.39.bb (limited to 'recipes-kernel') diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0001-OMAP3-beagle-add-support-for-beagleboard-xM-revision.patch b/recipes-kernel/linux/linux-omap-2.6.39/beagle/0001-OMAP3-beagle-add-support-for-beagleboard-xM-revision.patch deleted file mode 100644 index 7522d6c1..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0001-OMAP3-beagle-add-support-for-beagleboard-xM-revision.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 16c1bdb30f1bcd750b29dffd2ef3003be2d30610 Mon Sep 17 00:00:00 2001 -From: Koen Kooi -Date: Fri, 20 May 2011 12:48:37 +0200 -Subject: [PATCH 1/7] OMAP3: beagle: add support for beagleboard xM revision C - -The USB enable GPIO has been inverted and the USER button moved. - -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/board-omap3beagle.c | 34 +++++++++++++++++++++++------- - 1 files changed, 26 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c -index 2de4b02..77bafa8 100644 ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -62,7 +62,9 @@ - * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1 - * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0 - * C4 = GPIO173, GPIO172, GPIO171: 1 0 1 -- * XM = GPIO173, GPIO172, GPIO171: 0 0 0 -+ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0 -+ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1 -+ * XMC = GPIO173, GPIO172, GPIO171: 0 1 0 - */ - enum { - OMAP3BEAGLE_BOARD_UNKN = 0, -@@ -70,6 +72,7 @@ enum { - OMAP3BEAGLE_BOARD_C1_3, - OMAP3BEAGLE_BOARD_C4, - OMAP3BEAGLE_BOARD_XM, -+ OMAP3BEAGLE_BOARD_XMC, - }; - - static u8 omap3_beagle_version; -@@ -124,9 +127,18 @@ static void __init omap3_beagle_init_rev(void) - printk(KERN_INFO "OMAP3 Beagle Rev: xM\n"); - omap3_beagle_version = OMAP3BEAGLE_BOARD_XM; - break; -+ case 1: -+ printk(KERN_INFO "OMAP3 Beagle Rev: xM B\n"); -+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM; -+ break; -+ case 2: -+ printk(KERN_INFO "OMAP3 Beagle Rev: xM C\n"); -+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC; -+ break; - default: -- printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev); -- omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN; -+ printk(KERN_INFO -+ "OMAP3 Beagle Rev: unknown %hd, assuming xM C or newer\n", beagle_rev); -+ omap3_beagle_version = OMAP3BEAGLE_BOARD_XMC; - } - - return; -@@ -278,7 +290,7 @@ static int beagle_twl_gpio_setup(struct device *dev, - { - int r; - -- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { -+ if (cpu_is_omap3630()) { - mmc[0].gpio_wp = -EINVAL; - } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) || - (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C4)) { -@@ -298,7 +310,8 @@ static int beagle_twl_gpio_setup(struct device *dev, - /* REVISIT: need ehci-omap hooks for external VBUS - * power switch and overcurrent detect - */ -- if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) { -+ if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM -+ && omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XMC) { - r = gpio_request(gpio + 1, "EHCI_nOC"); - if (!r) { - r = gpio_direction_input(gpio + 1); -@@ -320,7 +333,7 @@ static int beagle_twl_gpio_setup(struct device *dev, - gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); - - /* DVI reset GPIO is different between beagle revisions */ -- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) -+ if (cpu_is_omap3630()) - beagle_dvi_device.reset_gpio = 129; - else - beagle_dvi_device.reset_gpio = 170; -@@ -334,7 +347,7 @@ static int beagle_twl_gpio_setup(struct device *dev, - * P7/P8 revisions(prototype): Camera EN - * A2+ revisions (production): LDO (supplies DVI, serial, led blocks) - */ -- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { -+ if (cpu_is_omap3630()) { - r = gpio_request(gpio + 1, "nDVI_PWR_EN"); - if (!r) { - r = gpio_direction_output(gpio + 1, 0); -@@ -625,7 +638,7 @@ static void __init beagle_opp_init(void) - } - - /* Custom OPP enabled for XM */ -- if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { -+ if (cpu_is_omap3630()) { - struct omap_hwmod *mh = omap_hwmod_lookup("mpu"); - struct omap_hwmod *dh = omap_hwmod_lookup("iva"); - struct device *dev; -@@ -665,6 +678,11 @@ static void __init omap3_beagle_init(void) - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - omap3_beagle_init_rev(); - omap3_beagle_i2c_init(); -+ -+ if (cpu_is_omap3630()) { -+ gpio_buttons[0].gpio = 4; -+ } -+ - platform_add_devices(omap3_beagle_devices, - ARRAY_SIZE(omap3_beagle_devices)); - omap_display_init(&beagle_dss_data); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0002-OMAP3-beagle-add-support-for-expansionboards.patch b/recipes-kernel/linux/linux-omap-2.6.39/beagle/0002-OMAP3-beagle-add-support-for-expansionboards.patch deleted file mode 100644 index 2e95c763..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0002-OMAP3-beagle-add-support-for-expansionboards.patch +++ /dev/null @@ -1,359 +0,0 @@ -From 27494059a5d005b8cad4e0e8640ff031b86220dc Mon Sep 17 00:00:00 2001 -From: Koen Kooi -Date: Fri, 20 May 2011 13:06:24 +0200 -Subject: [PATCH 2/7] OMAP3: beagle: add support for expansionboards - -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/board-omap3beagle.c | 272 ++++++++++++++++++++++++++++++- - 1 files changed, 269 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c -index 77bafa8..db285e1 100644 ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -154,6 +155,167 @@ fail0: - return; - } - -+char expansionboard_name[16]; -+ -+#if defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE) -+#include -+#include -+ -+#define OMAP_BEAGLE_WLAN_EN_GPIO (139) -+#define OMAP_BEAGLE_BT_EN_GPIO (138) -+#define OMAP_BEAGLE_WLAN_IRQ_GPIO (137) -+#define OMAP_BEAGLE_FM_EN_BT_WU (136) -+ -+struct wl12xx_platform_data omap_beagle_wlan_data __initdata = { -+ .irq = OMAP_GPIO_IRQ(OMAP_BEAGLE_WLAN_IRQ_GPIO), -+ .board_ref_clock = 2, /* 38.4 MHz */ -+}; -+ -+static int gpios[] = {OMAP_BEAGLE_BT_EN_GPIO, OMAP_BEAGLE_FM_EN_BT_WU, -1}; -+static struct platform_device wl12xx_device = { -+ .name = "kim", -+ .id = -1, -+ .dev.platform_data = &gpios, -+}; -+ -+static struct omap2_hsmmc_info mmcbbt[] = { -+ { -+ .mmc = 1, -+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, -+ .gpio_wp = 29, -+ }, -+ { -+ .name = "wl1271", -+ .mmc = 2, -+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, -+ .gpio_wp = -EINVAL, -+ .gpio_cd = -EINVAL, -+ .ocr_mask = MMC_VDD_165_195, -+ .nonremovable = true, -+ }, -+ {} /* Terminator */ -+ }; -+ -+static struct regulator_consumer_supply beagle_vmmc2_supply = -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"); -+ -+static struct regulator_init_data beagle_vmmc2 = { -+ .constraints = { -+ .min_uV = 1850000, -+ .max_uV = 1850000, -+ .apply_uV = true, -+ .valid_modes_mask = REGULATOR_MODE_NORMAL -+ | REGULATOR_MODE_STANDBY, -+ .valid_ops_mask = REGULATOR_CHANGE_MODE -+ | REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = 1, -+ .consumer_supplies = &beagle_vmmc2_supply, -+}; -+ -+static struct fixed_voltage_config beagle_vwlan = { -+ .supply_name = "vwl1271", -+ .microvolts = 1800000, /* 1.8V */ -+ .gpio = OMAP_BEAGLE_WLAN_EN_GPIO, -+ .startup_delay = 70000, /* 70ms */ -+ .enable_high = 1, -+ .enabled_at_boot = 0, -+ .init_data = &beagle_vmmc2, -+}; -+ -+static struct platform_device omap_vwlan_device = { -+ .name = "reg-fixed-voltage", -+ .id = 1, -+ .dev = { -+ .platform_data = &beagle_vwlan, -+ }, -+}; -+#endif -+ -+#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE) -+ -+#include -+#include -+ -+#define OMAP3BEAGLE_GPIO_ENC28J60_IRQ 157 -+ -+static struct omap2_mcspi_device_config enc28j60_spi_chip_info = { -+ .turbo_mode = 0, -+ .single_channel = 1, /* 0: slave, 1: master */ -+}; -+ -+static struct spi_board_info omap3beagle_zippy_spi_board_info[] __initdata = { -+ { -+ .modalias = "enc28j60", -+ .bus_num = 4, -+ .chip_select = 0, -+ .max_speed_hz = 20000000, -+ .controller_data = &enc28j60_spi_chip_info, -+ }, -+}; -+ -+static void __init omap3beagle_enc28j60_init(void) -+{ -+ if ((gpio_request(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, "ENC28J60_IRQ") == 0) && -+ (gpio_direction_input(OMAP3BEAGLE_GPIO_ENC28J60_IRQ) == 0)) { -+ gpio_export(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, 0); -+ omap3beagle_zippy_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_ENC28J60_IRQ); -+ irq_set_irq_type(omap3beagle_zippy_spi_board_info[0].irq, IRQ_TYPE_EDGE_FALLING); -+ } else { -+ printk(KERN_ERR "could not obtain gpio for ENC28J60_IRQ\n"); -+ return; -+ } -+ -+ spi_register_board_info(omap3beagle_zippy_spi_board_info, -+ ARRAY_SIZE(omap3beagle_zippy_spi_board_info)); -+} -+ -+#else -+static inline void __init omap3beagle_enc28j60_init(void) { return; } -+#endif -+ -+#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE) -+ -+#include -+#include -+ -+#define OMAP3BEAGLE_GPIO_KS8851_IRQ 157 -+ -+static struct omap2_mcspi_device_config ks8851_spi_chip_info = { -+ .turbo_mode = 0, -+ .single_channel = 1, /* 0: slave, 1: master */ -+}; -+ -+static struct spi_board_info omap3beagle_zippy2_spi_board_info[] __initdata = { -+ { -+ .modalias = "ks8851", -+ .bus_num = 4, -+ .chip_select = 0, -+ .max_speed_hz = 36000000, -+ .controller_data = &ks8851_spi_chip_info, -+ }, -+}; -+ -+static void __init omap3beagle_ks8851_init(void) -+{ -+ if ((gpio_request(OMAP3BEAGLE_GPIO_KS8851_IRQ, "KS8851_IRQ") == 0) && -+ (gpio_direction_input(OMAP3BEAGLE_GPIO_KS8851_IRQ) == 0)) { -+ gpio_export(OMAP3BEAGLE_GPIO_KS8851_IRQ, 0); -+ omap3beagle_zippy2_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_KS8851_IRQ); -+ irq_set_irq_type(omap3beagle_zippy2_spi_board_info[0].irq, IRQ_TYPE_EDGE_FALLING); -+ } else { -+ printk(KERN_ERR "could not obtain gpio for KS8851_IRQ\n"); -+ return; -+ } -+ -+ spi_register_board_info(omap3beagle_zippy2_spi_board_info, -+ ARRAY_SIZE(omap3beagle_zippy2_spi_board_info)); -+} -+ -+#else -+static inline void __init omap3beagle_ks8851_init(void) { return; } -+#endif -+ - static struct mtd_partition omap3beagle_nand_partitions[] = { - /* All the partition sizes are listed in terms of NAND block size */ - { -@@ -272,6 +434,12 @@ static struct omap2_hsmmc_info mmc[] = { - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, - .gpio_wp = 29, - }, -+ { -+ .mmc = 2, -+ .caps = MMC_CAP_4_BIT_DATA, -+ .transceiver = true, -+ .ocr_mask = 0x00100000, /* 3.3V */ -+ }, - {} /* Terminator */ - }; - -@@ -301,11 +469,25 @@ static int beagle_twl_gpio_setup(struct device *dev, - } - /* gpio + 0 is "mmc0_cd" (input/IRQ) */ - mmc[0].gpio_cd = gpio + 0; -+#if defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE) -+ if(!strcmp(expansionboard_name, "bbtoys-wifi")) { -+ omap2_hsmmc_init(mmcbbt); -+ /* link regulators to MMC adapters */ -+ beagle_vmmc1_supply.dev = mmcbbt[0].dev; -+ beagle_vsim_supply.dev = mmcbbt[0].dev; -+ } else { -+ omap2_hsmmc_init(mmc); -+ /* link regulators to MMC adapters */ -+ beagle_vmmc1_supply.dev = mmc[0].dev; -+ beagle_vsim_supply.dev = mmc[0].dev; -+ } -+#else - omap2_hsmmc_init(mmc); - - /* link regulators to MMC adapters */ - beagle_vmmc1_supply.dev = mmc[0].dev; - beagle_vsim_supply.dev = mmc[0].dev; -+#endif - - /* REVISIT: need ehci-omap hooks for external VBUS - * power switch and overcurrent detect -@@ -466,7 +648,7 @@ static struct twl4030_platform_data beagle_twldata = { - .vpll2 = &beagle_vpll2, - }; - --static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { -+static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = { - { - I2C_BOARD_INFO("twl4030", 0x48), - .flags = I2C_CLIENT_WAKE, -@@ -481,10 +663,24 @@ static struct i2c_board_info __initdata beagle_i2c_eeprom[] = { - }, - }; - -+#if defined(CONFIG_RTC_DRV_DS1307) || \ -+ defined(CONFIG_RTC_DRV_DS1307_MODULE) -+ -+static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = { -+ { -+ I2C_BOARD_INFO("ds1307", 0x68), -+ }, -+}; -+#else -+static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {}; -+#endif -+ - static int __init omap3_beagle_i2c_init(void) - { -- omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo, -- ARRAY_SIZE(beagle_i2c_boardinfo)); -+ omap_register_i2c_bus(1, 2600, beagle_i2c1_boardinfo, -+ ARRAY_SIZE(beagle_i2c1_boardinfo)); -+ omap_register_i2c_bus(2, 400, beagle_i2c2_boardinfo, -+ ARRAY_SIZE(beagle_i2c2_boardinfo)); - /* Bus 3 is attached to the DVI port where devices like the pico DLP - * projector don't work reliably with 400kHz */ - omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom)); -@@ -627,6 +823,15 @@ static struct omap_musb_board_data musb_board_data = { - .power = 100, - }; - -+static int __init expansionboard_setup(char *str) -+{ -+ if (!str) -+ return -EINVAL; -+ strncpy(expansionboard_name, str, 16); -+ printk(KERN_INFO "Beagle expansionboard: %s\n", expansionboard_name); -+ return 0; -+} -+ - static void __init beagle_opp_init(void) - { - int r = 0; -@@ -693,6 +898,65 @@ static void __init omap3_beagle_init(void) - /* REVISIT leave DVI powered down until it's needed ... */ - gpio_direction_output(170, true); - -+ if(!strcmp(expansionboard_name, "zippy")) -+ { -+ printk(KERN_INFO "Beagle expansionboard: initializing enc28j60\n"); -+ omap3beagle_enc28j60_init(); -+ printk(KERN_INFO "Beagle expansionboard: assigning GPIO 141 and 162 to MMC1\n"); -+ mmc[1].gpio_wp = 141; -+ mmc[1].gpio_cd = 162; -+ } -+ -+ if(!strcmp(expansionboard_name, "zippy2")) -+ { -+ printk(KERN_INFO "Beagle expansionboard: initializing ks_8851\n"); -+ omap3beagle_ks8851_init(); -+ printk(KERN_INFO "Beagle expansionboard: assigning GPIO 141 and 162 to MMC1\n"); -+ mmc[1].gpio_wp = 141; -+ mmc[1].gpio_cd = 162; -+ } -+ -+ if(!strcmp(expansionboard_name, "trainer")) -+ { -+ printk(KERN_INFO "Beagle expansionboard: exporting GPIOs 130-141,162 to userspace\n"); -+ gpio_request(130, "sysfs"); -+ gpio_export(130, 1); -+ gpio_request(131, "sysfs"); -+ gpio_export(131, 1); -+ gpio_request(132, "sysfs"); -+ gpio_export(132, 1); -+ gpio_request(133, "sysfs"); -+ gpio_export(133, 1); -+ gpio_request(134, "sysfs"); -+ gpio_export(134, 1); -+ gpio_request(135, "sysfs"); -+ gpio_export(135, 1); -+ gpio_request(136, "sysfs"); -+ gpio_export(136, 1); -+ gpio_request(137, "sysfs"); -+ gpio_export(137, 1); -+ gpio_request(138, "sysfs"); -+ gpio_export(138, 1); -+ gpio_request(139, "sysfs"); -+ gpio_export(139, 1); -+ gpio_request(140, "sysfs"); -+ gpio_export(140, 1); -+ gpio_request(141, "sysfs"); -+ gpio_export(141, 1); -+ gpio_request(162, "sysfs"); -+ gpio_export(162, 1); -+ } -+ -+ if(!strcmp(expansionboard_name, "bbtoys-wifi")) -+ { -+ if (wl12xx_set_platform_data(&omap_beagle_wlan_data)) -+ pr_err("error setting wl12xx data\n"); -+ printk(KERN_INFO "Beagle expansionboard: registering wl12xx bt platform device\n"); -+ platform_device_register(&wl12xx_device); -+ printk(KERN_INFO "Beagle expansionboard: registering wl12xx wifi platform device\n"); -+ platform_device_register(&omap_vwlan_device); -+ } -+ - usb_musb_init(&musb_board_data); - usbhs_init(&usbhs_bdata); - omap3beagle_flash_init(); -@@ -705,6 +969,8 @@ static void __init omap3_beagle_init(void) - beagle_opp_init(); - } - -+early_param("buddy", expansionboard_setup); -+ - MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") - /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */ - .boot_params = 0x80000100, --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0003-OMAP3-beagle-add-MADC-support.patch b/recipes-kernel/linux/linux-omap-2.6.39/beagle/0003-OMAP3-beagle-add-MADC-support.patch deleted file mode 100644 index 79097dbf..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0003-OMAP3-beagle-add-MADC-support.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 91e701f3287923d11dd295b6a62186909e362503 Mon Sep 17 00:00:00 2001 -From: Koen Kooi -Date: Sat, 21 May 2011 16:18:30 +0200 -Subject: [PATCH 3/7] OMAP3: beagle: add MADC support - -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/board-omap3beagle.c | 5 +++++ - 1 files changed, 5 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c -index db285e1..da4ba50 100644 ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -634,6 +634,10 @@ static struct twl4030_codec_data beagle_codec_data = { - .audio = &beagle_audio_data, - }; - -+static struct twl4030_madc_platform_data beagle_madc_data = { -+ .irq_line = 1, -+}; -+ - static struct twl4030_platform_data beagle_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, -@@ -642,6 +646,7 @@ static struct twl4030_platform_data beagle_twldata = { - .usb = &beagle_usb_data, - .gpio = &beagle_gpio_data, - .codec = &beagle_codec_data, -+ .madc = &beagle_madc_data, - .vmmc1 = &beagle_vmmc1, - .vsim = &beagle_vsim, - .vdac = &beagle_vdac, --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0004-OMAP3-beagle-add-regulators-for-camera-interface.patch b/recipes-kernel/linux/linux-omap-2.6.39/beagle/0004-OMAP3-beagle-add-regulators-for-camera-interface.patch deleted file mode 100644 index 29e99569..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0004-OMAP3-beagle-add-regulators-for-camera-interface.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 9d7f46abab88c74e674461a2f4e9ab35b524a6ef Mon Sep 17 00:00:00 2001 -From: Koen Kooi -Date: Wed, 25 May 2011 08:56:06 +0200 -Subject: [PATCH 4/7] OMAP3: beagle: add regulators for camera interface - -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/board-omap3beagle.c | 50 +++++++++++++++++++++++++++++++ - 1 files changed, 50 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c -index da4ba50..211cbdf 100644 ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -453,6 +453,44 @@ static struct regulator_consumer_supply beagle_vsim_supply = { - - static struct gpio_led gpio_leds[]; - -+static struct regulator_consumer_supply beagle_vaux3_supply = { -+ .supply = "cam_1v8", -+}; -+ -+static struct regulator_consumer_supply beagle_vaux4_supply = { -+ .supply = "cam_2v8", -+}; -+ -+/* VAUX3 for CAM_1V8 */ -+static struct regulator_init_data beagle_vaux3 = { -+ .constraints = { -+ .min_uV = 1800000, -+ .max_uV = 1800000, -+ .apply_uV = true, -+ .valid_modes_mask = REGULATOR_MODE_NORMAL -+ | REGULATOR_MODE_STANDBY, -+ .valid_ops_mask = REGULATOR_CHANGE_MODE -+ | REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = 1, -+ .consumer_supplies = &beagle_vaux3_supply, -+}; -+ -+/* VAUX4 for CAM_2V8 */ -+static struct regulator_init_data beagle_vaux4 = { -+ .constraints = { -+ .min_uV = 1800000, -+ .max_uV = 1800000, -+ .apply_uV = true, -+ .valid_modes_mask = REGULATOR_MODE_NORMAL -+ | REGULATOR_MODE_STANDBY, -+ .valid_ops_mask = REGULATOR_CHANGE_MODE -+ | REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = 1, -+ .consumer_supplies = &beagle_vaux4_supply, -+}; -+ - static int beagle_twl_gpio_setup(struct device *dev, - unsigned gpio, unsigned ngpio) - { -@@ -504,6 +542,16 @@ static int beagle_twl_gpio_setup(struct device *dev, - pr_err("%s: unable to configure EHCI_nOC\n", __func__); - } - -+ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { -+ /* -+ * Power on camera interface - only on pre-production, not -+ * needed on production boards -+ */ -+ gpio_request(gpio + 2, "CAM_EN"); -+ gpio_direction_output(gpio + 2, 1); -+ } -+ -+ - /* - * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active - * high / others active low) -@@ -651,6 +699,8 @@ static struct twl4030_platform_data beagle_twldata = { - .vsim = &beagle_vsim, - .vdac = &beagle_vdac, - .vpll2 = &beagle_vpll2, -+ .vaux3 = &beagle_vaux3, -+ .vaux4 = &beagle_vaux4, - }; - - static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = { --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0005-OMAP3-beagle-HACK-add-in-1GHz-OPP.patch b/recipes-kernel/linux/linux-omap-2.6.39/beagle/0005-OMAP3-beagle-HACK-add-in-1GHz-OPP.patch deleted file mode 100644 index 8b65b76e..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0005-OMAP3-beagle-HACK-add-in-1GHz-OPP.patch +++ /dev/null @@ -1,31 +0,0 @@ -From aa93263ed7827e33148396656b7e7ab4579509a5 Mon Sep 17 00:00:00 2001 -From: Koen Kooi -Date: Wed, 25 May 2011 08:57:40 +0200 -Subject: [PATCH 5/7] OMAP3: beagle: HACK! add in 1GHz OPP - -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/board-omap3beagle.c | 2 ++ - 1 files changed, 2 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c -index 211cbdf..221bfda 100644 ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -911,11 +911,13 @@ static void __init beagle_opp_init(void) - /* Enable MPU 1GHz and lower opps */ - dev = &mh->od->pdev.dev; - r = opp_enable(dev, 800000000); -+ r |= opp_enable(dev, 1000000000); - /* TODO: MPU 1GHz needs SR and ABB */ - - /* Enable IVA 800MHz and lower opps */ - dev = &dh->od->pdev.dev; - r |= opp_enable(dev, 660000000); -+ r |= opp_enable(dev, 800000000); - /* TODO: DSP 800MHz needs SR and ABB */ - if (r) { - pr_err("%s: failed to enable higher opp %d\n", --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0006-OMAP3-BEAGLE-fix-RTC.patch b/recipes-kernel/linux/linux-omap-2.6.39/beagle/0006-OMAP3-BEAGLE-fix-RTC.patch deleted file mode 100644 index 76443d94..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0006-OMAP3-BEAGLE-fix-RTC.patch +++ /dev/null @@ -1,27 +0,0 @@ -From dd2c7ba245ec1b17e3d323a6c4a1cad9697dbbbe Mon Sep 17 00:00:00 2001 -From: Koen Kooi -Date: Wed, 15 Jun 2011 16:25:50 +0200 -Subject: [PATCH 6/7] OMAP3: BEAGLE: fix RTC - -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/board-omap3beagle.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c -index 221bfda..61564a4 100644 ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -941,6 +941,9 @@ static void __init omap3_beagle_init(void) - omap3_beagle_init_rev(); - omap3_beagle_i2c_init(); - -+ /* Ensure msecure is mux'd to be able to set the RTC. */ -+ omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH); -+ - if (cpu_is_omap3630()) { - gpio_buttons[0].gpio = 4; - } --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0007-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch b/recipes-kernel/linux/linux-omap-2.6.39/beagle/0007-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch deleted file mode 100644 index 8cd314c6..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0007-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch +++ /dev/null @@ -1,33 +0,0 @@ -From bd0b2f97c48aa6aac0c6a494f1c6ba5af5de486b Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Mon, 18 Jul 2011 23:13:41 -0500 -Subject: [PATCH] omap_hsmmc: Set dto to max value of 14 to avoid SD Card timeouts - -This fixes MMC errors due to timeouts on certain SD Cards following suggestions -to set dto to 14 by Jason Kridner and Steven Kipisz - -Details of the issue: -http://talk.maemo.org/showthread.php?p=1000707#post1000707 - -This fix was originally proposed by Sukumar Ghoral of TI. ---- - drivers/mmc/host/omap_hsmmc.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index 9646a75..7443647 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -1049,6 +1049,9 @@ static void set_data_timeout(struct omap_hsmmc_host *host, - dto = 14; - } - -+ /* Set dto to max value of 14 to avoid SD Card timeouts */ -+ dto = 14; -+ - reg &= ~DTO_MASK; - reg |= dto << DTO_SHIFT; - OMAP_HSMMC_WRITE(host->base, SYSCTL, reg); --- -1.7.0.4 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0007-omap3-beagle-Use-GPTIMERi-1-for-clockevents.patch b/recipes-kernel/linux/linux-omap-2.6.39/beagle/0007-omap3-beagle-Use-GPTIMERi-1-for-clockevents.patch deleted file mode 100644 index d5a4cf67..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagle/0007-omap3-beagle-Use-GPTIMERi-1-for-clockevents.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 101b0aedf8152711847e2f9f347d267a3ac7f287 Mon Sep 17 00:00:00 2001 -From: Sanjeev Premi -Date: Fri, 24 Jun 2011 16:23:45 +0000 -Subject: [PATCH 7/7] omap3: beagle: Use GPTIMERi 1 for clockevents - -The current selection of the GPTIMER on was result of -a hardware issue in early versions of the Beagleboards -(Ax and B1 thru B4). [1] [2] - -Its been long since the hardware issue has been fixed. -This patch uses GPTIMER 1 for all newer board revisions -incl. Beagleboard XM. - - [1] http://thread.gmane.org/gmane.comp.hardware.beagleboard.general/91 - [2] Errata #7 at http://elinux.org/BeagleBoard#Errata - -Signed-off-by: Sanjeev Premi -Cc: Paul Walmsley -Reviewed-by: Paul Walmsley ---- - arch/arm/mach-omap2/board-omap3beagle.c | 5 ++++- - 1 files changed, 4 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c -index 61564a4..20d5912 100644 ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -806,7 +806,10 @@ static void __init omap3_beagle_init_irq(void) - { - omap_init_irq(); - #ifdef CONFIG_OMAP_32K_TIMER -- omap2_gp_clockevent_set_gptimer(12); -+ if (omap3_beagle_version == OMAP3BEAGLE_BOARD_AXBX) -+ omap2_gp_clockevent_set_gptimer(12); -+ else -+ omap2_gp_clockevent_set_gptimer(1); - #endif - } - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagleboard/configs/stock b/recipes-kernel/linux/linux-omap-2.6.39/beagleboard/configs/stock deleted file mode 100644 index dd288e24..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagleboard/configs/stock +++ /dev/null @@ -1,3490 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux/arm 2.6.39 Kernel Configuration -# Fri May 20 13:11:13 2011 -# -CONFIG_ARM=y -CONFIG_HAVE_PWM=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_HAVE_SCHED_CLOCK=y -CONFIG_GENERIC_GPIO=y -# CONFIG_ARCH_USES_GETTIMEOFFSET is not set -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_KTIME_SCALAR=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_ARCH_HAS_CPUFREQ=y -CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_VECTORS_BASE=0xffff0000 -# CONFIG_ARM_PATCH_PHYS_VIRT is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_CONSTRUCTORS=y -CONFIG_HAVE_IRQ_WORK=y -CONFIG_IRQ_WORK=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_LZO is not set -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -CONFIG_FHANDLE=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y -# CONFIG_AUDIT is not set -CONFIG_HAVE_GENERIC_HARDIRQS=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_HARDIRQS=y -CONFIG_HAVE_SPARSE_IRQ=y -CONFIG_GENERIC_IRQ_SHOW=y -# CONFIG_SPARSE_IRQ is not set - -# -# RCU Subsystem -# -CONFIG_TREE_PREEMPT_RCU=y -# CONFIG_TINY_RCU is not set -# CONFIG_TINY_PREEMPT_RCU is not set -CONFIG_PREEMPT_RCU=y -# CONFIG_RCU_TRACE is not set -CONFIG_RCU_FANOUT=32 -# CONFIG_RCU_FANOUT_EXACT is not set -# CONFIG_TREE_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=16 -CONFIG_CGROUPS=y -# CONFIG_CGROUP_DEBUG is not set -CONFIG_CGROUP_NS=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -CONFIG_CGROUP_MEM_RES_CTLR=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y -CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -# CONFIG_BLK_CGROUP is not set -# CONFIG_NAMESPACES is not set -CONFIG_SCHED_AUTOGROUP=y -CONFIG_MM_OWNER=y -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_EXPERT=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_EMBEDDED=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_PERF_USE_VMALLOC=y - -# -# Kernel Performance Events And Counters -# -CONFIG_PERF_EVENTS=y -# CONFIG_PERF_COUNTERS is not set -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -CONFIG_VM_EVENT_COUNTERS=y -# CONFIG_COMPAT_BRK is not set -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_HW_BREAKPOINT=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_BLOCK=y -CONFIG_LBDAF=y -CONFIG_BLK_DEV_BSG=y -# CONFIG_BLK_DEV_INTEGRITY 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_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -# CONFIG_INLINE_SPIN_UNLOCK is not set -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -# CONFIG_INLINE_READ_UNLOCK is not set -# CONFIG_INLINE_READ_UNLOCK_BH is not set -# CONFIG_INLINE_READ_UNLOCK_IRQ is not set -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -# CONFIG_INLINE_WRITE_UNLOCK is not set -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -# CONFIG_MUTEX_SPIN_ON_OWNER is not set -CONFIG_FREEZER=y - -# -# System Type -# -CONFIG_MMU=y -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_VEXPRESS is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CNS3XXX 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_MXC is not set -# CONFIG_ARCH_MXS is not set -# CONFIG_ARCH_STMP3XXX is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_KIRKWOOD is not set -# CONFIG_ARCH_LOKI is not set -# CONFIG_ARCH_LPC32XX is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_NUC93X is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_MSM is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_S5P64X0 is not set -# CONFIG_ARCH_S5P6442 is not set -# CONFIG_ARCH_S5PC100 is not set -# CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_EXYNOS4 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_TCC_926 is not set -# CONFIG_ARCH_U300 is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_NOMADIK is not set -# CONFIG_ARCH_DAVINCI is not set -CONFIG_ARCH_OMAP=y -# CONFIG_PLAT_SPEAR is not set -# CONFIG_ARCH_VT8500 is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_KEYBOARD_GPIO_POLLED is not set - -# -# TI OMAP Common Features -# -CONFIG_ARCH_OMAP_OTG=y -# CONFIG_ARCH_OMAP1 is not set -CONFIG_ARCH_OMAP2PLUS=y - -# -# OMAP Feature Selections -# -CONFIG_OMAP_SMARTREFLEX=y -CONFIG_OMAP_SMARTREFLEX_CLASS3=y -CONFIG_OMAP_RESET_CLOCKS=y -# CONFIG_OMAP_MUX is not set -CONFIG_OMAP_MCBSP=y -CONFIG_OMAP_MBOX_FWK=m -CONFIG_OMAP_MBOX_KFIFO_SIZE=256 -CONFIG_OMAP_IOMMU=y -CONFIG_OMAP_IOMMU_DEBUG=m -CONFIG_OMAP_32K_TIMER=y -# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set -CONFIG_OMAP_32K_TIMER_HZ=128 -CONFIG_OMAP_DM_TIMER=y -# CONFIG_OMAP_PM_NONE is not set -CONFIG_OMAP_PM_NOOP=y - -# -# TI OMAP2/3/4 Specific Features -# -CONFIG_ARCH_OMAP2PLUS_TYPICAL=y -# CONFIG_ARCH_OMAP2 is not set -CONFIG_ARCH_OMAP3=y -# CONFIG_ARCH_OMAP4 is not set -CONFIG_SOC_OMAP3430=y -# CONFIG_SOC_OMAPTI816X is not set -CONFIG_OMAP_PACKAGE_CBB=y - -# -# OMAP Board Type -# -CONFIG_MACH_OMAP3_BEAGLE=y -# CONFIG_MACH_DEVKIT8000 is not set -# CONFIG_MACH_OMAP_LDP is not set -# CONFIG_MACH_OMAP3530_LV_SOM is not set -# CONFIG_MACH_OMAP3_TORPEDO is not set -CONFIG_MACH_OVERO=y -CONFIG_MACH_OMAP3EVM=y -# CONFIG_MACH_OMAP3517EVM is not set -# CONFIG_MACH_CRANEBOARD is not set -# CONFIG_MACH_OMAP3_PANDORA is not set -CONFIG_MACH_OMAP3_TOUCHBOOK=y -# CONFIG_MACH_OMAP_3430SDP is not set -# CONFIG_MACH_NOKIA_RM680 is not set -# CONFIG_MACH_NOKIA_RX51 is not set -CONFIG_MACH_OMAP_ZOOM2=y -# CONFIG_MACH_OMAP_ZOOM3 is not set -# CONFIG_MACH_CM_T35 is not set -# CONFIG_MACH_CM_T3517 is not set -# CONFIG_MACH_IGEP0020 is not set -# CONFIG_MACH_IGEP0030 is not set -# CONFIG_MACH_SBC3530 is not set -# CONFIG_MACH_OMAP_3630SDP is not set -# CONFIG_OMAP3_EMU is not set -# CONFIG_OMAP3_SDRC_AC_TIMING is not set - -# -# System MMU -# - -# -# Processor Type -# -CONFIG_CPU_V7=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -# CONFIG_SWP_EMULATE is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_DMA_MEM_BUFFERABLE=y -CONFIG_ARM_ERRATA_430973=y -# CONFIG_ARM_ERRATA_458693 is not set -# CONFIG_ARM_ERRATA_460075 is not set -# CONFIG_ARM_ERRATA_743622 is not set -# CONFIG_ARM_ERRATA_754322 is not set - -# -# Bus support -# -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_HZ=128 -# CONFIG_THUMB2_KERNEL is not set -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_HIGHMEM is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_COMPACTION=y -CONFIG_MIGRATION=y -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_NEED_PER_CPU_KM=y -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_LEDS=y -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_UACCESS_WITH_MEMCPY is not set -# CONFIG_SECCOMP is not set -# CONFIG_CC_STACKPROTECTOR is not set -# CONFIG_DEPRECATED_PARAM_STRUCT is not set - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE=" debug " -# CONFIG_CMDLINE_FORCE is not set -# CONFIG_XIP_KERNEL is not set -CONFIG_KEXEC=y -CONFIG_ATAGS_PROC=y -# CONFIG_CRASH_DUMP is not set -# CONFIG_AUTO_ZRELADDR is not set - -# -# CPU Power Management -# -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -CONFIG_CPU_FREQ_DEBUG=y -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_STAT_DETAILS=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_CPU_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_NEON=y - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_HAVE_AOUT=y -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_MISC=y - -# -# Power management options -# -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_PM_SLEEP=y -CONFIG_PM_RUNTIME=y -CONFIG_PM=y -CONFIG_PM_DEBUG=y -# CONFIG_PM_VERBOSE is not set -# CONFIG_PM_ADVANCED_DEBUG is not set -# CONFIG_PM_TEST_SUSPEND is not set -CONFIG_CAN_PM_TRACE=y -# CONFIG_APM_EMULATION is not set -CONFIG_ARCH_HAS_OPP=y -CONFIG_PM_OPP=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM=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=m -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_ROUTE_CLASSID=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE_DEMUX=m -CONFIG_NET_IPGRE=m -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_LRO=y -CONFIG_INET_DIAG=m -CONFIG_INET_TCP_DIAG=m -CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_BIC=m -CONFIG_TCP_CONG_CUBIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m -CONFIG_TCP_CONG_HSTCP=m -CONFIG_TCP_CONG_HYBLA=m -CONFIG_TCP_CONG_VEGAS=m -CONFIG_TCP_CONG_SCALABLE=m -CONFIG_TCP_CONG_LP=m -CONFIG_TCP_CONG_VENO=m -CONFIG_TCP_CONG_YEAH=m -CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_DEFAULT_CUBIC=y -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_MIP6=m -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_SIT=m -# CONFIG_IPV6_SIT_6RD is not set -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=m -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_IPV6_MROUTE=y -CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -# CONFIG_IPV6_PIMSM_V2 is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETWORK_PHY_TIMESTAMPING=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=y - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_ZONES=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_TIMESTAMP=y -CONFIG_NF_CT_PROTO_DCCP=m -CONFIG_NF_CT_PROTO_GRE=m -CONFIG_NF_CT_PROTO_SCTP=m -CONFIG_NF_CT_PROTO_UDPLITE=m -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -CONFIG_NF_CONNTRACK_BROADCAST=m -CONFIG_NF_CONNTRACK_NETBIOS_NS=m -CONFIG_NF_CONNTRACK_SNMP=m -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CT_NETLINK=m -# CONFIG_NETFILTER_TPROXY is not set -CONFIG_NETFILTER_XTABLES=m - -# -# Xtables combined modules -# -CONFIG_NETFILTER_XT_MARK=m -CONFIG_NETFILTER_XT_CONNMARK=m -CONFIG_NETFILTER_XT_SET=m - -# -# Xtables targets -# -CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -CONFIG_NETFILTER_XT_TARGET_CT=m -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -CONFIG_NETFILTER_XT_TARGET_HL=m -CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -# CONFIG_NETFILTER_XT_TARGET_LED is not set -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -CONFIG_NETFILTER_XT_TARGET_RATEEST=m -CONFIG_NETFILTER_XT_TARGET_TEE=m -# CONFIG_NETFILTER_XT_TARGET_TRACE is not set -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set - -# -# Xtables matches -# -CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_CPU=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_HL=m -CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -CONFIG_NETFILTER_XT_MATCH_IPVS=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -# CONFIG_NETFILTER_XT_MATCH_OSF is not set -CONFIG_NETFILTER_XT_MATCH_OWNER=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_RATEEST=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_TIME=m -CONFIG_NETFILTER_XT_MATCH_U32=m -CONFIG_IP_SET=m -CONFIG_IP_SET_MAX=256 -# CONFIG_IP_SET_BITMAP_IP is not set -# CONFIG_IP_SET_BITMAP_IPMAC is not set -# CONFIG_IP_SET_BITMAP_PORT is not set -# CONFIG_IP_SET_HASH_IP is not set -# CONFIG_IP_SET_HASH_IPPORT is not set -# CONFIG_IP_SET_HASH_IPPORTIP is not set -# CONFIG_IP_SET_HASH_IPPORTNET is not set -# CONFIG_IP_SET_HASH_NET is not set -# CONFIG_IP_SET_HASH_NETPORT is not set -# CONFIG_IP_SET_LIST_SET is not set -CONFIG_IP_VS=m -CONFIG_IP_VS_IPV6=y -CONFIG_IP_VS_DEBUG=y -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_AH_ESP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y -# CONFIG_IP_VS_PROTO_SCTP is not set - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m -CONFIG_IP_VS_NFCT=y -CONFIG_IP_VS_PE_SIP=m - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=m -CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m -CONFIG_NF_NAT_PROTO_DCCP=m -CONFIG_NF_NAT_PROTO_GRE=m -CONFIG_NF_NAT_PROTO_UDPLITE=m -CONFIG_NF_NAT_PROTO_SCTP=m -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_IRC=m -CONFIG_NF_NAT_TFTP=m -CONFIG_NF_NAT_AMANDA=m -CONFIG_NF_NAT_PPTP=m -CONFIG_NF_NAT_H323=m -CONFIG_NF_NAT_SIP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# IPv6: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV6=m -CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_AH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_MH=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -# CONFIG_BRIDGE_NF_EBTABLES is not set -CONFIG_IP_DCCP=m -CONFIG_INET_DCCP_DIAG=m - -# -# DCCP CCIDs Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP_CCID2_DEBUG is not set -CONFIG_IP_DCCP_CCID3=y -# CONFIG_IP_DCCP_CCID3_DEBUG is not set -CONFIG_IP_DCCP_TFRC_LIB=y - -# -# DCCP Kernel Hacking -# -# CONFIG_IP_DCCP_DEBUG is not set -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -# CONFIG_RDS is not set -CONFIG_TIPC=m -# CONFIG_TIPC_ADVANCED is not set -# CONFIG_TIPC_DEBUG is not set -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -# CONFIG_ATM_CLIP_NO_ICMP is not set -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -# CONFIG_ATM_BR2684_IPFILTER is not set -CONFIG_L2TP=m -CONFIG_L2TP_DEBUGFS=m -CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=m -CONFIG_L2TP_ETH=m -CONFIG_STP=m -CONFIG_GARP=m -CONFIG_BRIDGE=m -CONFIG_BRIDGE_IGMP_SNOOPING=y -# CONFIG_NET_DSA is not set -CONFIG_VLAN_8021Q=m -CONFIG_VLAN_8021Q_GVRP=y -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -CONFIG_WAN_ROUTER=m -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_MULTIQ=m -CONFIG_NET_SCH_RED=m -# CONFIG_NET_SCH_SFB is not set -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_DRR=m -CONFIG_NET_SCH_MQPRIO=m -CONFIG_NET_SCH_CHOKE=m - -# -# Classification -# -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_CLS_U32_PERF=y -CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_FLOW=m -CONFIG_NET_CLS_CGROUP=m -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_CLS_ACT is not set -CONFIG_NET_CLS_IND=y -CONFIG_NET_SCH_FIFO=y -# CONFIG_DCB is not set -CONFIG_DNS_RESOLVER=y -# CONFIG_BATMAN_ADV is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -CONFIG_CAN=m -CONFIG_CAN_RAW=m -CONFIG_CAN_BCM=m - -# -# CAN Device Drivers -# -CONFIG_CAN_VCAN=m -CONFIG_CAN_SLCAN=m -# CONFIG_CAN_DEV is not set -# CONFIG_CAN_DEBUG_DEVICES is not set -CONFIG_IRDA=m - -# -# IrDA protocols -# -CONFIG_IRLAN=m -CONFIG_IRNET=m -CONFIG_IRCOMM=m -CONFIG_IRDA_ULTRA=y - -# -# IrDA options -# -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -CONFIG_IRDA_DEBUG=y - -# -# Infrared-port device drivers -# - -# -# SIR device drivers -# -CONFIG_IRTTY_SIR=m - -# -# Dongle support -# -CONFIG_DONGLE=y -CONFIG_ESI_DONGLE=m -CONFIG_ACTISYS_DONGLE=m -CONFIG_TEKRAM_DONGLE=m -CONFIG_TOIM3232_DONGLE=m -CONFIG_LITELINK_DONGLE=m -CONFIG_MA600_DONGLE=m -CONFIG_GIRBIL_DONGLE=m -CONFIG_MCP2120_DONGLE=m -CONFIG_OLD_BELKIN_DONGLE=m -# CONFIG_ACT200L_DONGLE is not set -CONFIG_KINGSUN_DONGLE=m -CONFIG_KSDAZZLE_DONGLE=m -CONFIG_KS959_DONGLE=m - -# -# FIR device drivers -# -CONFIG_USB_IRDA=m -CONFIG_SIGMATEL_FIR=m -CONFIG_MCS_FIR=m -CONFIG_BT=m -CONFIG_BT_L2CAP=y -CONFIG_BT_SCO=y -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=m - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIBTUSB=m -CONFIG_BT_HCIBTSDIO=m -CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_ATH3K=y -CONFIG_BT_HCIUART_LL=y -CONFIG_BT_HCIBCM203X=m -CONFIG_BT_HCIBPA10X=m -CONFIG_BT_HCIBFUSB=m -# CONFIG_BT_HCIVHCI is not set -# CONFIG_BT_MRVL is not set -CONFIG_BT_ATH3K=m -CONFIG_BT_WILINK=m -CONFIG_AF_RXRPC=m -# CONFIG_AF_RXRPC_DEBUG is not set -# CONFIG_RXKAD is not set -CONFIG_FIB_RULES=y -CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y -CONFIG_WEXT_CORE=y -CONFIG_WEXT_PROC=y -CONFIG_WEXT_SPY=y -CONFIG_WEXT_PRIV=y -CONFIG_CFG80211=m -CONFIG_NL80211_TESTMODE=y -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -# CONFIG_CFG80211_REG_DEBUG is not set -CONFIG_CFG80211_DEFAULT_PS=y -# CONFIG_CFG80211_DEBUGFS is not set -# CONFIG_CFG80211_INTERNAL_REGDB is not set -CONFIG_CFG80211_WEXT=y -CONFIG_WIRELESS_EXT_SYSFS=y -CONFIG_LIB80211=y -CONFIG_LIB80211_CRYPT_WEP=m -CONFIG_LIB80211_CRYPT_CCMP=m -CONFIG_LIB80211_CRYPT_TKIP=m -# CONFIG_LIB80211_DEBUG is not set -CONFIG_MAC80211=m -CONFIG_MAC80211_HAS_RC=y -CONFIG_MAC80211_RC_PID=y -# CONFIG_MAC80211_RC_MINSTREL is not set -CONFIG_MAC80211_RC_DEFAULT_PID=y -CONFIG_MAC80211_RC_DEFAULT="pid" -# CONFIG_MAC80211_MESH is not set -CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -CONFIG_WIMAX=m -CONFIG_WIMAX_DEBUG_LEVEL=8 -CONFIG_RFKILL=m -CONFIG_RFKILL_LEDS=y -CONFIG_RFKILL_INPUT=y -CONFIG_NET_9P=m -# CONFIG_NET_9P_DEBUG is not set -# CONFIG_CAIF is not set -CONFIG_CEPH_LIB=m -# CONFIG_CEPH_LIB_PRETTYDEBUG is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_TESTS is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -CONFIG_SM_FTL=m -# CONFIG_MTD_OOPS is not set -CONFIG_MTD_SWAP=m - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_M25P80 is not set -# CONFIG_MTD_SST25L is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -CONFIG_MTD_NAND_ECC=y -# CONFIG_MTD_NAND_ECC_SMC is not set -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_BCH is not set -# CONFIG_MTD_SM_COMMON is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -# CONFIG_MTD_NAND_GPIO is not set -CONFIG_MTD_NAND_OMAP2=y -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_NANDSIM is not set -CONFIG_MTD_NAND_PLATFORM=y -# CONFIG_MTD_ALAUDA is not set -# CONFIG_MTD_ONENAND is not set - -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MTD_UBI_BEB_RESERVE=1 -# CONFIG_MTD_UBI_GLUEBI is not set -# CONFIG_MTD_UBI_DEBUG is not set -# 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_CRYPTOLOOP=m - -# -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected -# -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB 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=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MG_DISK is not set -# CONFIG_BLK_DEV_RBD is not set -# CONFIG_SENSORS_LIS3LV02D is not set -CONFIG_MISC_DEVICES=y -# CONFIG_AD525X_DPOT is not set -# CONFIG_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=m -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -CONFIG_HMC6352=m -# CONFIG_DS1682 is not set -# CONFIG_TI_DAC7512 is not set -CONFIG_BMP085=m -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -CONFIG_EEPROM_AT24=m -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -CONFIG_EEPROM_93CX6=y -CONFIG_IWMC3200TOP=m -# CONFIG_IWMC3200TOP_DEBUG is not set -# CONFIG_IWMC3200TOP_DEBUGFS is not set - -# -# Texas Instruments shared transport line discipline -# -CONFIG_TI_ST=m -# CONFIG_SENSORS_LIS3_SPI is not set -# CONFIG_SENSORS_LIS3_I2C is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -CONFIG_RAID_ATTRS=m -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=y -CONFIG_CHR_DEV_SCH=m -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -CONFIG_SCSI_ISCSI_ATTRS=m -# 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=m -CONFIG_ISCSI_BOOT_SYSFS=m -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -# CONFIG_ATA is not set -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_RAID=m -# CONFIG_DM_LOG_USERSPACE is not set -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -# CONFIG_DM_MULTIPATH_QL is not set -# CONFIG_DM_MULTIPATH_ST is not set -CONFIG_DM_DELAY=m -# CONFIG_DM_UEVENT is not set -CONFIG_DM_FLAKEY=m -CONFIG_TARGET_CORE=m -CONFIG_TCM_IBLOCK=m -CONFIG_TCM_FILEIO=m -CONFIG_TCM_PSCSI=m -CONFIG_LOOPBACK_TARGET=m -# CONFIG_LOOPBACK_TARGET_CDB_DEBUG is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=m -CONFIG_BONDING=m -CONFIG_MACVLAN=m -CONFIG_MACVTAP=m -CONFIG_EQUALIZER=m -CONFIG_TUN=m -CONFIG_VETH=m -CONFIG_MII=y -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -CONFIG_BCM63XX_PHY=m -# 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=m -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -# CONFIG_AX88796 is not set -CONFIG_SMC91X=y -# CONFIG_TI_DAVINCI_EMAC is not set -CONFIG_TI_DAVINCI_MDIO=m -CONFIG_TI_DAVINCI_CPDMA=m -# CONFIG_DM9000 is not set -CONFIG_ENC28J60=y -# CONFIG_ENC28J60_WRITEVERIFY is not set -# CONFIG_ETHOC is not set -CONFIG_SMC911X=y -CONFIG_SMSC911X=y -# CONFIG_SMSC911X_ARCH_HOOKS is not set -# CONFIG_DNET is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -# CONFIG_B44 is not set -CONFIG_KS8842=m -CONFIG_KS8851=y -# CONFIG_KS8851_MLL is not set -# CONFIG_FTMAC100 is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set -CONFIG_WLAN=y -# CONFIG_LIBERTAS_THINFIRM is not set -CONFIG_AT76C50X_USB=m -CONFIG_USB_ZD1201=m -CONFIG_USB_NET_RNDIS_WLAN=m -CONFIG_RTL8187=m -CONFIG_RTL8187_LEDS=y -# CONFIG_MAC80211_HWSIM is not set -# CONFIG_ATH_COMMON is not set -CONFIG_B43=m -# CONFIG_B43_SDIO is not set -CONFIG_B43_PIO=y -CONFIG_B43_PHY_N=y -CONFIG_B43_PHY_LP=y -CONFIG_B43_LEDS=y -CONFIG_B43_HWRNG=y -# CONFIG_B43_DEBUG is not set -# CONFIG_B43LEGACY is not set -CONFIG_HOSTAP=m -CONFIG_HOSTAP_FIRMWARE=y -CONFIG_HOSTAP_FIRMWARE_NVRAM=y -# CONFIG_IWM is not set -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -# CONFIG_LIBERTAS_SDIO is not set -# CONFIG_LIBERTAS_SPI is not set -# CONFIG_LIBERTAS_DEBUG is not set -# CONFIG_LIBERTAS_MESH is not set -CONFIG_P54_COMMON=m -CONFIG_P54_USB=m -# CONFIG_P54_SPI is not set -CONFIG_P54_LEDS=y -CONFIG_RT2X00=m -CONFIG_RT2500USB=m -CONFIG_RT73USB=m -# CONFIG_RT2800USB is not set -CONFIG_RT2X00_LIB_USB=m -CONFIG_RT2X00_LIB=m -CONFIG_RT2X00_LIB_FIRMWARE=y -CONFIG_RT2X00_LIB_CRYPTO=y -CONFIG_RT2X00_LIB_LEDS=y -# CONFIG_RT2X00_DEBUG is not set -CONFIG_RTL8192CU=m -CONFIG_RTLWIFI=m -CONFIG_RTL8192C_COMMON=m -CONFIG_WL1251=m -CONFIG_WL1251_SPI=m -CONFIG_WL1251_SDIO=m -CONFIG_WL12XX_MENU=m -CONFIG_WL12XX=m -CONFIG_WL12XX_HT=y -CONFIG_WL12XX_SPI=m -CONFIG_WL12XX_SDIO=m -# CONFIG_WL12XX_SDIO_TEST is not set -CONFIG_WL12XX_PLATFORM_DATA=y -CONFIG_ZD1211RW=m -# CONFIG_ZD1211RW_DEBUG is not set - -# -# WiMAX Wireless Broadband devices -# -CONFIG_WIMAX_I2400M=m -CONFIG_WIMAX_I2400M_USB=m -CONFIG_WIMAX_I2400M_SDIO=m -CONFIG_WIMAX_IWMC3200_SDIO=y -CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 - -# -# USB Network Adapters -# -CONFIG_USB_CATC=y -CONFIG_USB_KAWETH=y -CONFIG_USB_PEGASUS=y -CONFIG_USB_RTL8150=y -CONFIG_USB_USBNET=y -CONFIG_USB_NET_AX8817X=y -CONFIG_USB_NET_CDCETHER=y -# CONFIG_USB_NET_CDC_EEM is not set -CONFIG_USB_NET_CDC_NCM=m -CONFIG_USB_NET_DM9601=y -CONFIG_USB_NET_SMSC75XX=m -CONFIG_USB_NET_SMSC95XX=y -CONFIG_USB_NET_GL620A=y -CONFIG_USB_NET_NET1080=y -CONFIG_USB_NET_PLUSB=y -CONFIG_USB_NET_MCS7830=y -CONFIG_USB_NET_RNDIS_HOST=y -CONFIG_USB_NET_CDC_SUBSET=y -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AN2720=y -CONFIG_USB_BELKIN=y -CONFIG_USB_ARMLINUX=y -CONFIG_USB_EPSON2888=y -CONFIG_USB_KC2190=y -CONFIG_USB_NET_ZAURUS=y -CONFIG_USB_NET_CX82310_ETH=m -CONFIG_USB_HSO=m -CONFIG_USB_NET_INT51X1=m -CONFIG_USB_IPHETH=m -CONFIG_USB_SIERRA_NET=m -CONFIG_USB_VL600=m -# CONFIG_WAN is not set -CONFIG_ATM_DRIVERS=y -# CONFIG_ATM_DUMMY is not set -# CONFIG_ATM_TCP is not set - -# -# CAIF transport drivers -# -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_PPTP=m -# CONFIG_PPPOATM is not set -CONFIG_PPPOL2TP=m -# CONFIG_SLIP is not set -CONFIG_SLHC=m -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_NETPOLL=y -CONFIG_NETPOLL_TRAP=y -CONFIG_NET_POLL_CONTROLLER=y -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=y -CONFIG_INPUT_POLLDEV=y -# CONFIG_INPUT_SPARSEKMAP is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV 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_ATKBD is not set -CONFIG_KEYBOARD_QT1070=m -CONFIG_KEYBOARD_QT2160=m -# CONFIG_KEYBOARD_LKKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_MAX7359 is not set -CONFIG_KEYBOARD_MCS=m -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OPENCORES is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_TWL4030 is not set -# CONFIG_KEYBOARD_XTKBD is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_ELANTECH is not set -# CONFIG_MOUSE_PS2_SENTELIC is not set -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_MOUSE_GPIO is not set -# CONFIG_MOUSE_SYNAPTICS_I2C is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -CONFIG_INPUT_MISC=y -CONFIG_INPUT_AD714X=m -CONFIG_INPUT_AD714X_I2C=m -CONFIG_INPUT_AD714X_SPI=m -# CONFIG_INPUT_ATI_REMOTE is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_CM109 is not set -CONFIG_INPUT_TWL4030_PWRBUTTON=y -CONFIG_INPUT_TWL4030_VIBRA=m -CONFIG_INPUT_UINPUT=y -CONFIG_INPUT_PCF8574=m -CONFIG_INPUT_PWM_BEEPER=m -# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -CONFIG_INPUT_ADXL34X=m -CONFIG_INPUT_ADXL34X_I2C=m -CONFIG_INPUT_ADXL34X_SPI=m -CONFIG_INPUT_CMA3000=m -CONFIG_INPUT_CMA3000_I2C=m - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_N_GSM=m -CONFIG_DEVKMEM=y - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=32 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX3107 is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_OMAP=y -CONFIG_SERIAL_OMAP_CONSOLE=y -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -CONFIG_SERIAL_IFX6X60=m -CONFIG_TTY_PRINTK=y -# CONFIG_HVC_DCC is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_RAMOOPS is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=m - -# -# Multiplexer I2C Chip support -# -CONFIG_I2C_MUX_GPIO=m -# CONFIG_I2C_MUX_PCA9541 is not set -# CONFIG_I2C_MUX_PCA954x is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_ALGOBIT=m - -# -# I2C Hardware Bus support -# - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_DESIGNWARE is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -CONFIG_I2C_OMAP=y -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_PXA_PCI is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_XILINX is not set - -# -# External I2C/SMBus adapter drivers -# -CONFIG_I2C_DIOLAN_U2C=m -# 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_OC_TINY is not set -CONFIG_SPI_OMAP24XX=y -# CONFIG_SPI_PXA2XX_PCI is not set -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_DESIGNWARE is not set - -# -# SPI Protocol Masters -# -CONFIG_SPI_SPIDEV=y -# CONFIG_SPI_TLE62X0 is not set - -# -# PPS support -# -# CONFIG_PPS is not set - -# -# PPS generators support -# -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_MAX730X=m - -# -# Memory mapped GPIO expanders: -# -# CONFIG_GPIO_BASIC_MMIO is not set -# CONFIG_GPIO_IT8761E is not set - -# -# I2C GPIO expanders: -# -CONFIG_GPIO_MAX7300=m -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_SX150X is not set -CONFIG_GPIO_TWL4030=y -CONFIG_GPIO_ADP5588=m - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MCP23S08 is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_74X164 is not set - -# -# AC97 GPIO expanders: -# - -# -# MODULbus GPIO expanders: -# -# CONFIG_W1 is not set -CONFIG_POWER_SUPPLY=m -# CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_PDA_POWER is not set -CONFIG_TEST_POWER=m -# CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_BQ20Z75 is not set -# CONFIG_BATTERY_BQ27x00 is not set -# CONFIG_BATTERY_MAX17040 is not set -CONFIG_BATTERY_MAX17042=m -CONFIG_CHARGER_ISP1704=m -CONFIG_CHARGER_TWL4030=m -CONFIG_CHARGER_GPIO=m -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Native drivers -# -# 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_ADT7411=m -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7475 is not set -CONFIG_SENSORS_ASC7621=m -# CONFIG_SENSORS_ATXP1 is not set -CONFIG_SENSORS_DS620=m -# 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=m -# CONFIG_SENSORS_IT87 is not set -CONFIG_SENSORS_JC42=m -# 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_LM95241 is not set -# CONFIG_SENSORS_MAX1111 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6639 is not set -# CONFIG_SENSORS_MAX6650 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_SMM665=m -# CONFIG_SENSORS_DME1737 is not set -CONFIG_SENSORS_EMC1403=m -CONFIG_SENSORS_EMC2103=m -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SCH5627 is not set -# CONFIG_SENSORS_ADS1015 is not set -# CONFIG_SENSORS_ADS7828 is not set -CONFIG_SENSORS_ADS7871=m -CONFIG_SENSORS_AMC6821=m -# CONFIG_SENSORS_THMC50 is not set -CONFIG_SENSORS_TMP102=m -# CONFIG_SENSORS_TMP401 is not set -# CONFIG_SENSORS_TMP421 is not set -CONFIG_SENSORS_TWL4030_MADC=m -# 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_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_OMAP_WATCHDOG=y -# CONFIG_TWL4030_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=y -CONFIG_SSB_BLOCKIO=y -CONFIG_SSB_SDIOHOST_POSSIBLE=y -# CONFIG_SSB_SDIOHOST is not set -# CONFIG_SSB_SILENT is not set -# CONFIG_SSB_DEBUG is not set -CONFIG_MFD_SUPPORT=y -CONFIG_MFD_CORE=y -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_ASIC3 is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -CONFIG_TPS6105X=m -# CONFIG_TPS65010 is not set -CONFIG_TPS6507X=m -CONFIG_TWL4030_CORE=y -CONFIG_TWL4030_MADC=m -CONFIG_TWL4030_POWER=y -CONFIG_TWL4030_CODEC=y -CONFIG_TWL4030_POWEROFF=y -CONFIG_TWL6030_PWM=m -# CONFIG_MFD_STMPE is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_MC13XXX is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_EZX_PCAP is not set -CONFIG_MFD_TPS6586X=y -CONFIG_MFD_WL1273_CORE=m -CONFIG_MFD_OMAP_USB_HOST=y -CONFIG_REGULATOR=y -# CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_DUMMY=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -# CONFIG_REGULATOR_BQ24022 is not set -# CONFIG_REGULATOR_MAX1586 is not set -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8952 is not set -CONFIG_REGULATOR_TWL4030=y -# CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_LP3972 is not set -CONFIG_REGULATOR_TPS6105X=m -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set -# CONFIG_REGULATOR_ISL6271A is not set -# CONFIG_REGULATOR_AD5398 is not set -CONFIG_REGULATOR_TPS6586X=m -CONFIG_REGULATOR_TPS6524X=m -CONFIG_MEDIA_SUPPORT=y - -# -# Multimedia core support -# -CONFIG_MEDIA_CONTROLLER=y -CONFIG_VIDEO_DEV=y -CONFIG_VIDEO_V4L2_COMMON=y -CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_DVB_CORE=m -CONFIG_VIDEO_MEDIA=m - -# -# Multimedia drivers -# -CONFIG_RC_CORE=m -CONFIG_LIRC=m -CONFIG_RC_MAP=m -CONFIG_IR_NEC_DECODER=m -CONFIG_IR_RC5_DECODER=m -CONFIG_IR_RC6_DECODER=m -CONFIG_IR_JVC_DECODER=m -CONFIG_IR_SONY_DECODER=m -CONFIG_IR_RC5_SZ_DECODER=m -CONFIG_IR_LIRC_CODEC=m -# CONFIG_IR_IMON is not set -# CONFIG_IR_MCEUSB is not set -# CONFIG_IR_STREAMZAP is not set -CONFIG_RC_LOOPBACK=m -CONFIG_MEDIA_ATTACH=y -CONFIG_MEDIA_TUNER=m -CONFIG_MEDIA_TUNER_CUSTOMISE=y - -# -# Customize TV tuners -# -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_TEA5761=m -CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MT2131=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_MEDIA_TUNER_MC44S803=m -CONFIG_MEDIA_TUNER_MAX2165=m -CONFIG_MEDIA_TUNER_TDA18218=m -CONFIG_VIDEO_V4L2=y -CONFIG_VIDEOBUF_GEN=y -CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_VIDEOBUF_DMA_CONTIG=y -CONFIG_VIDEOBUF_DVB=m -CONFIG_VIDEO_TVEEPROM=m -CONFIG_VIDEO_TUNER=m -CONFIG_V4L2_MEM2MEM_DEV=m -CONFIG_VIDEOBUF2_CORE=m -CONFIG_VIDEOBUF2_MEMOPS=m -CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set -CONFIG_VIDEO_IR_I2C=m - -# -# Encoders/decoders and other helper chips -# - -# -# Audio decoders -# -# CONFIG_VIDEO_TVAUDIO is not set -# CONFIG_VIDEO_TDA7432 is not set -# CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TEA6415C is not set -# CONFIG_VIDEO_TEA6420 is not set -CONFIG_VIDEO_MSP3400=m -# CONFIG_VIDEO_CS5345 is not set -CONFIG_VIDEO_CS53L32A=m -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_TLV320AIC23B is not set -CONFIG_VIDEO_WM8775=m -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_VP27SMPX is not set - -# -# RDS decoders -# -# CONFIG_VIDEO_SAA6588 is not set - -# -# Video decoders -# -CONFIG_VIDEO_ADV7180=m -# 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_OV7670 is not set -CONFIG_VIDEO_MT9V011=m -# CONFIG_VIDEO_TCM825X is not set -# CONFIG_VIDEO_SAA7110 is not set -CONFIG_VIDEO_SAA711X=m -# CONFIG_VIDEO_SAA717X 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_CX25840=m - -# -# MPEG video encoders -# -CONFIG_VIDEO_CX2341X=m - -# -# Video encoders -# -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_SAA7185 is not set -# CONFIG_VIDEO_ADV7170 is not set -# CONFIG_VIDEO_ADV7175 is not set -# CONFIG_VIDEO_THS7303 is not set -# CONFIG_VIDEO_ADV7343 is not set -# CONFIG_VIDEO_AK881X is not set - -# -# Video improvement chips -# -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set -CONFIG_VIDEO_VIVI=m -CONFIG_VIDEO_VPFE_CAPTURE=y -# CONFIG_VIDEO_DM6446_CCDC is not set -CONFIG_VIDEO_OMAP2_VOUT=y -# CONFIG_VIDEO_CPIA2 is not set -CONFIG_VIDEO_TIMBERDALE=m -# CONFIG_VIDEO_AU0828 is not set -CONFIG_VIDEO_SR030PC30=m -CONFIG_VIDEO_NOON010PC30=m -CONFIG_VIDEO_OMAP3=y -# CONFIG_VIDEO_OMAP3_DEBUG is not set -# CONFIG_SOC_CAMERA is not set -CONFIG_V4L_USB_DRIVERS=y -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -CONFIG_USB_M5602=m -CONFIG_USB_STV06XX=m -# CONFIG_USB_GL860 is not set -CONFIG_USB_GSPCA_BENQ=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_CPIA1=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -# CONFIG_USB_GSPCA_JEILINJ is not set -CONFIG_USB_GSPCA_KONICA=m -CONFIG_USB_GSPCA_MARS=m -# CONFIG_USB_GSPCA_MR97310A is not set -CONFIG_USB_GSPCA_NW80X=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_OV534=m -CONFIG_USB_GSPCA_OV534_9=m -CONFIG_USB_GSPCA_PAC207=m -# CONFIG_USB_GSPCA_PAC7302 is not set -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SN9C2028=m -# CONFIG_USB_GSPCA_SN9C20X is not set -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_SPCA1528=m -# CONFIG_USB_GSPCA_SQ905 is not set -# CONFIG_USB_GSPCA_SQ905C is not set -CONFIG_USB_GSPCA_SQ930X=m -CONFIG_USB_GSPCA_STK014=m -# CONFIG_USB_GSPCA_STV0680 is not set -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_VICAM=m -CONFIG_USB_GSPCA_XIRLINK_CIT=m -CONFIG_USB_GSPCA_ZC3XX=m -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_PVRUSB2_SYSFS=y -CONFIG_VIDEO_PVRUSB2_DVB=y -# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_EM28XX=m -CONFIG_VIDEO_EM28XX_ALSA=m -CONFIG_VIDEO_EM28XX_DVB=m -CONFIG_VIDEO_TLG2300=m -CONFIG_VIDEO_CX231XX=m -CONFIG_VIDEO_CX231XX_RC=y -# CONFIG_VIDEO_CX231XX_ALSA is not set -CONFIG_VIDEO_CX231XX_DVB=m -CONFIG_VIDEO_USBVISION=m -CONFIG_USB_ET61X251=m -CONFIG_USB_SN9C102=m -CONFIG_USB_PWC=m -# CONFIG_USB_PWC_DEBUG is not set -CONFIG_USB_PWC_INPUT_EVDEV=y -CONFIG_USB_ZR364XX=m -CONFIG_USB_STKWEBCAM=m -CONFIG_USB_S2255=m -CONFIG_V4L_MEM2MEM_DRIVERS=y -CONFIG_VIDEO_MEM2MEM_TESTDEV=m -CONFIG_RADIO_ADAPTERS=y -# CONFIG_I2C_SI4713 is not set -# CONFIG_RADIO_SI4713 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_RADIO_SI470X is not set -# CONFIG_USB_MR800 is not set -# CONFIG_RADIO_TEA5764 is not set -CONFIG_RADIO_SAA7706H=m -# CONFIG_RADIO_TEF6862 is not set -CONFIG_RADIO_WL1273=m - -# -# Texas Instruments WL128x FM driver (ST based) -# -CONFIG_RADIO_WL128X=m -CONFIG_DVB_MAX_ADAPTERS=8 -CONFIG_DVB_DYNAMIC_MINORS=y -CONFIG_DVB_CAPTURE_DRIVERS=y -# CONFIG_TTPCI_EEPROM is not set - -# -# Supported USB Adapters -# -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_AF9015=m -# CONFIG_DVB_USB_CE6230 is not set -# CONFIG_DVB_USB_FRIIO is not set -# CONFIG_DVB_USB_EC168 is not set -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -# CONFIG_SMS_SIANO_MDTV is not set - -# -# Supported FlexCopII (B2C2) Adapters -# -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set - -# -# Supported DVB Frontends -# -# CONFIG_DVB_FE_CUSTOMISE is not set - -# -# Multistandard (satellite) frontends -# -CONFIG_DVB_STB0899=m -CONFIG_DVB_STB6100=m -CONFIG_DVB_STV090x=m -CONFIG_DVB_STV6110x=m - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_CX24123=m -CONFIG_DVB_MT312=m -CONFIG_DVB_ZL10039=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_STV0288=m -CONFIG_DVB_STB6000=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_STV6110=m -CONFIG_DVB_STV0900=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_TUNER_CX24113=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_CX24116=m -CONFIG_DVB_SI21XX=m -CONFIG_DVB_DS3000=m - -# -# DVB-T (terrestrial) frontends -# -CONFIG_DVB_CX22702=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_AF9013=m - -# -# DVB-C (cable) frontends -# -CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -CONFIG_DVB_NXT200X=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_LGDT3305=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_S5H1411=m - -# -# ISDB-T (terrestrial) frontends -# -CONFIG_DVB_S921=m -CONFIG_DVB_DIB8000=m -CONFIG_DVB_MB86A20S=m - -# -# Digital terrestrial only tuners/PLL -# -CONFIG_DVB_PLL=m -CONFIG_DVB_TUNER_DIB0070=m -CONFIG_DVB_TUNER_DIB0090=m - -# -# SEC control devices for DVB-S -# -CONFIG_DVB_LNBP21=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_IX2505V=m - -# -# Tools to develop new frontends -# -# CONFIG_DVB_DUMMY_FE is not set - -# -# Graphics support -# -CONFIG_DRM=m -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID 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=m -CONFIG_FB_SYS_COPYAREA=m -CONFIG_FB_SYS_IMAGEBLIT=m -# CONFIG_FB_FOREIGN_ENDIAN is not set -CONFIG_FB_SYS_FOPS=m -# CONFIG_FB_WMT_GE_ROPS is not set -CONFIG_FB_DEFERRED_IO=y -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -CONFIG_FB_MODE_HELPERS=y -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_TMIO is not set -CONFIG_FB_UDL=m -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_BROADSHEET is not set -# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set -CONFIG_OMAP2_VRAM=y -CONFIG_OMAP2_VRFB=y -CONFIG_OMAP2_DSS=y -CONFIG_OMAP2_VRAM_SIZE=14 -CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y -# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set -CONFIG_OMAP2_DSS_DPI=y -# CONFIG_OMAP2_DSS_RFBI is not set -CONFIG_OMAP2_DSS_VENC=y -# CONFIG_OMAP2_DSS_SDI is not set -CONFIG_OMAP2_DSS_DSI=y -CONFIG_OMAP2_DSS_USE_DSI_PLL=y -# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set -CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0 -CONFIG_FB_OMAP2=y -CONFIG_FB_OMAP2_DEBUG_SUPPORT=y -CONFIG_FB_OMAP2_NUM_FBS=2 - -# -# OMAP2/3 Display Device Drivers -# -CONFIG_PANEL_GENERIC_DPI=y -# CONFIG_PANEL_LGPHILIPS_LB035Q02 is not set -CONFIG_PANEL_SHARP_LS037V7DW01=y -CONFIG_PANEL_NEC_NL8048HL11_01B=y -# CONFIG_PANEL_TAAL is not set -CONFIG_PANEL_TPO_TD043MTEA1=m -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y - -# -# Display device support -# -CONFIG_DISPLAY_SUPPORT=y - -# -# Display hardware drivers -# - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_LOGO_LINUX_CLUT224=y -CONFIG_SOUND=y -CONFIG_SOUND_OSS_CORE=y -CONFIG_SOUND_OSS_CORE_PRECLAIM=y -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_HWDEP=y -CONFIG_SND_RAWMIDI=y -CONFIG_SND_JACK=y -CONFIG_SND_SEQUENCER=m -# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=y -CONFIG_SND_HRTIMER=m -CONFIG_SND_SEQ_HRTIMER_DEFAULT=y -CONFIG_SND_DYNAMIC_MINORS=y -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -CONFIG_SND_RAWMIDI_SEQ=m -# CONFIG_SND_OPL3_LIB_SEQ is not set -# CONFIG_SND_OPL4_LIB_SEQ is not set -# CONFIG_SND_SBAWE_SEQ is not set -# CONFIG_SND_EMU10K1_SEQ is not set -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -CONFIG_SND_ALOOP=m -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_ARM is not set -CONFIG_SND_SPI=y -CONFIG_SND_USB=y -CONFIG_SND_USB_AUDIO=y -CONFIG_SND_USB_UA101=m -CONFIG_SND_USB_CAIAQ=m -CONFIG_SND_USB_CAIAQ_INPUT=y -CONFIG_SND_USB_6FIRE=m -CONFIG_SND_SOC=y -CONFIG_SND_SOC_CACHE_LZO=y -CONFIG_SND_OMAP_SOC=y -CONFIG_SND_OMAP_SOC_MCBSP=y -CONFIG_SND_OMAP_SOC_OVERO=y -CONFIG_SND_OMAP_SOC_OMAP3EVM=y -CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y -CONFIG_SND_OMAP_SOC_ZOOM2=y -CONFIG_SND_SOC_I2C_AND_SPI=y -# CONFIG_SND_SOC_ALL_CODECS is not set -CONFIG_SND_SOC_TWL4030=y -# CONFIG_SOUND_PRIME is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_HID_PID is not set -# CONFIG_USB_HIDDEV is not set - -# -# Special HID drivers -# -# CONFIG_HID_3M_PCT is not set -CONFIG_HID_A4TECH=y -CONFIG_HID_ACRUX=m -# CONFIG_HID_ACRUX_FF is not set -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -# CONFIG_HID_CANDO is not set -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -# CONFIG_HID_PRODIKEYS is not set -CONFIG_HID_CYPRESS=y -# CONFIG_HID_DRAGONRISE is not set -CONFIG_HID_EMS_FF=m -# CONFIG_HID_ELECOM is not set -CONFIG_HID_EZKEY=y -CONFIG_HID_KEYTOUCH=m -# CONFIG_HID_KYE is not set -CONFIG_HID_UCLOGIC=m -CONFIG_HID_WALTOP=m -CONFIG_HID_GYRATION=y -# CONFIG_HID_TWINHAN is not set -# CONFIG_HID_KENSINGTON is not set -CONFIG_HID_LCPOWER=m -CONFIG_HID_LOGITECH=y -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -# CONFIG_LOGIG940_FF is not set -# CONFIG_LOGIWII_FF is not set -CONFIG_HID_MAGICMOUSE=m -CONFIG_HID_MICROSOFT=y -# CONFIG_HID_MOSART is not set -CONFIG_HID_MONTEREY=y -CONFIG_HID_MULTITOUCH=m -CONFIG_HID_NTRIG=y -# CONFIG_HID_ORTEK is not set -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -CONFIG_HID_PICOLCD=m -CONFIG_HID_PICOLCD_FB=y -CONFIG_HID_PICOLCD_BACKLIGHT=y -CONFIG_HID_PICOLCD_LEDS=y -CONFIG_HID_QUANTA=m -CONFIG_HID_ROCCAT=m -CONFIG_HID_ROCCAT_COMMON=m -CONFIG_HID_ROCCAT_ARVO=m -CONFIG_HID_ROCCAT_KONE=m -CONFIG_HID_ROCCAT_KONEPLUS=m -CONFIG_HID_ROCCAT_KOVAPLUS=m -# CONFIG_HID_ROCCAT_PYRA is not set -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_STANTUM=m -CONFIG_HID_SUNPLUS=y -# CONFIG_HID_GREENASIA is not set -# CONFIG_HID_SMARTJOYPLUS is not set -CONFIG_HID_TOPSEED=y -# CONFIG_HID_THRUSTMASTER is not set -# CONFIG_HID_WACOM is not set -# CONFIG_HID_ZEROPLUS is not set -# CONFIG_HID_ZYDACRON is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -CONFIG_USB_SUSPEND=y -CONFIG_USB_OTG=y -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_MON=y -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -CONFIG_USB_EHCI_TT_NEWSCHED=y -CONFIG_USB_EHCI_HCD_OMAP=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_U132_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_HWA_HCD is not set -CONFIG_USB_MUSB_HDRC=y -# CONFIG_USB_MUSB_TUSB6010 is not set -CONFIG_USB_MUSB_OMAP2PLUS=y -# CONFIG_USB_MUSB_AM35X is not set -# CONFIG_USB_MUSB_HOST is not set -# CONFIG_USB_MUSB_PERIPHERAL is not set -CONFIG_USB_MUSB_OTG=y -CONFIG_USB_GADGET_MUSB_HDRC=y -CONFIG_USB_MUSB_HDRC_HCD=y -# CONFIG_MUSB_PIO_ONLY is not set -CONFIG_USB_INVENTRA_DMA=y -# CONFIG_USB_TI_CPPI_DMA is not set -# CONFIG_USB_MUSB_DEBUG is not set - -# -# USB Device Class drivers -# -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m -CONFIG_USB_WDM=m -CONFIG_USB_TMC=m - -# -# 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=m -# 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=m -CONFIG_USB_UAS=m -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -CONFIG_USB_SERIAL=m -CONFIG_USB_EZUSB=y -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_AIRCABLE=m -CONFIG_USB_SERIAL_ARK3116=m -CONFIG_USB_SERIAL_BELKIN=m -CONFIG_USB_SERIAL_CH341=m -CONFIG_USB_SERIAL_WHITEHEAT=n -CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -# CONFIG_USB_SERIAL_CP210X is not set -CONFIG_USB_SERIAL_CYPRESS_M8=m -CONFIG_USB_SERIAL_EMPEG=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_FUNSOFT=m -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_IPAQ=m -CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m -CONFIG_USB_SERIAL_GARMIN=m -CONFIG_USB_SERIAL_IPW=m -CONFIG_USB_SERIAL_IUU=m -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KEYSPAN=m -CONFIG_USB_SERIAL_KEYSPAN_MPR=y -CONFIG_USB_SERIAL_KEYSPAN_USA28=y -CONFIG_USB_SERIAL_KEYSPAN_USA28X=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -CONFIG_USB_SERIAL_KEYSPAN_USA19=y -CONFIG_USB_SERIAL_KEYSPAN_USA18X=y -CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -CONFIG_USB_SERIAL_KEYSPAN_USA49W=y -CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -CONFIG_USB_SERIAL_KLSI=m -CONFIG_USB_SERIAL_KOBIL_SCT=m -CONFIG_USB_SERIAL_MCT_U232=m -CONFIG_USB_SERIAL_MOS7720=m -CONFIG_USB_SERIAL_MOS7840=m -CONFIG_USB_SERIAL_MOTOROLA=m -CONFIG_USB_SERIAL_NAVMAN=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_OTI6858=m -CONFIG_USB_SERIAL_QCAUX=m -# CONFIG_USB_SERIAL_QUALCOMM is not set -CONFIG_USB_SERIAL_SPCP8X5=m -CONFIG_USB_SERIAL_HP4X=m -CONFIG_USB_SERIAL_SAFE=m -# CONFIG_USB_SERIAL_SAFE_PADDED is not set -CONFIG_USB_SERIAL_SAMBA=m -CONFIG_USB_SERIAL_SIEMENS_MPI=m -CONFIG_USB_SERIAL_SIERRAWIRELESS=m -# CONFIG_USB_SERIAL_SYMBOL is not set -CONFIG_USB_SERIAL_TI=n -CONFIG_USB_SERIAL_CYBERJACK=m -CONFIG_USB_SERIAL_XIRCOM=n -# CONFIG_USB_SERIAL_OPTION is not set -CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_SERIAL_OPTICON=m -CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m -CONFIG_USB_SERIAL_ZIO=m -CONFIG_USB_SERIAL_SSU100=m -CONFIG_USB_SERIAL_DEBUG=m - -# -# USB Miscellaneous drivers -# -CONFIG_USB_EMI62=m -CONFIG_USB_EMI26=m -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -CONFIG_USB_LEGOTOWER=m -CONFIG_USB_LCD=m -CONFIG_USB_LED=m -CONFIG_USB_CYPRESS_CY7C63=m -CONFIG_USB_CYTHERM=m -CONFIG_USB_IDMOUSE=m -CONFIG_USB_FTDI_ELAN=m -# CONFIG_USB_APPLEDISPLAY is not set -CONFIG_USB_SISUSBVGA=m -CONFIG_USB_SISUSBVGA_CON=y -CONFIG_USB_LD=m -CONFIG_USB_TRANCEVIBRATOR=m -# CONFIG_USB_IOWARRIOR is not set -CONFIG_USB_TEST=m -# CONFIG_USB_ISIGHTFW is not set -CONFIG_USB_YUREX=m -CONFIG_USB_ATM=m -CONFIG_USB_SPEEDTOUCH=m -CONFIG_USB_CXACRU=m -CONFIG_USB_UEAGLEATM=m -CONFIG_USB_XUSBATM=m -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG is not set -# CONFIG_USB_GADGET_DEBUG_FILES is not set -CONFIG_USB_GADGET_DEBUG_FS=y -CONFIG_USB_GADGET_VBUS_DRAW=480 -CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_FUSB300 is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_R8A66597 is not set -# CONFIG_USB_GADGET_PXA_U2O is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -CONFIG_USB_GADGET_DUALSPEED=y -# CONFIG_USB_ZERO is not set -# CONFIG_USB_AUDIO is not set -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -# CONFIG_USB_ETH_EEM is not set -CONFIG_USB_G_NCM=m -# CONFIG_USB_GADGETFS is not set -CONFIG_USB_FUNCTIONFS=m -# CONFIG_USB_FUNCTIONFS_ETH is not set -CONFIG_USB_FUNCTIONFS_RNDIS=y -# CONFIG_USB_FUNCTIONFS_GENERIC is not set -# CONFIG_USB_FILE_STORAGE 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_MULTI is not set -CONFIG_USB_G_HID=m -CONFIG_USB_G_DBGP=m -# CONFIG_USB_G_DBGP_PRINTK is not set -CONFIG_USB_G_DBGP_SERIAL=y -CONFIG_USB_G_WEBCAM=m - -# -# OTG and related infrastructure -# -CONFIG_USB_OTG_UTILS=y -CONFIG_USB_GPIO_VBUS=y -# CONFIG_ISP1301_OMAP is not set -# CONFIG_USB_ULPI is not set -CONFIG_TWL4030_USB=y -CONFIG_TWL6030_USB=m -CONFIG_NOP_USB_XCEIV=y -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_UNSAFE_RESUME=y -# CONFIG_MMC_CLKGATE is not set - -# -# MMC/SD/SDIO Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=8 -CONFIG_MMC_BLOCK_BOUNCE=y -CONFIG_SDIO_UART=y -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_OMAP is not set -CONFIG_MMC_OMAP_HS=y -CONFIG_MMC_SPI=m -# CONFIG_MMC_DW is not set -CONFIG_MMC_USHC=m -# CONFIG_MEMSTICK is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# -# CONFIG_LEDS_LM3530 is not set -# CONFIG_LEDS_PCA9532 is not set -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_GPIO_PLATFORM=y -# CONFIG_LEDS_LP3944 is not set -CONFIG_LEDS_LP5521=m -CONFIG_LEDS_LP5523=m -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_DAC124S085 is not set -CONFIG_LEDS_PWM=m -CONFIG_LEDS_REGULATOR=m -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_LT3593 is not set -CONFIG_LEDS_TRIGGERS=y - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGER_TIMER=m -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_BACKLIGHT=m -CONFIG_LEDS_TRIGGER_GPIO=m -CONFIG_LEDS_TRIGGER_DEFAULT_ON=m - -# -# iptables trigger is under Netfilter config (LED target) -# -CONFIG_NFC_DEVICES=y -CONFIG_PN544_NFC=m -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_ISL12022 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -CONFIG_RTC_DRV_BQ32K=m -CONFIG_RTC_DRV_TWL4030=m -# 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 - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_DS3234 is not set -# CONFIG_RTC_DRV_PCF2123 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_DMADEVICES is not set -CONFIG_TIMB_DMA=m -CONFIG_DMA_ENGINE=y -# CONFIG_AUXDISPLAY is not set -CONFIG_UIO=m -CONFIG_UIO_PDRV=m -CONFIG_UIO_PDRV_GENIRQ=m -CONFIG_STAGING=y -# CONFIG_STAGING_EXCLUDE_BUILD is not set -# CONFIG_VIDEO_TM6000 is not set -# CONFIG_USB_IP_COMMON is not set -CONFIG_W35UND=m -CONFIG_PRISM2_USB=m -CONFIG_ECHO=m -CONFIG_BRCM80211=m -CONFIG_BRCMFMAC=y -# CONFIG_BRCMDBG is not set -CONFIG_RT2870=m -# CONFIG_COMEDI is not set -# CONFIG_ASUS_OLED is not set -CONFIG_R8712U=m -CONFIG_R8712_AP=y -# CONFIG_TRANZPORT is not set -# CONFIG_POHMELFS is not set -# CONFIG_LINE6_USB is not set -# CONFIG_USB_SERIAL_QUATECH2 is not set -# CONFIG_USB_SERIAL_QUATECH_USB2 is not set -# CONFIG_VT6656 is not set -# CONFIG_IIO is not set -CONFIG_XVMALLOC=y -CONFIG_ZRAM=m -# CONFIG_ZRAM_DEBUG is not set -# CONFIG_FB_SM7XX is not set -# CONFIG_LIRC_STAGING is not set -# CONFIG_EASYCAP is not set -# CONFIG_TIDSPBRIDGE is not set -# CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL is not set -CONFIG_MACH_NO_WESTBRIDGE=y -# CONFIG_ATH6K_LEGACY is not set -CONFIG_USB_ENESTORAGE=m -CONFIG_BCM_WIMAX=m -CONFIG_FT1000=m -CONFIG_FT1000_USB=m - -# -# Speakup console speech -# -# CONFIG_SPEAKUP is not set -CONFIG_TOUCHSCREEN_CLEARPAD_TM1217=m -CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=m - -# -# Altera FPGA firmware download module -# -# CONFIG_ALTERA_STAPL is not set -CONFIG_CLKDEV_LOOKUP=y - -# -# File systems -# -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 is not set -# CONFIG_EXT3_FS_XATTR is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_XATTR=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=m -# CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y -CONFIG_REISERFS_FS_XATTR=y -# CONFIG_REISERFS_FS_POSIX_ACL is not set -# CONFIG_REISERFS_FS_SECURITY is not set -CONFIG_JFS_FS=m -# CONFIG_JFS_POSIX_ACL is not set -# CONFIG_JFS_SECURITY is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -CONFIG_XFS_FS=m -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_DEBUG is not set -CONFIG_GFS2_FS=m -# CONFIG_GFS2_FS_LOCKING_DLM is not set -CONFIG_OCFS2_FS=m -CONFIG_OCFS2_FS_O2CB=m -CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m -CONFIG_OCFS2_FS_STATS=y -CONFIG_OCFS2_DEBUG_MASKLOG=y -# CONFIG_OCFS2_DEBUG_FS is not set -CONFIG_BTRFS_FS=m -# CONFIG_BTRFS_FS_POSIX_ACL is not set -# CONFIG_NILFS2_FS is not set -CONFIG_FS_POSIX_ACL=y -CONFIG_EXPORTFS=y -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_FANOTIFY=y -CONFIG_QUOTA=y -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -CONFIG_PRINT_QUOTA_WARNING=y -# CONFIG_QUOTA_DEBUG is not set -CONFIG_QUOTA_TREE=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -CONFIG_QUOTACTL=y -CONFIG_AUTOFS4_FS=m -CONFIG_FUSE_FS=m -# CONFIG_CUSE is not set -CONFIG_GENERIC_ACL=y - -# -# Caches -# -# CONFIG_FSCACHE is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=m -# CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_RW=y - -# -# 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_HUGETLB_PAGE is not set -CONFIG_CONFIGFS_FS=m -CONFIG_MISC_FILESYSTEMS=y -CONFIG_ADFS_FS=m -# CONFIG_ADFS_FS_RW is not set -CONFIG_AFFS_FS=m -# CONFIG_ECRYPT_FS is not set -CONFIG_UNION_FS=m -CONFIG_UNION_FS_XATTR=y -# CONFIG_UNION_FS_DEBUG is not set -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -CONFIG_JFFS2_SUMMARY=y -CONFIG_JFFS2_FS_XATTR=y -CONFIG_JFFS2_FS_POSIX_ACL=y -CONFIG_JFFS2_FS_SECURITY=y -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_LZO=y -CONFIG_JFFS2_RTIME=y -CONFIG_JFFS2_RUBIN=y -# CONFIG_JFFS2_CMODE_NONE is not set -# CONFIG_JFFS2_CMODE_PRIORITY is not set -# CONFIG_JFFS2_CMODE_SIZE is not set -CONFIG_JFFS2_CMODE_FAVOURLZO=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_XATTR=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_UBIFS_FS_LZO=y -CONFIG_UBIFS_FS_ZLIB=y -# CONFIG_UBIFS_FS_DEBUG is not set -CONFIG_LOGFS=m -CONFIG_CRAMFS=m -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_XATTR is not set -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -CONFIG_VXFS_FS=m -CONFIG_MINIX_FS=m -CONFIG_OMFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_ROMFS_FS=m -CONFIG_ROMFS_BACKED_BY_BLOCK=y -# CONFIG_ROMFS_BACKED_BY_MTD is not set -# CONFIG_ROMFS_BACKED_BY_BOTH is not set -CONFIG_ROMFS_ON_BLOCK=y -CONFIG_PSTORE=y -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_UFS_DEBUG is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -# CONFIG_NFS_V4_1 is not set -CONFIG_ROOT_NFS=y -# CONFIG_NFS_USE_LEGACY_DNS is not set -CONFIG_NFS_USE_KERNEL_DNS=y -# CONFIG_NFS_USE_NEW_IDMAPPER is not set -CONFIG_NFSD=m -CONFIG_NFSD_DEPRECATED=y -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=m -CONFIG_CEPH_FS=m -CONFIG_CIFS=m -CONFIG_CIFS_STATS=y -CONFIG_CIFS_STATS2=y -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_UPCALL is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_DFS_UPCALL is not set -CONFIG_CIFS_EXPERIMENTAL=y -CONFIG_NCP_FS=m -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -CONFIG_CODA_FS=m -CONFIG_AFS_FS=m -# CONFIG_AFS_DEBUG is not set -CONFIG_9P_FS=m -# CONFIG_9P_FS_POSIX_ACL is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -# CONFIG_UNIXWARE_DISKLABEL is not set -CONFIG_LDM_PARTITION=y -CONFIG_LDM_DEBUG=y -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -CONFIG_EFI_PARTITION=y -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=y -CONFIG_DLM=m -# CONFIG_DLM_DEBUG 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_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -# CONFIG_LOCKUP_DETECTOR is not set -# CONFIG_HARDLOCKUP_DETECTOR is not set -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_KMEMLEAK is not set -CONFIG_DEBUG_PREEMPT=y -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_RCU_CPU_STALL_DETECTOR is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_LKDTM is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_RING_BUFFER=y -CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_PREEMPT_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_DMA_API_DEBUG is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_ASYNC_RAID6_TEST is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_TEST_KSTRTOX is not set -# CONFIG_STRICT_DEVMEM is not set -CONFIG_ARM_UNWIND=y -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_LL is not set -# CONFIG_OC_ETM is not set - -# -# Security options -# -CONFIG_KEYS=y -# CONFIG_KEYS_DEBUG_PROC_KEYS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_XOR_BLOCKS=m -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_XOR=m -CONFIG_ASYNC_PQ=m -CONFIG_ASYNC_RAID6_RECOV=m -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=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_MANAGER_DISABLE_TESTS=y -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_AUTHENC=m -CONFIG_CRYPTO_TEST=m - -# -# Authenticated Encryption with Associated Data -# -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_SEQIV=m - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_CTS=m -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=m -CONFIG_CRYPTO_XCBC=m -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_GHASH=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=y -CONFIG_CRYPTO_RMD128=m -CONFIG_CRYPTO_RMD160=m -CONFIG_CRYPTO_RMD256=m -CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_WP512=m - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SEED=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_ZLIB is not set -CONFIG_CRYPTO_LZO=y - -# -# Random Number Generation -# -CONFIG_CRYPTO_ANSI_CPRNG=m -CONFIG_CRYPTO_USER_API=m -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_DEV_OMAP_SHAM=m -CONFIG_CRYPTO_DEV_OMAP_AES=m -# CONFIG_BINARY_PRINTF is not set - -# -# Library routines -# -CONFIG_RAID6_PQ=m -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=y -CONFIG_CRC32=y -CONFIG_CRC7=y -CONFIG_LIBCRC32C=y -CONFIG_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=m -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_XZ=y -CONFIG_DECOMPRESS_LZO=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_BTREE=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_NLATTR=y -CONFIG_AVERAGE=y diff --git a/recipes-kernel/linux/linux-omap-2.6.39/beagleboard/defconfig b/recipes-kernel/linux/linux-omap-2.6.39/beagleboard/defconfig deleted file mode 100644 index 6f97d93b..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/beagleboard/defconfig +++ /dev/null @@ -1,3517 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux/arm 2.6.39 Kernel Configuration -# Sun Jun 5 11:03:19 2011 -# -CONFIG_ARM=y -CONFIG_HAVE_PWM=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_HAVE_SCHED_CLOCK=y -CONFIG_GENERIC_GPIO=y -# CONFIG_ARCH_USES_GETTIMEOFFSET is not set -CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_KTIME_SCALAR=y -CONFIG_HAVE_PROC_CPU=y -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_HAVE_LATENCYTOP_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_ARCH_HAS_CPUFREQ=y -CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_NEED_DMA_MAP_STATE=y -CONFIG_VECTORS_BASE=0xffff0000 -# CONFIG_ARM_PATCH_PHYS_VIRT is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -CONFIG_CONSTRUCTORS=y -CONFIG_HAVE_IRQ_WORK=y -CONFIG_IRQ_WORK=y - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_CROSS_COMPILE="" -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_HAVE_KERNEL_GZIP=y -CONFIG_HAVE_KERNEL_LZMA=y -CONFIG_HAVE_KERNEL_LZO=y -CONFIG_KERNEL_GZIP=y -# CONFIG_KERNEL_LZMA is not set -# CONFIG_KERNEL_LZO is not set -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_POSIX_MQUEUE_SYSCTL=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -CONFIG_FHANDLE=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y -# CONFIG_AUDIT is not set -CONFIG_HAVE_GENERIC_HARDIRQS=y - -# -# IRQ subsystem -# -CONFIG_GENERIC_HARDIRQS=y -CONFIG_HAVE_SPARSE_IRQ=y -CONFIG_GENERIC_IRQ_SHOW=y -# CONFIG_SPARSE_IRQ is not set - -# -# RCU Subsystem -# -CONFIG_TINY_RCU=y -# CONFIG_PREEMPT_RCU is not set -# CONFIG_RCU_TRACE is not set -# CONFIG_TREE_RCU_TRACE is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=16 -CONFIG_CGROUPS=y -# CONFIG_CGROUP_DEBUG is not set -CONFIG_CGROUP_NS=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y -CONFIG_CPUSETS=y -CONFIG_PROC_PID_CPUSET=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -CONFIG_CGROUP_MEM_RES_CTLR=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y -CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y -CONFIG_CGROUP_PERF=y -CONFIG_CGROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_BLK_CGROUP=y -# CONFIG_DEBUG_BLK_CGROUP is not set -CONFIG_NAMESPACES=y -CONFIG_UTS_NS=y -CONFIG_IPC_NS=y -CONFIG_USER_NS=y -CONFIG_PID_NS=y -CONFIG_NET_NS=y -CONFIG_SCHED_AUTOGROUP=y -CONFIG_MM_OWNER=y -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y -CONFIG_EXPERT=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_SHMEM=y -CONFIG_AIO=y -CONFIG_EMBEDDED=y -CONFIG_HAVE_PERF_EVENTS=y -CONFIG_PERF_USE_VMALLOC=y - -# -# Kernel Performance Events And Counters -# -CONFIG_PERF_EVENTS=y -# CONFIG_PERF_COUNTERS is not set -# CONFIG_DEBUG_PERF_USE_VMALLOC is not set -CONFIG_VM_EVENT_COUNTERS=y -# CONFIG_COMPAT_BRK is not set -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_KPROBES is not set -CONFIG_HAVE_KPROBES=y -CONFIG_HAVE_KRETPROBES=y -CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y -CONFIG_HAVE_CLK=y -CONFIG_HAVE_DMA_API_DEBUG=y -CONFIG_HAVE_HW_BREAKPOINT=y - -# -# GCOV-based kernel profiling -# -# CONFIG_GCOV_KERNEL is not set -CONFIG_HAVE_GENERIC_DMA_COHERENT=y -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -CONFIG_MODULE_FORCE_LOAD=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -CONFIG_MODULE_SRCVERSION_ALL=y -CONFIG_BLOCK=y -CONFIG_LBDAF=y -CONFIG_BLK_DEV_BSG=y -CONFIG_BLK_DEV_INTEGRITY=y -CONFIG_BLK_DEV_THROTTLING=y - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_CFQ_GROUP_IOSCHED=y -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" -# CONFIG_INLINE_SPIN_TRYLOCK is not set -# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK is not set -# CONFIG_INLINE_SPIN_LOCK_BH is not set -# CONFIG_INLINE_SPIN_LOCK_IRQ is not set -# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set -CONFIG_INLINE_SPIN_UNLOCK=y -# CONFIG_INLINE_SPIN_UNLOCK_BH is not set -CONFIG_INLINE_SPIN_UNLOCK_IRQ=y -# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_READ_TRYLOCK is not set -# CONFIG_INLINE_READ_LOCK is not set -# CONFIG_INLINE_READ_LOCK_BH is not set -# CONFIG_INLINE_READ_LOCK_IRQ is not set -# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set -CONFIG_INLINE_READ_UNLOCK=y -# CONFIG_INLINE_READ_UNLOCK_BH is not set -CONFIG_INLINE_READ_UNLOCK_IRQ=y -# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set -# CONFIG_INLINE_WRITE_TRYLOCK is not set -# CONFIG_INLINE_WRITE_LOCK is not set -# CONFIG_INLINE_WRITE_LOCK_BH is not set -# CONFIG_INLINE_WRITE_LOCK_IRQ is not set -# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set -CONFIG_INLINE_WRITE_UNLOCK=y -# CONFIG_INLINE_WRITE_UNLOCK_BH is not set -CONFIG_INLINE_WRITE_UNLOCK_IRQ=y -# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set -# CONFIG_MUTEX_SPIN_ON_OWNER is not set -CONFIG_FREEZER=y - -# -# System Type -# -CONFIG_MMU=y -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_VEXPRESS is not set -# CONFIG_ARCH_AT91 is not set -# CONFIG_ARCH_BCMRING is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CNS3XXX 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_MXC is not set -# CONFIG_ARCH_MXS is not set -# CONFIG_ARCH_STMP3XXX is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_DOVE is not set -# CONFIG_ARCH_KIRKWOOD is not set -# CONFIG_ARCH_LOKI is not set -# CONFIG_ARCH_LPC32XX is not set -# CONFIG_ARCH_MV78XX0 is not set -# CONFIG_ARCH_ORION5X is not set -# CONFIG_ARCH_MMP is not set -# CONFIG_ARCH_KS8695 is not set -# CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_W90X900 is not set -# CONFIG_ARCH_NUC93X is not set -# CONFIG_ARCH_TEGRA is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_MSM is not set -# CONFIG_ARCH_SHMOBILE is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_S3C64XX is not set -# CONFIG_ARCH_S5P64X0 is not set -# CONFIG_ARCH_S5P6442 is not set -# CONFIG_ARCH_S5PC100 is not set -# CONFIG_ARCH_S5PV210 is not set -# CONFIG_ARCH_EXYNOS4 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_TCC_926 is not set -# CONFIG_ARCH_U300 is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_NOMADIK is not set -# CONFIG_ARCH_DAVINCI is not set -CONFIG_ARCH_OMAP=y -# CONFIG_PLAT_SPEAR is not set -# CONFIG_ARCH_VT8500 is not set -# CONFIG_GPIO_PCA953X is not set -# CONFIG_KEYBOARD_GPIO_POLLED is not set - -# -# TI OMAP Common Features -# -CONFIG_ARCH_OMAP_OTG=y -# CONFIG_ARCH_OMAP1 is not set -CONFIG_ARCH_OMAP2PLUS=y - -# -# OMAP Feature Selections -# -CONFIG_OMAP_SMARTREFLEX=y -CONFIG_OMAP_SMARTREFLEX_CLASS3=y -CONFIG_OMAP_RESET_CLOCKS=y -# CONFIG_OMAP_MUX is not set -CONFIG_OMAP_MCBSP=y -CONFIG_OMAP_MBOX_FWK=m -CONFIG_OMAP_MBOX_KFIFO_SIZE=256 -CONFIG_OMAP_IOMMU=y -CONFIG_OMAP_IOMMU_DEBUG=m -CONFIG_OMAP_32K_TIMER=y -# CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE is not set -CONFIG_OMAP_32K_TIMER_HZ=128 -CONFIG_OMAP_DM_TIMER=y -# CONFIG_OMAP_PM_NONE is not set -CONFIG_OMAP_PM_NOOP=y - -# -# TI OMAP2/3/4 Specific Features -# -CONFIG_ARCH_OMAP2PLUS_TYPICAL=y -# CONFIG_ARCH_OMAP2 is not set -CONFIG_ARCH_OMAP3=y -# CONFIG_ARCH_OMAP4 is not set -CONFIG_SOC_OMAP3430=y -# CONFIG_SOC_OMAPTI816X is not set -CONFIG_OMAP_PACKAGE_CBB=y - -# -# OMAP Board Type -# -CONFIG_MACH_OMAP3_BEAGLE=y -# CONFIG_MACH_DEVKIT8000 is not set -# CONFIG_MACH_OMAP_LDP is not set -# CONFIG_MACH_OMAP3530_LV_SOM is not set -# CONFIG_MACH_OMAP3_TORPEDO is not set -CONFIG_MACH_OVERO=y -CONFIG_MACH_OMAP3EVM=y -# CONFIG_MACH_OMAP3517EVM is not set -# CONFIG_MACH_CRANEBOARD is not set -# CONFIG_MACH_OMAP3_PANDORA is not set -CONFIG_MACH_OMAP3_TOUCHBOOK=y -# CONFIG_MACH_OMAP_3430SDP is not set -# CONFIG_MACH_NOKIA_RM680 is not set -# CONFIG_MACH_NOKIA_RX51 is not set -CONFIG_MACH_OMAP_ZOOM2=y -# CONFIG_MACH_OMAP_ZOOM3 is not set -# CONFIG_MACH_CM_T35 is not set -# CONFIG_MACH_CM_T3517 is not set -# CONFIG_MACH_IGEP0020 is not set -# CONFIG_MACH_IGEP0030 is not set -# CONFIG_MACH_SBC3530 is not set -# CONFIG_MACH_OMAP_3630SDP is not set -# CONFIG_OMAP3_EMU is not set -# CONFIG_OMAP3_SDRC_AC_TIMING is not set - -# -# System MMU -# - -# -# Processor Type -# -CONFIG_CPU_V7=y -CONFIG_CPU_32v6K=y -CONFIG_CPU_32v7=y -CONFIG_CPU_ABRT_EV7=y -CONFIG_CPU_PABRT_V7=y -CONFIG_CPU_CACHE_V7=y -CONFIG_CPU_CACHE_VIPT=y -CONFIG_CPU_COPY_V6=y -CONFIG_CPU_TLB_V7=y -CONFIG_CPU_HAS_ASID=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -CONFIG_ARM_THUMBEE=y -# CONFIG_SWP_EMULATE is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_BPREDICT_DISABLE is not set -CONFIG_ARM_L1_CACHE_SHIFT_6=y -CONFIG_ARM_L1_CACHE_SHIFT=6 -CONFIG_ARM_DMA_MEM_BUFFERABLE=y -CONFIG_ARM_ERRATA_430973=y -# CONFIG_ARM_ERRATA_458693 is not set -# CONFIG_ARM_ERRATA_460075 is not set -# CONFIG_ARM_ERRATA_743622 is not set -# CONFIG_ARM_ERRATA_754322 is not set - -# -# Bus support -# -# CONFIG_PCI_SYSCALL is not set -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set -CONFIG_PAGE_OFFSET=0xC0000000 -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set -CONFIG_HZ=128 -# CONFIG_THUMB2_KERNEL is not set -CONFIG_AEABI=y -# CONFIG_OABI_COMPAT is not set -CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y -# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set -# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set -# CONFIG_HIGHMEM is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_HAVE_MEMBLOCK=y -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_COMPACTION=y -CONFIG_MIGRATION=y -# CONFIG_PHYS_ADDR_T_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_VIRT_TO_BUS=y -# CONFIG_KSM is not set -CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 -CONFIG_NEED_PER_CPU_KM=y -CONFIG_FORCE_MAX_ZONEORDER=11 -CONFIG_LEDS=y -CONFIG_ALIGNMENT_TRAP=y -# CONFIG_UACCESS_WITH_MEMCPY is not set -# CONFIG_SECCOMP is not set -# CONFIG_CC_STACKPROTECTOR is not set -# CONFIG_DEPRECATED_PARAM_STRUCT is not set - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE=" debug " -# CONFIG_CMDLINE_FORCE is not set -# CONFIG_XIP_KERNEL is not set -CONFIG_KEXEC=y -CONFIG_ATAGS_PROC=y -# CONFIG_CRASH_DUMP is not set -CONFIG_AUTO_ZRELADDR=y - -# -# CPU Power Management -# -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -# CONFIG_CPU_FREQ_DEBUG is not set -CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_STAT_DETAILS=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG 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_IDLE=y -CONFIG_CPU_IDLE_GOV_LADDER=y -CONFIG_CPU_IDLE_GOV_MENU=y - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_VFP=y -CONFIG_VFPv3=y -CONFIG_NEON=y - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_HAVE_AOUT=y -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_MISC=y - -# -# Power management options -# -CONFIG_SUSPEND=y -CONFIG_SUSPEND_FREEZER=y -CONFIG_PM_SLEEP=y -CONFIG_PM_RUNTIME=y -CONFIG_PM=y -CONFIG_PM_DEBUG=y -# CONFIG_PM_VERBOSE is not set -# CONFIG_PM_ADVANCED_DEBUG is not set -# CONFIG_PM_TEST_SUSPEND is not set -CONFIG_CAN_PM_TRACE=y -# CONFIG_APM_EMULATION is not set -CONFIG_ARCH_HAS_OPP=y -CONFIG_PM_OPP=y -CONFIG_ARCH_SUSPEND_POSSIBLE=y -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM=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=m -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_ROUTE_CLASSID=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE_DEMUX=m -CONFIG_NET_IPGRE=m -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_LRO=y -CONFIG_INET_DIAG=m -CONFIG_INET_TCP_DIAG=m -CONFIG_TCP_CONG_ADVANCED=y -CONFIG_TCP_CONG_BIC=m -CONFIG_TCP_CONG_CUBIC=y -CONFIG_TCP_CONG_WESTWOOD=m -CONFIG_TCP_CONG_HTCP=m -CONFIG_TCP_CONG_HSTCP=m -CONFIG_TCP_CONG_HYBLA=m -CONFIG_TCP_CONG_VEGAS=m -CONFIG_TCP_CONG_SCALABLE=m -CONFIG_TCP_CONG_LP=m -CONFIG_TCP_CONG_VENO=m -CONFIG_TCP_CONG_YEAH=m -CONFIG_TCP_CONG_ILLINOIS=m -CONFIG_DEFAULT_CUBIC=y -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_MIP6=m -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_SIT=m -# CONFIG_IPV6_SIT_6RD is not set -CONFIG_IPV6_NDISC_NODETYPE=y -CONFIG_IPV6_TUNNEL=m -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_IPV6_SUBTREES=y -CONFIG_IPV6_MROUTE=y -CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y -# CONFIG_IPV6_PIMSM_V2 is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETWORK_PHY_TIMESTAMPING=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_NETFILTER_ADVANCED=y -CONFIG_BRIDGE_NETFILTER=y - -# -# Core Netfilter Configuration -# -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m -CONFIG_NF_CONNTRACK=m -CONFIG_NF_CONNTRACK_MARK=y -CONFIG_NF_CONNTRACK_ZONES=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_TIMESTAMP=y -CONFIG_NF_CT_PROTO_DCCP=m -CONFIG_NF_CT_PROTO_GRE=m -CONFIG_NF_CT_PROTO_SCTP=m -CONFIG_NF_CT_PROTO_UDPLITE=m -CONFIG_NF_CONNTRACK_AMANDA=m -CONFIG_NF_CONNTRACK_FTP=m -CONFIG_NF_CONNTRACK_H323=m -CONFIG_NF_CONNTRACK_IRC=m -CONFIG_NF_CONNTRACK_BROADCAST=m -CONFIG_NF_CONNTRACK_NETBIOS_NS=m -CONFIG_NF_CONNTRACK_SNMP=m -CONFIG_NF_CONNTRACK_PPTP=m -CONFIG_NF_CONNTRACK_SANE=m -CONFIG_NF_CONNTRACK_SIP=m -CONFIG_NF_CONNTRACK_TFTP=m -CONFIG_NF_CT_NETLINK=m -# CONFIG_NETFILTER_TPROXY is not set -CONFIG_NETFILTER_XTABLES=m - -# -# Xtables combined modules -# -CONFIG_NETFILTER_XT_MARK=m -CONFIG_NETFILTER_XT_CONNMARK=m -CONFIG_NETFILTER_XT_SET=m - -# -# Xtables targets -# -CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m -CONFIG_NETFILTER_XT_TARGET_CT=m -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -CONFIG_NETFILTER_XT_TARGET_HL=m -CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m -# CONFIG_NETFILTER_XT_TARGET_LED is not set -CONFIG_NETFILTER_XT_TARGET_MARK=m -CONFIG_NETFILTER_XT_TARGET_NFLOG=m -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -CONFIG_NETFILTER_XT_TARGET_RATEEST=m -CONFIG_NETFILTER_XT_TARGET_TEE=m -# CONFIG_NETFILTER_XT_TARGET_TRACE is not set -CONFIG_NETFILTER_XT_TARGET_TCPMSS=m -# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set - -# -# Xtables matches -# -CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set -CONFIG_NETFILTER_XT_MATCH_COMMENT=m -CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m -CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m -CONFIG_NETFILTER_XT_MATCH_CPU=m -CONFIG_NETFILTER_XT_MATCH_DCCP=m -CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m -CONFIG_NETFILTER_XT_MATCH_DSCP=m -CONFIG_NETFILTER_XT_MATCH_ESP=m -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m -CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_HL=m -CONFIG_NETFILTER_XT_MATCH_IPRANGE=m -CONFIG_NETFILTER_XT_MATCH_IPVS=m -CONFIG_NETFILTER_XT_MATCH_LENGTH=m -CONFIG_NETFILTER_XT_MATCH_LIMIT=m -CONFIG_NETFILTER_XT_MATCH_MAC=m -CONFIG_NETFILTER_XT_MATCH_MARK=m -CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m -# CONFIG_NETFILTER_XT_MATCH_OSF is not set -CONFIG_NETFILTER_XT_MATCH_OWNER=m -CONFIG_NETFILTER_XT_MATCH_POLICY=m -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m -CONFIG_NETFILTER_XT_MATCH_RATEEST=m -CONFIG_NETFILTER_XT_MATCH_REALM=m -CONFIG_NETFILTER_XT_MATCH_RECENT=m -CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_STATE=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m -CONFIG_NETFILTER_XT_MATCH_STRING=m -CONFIG_NETFILTER_XT_MATCH_TCPMSS=m -CONFIG_NETFILTER_XT_MATCH_TIME=m -CONFIG_NETFILTER_XT_MATCH_U32=m -CONFIG_IP_SET=m -CONFIG_IP_SET_MAX=256 -# CONFIG_IP_SET_BITMAP_IP is not set -# CONFIG_IP_SET_BITMAP_IPMAC is not set -# CONFIG_IP_SET_BITMAP_PORT is not set -# CONFIG_IP_SET_HASH_IP is not set -# CONFIG_IP_SET_HASH_IPPORT is not set -# CONFIG_IP_SET_HASH_IPPORTIP is not set -# CONFIG_IP_SET_HASH_IPPORTNET is not set -# CONFIG_IP_SET_HASH_NET is not set -# CONFIG_IP_SET_HASH_NETPORT is not set -# CONFIG_IP_SET_LIST_SET is not set -CONFIG_IP_VS=m -CONFIG_IP_VS_IPV6=y -CONFIG_IP_VS_DEBUG=y -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS transport protocol load balancing support -# -CONFIG_IP_VS_PROTO_TCP=y -CONFIG_IP_VS_PROTO_UDP=y -CONFIG_IP_VS_PROTO_AH_ESP=y -CONFIG_IP_VS_PROTO_ESP=y -CONFIG_IP_VS_PROTO_AH=y -# CONFIG_IP_VS_PROTO_SCTP is not set - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m -CONFIG_IP_VS_NFCT=y -CONFIG_IP_VS_PE_SIP=m - -# -# IP: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV4=m -CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_AH=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_NF_NAT=m -CONFIG_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_NF_NAT_SNMP_BASIC=m -CONFIG_NF_NAT_PROTO_DCCP=m -CONFIG_NF_NAT_PROTO_GRE=m -CONFIG_NF_NAT_PROTO_UDPLITE=m -CONFIG_NF_NAT_PROTO_SCTP=m -CONFIG_NF_NAT_FTP=m -CONFIG_NF_NAT_IRC=m -CONFIG_NF_NAT_TFTP=m -CONFIG_NF_NAT_AMANDA=m -CONFIG_NF_NAT_PPTP=m -CONFIG_NF_NAT_H323=m -CONFIG_NF_NAT_SIP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# IPv6: Netfilter Configuration -# -CONFIG_NF_DEFRAG_IPV6=m -CONFIG_NF_CONNTRACK_IPV6=m -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_AH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_MH=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -# CONFIG_BRIDGE_NF_EBTABLES is not set -CONFIG_IP_DCCP=m -CONFIG_INET_DCCP_DIAG=m - -# -# DCCP CCIDs Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP_CCID2_DEBUG is not set -CONFIG_IP_DCCP_CCID3=y -# CONFIG_IP_DCCP_CCID3_DEBUG is not set -CONFIG_IP_DCCP_TFRC_LIB=y - -# -# DCCP Kernel Hacking -# -# CONFIG_IP_DCCP_DEBUG is not set -CONFIG_IP_SCTP=m -# CONFIG_SCTP_DBG_MSG is not set -# CONFIG_SCTP_DBG_OBJCNT is not set -# CONFIG_SCTP_HMAC_NONE is not set -# CONFIG_SCTP_HMAC_SHA1 is not set -CONFIG_SCTP_HMAC_MD5=y -# CONFIG_RDS is not set -CONFIG_TIPC=m -# CONFIG_TIPC_ADVANCED is not set -# CONFIG_TIPC_DEBUG is not set -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -# CONFIG_ATM_CLIP_NO_ICMP is not set -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -# CONFIG_ATM_BR2684_IPFILTER is not set -CONFIG_L2TP=m -CONFIG_L2TP_DEBUGFS=m -CONFIG_L2TP_V3=y -CONFIG_L2TP_IP=m -CONFIG_L2TP_ETH=m -CONFIG_STP=m -CONFIG_GARP=m -CONFIG_BRIDGE=m -CONFIG_BRIDGE_IGMP_SNOOPING=y -# CONFIG_NET_DSA is not set -CONFIG_VLAN_8021Q=m -CONFIG_VLAN_8021Q_GVRP=y -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -CONFIG_WAN_ROUTER=m -# CONFIG_PHONET is not set -# CONFIG_IEEE802154 is not set -CONFIG_NET_SCHED=y - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_MULTIQ=m -CONFIG_NET_SCH_RED=m -# CONFIG_NET_SCH_SFB is not set -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_DRR=m -CONFIG_NET_SCH_MQPRIO=m -CONFIG_NET_SCH_CHOKE=m - -# -# Classification -# -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_CLS_U32_PERF=y -CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_FLOW=m -CONFIG_NET_CLS_CGROUP=m -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_CLS_ACT is not set -CONFIG_NET_CLS_IND=y -CONFIG_NET_SCH_FIFO=y -# CONFIG_DCB is not set -CONFIG_DNS_RESOLVER=y -# CONFIG_BATMAN_ADV is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -CONFIG_CAN=m -CONFIG_CAN_RAW=m -CONFIG_CAN_BCM=m - -# -# CAN Device Drivers -# -CONFIG_CAN_VCAN=m -CONFIG_CAN_SLCAN=m -# CONFIG_CAN_DEV is not set -# CONFIG_CAN_DEBUG_DEVICES is not set -CONFIG_IRDA=m - -# -# IrDA protocols -# -CONFIG_IRLAN=m -CONFIG_IRNET=m -CONFIG_IRCOMM=m -CONFIG_IRDA_ULTRA=y - -# -# IrDA options -# -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -CONFIG_IRDA_DEBUG=y - -# -# Infrared-port device drivers -# - -# -# SIR device drivers -# -CONFIG_IRTTY_SIR=m - -# -# Dongle support -# -CONFIG_DONGLE=y -CONFIG_ESI_DONGLE=m -CONFIG_ACTISYS_DONGLE=m -CONFIG_TEKRAM_DONGLE=m -CONFIG_TOIM3232_DONGLE=m -CONFIG_LITELINK_DONGLE=m -CONFIG_MA600_DONGLE=m -CONFIG_GIRBIL_DONGLE=m -CONFIG_MCP2120_DONGLE=m -CONFIG_OLD_BELKIN_DONGLE=m -# CONFIG_ACT200L_DONGLE is not set -CONFIG_KINGSUN_DONGLE=m -CONFIG_KSDAZZLE_DONGLE=m -CONFIG_KS959_DONGLE=m - -# -# FIR device drivers -# -CONFIG_USB_IRDA=m -CONFIG_SIGMATEL_FIR=m -CONFIG_MCS_FIR=m -CONFIG_BT=y -CONFIG_BT_L2CAP=y -CONFIG_BT_SCO=y -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=m - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIBTUSB=y -CONFIG_BT_HCIBTSDIO=m -CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_ATH3K=y -CONFIG_BT_HCIUART_LL=y -CONFIG_BT_HCIBCM203X=m -CONFIG_BT_HCIBPA10X=m -CONFIG_BT_HCIBFUSB=m -# CONFIG_BT_HCIVHCI is not set -CONFIG_BT_MRVL=m -# CONFIG_BT_MRVL_SDIO is not set -CONFIG_BT_ATH3K=m -CONFIG_BT_WILINK=m -CONFIG_AF_RXRPC=m -# CONFIG_AF_RXRPC_DEBUG is not set -# CONFIG_RXKAD is not set -CONFIG_FIB_RULES=y -CONFIG_WIRELESS=y -CONFIG_WIRELESS_EXT=y -CONFIG_WEXT_CORE=y -CONFIG_WEXT_PROC=y -CONFIG_WEXT_SPY=y -CONFIG_WEXT_PRIV=y -CONFIG_CFG80211=m -CONFIG_NL80211_TESTMODE=y -# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set -# CONFIG_CFG80211_REG_DEBUG is not set -CONFIG_CFG80211_DEFAULT_PS=y -# CONFIG_CFG80211_DEBUGFS is not set -# CONFIG_CFG80211_INTERNAL_REGDB is not set -CONFIG_CFG80211_WEXT=y -CONFIG_WIRELESS_EXT_SYSFS=y -CONFIG_LIB80211=y -CONFIG_LIB80211_CRYPT_WEP=m -CONFIG_LIB80211_CRYPT_CCMP=m -CONFIG_LIB80211_CRYPT_TKIP=m -# CONFIG_LIB80211_DEBUG is not set -CONFIG_MAC80211=m -CONFIG_MAC80211_HAS_RC=y -CONFIG_MAC80211_RC_PID=y -# CONFIG_MAC80211_RC_MINSTREL is not set -CONFIG_MAC80211_RC_DEFAULT_PID=y -CONFIG_MAC80211_RC_DEFAULT="pid" -# CONFIG_MAC80211_MESH is not set -CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set -# CONFIG_MAC80211_DEBUG_MENU is not set -CONFIG_WIMAX=m -CONFIG_WIMAX_DEBUG_LEVEL=8 -CONFIG_RFKILL=y -CONFIG_RFKILL_LEDS=y -CONFIG_RFKILL_INPUT=y -CONFIG_NET_9P=m -# CONFIG_NET_9P_DEBUG is not set -# CONFIG_CAIF is not set -CONFIG_CEPH_LIB=m -# CONFIG_CEPH_LIB_PRETTYDEBUG is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="" -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -CONFIG_FIRMWARE_IN_KERNEL=y -CONFIG_EXTRA_FIRMWARE="" -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_TESTS is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -CONFIG_SM_FTL=m -# CONFIG_MTD_OOPS is not set -CONFIG_MTD_SWAP=m - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_M25P80 is not set -# CONFIG_MTD_SST25L is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -CONFIG_MTD_NAND_ECC=y -# CONFIG_MTD_NAND_ECC_SMC is not set -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_BCH is not set -# CONFIG_MTD_SM_COMMON is not set -# CONFIG_MTD_NAND_MUSEUM_IDS is not set -# CONFIG_MTD_NAND_GPIO is not set -CONFIG_MTD_NAND_OMAP2=y -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_NANDSIM is not set -CONFIG_MTD_NAND_PLATFORM=y -# CONFIG_MTD_ALAUDA is not set -# CONFIG_MTD_ONENAND is not set - -# -# LPDDR flash memory drivers -# -# CONFIG_MTD_LPDDR is not set -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_WL_THRESHOLD=4096 -CONFIG_MTD_UBI_BEB_RESERVE=1 -# CONFIG_MTD_UBI_GLUEBI is not set -# CONFIG_MTD_UBI_DEBUG is not set -# 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_CRYPTOLOOP=m - -# -# DRBD disabled because PROC_FS, INET or CONNECTOR not selected -# -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB 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=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_MG_DISK is not set -# CONFIG_BLK_DEV_RBD is not set -# CONFIG_SENSORS_LIS3LV02D is not set -CONFIG_MISC_DEVICES=y -# CONFIG_AD525X_DPOT is not set -# CONFIG_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=m -# CONFIG_SENSORS_BH1770 is not set -# CONFIG_SENSORS_APDS990X is not set -CONFIG_HMC6352=m -# CONFIG_DS1682 is not set -# CONFIG_TI_DAC7512 is not set -CONFIG_BMP085=m -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -CONFIG_EEPROM_AT24=m -# CONFIG_EEPROM_AT25 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_MAX6875 is not set -CONFIG_EEPROM_93CX6=y -CONFIG_IWMC3200TOP=m -# CONFIG_IWMC3200TOP_DEBUG is not set -# CONFIG_IWMC3200TOP_DEBUGFS is not set - -# -# Texas Instruments shared transport line discipline -# -CONFIG_TI_ST=m -# CONFIG_SENSORS_LIS3_SPI is not set -# CONFIG_SENSORS_LIS3_I2C is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -CONFIG_SCSI_MOD=y -CONFIG_RAID_ATTRS=m -CONFIG_SCSI=y -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=y -CONFIG_CHR_DEV_SCH=m -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -CONFIG_SCSI_ISCSI_ATTRS=m -# 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=m -CONFIG_ISCSI_BOOT_SYSFS=m -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set -# CONFIG_ATA is not set -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID10=m -CONFIG_MD_RAID456=m -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m -CONFIG_BLK_DEV_DM=m -# CONFIG_DM_DEBUG is not set -CONFIG_DM_CRYPT=m -CONFIG_DM_SNAPSHOT=m -CONFIG_DM_MIRROR=m -CONFIG_DM_RAID=m -# CONFIG_DM_LOG_USERSPACE is not set -CONFIG_DM_ZERO=m -CONFIG_DM_MULTIPATH=m -# CONFIG_DM_MULTIPATH_QL is not set -# CONFIG_DM_MULTIPATH_ST is not set -CONFIG_DM_DELAY=m -# CONFIG_DM_UEVENT is not set -CONFIG_DM_FLAKEY=m -CONFIG_TARGET_CORE=m -CONFIG_TCM_IBLOCK=m -CONFIG_TCM_FILEIO=m -CONFIG_TCM_PSCSI=m -CONFIG_LOOPBACK_TARGET=m -# CONFIG_LOOPBACK_TARGET_CDB_DEBUG is not set -CONFIG_NETDEVICES=y -CONFIG_DUMMY=m -CONFIG_BONDING=m -CONFIG_MACVLAN=m -CONFIG_MACVTAP=m -CONFIG_EQUALIZER=m -CONFIG_TUN=m -CONFIG_VETH=m -CONFIG_MII=y -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -CONFIG_BCM63XX_PHY=m -# 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=m -# CONFIG_FIXED_PHY is not set -# CONFIG_MDIO_BITBANG is not set -CONFIG_NET_ETHERNET=y -# CONFIG_AX88796 is not set -CONFIG_SMC91X=y -# CONFIG_TI_DAVINCI_EMAC is not set -CONFIG_TI_DAVINCI_MDIO=m -CONFIG_TI_DAVINCI_CPDMA=m -# CONFIG_DM9000 is not set -CONFIG_ENC28J60=y -# CONFIG_ENC28J60_WRITEVERIFY is not set -# CONFIG_ETHOC is not set -CONFIG_SMC911X=y -CONFIG_SMSC911X=y -# CONFIG_SMSC911X_ARCH_HOOKS is not set -# CONFIG_DNET is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -# CONFIG_B44 is not set -CONFIG_KS8842=m -CONFIG_KS8851=y -# CONFIG_KS8851_MLL is not set -# CONFIG_FTMAC100 is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set -CONFIG_WLAN=y -# CONFIG_LIBERTAS_THINFIRM is not set -CONFIG_AT76C50X_USB=m -CONFIG_USB_ZD1201=m -CONFIG_USB_NET_RNDIS_WLAN=m -CONFIG_RTL8187=m -CONFIG_RTL8187_LEDS=y -# CONFIG_MAC80211_HWSIM is not set -# CONFIG_ATH_COMMON is not set -CONFIG_B43=m -# CONFIG_B43_SDIO is not set -CONFIG_B43_PIO=y -CONFIG_B43_PHY_N=y -CONFIG_B43_PHY_LP=y -CONFIG_B43_LEDS=y -CONFIG_B43_HWRNG=y -# CONFIG_B43_DEBUG is not set -# CONFIG_B43LEGACY is not set -CONFIG_HOSTAP=m -CONFIG_HOSTAP_FIRMWARE=y -CONFIG_HOSTAP_FIRMWARE_NVRAM=y -# CONFIG_IWM is not set -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -# CONFIG_LIBERTAS_SDIO is not set -# CONFIG_LIBERTAS_SPI is not set -# CONFIG_LIBERTAS_DEBUG is not set -# CONFIG_LIBERTAS_MESH is not set -CONFIG_P54_COMMON=m -CONFIG_P54_USB=m -# CONFIG_P54_SPI is not set -CONFIG_P54_LEDS=y -CONFIG_RT2X00=m -CONFIG_RT2500USB=m -CONFIG_RT73USB=m -# CONFIG_RT2800USB is not set -CONFIG_RT2X00_LIB_USB=m -CONFIG_RT2X00_LIB=m -CONFIG_RT2X00_LIB_FIRMWARE=y -CONFIG_RT2X00_LIB_CRYPTO=y -CONFIG_RT2X00_LIB_LEDS=y -# CONFIG_RT2X00_DEBUG is not set -CONFIG_RTL8192CU=m -CONFIG_RTLWIFI=m -CONFIG_RTL8192C_COMMON=m -CONFIG_WL1251=m -CONFIG_WL1251_SPI=m -CONFIG_WL1251_SDIO=m -CONFIG_WL12XX_MENU=m -CONFIG_WL12XX=m -CONFIG_WL12XX_HT=y -CONFIG_WL12XX_SPI=m -CONFIG_WL12XX_SDIO=m -# CONFIG_WL12XX_SDIO_TEST is not set -CONFIG_WL12XX_PLATFORM_DATA=y -CONFIG_ZD1211RW=m -# CONFIG_ZD1211RW_DEBUG is not set - -# -# WiMAX Wireless Broadband devices -# -CONFIG_WIMAX_I2400M=m -CONFIG_WIMAX_I2400M_USB=m -CONFIG_WIMAX_I2400M_SDIO=m -CONFIG_WIMAX_IWMC3200_SDIO=y -CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 - -# -# USB Network Adapters -# -CONFIG_USB_CATC=y -CONFIG_USB_KAWETH=y -CONFIG_USB_PEGASUS=y -CONFIG_USB_RTL8150=y -CONFIG_USB_USBNET=y -CONFIG_USB_NET_AX8817X=y -CONFIG_USB_NET_CDCETHER=y -# CONFIG_USB_NET_CDC_EEM is not set -CONFIG_USB_NET_CDC_NCM=m -CONFIG_USB_NET_DM9601=y -CONFIG_USB_NET_SMSC75XX=m -CONFIG_USB_NET_SMSC95XX=y -CONFIG_USB_NET_GL620A=y -CONFIG_USB_NET_NET1080=y -CONFIG_USB_NET_PLUSB=y -CONFIG_USB_NET_MCS7830=y -CONFIG_USB_NET_RNDIS_HOST=y -CONFIG_USB_NET_CDC_SUBSET=y -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AN2720=y -CONFIG_USB_BELKIN=y -CONFIG_USB_ARMLINUX=y -CONFIG_USB_EPSON2888=y -CONFIG_USB_KC2190=y -CONFIG_USB_NET_ZAURUS=y -CONFIG_USB_NET_CX82310_ETH=m -CONFIG_USB_HSO=m -CONFIG_USB_NET_INT51X1=m -CONFIG_USB_IPHETH=m -CONFIG_USB_SIERRA_NET=m -CONFIG_USB_VL600=m -# CONFIG_WAN is not set -CONFIG_ATM_DRIVERS=y -# CONFIG_ATM_DUMMY is not set -# CONFIG_ATM_TCP is not set - -# -# CAIF transport drivers -# -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_PPTP=m -# CONFIG_PPPOATM is not set -CONFIG_PPPOL2TP=m -# CONFIG_SLIP is not set -CONFIG_SLHC=m -CONFIG_NETCONSOLE=m -CONFIG_NETCONSOLE_DYNAMIC=y -CONFIG_NETPOLL=y -CONFIG_NETPOLL_TRAP=y -CONFIG_NET_POLL_CONTROLLER=y -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -CONFIG_INPUT_FF_MEMLESS=y -CONFIG_INPUT_POLLDEV=y -# CONFIG_INPUT_SPARSEKMAP is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV 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_ATKBD is not set -CONFIG_KEYBOARD_QT1070=m -CONFIG_KEYBOARD_QT2160=m -# CONFIG_KEYBOARD_LKKBD is not set -CONFIG_KEYBOARD_GPIO=y -# CONFIG_KEYBOARD_TCA6416 is not set -# CONFIG_KEYBOARD_MATRIX is not set -# CONFIG_KEYBOARD_LM8323 is not set -# CONFIG_KEYBOARD_MAX7359 is not set -CONFIG_KEYBOARD_MCS=m -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_OPENCORES is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_TWL4030 is not set -# CONFIG_KEYBOARD_XTKBD is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_ELANTECH is not set -# CONFIG_MOUSE_PS2_SENTELIC is not set -# CONFIG_MOUSE_PS2_TOUCHKIT is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_BCM5974 is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_MOUSE_GPIO is not set -# CONFIG_MOUSE_SYNAPTICS_I2C is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -CONFIG_INPUT_MISC=y -CONFIG_INPUT_AD714X=m -CONFIG_INPUT_AD714X_I2C=m -CONFIG_INPUT_AD714X_SPI=m -# CONFIG_INPUT_ATI_REMOTE is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_YEALINK is not set -# CONFIG_INPUT_CM109 is not set -CONFIG_INPUT_TWL4030_PWRBUTTON=y -CONFIG_INPUT_TWL4030_VIBRA=m -CONFIG_INPUT_UINPUT=y -CONFIG_INPUT_PCF8574=m -CONFIG_INPUT_PWM_BEEPER=m -# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set -CONFIG_INPUT_ADXL34X=m -CONFIG_INPUT_ADXL34X_I2C=m -CONFIG_INPUT_ADXL34X_SPI=m -CONFIG_INPUT_CMA3000=m -CONFIG_INPUT_CMA3000_I2C=m - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_SERIO_ALTERA_PS2 is not set -# CONFIG_SERIO_PS2MULT is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_CONSOLE_TRANSLATIONS=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_N_GSM=m -CONFIG_DEVKMEM=y - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=32 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_MAX3100 is not set -# CONFIG_SERIAL_MAX3107 is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_OMAP=y -CONFIG_SERIAL_OMAP_CONSOLE=y -# CONFIG_SERIAL_TIMBERDALE is not set -# CONFIG_SERIAL_ALTERA_JTAGUART is not set -# CONFIG_SERIAL_ALTERA_UART is not set -CONFIG_SERIAL_IFX6X60=m -CONFIG_TTY_PRINTK=y -# CONFIG_HVC_DCC is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_HW_RANDOM=y -# CONFIG_HW_RANDOM_TIMERIOMEM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_RAMOOPS is not set -CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y -CONFIG_I2C_COMPAT=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MUX=m - -# -# Multiplexer I2C Chip support -# -CONFIG_I2C_MUX_GPIO=m -# CONFIG_I2C_MUX_PCA9541 is not set -# CONFIG_I2C_MUX_PCA954x is not set -CONFIG_I2C_HELPER_AUTO=y -CONFIG_I2C_ALGOBIT=m - -# -# I2C Hardware Bus support -# - -# -# I2C system bus drivers (mostly embedded / system-on-chip) -# -# CONFIG_I2C_DESIGNWARE is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_OCORES is not set -CONFIG_I2C_OMAP=y -# CONFIG_I2C_PCA_PLATFORM is not set -# CONFIG_I2C_PXA_PCI is not set -# CONFIG_I2C_SIMTEC is not set -# CONFIG_I2C_XILINX is not set - -# -# External I2C/SMBus adapter drivers -# -CONFIG_I2C_DIOLAN_U2C=m -# 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_OC_TINY is not set -CONFIG_SPI_OMAP24XX=y -# CONFIG_SPI_PXA2XX_PCI is not set -# CONFIG_SPI_XILINX is not set -# CONFIG_SPI_DESIGNWARE is not set - -# -# SPI Protocol Masters -# -CONFIG_SPI_SPIDEV=y -# CONFIG_SPI_TLE62X0 is not set - -# -# PPS support -# -# CONFIG_PPS is not set - -# -# PPS generators support -# -CONFIG_ARCH_REQUIRE_GPIOLIB=y -CONFIG_GPIOLIB=y -# CONFIG_DEBUG_GPIO is not set -CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_MAX730X=m - -# -# Memory mapped GPIO expanders: -# -# CONFIG_GPIO_BASIC_MMIO is not set -# CONFIG_GPIO_IT8761E is not set - -# -# I2C GPIO expanders: -# -CONFIG_GPIO_MAX7300=m -# CONFIG_GPIO_MAX732X is not set -# CONFIG_GPIO_PCF857X is not set -# CONFIG_GPIO_SX150X is not set -CONFIG_GPIO_TWL4030=y -CONFIG_GPIO_ADP5588=m - -# -# PCI GPIO expanders: -# - -# -# SPI GPIO expanders: -# -# CONFIG_GPIO_MAX7301 is not set -# CONFIG_GPIO_MCP23S08 is not set -# CONFIG_GPIO_MC33880 is not set -# CONFIG_GPIO_74X164 is not set - -# -# AC97 GPIO expanders: -# - -# -# MODULbus GPIO expanders: -# -# CONFIG_W1 is not set -CONFIG_POWER_SUPPLY=m -# CONFIG_POWER_SUPPLY_DEBUG is not set -# CONFIG_PDA_POWER is not set -CONFIG_TEST_POWER=m -# CONFIG_BATTERY_DS2782 is not set -# CONFIG_BATTERY_BQ20Z75 is not set -# CONFIG_BATTERY_BQ27x00 is not set -# CONFIG_BATTERY_MAX17040 is not set -CONFIG_BATTERY_MAX17042=m -CONFIG_CHARGER_ISP1704=m -CONFIG_CHARGER_TWL4030=m -CONFIG_CHARGER_GPIO=m -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Native drivers -# -# 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_ADT7411=m -# CONFIG_SENSORS_ADT7462 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_ADT7475 is not set -CONFIG_SENSORS_ASC7621=m -# CONFIG_SENSORS_ATXP1 is not set -CONFIG_SENSORS_DS620=m -# 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=m -# CONFIG_SENSORS_IT87 is not set -CONFIG_SENSORS_JC42=m -# 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_LM95241 is not set -# CONFIG_SENSORS_MAX1111 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6639 is not set -# CONFIG_SENSORS_MAX6650 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_SMM665=m -# CONFIG_SENSORS_DME1737 is not set -CONFIG_SENSORS_EMC1403=m -CONFIG_SENSORS_EMC2103=m -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SCH5627 is not set -# CONFIG_SENSORS_ADS1015 is not set -# CONFIG_SENSORS_ADS7828 is not set -CONFIG_SENSORS_ADS7871=m -CONFIG_SENSORS_AMC6821=m -# CONFIG_SENSORS_THMC50 is not set -CONFIG_SENSORS_TMP102=m -# CONFIG_SENSORS_TMP401 is not set -# CONFIG_SENSORS_TMP421 is not set -CONFIG_SENSORS_TWL4030_MADC=m -# 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_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_OMAP_WATCHDOG=y -# CONFIG_TWL4030_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=y -CONFIG_SSB_BLOCKIO=y -CONFIG_SSB_SDIOHOST_POSSIBLE=y -# CONFIG_SSB_SDIOHOST is not set -# CONFIG_SSB_SILENT is not set -# CONFIG_SSB_DEBUG is not set -CONFIG_MFD_SUPPORT=y -CONFIG_MFD_CORE=y -# CONFIG_MFD_88PM860X is not set -# CONFIG_MFD_SM501 is not set -# CONFIG_MFD_ASIC3 is not set -# CONFIG_HTC_EGPIO is not set -# CONFIG_HTC_PASIC3 is not set -# CONFIG_HTC_I2CPLD is not set -CONFIG_TPS6105X=m -# CONFIG_TPS65010 is not set -CONFIG_TPS6507X=m -CONFIG_TWL4030_CORE=y -CONFIG_TWL4030_MADC=m -CONFIG_TWL4030_POWER=y -CONFIG_TWL4030_SCRIPT=y -CONFIG_TWL4030_CODEC=y -CONFIG_TWL4030_POWEROFF=y -CONFIG_TWL6030_PWM=m -# CONFIG_MFD_STMPE is not set -# CONFIG_MFD_TC3589X is not set -# CONFIG_MFD_TMIO is not set -# CONFIG_MFD_T7L66XB is not set -# CONFIG_MFD_TC6387XB is not set -# CONFIG_MFD_TC6393XB is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_PMIC_ADP5520 is not set -# CONFIG_MFD_MAX8925 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX8998 is not set -# CONFIG_MFD_WM8400 is not set -# CONFIG_MFD_WM831X_I2C is not set -# CONFIG_MFD_WM831X_SPI is not set -# CONFIG_MFD_WM8350_I2C is not set -# CONFIG_MFD_WM8994 is not set -# CONFIG_MFD_PCF50633 is not set -# CONFIG_MFD_MC13XXX is not set -# CONFIG_ABX500_CORE is not set -# CONFIG_EZX_PCAP is not set -CONFIG_MFD_TPS6586X=y -CONFIG_MFD_WL1273_CORE=m -CONFIG_MFD_OMAP_USB_HOST=y -CONFIG_REGULATOR=y -# CONFIG_REGULATOR_DEBUG is not set -CONFIG_REGULATOR_DUMMY=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set -# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set -# CONFIG_REGULATOR_BQ24022 is not set -# CONFIG_REGULATOR_MAX1586 is not set -# CONFIG_REGULATOR_MAX8649 is not set -# CONFIG_REGULATOR_MAX8660 is not set -# CONFIG_REGULATOR_MAX8952 is not set -CONFIG_REGULATOR_TWL4030=y -# CONFIG_REGULATOR_LP3971 is not set -# CONFIG_REGULATOR_LP3972 is not set -CONFIG_REGULATOR_TPS6105X=m -# CONFIG_REGULATOR_TPS65023 is not set -# CONFIG_REGULATOR_TPS6507X is not set -# CONFIG_REGULATOR_ISL6271A is not set -# CONFIG_REGULATOR_AD5398 is not set -CONFIG_REGULATOR_TPS6586X=m -CONFIG_REGULATOR_TPS6524X=m -CONFIG_MEDIA_SUPPORT=y - -# -# Multimedia core support -# -CONFIG_MEDIA_CONTROLLER=y -CONFIG_VIDEO_DEV=y -CONFIG_VIDEO_V4L2_COMMON=y -CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_DVB_CORE=m -CONFIG_VIDEO_MEDIA=m - -# -# Multimedia drivers -# -CONFIG_RC_CORE=m -CONFIG_LIRC=m -CONFIG_RC_MAP=m -CONFIG_IR_NEC_DECODER=m -CONFIG_IR_RC5_DECODER=m -CONFIG_IR_RC6_DECODER=m -CONFIG_IR_JVC_DECODER=m -CONFIG_IR_SONY_DECODER=m -CONFIG_IR_RC5_SZ_DECODER=m -CONFIG_IR_LIRC_CODEC=m -# CONFIG_IR_IMON is not set -# CONFIG_IR_MCEUSB is not set -# CONFIG_IR_STREAMZAP is not set -CONFIG_RC_LOOPBACK=m -CONFIG_MEDIA_ATTACH=y -CONFIG_MEDIA_TUNER=m -CONFIG_MEDIA_TUNER_CUSTOMISE=y - -# -# Customize TV tuners -# -CONFIG_MEDIA_TUNER_SIMPLE=m -CONFIG_MEDIA_TUNER_TDA8290=m -CONFIG_MEDIA_TUNER_TDA827X=m -CONFIG_MEDIA_TUNER_TDA18271=m -CONFIG_MEDIA_TUNER_TDA9887=m -CONFIG_MEDIA_TUNER_TEA5761=m -CONFIG_MEDIA_TUNER_TEA5767=m -CONFIG_MEDIA_TUNER_MT20XX=m -CONFIG_MEDIA_TUNER_MT2060=m -CONFIG_MEDIA_TUNER_MT2266=m -CONFIG_MEDIA_TUNER_MT2131=m -CONFIG_MEDIA_TUNER_QT1010=m -CONFIG_MEDIA_TUNER_XC2028=m -CONFIG_MEDIA_TUNER_XC5000=m -CONFIG_MEDIA_TUNER_MXL5005S=m -CONFIG_MEDIA_TUNER_MXL5007T=m -CONFIG_MEDIA_TUNER_MC44S803=m -CONFIG_MEDIA_TUNER_MAX2165=m -CONFIG_MEDIA_TUNER_TDA18218=m -CONFIG_VIDEO_V4L2=y -CONFIG_VIDEOBUF_GEN=y -CONFIG_VIDEOBUF_VMALLOC=m -CONFIG_VIDEOBUF_DMA_CONTIG=y -CONFIG_VIDEOBUF_DVB=m -CONFIG_VIDEO_TVEEPROM=m -CONFIG_VIDEO_TUNER=m -CONFIG_V4L2_MEM2MEM_DEV=m -CONFIG_VIDEOBUF2_CORE=m -CONFIG_VIDEOBUF2_MEMOPS=m -CONFIG_VIDEOBUF2_VMALLOC=m -CONFIG_VIDEO_CAPTURE_DRIVERS=y -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set -# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set -CONFIG_VIDEO_IR_I2C=m - -# -# Encoders/decoders and other helper chips -# - -# -# Audio decoders -# -# CONFIG_VIDEO_TVAUDIO is not set -# CONFIG_VIDEO_TDA7432 is not set -# CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TEA6415C is not set -# CONFIG_VIDEO_TEA6420 is not set -CONFIG_VIDEO_MSP3400=m -# CONFIG_VIDEO_CS5345 is not set -CONFIG_VIDEO_CS53L32A=m -# CONFIG_VIDEO_M52790 is not set -# CONFIG_VIDEO_TLV320AIC23B is not set -CONFIG_VIDEO_WM8775=m -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_VP27SMPX is not set - -# -# RDS decoders -# -# CONFIG_VIDEO_SAA6588 is not set - -# -# Video decoders -# -CONFIG_VIDEO_ADV7180=m -# 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_OV7670=m -CONFIG_VIDEO_MT9P031=y -CONFIG_VIDEO_MT9V011=m -CONFIG_VIDEO_MT9V032=y -# CONFIG_VIDEO_TCM825X is not set -# CONFIG_VIDEO_SAA7110 is not set -CONFIG_VIDEO_SAA711X=m -# CONFIG_VIDEO_SAA717X is not set -# CONFIG_VIDEO_SAA7191 is not set -CONFIG_VIDEO_TVP514X=m -CONFIG_VIDEO_TVP5150=m -CONFIG_VIDEO_TVP7002=m -# CONFIG_VIDEO_VPX3220 is not set - -# -# Video and audio decoders -# -CONFIG_VIDEO_CX25840=m - -# -# MPEG video encoders -# -CONFIG_VIDEO_CX2341X=m - -# -# Video encoders -# -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_SAA7185 is not set -# CONFIG_VIDEO_ADV7170 is not set -# CONFIG_VIDEO_ADV7175 is not set -# CONFIG_VIDEO_THS7303 is not set -# CONFIG_VIDEO_ADV7343 is not set -# CONFIG_VIDEO_AK881X is not set - -# -# Video improvement chips -# -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set -CONFIG_VIDEO_VIVI=m -CONFIG_VIDEO_VPSS_SYSTEM=m -CONFIG_VIDEO_VPFE_CAPTURE=y -CONFIG_VIDEO_DM6446_CCDC=m -CONFIG_VIDEO_OMAP2_VOUT=y -# CONFIG_VIDEO_CPIA2 is not set -CONFIG_VIDEO_TIMBERDALE=m -# CONFIG_VIDEO_AU0828 is not set -CONFIG_VIDEO_SR030PC30=m -CONFIG_VIDEO_NOON010PC30=m -CONFIG_VIDEO_OMAP3=y -CONFIG_VIDEO_OMAP3_DEBUG=y -# CONFIG_SOC_CAMERA is not set -CONFIG_V4L_USB_DRIVERS=y -CONFIG_USB_VIDEO_CLASS=m -CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y -CONFIG_USB_GSPCA=m -CONFIG_USB_M5602=m -CONFIG_USB_STV06XX=m -# CONFIG_USB_GL860 is not set -CONFIG_USB_GSPCA_BENQ=m -CONFIG_USB_GSPCA_CONEX=m -CONFIG_USB_GSPCA_CPIA1=m -CONFIG_USB_GSPCA_ETOMS=m -CONFIG_USB_GSPCA_FINEPIX=m -# CONFIG_USB_GSPCA_JEILINJ is not set -CONFIG_USB_GSPCA_KONICA=m -CONFIG_USB_GSPCA_MARS=m -# CONFIG_USB_GSPCA_MR97310A is not set -CONFIG_USB_GSPCA_NW80X=m -CONFIG_USB_GSPCA_OV519=m -CONFIG_USB_GSPCA_OV534=m -CONFIG_USB_GSPCA_OV534_9=m -CONFIG_USB_GSPCA_PAC207=m -# CONFIG_USB_GSPCA_PAC7302 is not set -CONFIG_USB_GSPCA_PAC7311=m -CONFIG_USB_GSPCA_SN9C2028=m -# CONFIG_USB_GSPCA_SN9C20X is not set -CONFIG_USB_GSPCA_SONIXB=m -CONFIG_USB_GSPCA_SONIXJ=m -CONFIG_USB_GSPCA_SPCA500=m -CONFIG_USB_GSPCA_SPCA501=m -CONFIG_USB_GSPCA_SPCA505=m -CONFIG_USB_GSPCA_SPCA506=m -CONFIG_USB_GSPCA_SPCA508=m -CONFIG_USB_GSPCA_SPCA561=m -CONFIG_USB_GSPCA_SPCA1528=m -# CONFIG_USB_GSPCA_SQ905 is not set -# CONFIG_USB_GSPCA_SQ905C is not set -CONFIG_USB_GSPCA_SQ930X=m -CONFIG_USB_GSPCA_STK014=m -# CONFIG_USB_GSPCA_STV0680 is not set -CONFIG_USB_GSPCA_SUNPLUS=m -CONFIG_USB_GSPCA_T613=m -CONFIG_USB_GSPCA_TV8532=m -CONFIG_USB_GSPCA_VC032X=m -CONFIG_USB_GSPCA_VICAM=m -CONFIG_USB_GSPCA_XIRLINK_CIT=m -CONFIG_USB_GSPCA_ZC3XX=m -CONFIG_VIDEO_PVRUSB2=m -CONFIG_VIDEO_PVRUSB2_SYSFS=y -CONFIG_VIDEO_PVRUSB2_DVB=y -# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set -CONFIG_VIDEO_HDPVR=m -CONFIG_VIDEO_EM28XX=m -CONFIG_VIDEO_EM28XX_ALSA=m -CONFIG_VIDEO_EM28XX_DVB=m -CONFIG_VIDEO_TLG2300=m -CONFIG_VIDEO_CX231XX=m -CONFIG_VIDEO_CX231XX_RC=y -# CONFIG_VIDEO_CX231XX_ALSA is not set -CONFIG_VIDEO_CX231XX_DVB=m -CONFIG_VIDEO_USBVISION=m -CONFIG_USB_ET61X251=m -CONFIG_USB_SN9C102=m -CONFIG_USB_PWC=m -# CONFIG_USB_PWC_DEBUG is not set -CONFIG_USB_PWC_INPUT_EVDEV=y -CONFIG_USB_ZR364XX=m -CONFIG_USB_STKWEBCAM=m -CONFIG_USB_S2255=m -CONFIG_V4L_MEM2MEM_DRIVERS=y -CONFIG_VIDEO_MEM2MEM_TESTDEV=m -CONFIG_RADIO_ADAPTERS=y -# CONFIG_I2C_SI4713 is not set -# CONFIG_RADIO_SI4713 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_RADIO_SI470X is not set -# CONFIG_USB_MR800 is not set -# CONFIG_RADIO_TEA5764 is not set -CONFIG_RADIO_SAA7706H=m -# CONFIG_RADIO_TEF6862 is not set -CONFIG_RADIO_WL1273=m - -# -# Texas Instruments WL128x FM driver (ST based) -# -CONFIG_RADIO_WL128X=m -CONFIG_DVB_MAX_ADAPTERS=8 -CONFIG_DVB_DYNAMIC_MINORS=y -CONFIG_DVB_CAPTURE_DRIVERS=y -# CONFIG_TTPCI_EEPROM is not set - -# -# Supported USB Adapters -# -CONFIG_DVB_USB=m -# CONFIG_DVB_USB_DEBUG is not set -CONFIG_DVB_USB_A800=m -CONFIG_DVB_USB_DIBUSB_MB=m -# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set -CONFIG_DVB_USB_DIBUSB_MC=m -CONFIG_DVB_USB_DIB0700=m -CONFIG_DVB_USB_UMT_010=m -CONFIG_DVB_USB_CXUSB=m -CONFIG_DVB_USB_M920X=m -CONFIG_DVB_USB_GL861=m -CONFIG_DVB_USB_AU6610=m -CONFIG_DVB_USB_DIGITV=m -CONFIG_DVB_USB_VP7045=m -CONFIG_DVB_USB_VP702X=m -CONFIG_DVB_USB_GP8PSK=m -CONFIG_DVB_USB_NOVA_T_USB2=m -CONFIG_DVB_USB_TTUSB2=m -CONFIG_DVB_USB_DTT200U=m -CONFIG_DVB_USB_OPERA1=m -CONFIG_DVB_USB_AF9005=m -CONFIG_DVB_USB_AF9005_REMOTE=m -CONFIG_DVB_USB_DW2102=m -CONFIG_DVB_USB_CINERGY_T2=m -CONFIG_DVB_USB_ANYSEE=m -CONFIG_DVB_USB_DTV5100=m -CONFIG_DVB_USB_AF9015=m -# CONFIG_DVB_USB_CE6230 is not set -# CONFIG_DVB_USB_FRIIO is not set -# CONFIG_DVB_USB_EC168 is not set -CONFIG_DVB_USB_AZ6027=m -CONFIG_DVB_USB_LME2510=m -CONFIG_DVB_USB_TECHNISAT_USB2=m -# CONFIG_SMS_SIANO_MDTV is not set - -# -# Supported FlexCopII (B2C2) Adapters -# -CONFIG_DVB_B2C2_FLEXCOP=m -CONFIG_DVB_B2C2_FLEXCOP_USB=m -# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set - -# -# Supported DVB Frontends -# -# CONFIG_DVB_FE_CUSTOMISE is not set - -# -# Multistandard (satellite) frontends -# -CONFIG_DVB_STB0899=m -CONFIG_DVB_STB6100=m -CONFIG_DVB_STV090x=m -CONFIG_DVB_STV6110x=m - -# -# DVB-S (satellite) frontends -# -CONFIG_DVB_CX24123=m -CONFIG_DVB_MT312=m -CONFIG_DVB_ZL10039=m -CONFIG_DVB_S5H1420=m -CONFIG_DVB_STV0288=m -CONFIG_DVB_STB6000=m -CONFIG_DVB_STV0299=m -CONFIG_DVB_STV6110=m -CONFIG_DVB_STV0900=m -CONFIG_DVB_TDA10086=m -CONFIG_DVB_TUNER_ITD1000=m -CONFIG_DVB_TUNER_CX24113=m -CONFIG_DVB_TDA826X=m -CONFIG_DVB_CX24116=m -CONFIG_DVB_SI21XX=m -CONFIG_DVB_DS3000=m - -# -# DVB-T (terrestrial) frontends -# -CONFIG_DVB_CX22702=m -CONFIG_DVB_TDA1004X=m -CONFIG_DVB_NXT6000=m -CONFIG_DVB_MT352=m -CONFIG_DVB_ZL10353=m -CONFIG_DVB_DIB3000MB=m -CONFIG_DVB_DIB3000MC=m -CONFIG_DVB_DIB7000M=m -CONFIG_DVB_DIB7000P=m -CONFIG_DVB_TDA10048=m -CONFIG_DVB_AF9013=m - -# -# DVB-C (cable) frontends -# -CONFIG_DVB_TDA10023=m -CONFIG_DVB_STV0297=m - -# -# ATSC (North American/Korean Terrestrial/Cable DTV) frontends -# -CONFIG_DVB_NXT200X=m -CONFIG_DVB_BCM3510=m -CONFIG_DVB_LGDT330X=m -CONFIG_DVB_LGDT3305=m -CONFIG_DVB_S5H1409=m -CONFIG_DVB_S5H1411=m - -# -# ISDB-T (terrestrial) frontends -# -CONFIG_DVB_S921=m -CONFIG_DVB_DIB8000=m -CONFIG_DVB_MB86A20S=m - -# -# Digital terrestrial only tuners/PLL -# -CONFIG_DVB_PLL=m -CONFIG_DVB_TUNER_DIB0070=m -CONFIG_DVB_TUNER_DIB0090=m - -# -# SEC control devices for DVB-S -# -CONFIG_DVB_LNBP21=m -CONFIG_DVB_ISL6421=m -CONFIG_DVB_LGS8GXX=m -CONFIG_DVB_ATBM8830=m -CONFIG_DVB_IX2505V=m - -# -# Tools to develop new frontends -# -# CONFIG_DVB_DUMMY_FE is not set - -# -# Graphics support -# -CONFIG_DRM=m -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID 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=m -CONFIG_FB_SYS_COPYAREA=m -CONFIG_FB_SYS_IMAGEBLIT=m -# CONFIG_FB_FOREIGN_ENDIAN is not set -CONFIG_FB_SYS_FOPS=m -# CONFIG_FB_WMT_GE_ROPS is not set -CONFIG_FB_DEFERRED_IO=y -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -CONFIG_FB_MODE_HELPERS=y -# CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_TMIO is not set -CONFIG_FB_UDL=m -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FB_METRONOME is not set -# CONFIG_FB_MB862XX is not set -# CONFIG_FB_BROADSHEET is not set -# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set -CONFIG_OMAP2_VRAM=y -CONFIG_OMAP2_VRFB=y -CONFIG_OMAP2_DSS=y -CONFIG_OMAP2_VRAM_SIZE=14 -CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y -# CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS is not set -CONFIG_OMAP2_DSS_DPI=y -# CONFIG_OMAP2_DSS_RFBI is not set -CONFIG_OMAP2_DSS_VENC=y -# CONFIG_OMAP2_DSS_SDI is not set -CONFIG_OMAP2_DSS_DSI=y -CONFIG_OMAP2_DSS_USE_DSI_PLL=y -# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set -CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0 -CONFIG_FB_OMAP2=y -CONFIG_FB_OMAP2_DEBUG_SUPPORT=y -CONFIG_FB_OMAP2_NUM_FBS=2 - -# -# OMAP2/3 Display Device Drivers -# -CONFIG_PANEL_GENERIC_DPI=y -# CONFIG_PANEL_LGPHILIPS_LB035Q02 is not set -CONFIG_PANEL_SHARP_LS037V7DW01=y -CONFIG_PANEL_NEC_NL8048HL11_01B=y -# CONFIG_PANEL_TAAL is not set -CONFIG_PANEL_TPO_TD043MTEA1=m -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y - -# -# Display device support -# -CONFIG_DISPLAY_SUPPORT=y - -# -# Display hardware drivers -# - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_LOGO_LINUX_CLUT224=y -CONFIG_SOUND=y -CONFIG_SOUND_OSS_CORE=y -CONFIG_SOUND_OSS_CORE_PRECLAIM=y -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_HWDEP=y -CONFIG_SND_RAWMIDI=y -CONFIG_SND_JACK=y -CONFIG_SND_SEQUENCER=m -# CONFIG_SND_SEQ_DUMMY 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_SEQUENCER_OSS=y -CONFIG_SND_HRTIMER=m -CONFIG_SND_SEQ_HRTIMER_DEFAULT=y -CONFIG_SND_DYNAMIC_MINORS=y -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -CONFIG_SND_RAWMIDI_SEQ=m -# CONFIG_SND_OPL3_LIB_SEQ is not set -# CONFIG_SND_OPL4_LIB_SEQ is not set -# CONFIG_SND_SBAWE_SEQ is not set -# CONFIG_SND_EMU10K1_SEQ is not set -CONFIG_SND_DRIVERS=y -# CONFIG_SND_DUMMY is not set -CONFIG_SND_ALOOP=m -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_ARM is not set -CONFIG_SND_SPI=y -CONFIG_SND_USB=y -CONFIG_SND_USB_AUDIO=y -CONFIG_SND_USB_UA101=m -CONFIG_SND_USB_CAIAQ=m -CONFIG_SND_USB_CAIAQ_INPUT=y -CONFIG_SND_USB_6FIRE=m -CONFIG_SND_SOC=y -CONFIG_SND_SOC_CACHE_LZO=y -CONFIG_SND_OMAP_SOC=y -CONFIG_SND_OMAP_SOC_MCBSP=y -CONFIG_SND_OMAP_SOC_OVERO=y -CONFIG_SND_OMAP_SOC_OMAP3EVM=y -CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE=y -CONFIG_SND_OMAP_SOC_ZOOM2=y -CONFIG_SND_SOC_I2C_AND_SPI=y -# CONFIG_SND_SOC_ALL_CODECS is not set -CONFIG_SND_SOC_TWL4030=y -# CONFIG_SOUND_PRIME is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HIDRAW is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_HID_PID is not set -# CONFIG_USB_HIDDEV is not set - -# -# Special HID drivers -# -# CONFIG_HID_3M_PCT is not set -CONFIG_HID_A4TECH=y -CONFIG_HID_ACRUX=m -# CONFIG_HID_ACRUX_FF is not set -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -# CONFIG_HID_CANDO is not set -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -# CONFIG_HID_PRODIKEYS is not set -CONFIG_HID_CYPRESS=y -# CONFIG_HID_DRAGONRISE is not set -CONFIG_HID_EMS_FF=m -# CONFIG_HID_ELECOM is not set -CONFIG_HID_EZKEY=y -CONFIG_HID_KEYTOUCH=m -# CONFIG_HID_KYE is not set -CONFIG_HID_UCLOGIC=m -CONFIG_HID_WALTOP=m -CONFIG_HID_GYRATION=y -# CONFIG_HID_TWINHAN is not set -# CONFIG_HID_KENSINGTON is not set -CONFIG_HID_LCPOWER=m -CONFIG_HID_LOGITECH=y -# CONFIG_LOGITECH_FF is not set -# CONFIG_LOGIRUMBLEPAD2_FF is not set -# CONFIG_LOGIG940_FF is not set -# CONFIG_LOGIWII_FF is not set -CONFIG_HID_MAGICMOUSE=m -CONFIG_HID_MICROSOFT=y -# CONFIG_HID_MOSART is not set -CONFIG_HID_MONTEREY=y -CONFIG_HID_MULTITOUCH=m -CONFIG_HID_NTRIG=y -# CONFIG_HID_ORTEK is not set -CONFIG_HID_PANTHERLORD=y -# CONFIG_PANTHERLORD_FF is not set -CONFIG_HID_PETALYNX=y -CONFIG_HID_PICOLCD=m -CONFIG_HID_PICOLCD_FB=y -CONFIG_HID_PICOLCD_BACKLIGHT=y -CONFIG_HID_PICOLCD_LEDS=y -CONFIG_HID_QUANTA=m -CONFIG_HID_ROCCAT=m -CONFIG_HID_ROCCAT_COMMON=m -CONFIG_HID_ROCCAT_ARVO=m -CONFIG_HID_ROCCAT_KONE=m -CONFIG_HID_ROCCAT_KONEPLUS=m -CONFIG_HID_ROCCAT_KOVAPLUS=m -# CONFIG_HID_ROCCAT_PYRA is not set -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SONY=y -CONFIG_HID_STANTUM=m -CONFIG_HID_SUNPLUS=y -# CONFIG_HID_GREENASIA is not set -# CONFIG_HID_SMARTJOYPLUS is not set -CONFIG_HID_TOPSEED=y -# CONFIG_HID_THRUSTMASTER is not set -# CONFIG_HID_WACOM is not set -# CONFIG_HID_ZEROPLUS is not set -# CONFIG_HID_ZYDACRON is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -CONFIG_USB_DEVICE_CLASS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -CONFIG_USB_SUSPEND=y -CONFIG_USB_OTG=y -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set -CONFIG_USB_MON=y -# CONFIG_USB_WUSB is not set -# CONFIG_USB_WUSB_CBAF is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_C67X00_HCD is not set -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -CONFIG_USB_EHCI_TT_NEWSCHED=y -CONFIG_USB_EHCI_HCD_OMAP=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_U132_HCD is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_HWA_HCD is not set -CONFIG_USB_MUSB_HDRC=y -# CONFIG_USB_MUSB_TUSB6010 is not set -CONFIG_USB_MUSB_OMAP2PLUS=y -# CONFIG_USB_MUSB_AM35X is not set -# CONFIG_USB_MUSB_HOST is not set -# CONFIG_USB_MUSB_PERIPHERAL is not set -CONFIG_USB_MUSB_OTG=y -CONFIG_USB_GADGET_MUSB_HDRC=y -CONFIG_USB_MUSB_HDRC_HCD=y -# CONFIG_MUSB_PIO_ONLY is not set -CONFIG_USB_INVENTRA_DMA=y -# CONFIG_USB_TI_CPPI_DMA is not set -# CONFIG_USB_MUSB_DEBUG is not set - -# -# USB Device Class drivers -# -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m -CONFIG_USB_WDM=m -CONFIG_USB_TMC=m - -# -# 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=m -# 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=m -CONFIG_USB_UAS=m -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB port drivers -# -CONFIG_USB_SERIAL=m -CONFIG_USB_EZUSB=y -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_AIRCABLE=m -CONFIG_USB_SERIAL_ARK3116=m -CONFIG_USB_SERIAL_BELKIN=m -CONFIG_USB_SERIAL_CH341=m -# CONFIG_USB_SERIAL_WHITEHEAT is not set -CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -# CONFIG_USB_SERIAL_CP210X is not set -CONFIG_USB_SERIAL_CYPRESS_M8=m -CONFIG_USB_SERIAL_EMPEG=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_FUNSOFT=m -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_IPAQ=m -CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m -CONFIG_USB_SERIAL_GARMIN=m -CONFIG_USB_SERIAL_IPW=m -CONFIG_USB_SERIAL_IUU=m -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KEYSPAN=m -CONFIG_USB_SERIAL_KEYSPAN_MPR=y -CONFIG_USB_SERIAL_KEYSPAN_USA28=y -CONFIG_USB_SERIAL_KEYSPAN_USA28X=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -CONFIG_USB_SERIAL_KEYSPAN_USA19=y -CONFIG_USB_SERIAL_KEYSPAN_USA18X=y -CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -CONFIG_USB_SERIAL_KEYSPAN_USA49W=y -CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -CONFIG_USB_SERIAL_KLSI=m -CONFIG_USB_SERIAL_KOBIL_SCT=m -CONFIG_USB_SERIAL_MCT_U232=m -CONFIG_USB_SERIAL_MOS7720=m -CONFIG_USB_SERIAL_MOS7840=m -CONFIG_USB_SERIAL_MOTOROLA=m -CONFIG_USB_SERIAL_NAVMAN=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_OTI6858=m -CONFIG_USB_SERIAL_QCAUX=m -# CONFIG_USB_SERIAL_QUALCOMM is not set -CONFIG_USB_SERIAL_SPCP8X5=m -CONFIG_USB_SERIAL_HP4X=m -CONFIG_USB_SERIAL_SAFE=m -# CONFIG_USB_SERIAL_SAFE_PADDED is not set -CONFIG_USB_SERIAL_SAMBA=m -CONFIG_USB_SERIAL_SIEMENS_MPI=m -CONFIG_USB_SERIAL_SIERRAWIRELESS=m -# CONFIG_USB_SERIAL_SYMBOL is not set -# CONFIG_USB_SERIAL_TI is not set -CONFIG_USB_SERIAL_CYBERJACK=m -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OPTION is not set -CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_SERIAL_OPTICON=m -CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m -CONFIG_USB_SERIAL_ZIO=m -CONFIG_USB_SERIAL_SSU100=m -CONFIG_USB_SERIAL_DEBUG=m - -# -# USB Miscellaneous drivers -# -CONFIG_USB_EMI62=m -CONFIG_USB_EMI26=m -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_SEVSEG is not set -# CONFIG_USB_RIO500 is not set -CONFIG_USB_LEGOTOWER=m -CONFIG_USB_LCD=m -CONFIG_USB_LED=m -CONFIG_USB_CYPRESS_CY7C63=m -CONFIG_USB_CYTHERM=m -CONFIG_USB_IDMOUSE=m -CONFIG_USB_FTDI_ELAN=m -# CONFIG_USB_APPLEDISPLAY is not set -CONFIG_USB_SISUSBVGA=m -CONFIG_USB_SISUSBVGA_CON=y -CONFIG_USB_LD=m -CONFIG_USB_TRANCEVIBRATOR=m -# CONFIG_USB_IOWARRIOR is not set -CONFIG_USB_TEST=m -# CONFIG_USB_ISIGHTFW is not set -CONFIG_USB_YUREX=m -CONFIG_USB_ATM=m -CONFIG_USB_SPEEDTOUCH=m -CONFIG_USB_CXACRU=m -CONFIG_USB_UEAGLEATM=m -CONFIG_USB_XUSBATM=m -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG is not set -# CONFIG_USB_GADGET_DEBUG_FILES is not set -CONFIG_USB_GADGET_DEBUG_FS=y -CONFIG_USB_GADGET_VBUS_DRAW=480 -CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_FUSB300 is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_R8A66597 is not set -# CONFIG_USB_GADGET_PXA_U2O is not set -# CONFIG_USB_GADGET_M66592 is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -CONFIG_USB_GADGET_DUALSPEED=y -# CONFIG_USB_ZERO is not set -# CONFIG_USB_AUDIO is not set -CONFIG_USB_ETH=m -CONFIG_USB_ETH_RNDIS=y -# CONFIG_USB_ETH_EEM is not set -CONFIG_USB_G_NCM=m -# CONFIG_USB_GADGETFS is not set -CONFIG_USB_FUNCTIONFS=m -# CONFIG_USB_FUNCTIONFS_ETH is not set -CONFIG_USB_FUNCTIONFS_RNDIS=y -# CONFIG_USB_FUNCTIONFS_GENERIC is not set -# CONFIG_USB_FILE_STORAGE 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_MULTI is not set -CONFIG_USB_G_HID=m -CONFIG_USB_G_DBGP=m -# CONFIG_USB_G_DBGP_PRINTK is not set -CONFIG_USB_G_DBGP_SERIAL=y -CONFIG_USB_G_WEBCAM=m - -# -# OTG and related infrastructure -# -CONFIG_USB_OTG_UTILS=y -CONFIG_USB_GPIO_VBUS=y -# CONFIG_ISP1301_OMAP is not set -# CONFIG_USB_ULPI is not set -CONFIG_TWL4030_USB=y -CONFIG_TWL6030_USB=m -CONFIG_NOP_USB_XCEIV=y -CONFIG_MMC=y -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_UNSAFE_RESUME=y -# CONFIG_MMC_CLKGATE is not set - -# -# MMC/SD/SDIO Card Drivers -# -CONFIG_MMC_BLOCK=y -CONFIG_MMC_BLOCK_MINORS=8 -CONFIG_MMC_BLOCK_BOUNCE=y -CONFIG_SDIO_UART=y -# CONFIG_MMC_TEST is not set - -# -# MMC/SD/SDIO Host Controller Drivers -# -# CONFIG_MMC_SDHCI is not set -# CONFIG_MMC_OMAP is not set -CONFIG_MMC_OMAP_HS=y -CONFIG_MMC_SPI=m -# CONFIG_MMC_DW is not set -CONFIG_MMC_USHC=m -# CONFIG_MEMSTICK is not set -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# -# CONFIG_LEDS_LM3530 is not set -# CONFIG_LEDS_PCA9532 is not set -CONFIG_LEDS_GPIO=y -CONFIG_LEDS_GPIO_PLATFORM=y -# CONFIG_LEDS_LP3944 is not set -CONFIG_LEDS_LP5521=m -CONFIG_LEDS_LP5523=m -# CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_DAC124S085 is not set -CONFIG_LEDS_PWM=m -CONFIG_LEDS_REGULATOR=m -# CONFIG_LEDS_BD2802 is not set -# CONFIG_LEDS_LT3593 is not set -CONFIG_LEDS_TRIGGERS=y - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGER_TIMER=m -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_BACKLIGHT=m -CONFIG_LEDS_TRIGGER_GPIO=m -CONFIG_LEDS_TRIGGER_DEFAULT_ON=m - -# -# iptables trigger is under Netfilter config (LED target) -# -CONFIG_NFC_DEVICES=y -CONFIG_PN544_NFC=m -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# I2C RTC drivers -# -CONFIG_RTC_DRV_DS1307=y -# CONFIG_RTC_DRV_DS1374 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS3232 is not set -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_ISL12022 is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_M41T80 is not set -CONFIG_RTC_DRV_BQ32K=m -CONFIG_RTC_DRV_TWL4030=m -# 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 - -# -# SPI RTC drivers -# -# CONFIG_RTC_DRV_M41T94 is not set -# CONFIG_RTC_DRV_DS1305 is not set -# CONFIG_RTC_DRV_DS1390 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_R9701 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_DS3234 is not set -# CONFIG_RTC_DRV_PCF2123 is not set - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_DS1286 is not set -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T35 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_MSM6242 is not set -# CONFIG_RTC_DRV_BQ4802 is not set -# CONFIG_RTC_DRV_RP5C01 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -# CONFIG_DMADEVICES is not set -CONFIG_TIMB_DMA=m -CONFIG_DMA_ENGINE=y -# CONFIG_AUXDISPLAY is not set -CONFIG_UIO=m -CONFIG_UIO_PDRV=m -CONFIG_UIO_PDRV_GENIRQ=m -CONFIG_STAGING=y -# CONFIG_STAGING_EXCLUDE_BUILD is not set -# CONFIG_VIDEO_TM6000 is not set -# CONFIG_USB_IP_COMMON is not set -CONFIG_W35UND=m -CONFIG_PRISM2_USB=m -CONFIG_ECHO=m -CONFIG_BRCM80211=m -CONFIG_BRCMFMAC=y -# CONFIG_BRCMDBG is not set -CONFIG_RT2870=m -# CONFIG_COMEDI is not set -# CONFIG_ASUS_OLED is not set -CONFIG_R8712U=m -CONFIG_R8712_AP=y -# CONFIG_TRANZPORT is not set -# CONFIG_POHMELFS is not set -# CONFIG_LINE6_USB is not set -# CONFIG_USB_SERIAL_QUATECH2 is not set -# CONFIG_USB_SERIAL_QUATECH_USB2 is not set -# CONFIG_VT6656 is not set -# CONFIG_IIO is not set -CONFIG_XVMALLOC=y -CONFIG_ZRAM=m -# CONFIG_ZRAM_DEBUG is not set -# CONFIG_FB_SM7XX is not set -# CONFIG_LIRC_STAGING is not set -# CONFIG_EASYCAP is not set -# CONFIG_TIDSPBRIDGE is not set -# CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL is not set -CONFIG_MACH_NO_WESTBRIDGE=y -# CONFIG_ATH6K_LEGACY is not set -CONFIG_USB_ENESTORAGE=m -CONFIG_BCM_WIMAX=m -CONFIG_FT1000=m -CONFIG_FT1000_USB=m - -# -# Speakup console speech -# -# CONFIG_SPEAKUP is not set -CONFIG_TOUCHSCREEN_CLEARPAD_TM1217=m -CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=m - -# -# Altera FPGA firmware download module -# -# CONFIG_ALTERA_STAPL is not set -CONFIG_CLKDEV_LOOKUP=y - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_XATTR=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y -# CONFIG_EXT4_DEBUG is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y -CONFIG_REISERFS_FS_XATTR=y -# CONFIG_REISERFS_FS_POSIX_ACL is not set -# CONFIG_REISERFS_FS_SECURITY is not set -CONFIG_JFS_FS=m -CONFIG_JFS_POSIX_ACL=y -# CONFIG_JFS_SECURITY is not set -# CONFIG_JFS_DEBUG is not set -CONFIG_JFS_STATISTICS=y -CONFIG_XFS_FS=m -CONFIG_XFS_QUOTA=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_XFS_RT=y -# CONFIG_XFS_DEBUG is not set -CONFIG_GFS2_FS=m -CONFIG_GFS2_FS_LOCKING_DLM=y -CONFIG_OCFS2_FS=m -CONFIG_OCFS2_FS_O2CB=m -CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m -CONFIG_OCFS2_FS_STATS=y -CONFIG_OCFS2_DEBUG_MASKLOG=y -# CONFIG_OCFS2_DEBUG_FS is not set -CONFIG_BTRFS_FS=m -CONFIG_BTRFS_FS_POSIX_ACL=y -CONFIG_NILFS2_FS=m -CONFIG_FS_POSIX_ACL=y -CONFIG_EXPORTFS=y -CONFIG_FILE_LOCKING=y -CONFIG_FSNOTIFY=y -CONFIG_DNOTIFY=y -CONFIG_INOTIFY_USER=y -CONFIG_FANOTIFY=y -CONFIG_QUOTA=y -# CONFIG_QUOTA_NETLINK_INTERFACE is not set -CONFIG_PRINT_QUOTA_WARNING=y -# CONFIG_QUOTA_DEBUG is not set -CONFIG_QUOTA_TREE=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -CONFIG_QUOTACTL=y -CONFIG_AUTOFS4_FS=y -CONFIG_FUSE_FS=m -CONFIG_CUSE=m -CONFIG_GENERIC_ACL=y - -# -# Caches -# -CONFIG_FSCACHE=m -CONFIG_FSCACHE_STATS=y -CONFIG_FSCACHE_HISTOGRAM=y -# CONFIG_FSCACHE_DEBUG is not set -# CONFIG_FSCACHE_OBJECT_LIST is not set -CONFIG_CACHEFILES=m -# CONFIG_CACHEFILES_DEBUG is not set -CONFIG_CACHEFILES_HISTOGRAM=y - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=m -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW 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_HUGETLB_PAGE is not set -CONFIG_CONFIGFS_FS=m -CONFIG_MISC_FILESYSTEMS=y -CONFIG_ADFS_FS=m -# CONFIG_ADFS_FS_RW is not set -CONFIG_AFFS_FS=m -# CONFIG_ECRYPT_FS is not set -CONFIG_UNION_FS=m -CONFIG_UNION_FS_XATTR=y -# CONFIG_UNION_FS_DEBUG is not set -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -CONFIG_JFFS2_SUMMARY=y -CONFIG_JFFS2_FS_XATTR=y -CONFIG_JFFS2_FS_POSIX_ACL=y -CONFIG_JFFS2_FS_SECURITY=y -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_LZO=y -CONFIG_JFFS2_RTIME=y -CONFIG_JFFS2_RUBIN=y -# CONFIG_JFFS2_CMODE_NONE is not set -# CONFIG_JFFS2_CMODE_PRIORITY is not set -# CONFIG_JFFS2_CMODE_SIZE is not set -CONFIG_JFFS2_CMODE_FAVOURLZO=y -CONFIG_UBIFS_FS=y -CONFIG_UBIFS_FS_XATTR=y -CONFIG_UBIFS_FS_ADVANCED_COMPR=y -CONFIG_UBIFS_FS_LZO=y -CONFIG_UBIFS_FS_ZLIB=y -# CONFIG_UBIFS_FS_DEBUG is not set -CONFIG_LOGFS=m -CONFIG_CRAMFS=m -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_XATTR is not set -CONFIG_SQUASHFS_LZO=y -CONFIG_SQUASHFS_XZ=y -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -CONFIG_VXFS_FS=m -CONFIG_MINIX_FS=m -CONFIG_OMFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_ROMFS_FS=m -CONFIG_ROMFS_BACKED_BY_BLOCK=y -# CONFIG_ROMFS_BACKED_BY_MTD is not set -# CONFIG_ROMFS_BACKED_BY_BOTH is not set -CONFIG_ROMFS_ON_BLOCK=y -CONFIG_PSTORE=y -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_UFS_DEBUG is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_NFS_V3_ACL=y -CONFIG_NFS_V4=y -CONFIG_NFS_V4_1=y -CONFIG_PNFS_FILE_LAYOUT=y -CONFIG_ROOT_NFS=y -# CONFIG_NFS_USE_LEGACY_DNS is not set -CONFIG_NFS_USE_KERNEL_DNS=y -# CONFIG_NFS_USE_NEW_IDMAPPER is not set -CONFIG_NFSD=m -CONFIG_NFSD_DEPRECATED=y -CONFIG_NFSD_V2_ACL=y -CONFIG_NFSD_V3=y -CONFIG_NFSD_V3_ACL=y -CONFIG_NFSD_V4=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_ACL_SUPPORT=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=m -CONFIG_CEPH_FS=m -CONFIG_CIFS=m -CONFIG_CIFS_STATS=y -CONFIG_CIFS_STATS2=y -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_UPCALL is not set -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -# CONFIG_CIFS_DEBUG2 is not set -CONFIG_CIFS_DFS_UPCALL=y -CONFIG_CIFS_FSCACHE=y -CONFIG_CIFS_ACL=y -CONFIG_CIFS_EXPERIMENTAL=y -CONFIG_NCP_FS=m -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -CONFIG_CODA_FS=m -CONFIG_AFS_FS=m -# CONFIG_AFS_DEBUG is not set -# CONFIG_AFS_FSCACHE is not set -CONFIG_9P_FS=m -CONFIG_9P_FSCACHE=y -CONFIG_9P_FS_POSIX_ACL=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -# CONFIG_UNIXWARE_DISKLABEL is not set -CONFIG_LDM_PARTITION=y -CONFIG_LDM_DEBUG=y -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -CONFIG_EFI_PARTITION=y -# CONFIG_SYSV68_PARTITION is not set -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=y -CONFIG_DLM=m -# CONFIG_DLM_DEBUG 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_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_SECTION_MISMATCH is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -# CONFIG_LOCKUP_DETECTOR is not set -# CONFIG_HARDLOCKUP_DETECTOR is not set -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 -CONFIG_SCHED_DEBUG=y -CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_KMEMLEAK is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_SPARSE_RCU_POINTER is not set -# CONFIG_LOCK_STAT is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_MEMORY_INIT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_TEST_LIST_SORT is not set -# CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS is not set -# CONFIG_DEBUG_CREDENTIALS is not set -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set -# CONFIG_LKDTM is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_LATENCYTOP is not set -# CONFIG_SYSCTL_SYSCALL_CHECK is not set -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_C_RECORDMCOUNT=y -CONFIG_RING_BUFFER=y -CONFIG_RING_BUFFER_ALLOW_SWAP=y -CONFIG_TRACING_SUPPORT=y -CONFIG_FTRACE=y -# CONFIG_FUNCTION_TRACER is not set -# CONFIG_IRQSOFF_TRACER is not set -# CONFIG_SCHED_TRACER is not set -# CONFIG_ENABLE_DEFAULT_TRACERS is not set -CONFIG_BRANCH_PROFILE_NONE=y -# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set -# CONFIG_PROFILE_ALL_BRANCHES is not set -# CONFIG_STACK_TRACER is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_RING_BUFFER_BENCHMARK is not set -# CONFIG_DYNAMIC_DEBUG is not set -# CONFIG_DMA_API_DEBUG is not set -# CONFIG_ATOMIC64_SELFTEST is not set -# CONFIG_ASYNC_RAID6_TEST is not set -# CONFIG_SAMPLES is not set -CONFIG_HAVE_ARCH_KGDB=y -# CONFIG_KGDB is not set -# CONFIG_TEST_KSTRTOX is not set -# CONFIG_STRICT_DEVMEM is not set -CONFIG_ARM_UNWIND=y -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_LL is not set -# CONFIG_OC_ETM is not set - -# -# Security options -# -CONFIG_KEYS=y -# CONFIG_KEYS_DEBUG_PROC_KEYS is not set -# CONFIG_SECURITY_DMESG_RESTRICT is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITYFS is not set -CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_DEFAULT_SECURITY="" -CONFIG_XOR_BLOCKS=m -CONFIG_ASYNC_CORE=m -CONFIG_ASYNC_MEMCPY=m -CONFIG_ASYNC_XOR=m -CONFIG_ASYNC_PQ=m -CONFIG_ASYNC_RAID6_RECOV=m -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y -CONFIG_CRYPTO_AEAD=m -CONFIG_CRYPTO_AEAD2=y -CONFIG_CRYPTO_BLKCIPHER=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_MANAGER_DISABLE_TESTS=y -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_WORKQUEUE=y -CONFIG_CRYPTO_CRYPTD=m -CONFIG_CRYPTO_AUTHENC=m -CONFIG_CRYPTO_TEST=m - -# -# Authenticated Encryption with Associated Data -# -CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m -CONFIG_CRYPTO_SEQIV=m - -# -# Block modes -# -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_CTR=m -CONFIG_CRYPTO_CTS=m -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m - -# -# Hash modes -# -CONFIG_CRYPTO_HMAC=m -CONFIG_CRYPTO_XCBC=m -# CONFIG_CRYPTO_VMAC is not set - -# -# Digest -# -CONFIG_CRYPTO_CRC32C=y -CONFIG_CRYPTO_GHASH=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=y -CONFIG_CRYPTO_RMD128=m -CONFIG_CRYPTO_RMD160=m -CONFIG_CRYPTO_RMD256=m -CONFIG_CRYPTO_RMD320=m -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_WP512=m - -# -# Ciphers -# -CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_ARC4=y -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_DES=y -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_SALSA20=m -CONFIG_CRYPTO_SEED=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_ZLIB is not set -CONFIG_CRYPTO_LZO=y - -# -# Random Number Generation -# -CONFIG_CRYPTO_ANSI_CPRNG=m -CONFIG_CRYPTO_USER_API=m -CONFIG_CRYPTO_USER_API_HASH=m -CONFIG_CRYPTO_USER_API_SKCIPHER=m -CONFIG_CRYPTO_HW=y -CONFIG_CRYPTO_DEV_OMAP_SHAM=m -CONFIG_CRYPTO_DEV_OMAP_AES=m -# CONFIG_BINARY_PRINTF is not set - -# -# Library routines -# -CONFIG_RAID6_PQ=m -CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -CONFIG_CRC_T10DIF=y -CONFIG_CRC_ITU_T=y -CONFIG_CRC32=y -CONFIG_CRC7=y -CONFIG_LIBCRC32C=y -CONFIG_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=m -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_LZMA=y -CONFIG_DECOMPRESS_XZ=y -CONFIG_DECOMPRESS_LZO=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m -CONFIG_BTREE=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y -CONFIG_NLATTR=y -CONFIG_AVERAGE=y diff --git a/recipes-kernel/linux/linux-omap-2.6.39/camera/0001-Add-driver-for-Aptina-Micron-mt9p031-sensor.patch b/recipes-kernel/linux/linux-omap-2.6.39/camera/0001-Add-driver-for-Aptina-Micron-mt9p031-sensor.patch deleted file mode 100644 index cf9e116d..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/camera/0001-Add-driver-for-Aptina-Micron-mt9p031-sensor.patch +++ /dev/null @@ -1,859 +0,0 @@ -From e630a914bf14bf190feaf4a2cc57f6b27c4024e1 Mon Sep 17 00:00:00 2001 -From: Javier Martin -Date: Wed, 1 Jun 2011 17:36:48 +0200 -Subject: [PATCH 1/3] Add driver for Aptina (Micron) mt9p031 sensor. - -Clock frequency of 57MHz used in previous version was wrong since -when VDD_IO is 1.8V it can only support 48MHz. - -Two new platform flags have been added: - -- vdd_io: indicates whether the chip is powered with 1.8 or 2.8 VDD_IO. -So that it can use the maximum allowed frequency. -- version: monochrome and color versions of the chip have exactly -the same ID, so the only way to select one of them is through -platform data. - -Internal PLL is now used to generate PIXCLK depending on VDD_IO. - -Signed-off-by: Javier Martin ---- - drivers/media/video/Kconfig | 7 + - drivers/media/video/Makefile | 1 + - drivers/media/video/mt9p031.c | 763 +++++++++++++++++++++++++++++++++++++++++ - include/media/mt9p031.h | 23 ++ - 4 files changed, 794 insertions(+), 0 deletions(-) - create mode 100644 drivers/media/video/mt9p031.c - create mode 100644 include/media/mt9p031.h - -diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig -index 00f51dd..cb87e35 100644 ---- a/drivers/media/video/Kconfig -+++ b/drivers/media/video/Kconfig -@@ -329,6 +329,13 @@ config VIDEO_OV7670 - OV7670 VGA camera. It currently only works with the M88ALP01 - controller. - -+config VIDEO_MT9P031 -+ tristate "Aptina MT9P031 support" -+ depends on I2C && VIDEO_V4L2 -+ ---help--- -+ This is a Video4Linux2 sensor-level driver for the Aptina -+ (Micron) mt9p031 5 Mpixel camera. -+ - config VIDEO_MT9V011 - tristate "Micron mt9v011 sensor support" - depends on I2C && VIDEO_V4L2 -diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile -index ace5d8b..912b29b 100644 ---- a/drivers/media/video/Makefile -+++ b/drivers/media/video/Makefile -@@ -65,6 +65,7 @@ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o - obj-$(CONFIG_VIDEO_OV7670) += ov7670.o - obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o - obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o -+obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o - obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o - obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o - obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o -diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c -new file mode 100644 -index 0000000..cd830b1 ---- /dev/null -+++ b/drivers/media/video/mt9p031.c -@@ -0,0 +1,763 @@ -+/* -+ * Driver for MT9P031 CMOS Image Sensor from Aptina -+ * -+ * Copyright (C) 2011, Javier Martin -+ * -+ * Copyright (C) 2011, Guennadi Liakhovetski -+ * -+ * Based on the MT9V032 driver and Bastian Hecht's code. -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define MT9P031_EXTCLK_FREQ 20000000 -+ -+#define MT9P031_CHIP_VERSION 0x00 -+#define MT9P031_CHIP_VERSION_VALUE 0x1801 -+#define MT9P031_ROW_START 0x01 -+#define MT9P031_ROW_START_MIN 1 -+#define MT9P031_ROW_START_MAX 2004 -+#define MT9P031_ROW_START_DEF 54 -+#define MT9P031_COLUMN_START 0x02 -+#define MT9P031_COLUMN_START_MIN 1 -+#define MT9P031_COLUMN_START_MAX 2750 -+#define MT9P031_COLUMN_START_DEF 16 -+#define MT9P031_WINDOW_HEIGHT 0x03 -+#define MT9P031_WINDOW_HEIGHT_MIN 2 -+#define MT9P031_WINDOW_HEIGHT_MAX 2003 -+#define MT9P031_WINDOW_HEIGHT_DEF 2003 -+#define MT9P031_WINDOW_WIDTH 0x04 -+#define MT9P031_WINDOW_WIDTH_MIN 18 -+#define MT9P031_WINDOW_WIDTH_MAX 2751 -+#define MT9P031_WINDOW_WIDTH_DEF 2751 -+#define MT9P031_H_BLANKING 0x05 -+#define MT9P031_H_BLANKING_VALUE 0 -+#define MT9P031_V_BLANKING 0x06 -+#define MT9P031_V_BLANKING_VALUE 25 -+#define MT9P031_OUTPUT_CONTROL 0x07 -+#define MT9P031_OUTPUT_CONTROL_CEN 2 -+#define MT9P031_OUTPUT_CONTROL_SYN 1 -+#define MT9P031_SHUTTER_WIDTH_UPPER 0x08 -+#define MT9P031_SHUTTER_WIDTH 0x09 -+#define MT9P031_PLL_CONTROL 0x10 -+#define MT9P031_PLL_CONTROL_PWROFF 0x0050 -+#define MT9P031_PLL_CONTROL_PWRON 0x0051 -+#define MT9P031_PLL_CONTROL_USEPLL 0x0052 -+#define MT9P031_PLL_CONFIG_1 0x11 -+#define MT9P031_PLL_CONFIG_1_M_48MHZ 0x5000 -+#define MT9P031_PLL_CONFIG_1_N_48MHZ 0x05 -+#define MT9P031_PLL_CONFIG_1_M_96MHZ 0x3600 -+#define MT9P031_PLL_CONFIG_1_N_96MHZ 0x05 -+#define MT9P031_PLL_CONFIG_2 0x12 -+#define MT9P031_PLL_CONFIG_2_P1_48MHZ 5 -+#define MT9P031_PLL_CONFIG_2_P1_96MHZ 2 -+#define MT9P031_PIXEL_CLOCK_CONTROL 0x0a -+#define MT9P031_FRAME_RESTART 0x0b -+#define MT9P031_SHUTTER_DELAY 0x0c -+#define MT9P031_RST 0x0d -+#define MT9P031_RST_ENABLE 1 -+#define MT9P031_RST_DISABLE 0 -+#define MT9P031_READ_MODE_1 0x1e -+#define MT9P031_READ_MODE_2 0x20 -+#define MT9P031_READ_MODE_2_ROW_MIR 0x8000 -+#define MT9P031_READ_MODE_2_COL_MIR 0x4000 -+#define MT9P031_ROW_ADDRESS_MODE 0x22 -+#define MT9P031_COLUMN_ADDRESS_MODE 0x23 -+#define MT9P031_GLOBAL_GAIN 0x35 -+ -+struct mt9p031 { -+ struct v4l2_subdev subdev; -+ struct media_pad pad; -+ struct v4l2_rect rect; /* Sensor window */ -+ struct v4l2_mbus_framefmt format; -+ struct mt9p031_platform_data *pdata; -+ struct mutex power_lock; /* lock to protect power_count */ -+ int power_count; -+ u16 xskip; -+ u16 yskip; -+ /* cache register values */ -+ u16 output_control; -+}; -+ -+static struct mt9p031 *to_mt9p031(const struct i2c_client *client) -+{ -+ return container_of(i2c_get_clientdata(client), struct mt9p031, subdev); -+} -+ -+static int reg_read(struct i2c_client *client, const u8 reg) -+{ -+ s32 data = i2c_smbus_read_word_data(client, reg); -+ return data < 0 ? data : swab16(data); -+} -+ -+static int reg_write(struct i2c_client *client, const u8 reg, -+ const u16 data) -+{ -+ return i2c_smbus_write_word_data(client, reg, swab16(data)); -+} -+ -+static int mt9p031_set_output_control(struct mt9p031 *mt9p031, u16 clear, -+ u16 set) -+{ -+ struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); -+ u16 value = (mt9p031->output_control & ~clear) | set; -+ int ret; -+ -+ ret = reg_write(client, MT9P031_OUTPUT_CONTROL, value); -+ if (ret < 0) -+ return ret; -+ mt9p031->output_control = value; -+ return 0; -+} -+ -+static int mt9p031_reset(struct i2c_client *client) -+{ -+ struct mt9p031 *mt9p031 = to_mt9p031(client); -+ int ret; -+ -+ /* Disable chip output, synchronous option update */ -+ ret = reg_write(client, MT9P031_RST, MT9P031_RST_ENABLE); -+ if (ret < 0) -+ return ret; -+ ret = reg_write(client, MT9P031_RST, MT9P031_RST_DISABLE); -+ if (ret < 0) -+ return ret; -+ return mt9p031_set_output_control(mt9p031, -+ MT9P031_OUTPUT_CONTROL_CEN, 0); -+} -+ -+static int mt9p031_power_on(struct mt9p031 *mt9p031) -+{ -+ struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); -+ int ret; -+ -+ /* Ensure RESET_BAR is low */ -+ if (mt9p031->pdata->reset) { -+ mt9p031->pdata->reset(&mt9p031->subdev, 1); -+ msleep(1); -+ } -+ /* Emable clock */ -+ if (mt9p031->pdata->set_xclk) -+ mt9p031->pdata->set_xclk(&mt9p031->subdev, MT9P031_EXTCLK_FREQ); -+ /* Now RESET_BAR must be high */ -+ if (mt9p031->pdata->reset) { -+ mt9p031->pdata->reset(&mt9p031->subdev, 0); -+ msleep(1); -+ } -+ /* soft reset */ -+ ret = mt9p031_reset(client); -+ if (ret < 0) { -+ dev_err(&client->dev, "Failed to reset the camera\n"); -+ return ret; -+ } -+ return 0; -+} -+ -+static void mt9p031_power_off(struct mt9p031 *mt9p031) -+{ -+ if (mt9p031->pdata->reset) { -+ mt9p031->pdata->reset(&mt9p031->subdev, 1); -+ msleep(1); -+ } -+ if (mt9p031->pdata->set_xclk) -+ mt9p031->pdata->set_xclk(&mt9p031->subdev, 0); -+} -+ -+static int mt9p031_enum_mbus_code(struct v4l2_subdev *sd, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_mbus_code_enum *code) -+{ -+ struct mt9p031 *mt9p031 = container_of(sd, struct mt9p031, subdev); -+ -+ if (code->pad || code->index) -+ return -EINVAL; -+ -+ code->code = mt9p031->format.code; -+ return 0; -+} -+ -+static struct v4l2_mbus_framefmt *mt9p031_get_pad_format( -+ struct mt9p031 *mt9p031, -+ struct v4l2_subdev_fh *fh, -+ unsigned int pad, u32 which) -+{ -+ switch (which) { -+ case V4L2_SUBDEV_FORMAT_TRY: -+ return v4l2_subdev_get_try_format(fh, pad); -+ case V4L2_SUBDEV_FORMAT_ACTIVE: -+ return &mt9p031->format; -+ default: -+ return NULL; -+ } -+} -+ -+static struct v4l2_rect *mt9p031_get_pad_crop(struct mt9p031 *mt9p031, -+ struct v4l2_subdev_fh *fh, unsigned int pad, u32 which) -+{ -+ switch (which) { -+ case V4L2_SUBDEV_FORMAT_TRY: -+ return v4l2_subdev_get_try_crop(fh, pad); -+ case V4L2_SUBDEV_FORMAT_ACTIVE: -+ return &mt9p031->rect; -+ default: -+ return NULL; -+ } -+} -+ -+static int mt9p031_get_crop(struct v4l2_subdev *sd, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_crop *crop) -+{ -+ struct mt9p031 *mt9p031 = container_of(sd, struct mt9p031, subdev); -+ struct v4l2_rect *rect = mt9p031_get_pad_crop(mt9p031, fh, crop->pad, -+ crop->which); -+ if (!rect) -+ return -EINVAL; -+ -+ crop->rect = *rect; -+ -+ return 0; -+} -+ -+static u16 mt9p031_skip_for_crop(s32 source, s32 *target, s32 max_skip) -+{ -+ unsigned int skip; -+ -+ if (source - source / 4 < *target) { -+ *target = source; -+ return 1; -+ } -+ -+ skip = DIV_ROUND_CLOSEST(source, *target); -+ if (skip > max_skip) -+ skip = max_skip; -+ *target = 2 * DIV_ROUND_UP(source, 2 * skip); -+ -+ return skip; -+} -+ -+static int mt9p031_set_params(struct i2c_client *client, -+ struct v4l2_rect *rect, u16 xskip, u16 yskip) -+{ -+ struct mt9p031 *mt9p031 = to_mt9p031(client); -+ int ret; -+ u16 xbin, ybin; -+ const u16 hblank = MT9P031_H_BLANKING_VALUE, -+ vblank = MT9P031_V_BLANKING_VALUE; -+ __s32 left; -+ -+ /* -+ * TODO: Attention! When implementing horizontal flipping, adjust -+ * alignment according to R2 "Column Start" description in the datasheet -+ */ -+ if (xskip & 1) { -+ xbin = 1; -+ left = rect->left & (~3); -+ } else if (xskip & 2) { -+ xbin = 2; -+ left = rect->left & (~7); -+ } else { -+ xbin = 4; -+ left = rect->left & (~15); -+ } -+ ybin = min(yskip, (u16)4); -+ -+ /* Disable register update, reconfigure atomically */ -+ ret = mt9p031_set_output_control(mt9p031, 0, -+ MT9P031_OUTPUT_CONTROL_SYN); -+ if (ret < 0) -+ return ret; -+ -+ dev_dbg(&client->dev, "skip %u:%u, rect %ux%u@%u:%u\n", -+ xskip, yskip, rect->width, rect->height, rect->left, rect->top); -+ -+ /* Blanking and start values - default... */ -+ ret = reg_write(client, MT9P031_H_BLANKING, hblank); -+ if (ret < 0) -+ return ret; -+ ret = reg_write(client, MT9P031_V_BLANKING, vblank); -+ if (ret < 0) -+ return ret; -+ -+ ret = reg_write(client, MT9P031_COLUMN_ADDRESS_MODE, -+ ((xbin - 1) << 4) | (xskip - 1)); -+ if (ret < 0) -+ return ret; -+ ret = reg_write(client, MT9P031_ROW_ADDRESS_MODE, -+ ((ybin - 1) << 4) | (yskip - 1)); -+ if (ret < 0) -+ return ret; -+ -+ dev_dbg(&client->dev, "new physical left %u, top %u\n", -+ rect->left, rect->top); -+ -+ ret = reg_write(client, MT9P031_COLUMN_START, -+ rect->left); -+ if (ret < 0) -+ return ret; -+ ret = reg_write(client, MT9P031_ROW_START, -+ rect->top); -+ if (ret < 0) -+ return ret; -+ -+ ret = reg_write(client, MT9P031_WINDOW_WIDTH, -+ rect->width - 1); -+ if (ret < 0) -+ return ret; -+ ret = reg_write(client, MT9P031_WINDOW_HEIGHT, -+ rect->height - 1); -+ if (ret < 0) -+ return ret; -+ -+ /* Re-enable register update, commit all changes */ -+ ret = mt9p031_set_output_control(mt9p031, -+ MT9P031_OUTPUT_CONTROL_SYN, 0); -+ if (ret < 0) -+ return ret; -+ -+ mt9p031->xskip = xskip; -+ mt9p031->yskip = yskip; -+ return ret; -+} -+ -+static int mt9p031_set_crop(struct v4l2_subdev *sd, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_crop *crop) -+{ -+ struct mt9p031 *mt9p031 = container_of(sd, struct mt9p031, subdev); -+ struct v4l2_mbus_framefmt *f; -+ struct v4l2_rect *c; -+ struct v4l2_rect rect; -+ u16 xskip, yskip; -+ s32 width, height; -+ -+ dev_dbg(mt9p031->subdev.v4l2_dev->dev, "%s(%ux%u@%u:%u : %u)\n", -+ __func__, crop->rect.width, crop->rect.height, -+ crop->rect.left, crop->rect.top, crop->which); -+ -+ /* -+ * Clamp the crop rectangle boundaries and align them to a multiple of 2 -+ * pixels. -+ */ -+ rect.width = ALIGN(clamp(crop->rect.width, -+ MT9P031_WINDOW_WIDTH_MIN, -+ MT9P031_WINDOW_WIDTH_MAX), 2); -+ rect.height = ALIGN(clamp(crop->rect.height, -+ MT9P031_WINDOW_HEIGHT_MIN, -+ MT9P031_WINDOW_HEIGHT_MAX), 2); -+ rect.left = ALIGN(clamp(crop->rect.left, -+ MT9P031_COLUMN_START_MIN, -+ MT9P031_COLUMN_START_MAX), 2); -+ rect.top = ALIGN(clamp(crop->rect.top, -+ MT9P031_ROW_START_MIN, -+ MT9P031_ROW_START_MAX), 2); -+ -+ c = mt9p031_get_pad_crop(mt9p031, fh, crop->pad, crop->which); -+ -+ if (rect.width != c->width || rect.height != c->height) { -+ /* -+ * Reset the output image size if the crop rectangle size has -+ * been modified. -+ */ -+ f = mt9p031_get_pad_format(mt9p031, fh, crop->pad, -+ crop->which); -+ width = f->width; -+ height = f->height; -+ -+ xskip = mt9p031_skip_for_crop(rect.width, &width, 7); -+ yskip = mt9p031_skip_for_crop(rect.height, &height, 8); -+ } else { -+ xskip = mt9p031->xskip; -+ yskip = mt9p031->yskip; -+ f = NULL; -+ } -+ if (f) { -+ f->width = width; -+ f->height = height; -+ } -+ -+ *c = rect; -+ crop->rect = rect; -+ -+ mt9p031->xskip = xskip; -+ mt9p031->yskip = yskip; -+ mt9p031->rect = *c; -+ return 0; -+} -+ -+static int mt9p031_get_format(struct v4l2_subdev *sd, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_format *fmt) -+{ -+ struct mt9p031 *mt9p031 = container_of(sd, struct mt9p031, subdev); -+ -+ fmt->format = -+ *mt9p031_get_pad_format(mt9p031, fh, fmt->pad, fmt->which); -+ return 0; -+} -+ -+static u16 mt9p031_skip_for_scale(s32 *source, s32 target, -+ s32 max_skip, s32 max) -+{ -+ unsigned int skip; -+ -+ if (*source - *source / 4 < target) { -+ *source = target; -+ return 1; -+ } -+ -+ skip = min(max, *source + target / 2) / target; -+ if (skip > max_skip) -+ skip = max_skip; -+ *source = target * skip; -+ -+ return skip; -+} -+ -+static int mt9p031_set_format(struct v4l2_subdev *sd, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_format *format) -+{ -+ struct v4l2_mbus_framefmt *__format; -+ struct v4l2_rect *__crop, rect; -+ struct mt9p031 *mt9p031 = container_of(sd, struct mt9p031, subdev); -+ unsigned int width; -+ unsigned int height; -+ u16 xskip, yskip; -+ -+ __crop = mt9p031_get_pad_crop(mt9p031, fh, format->pad, format->which); -+ -+ width = clamp_t(int, ALIGN(format->format.width, 2), 2, -+ MT9P031_WINDOW_WIDTH_MAX); -+ height = clamp_t(int, ALIGN(format->format.height, 2), 2, -+ MT9P031_WINDOW_HEIGHT_MAX); -+ -+ rect.width = __crop->width; -+ rect.height = __crop->height; -+ -+ xskip = mt9p031_skip_for_scale(&rect.width, width, 7, -+ MT9P031_WINDOW_WIDTH_MAX); -+ if (rect.width + __crop->left > MT9P031_WINDOW_WIDTH_MAX) -+ rect.left = (MT9P031_WINDOW_WIDTH_MAX - rect.width) / 2; -+ else -+ rect.left = __crop->left; -+ yskip = mt9p031_skip_for_scale(&rect.height, height, 8, -+ MT9P031_WINDOW_HEIGHT_MAX); -+ if (rect.height + __crop->top > MT9P031_WINDOW_HEIGHT_MAX) -+ rect.top = (MT9P031_WINDOW_HEIGHT_MAX - rect.height) / 2; -+ else -+ rect.top = __crop->top; -+ -+ dev_dbg(mt9p031->subdev.v4l2_dev->dev, "%s(%ux%u : %u)\n", __func__, -+ width, height, format->which); -+ if (__crop) -+ *__crop = rect; -+ -+ __format = mt9p031_get_pad_format(mt9p031, fh, format->pad, -+ format->which); -+ __format->width = width; -+ __format->height = height; -+ format->format = *__format; -+ -+ mt9p031->xskip = xskip; -+ mt9p031->yskip = yskip; -+ mt9p031->rect = *__crop; -+ return 0; -+} -+ -+static int mt9p031_pll_enable(struct i2c_client *client) -+{ -+ struct mt9p031 *mt9p031 = to_mt9p031(client); -+ int ret; -+ -+ ret = reg_write(client, MT9P031_PLL_CONTROL, MT9P031_PLL_CONTROL_PWRON); -+ if (ret < 0) -+ return ret; -+ -+ /* Always set the maximum frequency allowed by VDD_IO */ -+ if (mt9p031->pdata->vdd_io == MT9P031_VDD_IO_2V8) { -+ ret = reg_write(client, MT9P031_PLL_CONFIG_1, -+ MT9P031_PLL_CONFIG_1_M_96MHZ | -+ MT9P031_PLL_CONFIG_1_N_96MHZ); -+ if (ret < 0) -+ return ret; -+ ret = reg_write(client, MT9P031_PLL_CONFIG_2, -+ MT9P031_PLL_CONFIG_2_P1_96MHZ); -+ if (ret < 0) -+ return ret; -+ } else { -+ ret = reg_write(client, MT9P031_PLL_CONFIG_1, -+ MT9P031_PLL_CONFIG_1_M_48MHZ | -+ MT9P031_PLL_CONFIG_1_N_48MHZ); -+ if (ret < 0) -+ return ret; -+ ret = reg_write(client, MT9P031_PLL_CONFIG_2, -+ MT9P031_PLL_CONFIG_2_P1_48MHZ); -+ if (ret < 0) -+ return ret; -+ } -+ mdelay(1); -+ ret = reg_write(client, MT9P031_PLL_CONTROL, -+ MT9P031_PLL_CONTROL_PWRON | -+ MT9P031_PLL_CONTROL_USEPLL); -+ mdelay(1); -+ return ret; -+} -+ -+static inline int mt9p031_pll_disable(struct i2c_client *client) -+{ -+ return reg_write(client, MT9P031_PLL_CONTROL, -+ MT9P031_PLL_CONTROL_PWROFF); -+} -+ -+static int mt9p031_s_stream(struct v4l2_subdev *sd, int enable) -+{ -+ struct mt9p031 *mt9p031 = container_of(sd, struct mt9p031, subdev); -+ struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); -+ struct v4l2_rect rect = mt9p031->rect; -+ u16 xskip = mt9p031->xskip; -+ u16 yskip = mt9p031->yskip; -+ int ret; -+ -+ if (enable) { -+ ret = mt9p031_set_params(client, &rect, xskip, yskip); -+ if (ret < 0) -+ return ret; -+ /* Switch to master "normal" mode */ -+ ret = mt9p031_set_output_control(mt9p031, 0, -+ MT9P031_OUTPUT_CONTROL_CEN); -+ if (ret < 0) -+ return ret; -+ ret = mt9p031_pll_enable(client); -+ } else { -+ /* Stop sensor readout */ -+ ret = mt9p031_set_output_control(mt9p031, -+ MT9P031_OUTPUT_CONTROL_CEN, 0); -+ if (ret < 0) -+ return ret; -+ ret = mt9p031_pll_disable(client); -+ } -+ return ret; -+} -+ -+static int mt9p031_video_probe(struct i2c_client *client) -+{ -+ s32 data; -+ -+ /* Read out the chip version register */ -+ data = reg_read(client, MT9P031_CHIP_VERSION); -+ if (data != MT9P031_CHIP_VERSION_VALUE) { -+ dev_err(&client->dev, -+ "No MT9P031 chip detected, register read %x\n", data); -+ return -ENODEV; -+ } -+ -+ dev_info(&client->dev, "Detected a MT9P031 chip ID %x\n", data); -+ -+ return 0; -+} -+ -+static int mt9p031_set_power(struct v4l2_subdev *sd, int on) -+{ -+ struct mt9p031 *mt9p031 = container_of(sd, struct mt9p031, subdev); -+ int ret = 0; -+ -+ mutex_lock(&mt9p031->power_lock); -+ -+ /* -+ * If the power count is modified from 0 to != 0 or from != 0 to 0, -+ * update the power state. -+ */ -+ if (mt9p031->power_count == !on) { -+ if (on) { -+ ret = mt9p031_power_on(mt9p031); -+ if (ret) { -+ dev_err(mt9p031->subdev.v4l2_dev->dev, -+ "Failed to power on: %d\n", ret); -+ goto out; -+ } -+ } else { -+ mt9p031_power_off(mt9p031); -+ } -+ } -+ -+ /* Update the power count. */ -+ mt9p031->power_count += on ? 1 : -1; -+ WARN_ON(mt9p031->power_count < 0); -+ -+out: -+ mutex_unlock(&mt9p031->power_lock); -+ return ret; -+} -+ -+static int mt9p031_registered(struct v4l2_subdev *sd) -+{ -+ struct mt9p031 *mt9p031 = container_of(sd, struct mt9p031, subdev); -+ struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); -+ int ret; -+ -+ ret = mt9p031_set_power(&mt9p031->subdev, 1); -+ if (ret) { -+ dev_err(&client->dev, -+ "Failed to power on device: %d\n", ret); -+ return ret; -+ } -+ -+ ret = mt9p031_video_probe(client); -+ -+ mt9p031_set_power(&mt9p031->subdev, 0); -+ -+ return ret; -+} -+ -+static int mt9p031_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -+{ -+ struct mt9p031 *mt9p031; -+ mt9p031 = container_of(sd, struct mt9p031, subdev); -+ -+ mt9p031->rect.width = MT9P031_WINDOW_WIDTH_DEF; -+ mt9p031->rect.height = MT9P031_WINDOW_HEIGHT_DEF; -+ mt9p031->rect.left = MT9P031_COLUMN_START_DEF; -+ mt9p031->rect.top = MT9P031_ROW_START_DEF; -+ -+ if (mt9p031->pdata->version == MT9P031_MONOCHROME_VERSION) -+ mt9p031->format.code = V4L2_MBUS_FMT_Y12_1X12; -+ else -+ mt9p031->format.code = V4L2_MBUS_FMT_SGRBG12_1X12; -+ -+ mt9p031->format.width = MT9P031_WINDOW_WIDTH_DEF; -+ mt9p031->format.height = MT9P031_WINDOW_HEIGHT_DEF; -+ mt9p031->format.field = V4L2_FIELD_NONE; -+ mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB; -+ -+ mt9p031->xskip = 1; -+ mt9p031->yskip = 1; -+ return mt9p031_set_power(sd, 1); -+} -+ -+static int mt9p031_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) -+{ -+ return mt9p031_set_power(sd, 0); -+} -+ -+static struct v4l2_subdev_core_ops mt9p031_subdev_core_ops = { -+ .s_power = mt9p031_set_power, -+}; -+ -+static struct v4l2_subdev_video_ops mt9p031_subdev_video_ops = { -+ .s_stream = mt9p031_s_stream, -+}; -+ -+static struct v4l2_subdev_pad_ops mt9p031_subdev_pad_ops = { -+ .enum_mbus_code = mt9p031_enum_mbus_code, -+ .get_fmt = mt9p031_get_format, -+ .set_fmt = mt9p031_set_format, -+ .get_crop = mt9p031_get_crop, -+ .set_crop = mt9p031_set_crop, -+}; -+ -+static struct v4l2_subdev_ops mt9p031_subdev_ops = { -+ .core = &mt9p031_subdev_core_ops, -+ .video = &mt9p031_subdev_video_ops, -+ .pad = &mt9p031_subdev_pad_ops, -+}; -+ -+static const struct v4l2_subdev_internal_ops mt9p031_subdev_internal_ops = { -+ .registered = mt9p031_registered, -+ .open = mt9p031_open, -+ .close = mt9p031_close, -+}; -+ -+static int mt9p031_probe(struct i2c_client *client, -+ const struct i2c_device_id *did) -+{ -+ int ret; -+ struct mt9p031 *mt9p031; -+ struct mt9p031_platform_data *pdata = client->dev.platform_data; -+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); -+ -+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { -+ dev_warn(&adapter->dev, -+ "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); -+ return -EIO; -+ } -+ -+ mt9p031 = kzalloc(sizeof(struct mt9p031), GFP_KERNEL); -+ if (!mt9p031) -+ return -ENOMEM; -+ -+ mutex_init(&mt9p031->power_lock); -+ v4l2_i2c_subdev_init(&mt9p031->subdev, client, &mt9p031_subdev_ops); -+ mt9p031->subdev.internal_ops = &mt9p031_subdev_internal_ops; -+ -+ mt9p031->pdata = pdata; -+ -+ mt9p031->pad.flags = MEDIA_PAD_FL_SOURCE; -+ ret = media_entity_init(&mt9p031->subdev.entity, 1, &mt9p031->pad, 0); -+ if (ret) -+ return ret; -+ -+ mt9p031->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; -+ -+ return 0; -+} -+ -+static int mt9p031_remove(struct i2c_client *client) -+{ -+ struct v4l2_subdev *sd = i2c_get_clientdata(client); -+ struct mt9p031 *mt9p031 = container_of(sd, struct mt9p031, subdev); -+ -+ v4l2_device_unregister_subdev(sd); -+ media_entity_cleanup(&sd->entity); -+ kfree(mt9p031); -+ -+ return 0; -+} -+ -+static const struct i2c_device_id mt9p031_id[] = { -+ { "mt9p031", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, mt9p031_id); -+ -+static struct i2c_driver mt9p031_i2c_driver = { -+ .driver = { -+ .name = "mt9p031", -+ }, -+ .probe = mt9p031_probe, -+ .remove = mt9p031_remove, -+ .id_table = mt9p031_id, -+}; -+ -+static int __init mt9p031_mod_init(void) -+{ -+ return i2c_add_driver(&mt9p031_i2c_driver); -+} -+ -+static void __exit mt9p031_mod_exit(void) -+{ -+ i2c_del_driver(&mt9p031_i2c_driver); -+} -+ -+module_init(mt9p031_mod_init); -+module_exit(mt9p031_mod_exit); -+ -+MODULE_DESCRIPTION("Aptina MT9P031 Camera driver"); -+MODULE_AUTHOR("Bastian Hecht "); -+MODULE_LICENSE("GPL v2"); -diff --git a/include/media/mt9p031.h b/include/media/mt9p031.h -new file mode 100644 -index 0000000..27b4c75 ---- /dev/null -+++ b/include/media/mt9p031.h -@@ -0,0 +1,23 @@ -+#ifndef MT9P031_H -+#define MT9P031_H -+ -+struct v4l2_subdev; -+ -+enum { -+ MT9P031_COLOR_VERSION = 0, -+ MT9P031_MONOCHROME_VERSION = 1, -+}; -+ -+enum { -+ MT9P031_VDD_IO_1V8 = 0, -+ MT9P031_VDD_IO_2V8 = 1, -+}; -+ -+struct mt9p031_platform_data { -+ int (*set_xclk)(struct v4l2_subdev *subdev, int hz); -+ int (*reset)(struct v4l2_subdev *subdev, int active); -+ int vdd_io; /* MT9P031_VDD_IO_1V8 or MT9P031_VDD_IO_2V8 */ -+ int version; /* MT9P031_COLOR_VERSION or MT9P031_MONOCHROME_VERSION */ -+}; -+ -+#endif --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/camera/0002-v4l-Add-mt9v032-sensor-driver.patch b/recipes-kernel/linux/linux-omap-2.6.39/camera/0002-v4l-Add-mt9v032-sensor-driver.patch deleted file mode 100644 index fb7cd205..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/camera/0002-v4l-Add-mt9v032-sensor-driver.patch +++ /dev/null @@ -1,853 +0,0 @@ -From ba65e798c98e9c4d331deb2b51337964336d3f78 Mon Sep 17 00:00:00 2001 -From: Detlev Casanova -Date: Sun, 28 Nov 2010 19:07:20 +0100 -Subject: [PATCH 2/3] v4l: Add mt9v032 sensor driver - -The MT9V032 is a parallel wide VGA sensor from Aptina (formerly Micron) -controlled through I2C. - -The driver creates a V4L2 subdevice. It currently supports binning and -cropping, and the gain, auto gain, exposure, auto exposure and test -pattern controls. - -Signed-off-by: Detlev Casanova -Signed-off-by: Laurent Pinchart ---- - drivers/media/video/Kconfig | 7 + - drivers/media/video/Makefile | 1 + - drivers/media/video/mt9v032.c | 773 +++++++++++++++++++++++++++++++++++++++++ - include/media/mt9v032.h | 12 + - 4 files changed, 793 insertions(+), 0 deletions(-) - create mode 100644 drivers/media/video/mt9v032.c - create mode 100644 include/media/mt9v032.h - -diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig -index cb87e35..3a5bc57 100644 ---- a/drivers/media/video/Kconfig -+++ b/drivers/media/video/Kconfig -@@ -344,6 +344,13 @@ config VIDEO_MT9V011 - mt0v011 1.3 Mpixel camera. It currently only works with the - em28xx driver. - -+config VIDEO_MT9V032 -+ tristate "Micron MT9V032 sensor support" -+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API -+ ---help--- -+ This is a Video4Linux2 sensor-level driver for the Micron -+ MT9V032 752x480 CMOS sensor. -+ - config VIDEO_TCM825X - tristate "TCM825x camera sensor support" - depends on I2C && VIDEO_V4L2 -diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile -index 912b29b..6679c6a 100644 ---- a/drivers/media/video/Makefile -+++ b/drivers/media/video/Makefile -@@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o - obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o - obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o - obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o -+obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o - obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o - obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o - -diff --git a/drivers/media/video/mt9v032.c b/drivers/media/video/mt9v032.c -new file mode 100644 -index 0000000..c64e1dc ---- /dev/null -+++ b/drivers/media/video/mt9v032.c -@@ -0,0 +1,773 @@ -+/* -+ * Driver for MT9V032 CMOS Image Sensor from Micron -+ * -+ * Copyright (C) 2010, Laurent Pinchart -+ * -+ * Based on the MT9M001 driver, -+ * -+ * Copyright (C) 2008, Guennadi Liakhovetski -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define MT9V032_PIXEL_ARRAY_HEIGHT 492 -+#define MT9V032_PIXEL_ARRAY_WIDTH 782 -+ -+#define MT9V032_CHIP_VERSION 0x00 -+#define MT9V032_CHIP_ID_REV1 0x1311 -+#define MT9V032_CHIP_ID_REV3 0x1313 -+#define MT9V032_COLUMN_START 0x01 -+#define MT9V032_COLUMN_START_MIN 1 -+#define MT9V032_COLUMN_START_DEF 1 -+#define MT9V032_COLUMN_START_MAX 752 -+#define MT9V032_ROW_START 0x02 -+#define MT9V032_ROW_START_MIN 4 -+#define MT9V032_ROW_START_DEF 5 -+#define MT9V032_ROW_START_MAX 482 -+#define MT9V032_WINDOW_HEIGHT 0x03 -+#define MT9V032_WINDOW_HEIGHT_MIN 1 -+#define MT9V032_WINDOW_HEIGHT_DEF 480 -+#define MT9V032_WINDOW_HEIGHT_MAX 480 -+#define MT9V032_WINDOW_WIDTH 0x04 -+#define MT9V032_WINDOW_WIDTH_MIN 1 -+#define MT9V032_WINDOW_WIDTH_DEF 752 -+#define MT9V032_WINDOW_WIDTH_MAX 752 -+#define MT9V032_HORIZONTAL_BLANKING 0x05 -+#define MT9V032_HORIZONTAL_BLANKING_MIN 43 -+#define MT9V032_HORIZONTAL_BLANKING_MAX 1023 -+#define MT9V032_VERTICAL_BLANKING 0x06 -+#define MT9V032_VERTICAL_BLANKING_MIN 4 -+#define MT9V032_VERTICAL_BLANKING_MAX 3000 -+#define MT9V032_CHIP_CONTROL 0x07 -+#define MT9V032_CHIP_CONTROL_MASTER_MODE (1 << 3) -+#define MT9V032_CHIP_CONTROL_DOUT_ENABLE (1 << 7) -+#define MT9V032_CHIP_CONTROL_SEQUENTIAL (1 << 8) -+#define MT9V032_SHUTTER_WIDTH1 0x08 -+#define MT9V032_SHUTTER_WIDTH2 0x09 -+#define MT9V032_SHUTTER_WIDTH_CONTROL 0x0a -+#define MT9V032_TOTAL_SHUTTER_WIDTH 0x0b -+#define MT9V032_TOTAL_SHUTTER_WIDTH_MIN 1 -+#define MT9V032_TOTAL_SHUTTER_WIDTH_DEF 480 -+#define MT9V032_TOTAL_SHUTTER_WIDTH_MAX 32767 -+#define MT9V032_RESET 0x0c -+#define MT9V032_READ_MODE 0x0d -+#define MT9V032_READ_MODE_ROW_BIN_MASK (3 << 0) -+#define MT9V032_READ_MODE_ROW_BIN_SHIFT 0 -+#define MT9V032_READ_MODE_COLUMN_BIN_MASK (3 << 2) -+#define MT9V032_READ_MODE_COLUMN_BIN_SHIFT 2 -+#define MT9V032_READ_MODE_ROW_FLIP (1 << 4) -+#define MT9V032_READ_MODE_COLUMN_FLIP (1 << 5) -+#define MT9V032_READ_MODE_DARK_COLUMNS (1 << 6) -+#define MT9V032_READ_MODE_DARK_ROWS (1 << 7) -+#define MT9V032_PIXEL_OPERATION_MODE 0x0f -+#define MT9V032_PIXEL_OPERATION_MODE_COLOR (1 << 2) -+#define MT9V032_PIXEL_OPERATION_MODE_HDR (1 << 6) -+#define MT9V032_ANALOG_GAIN 0x35 -+#define MT9V032_ANALOG_GAIN_MIN 16 -+#define MT9V032_ANALOG_GAIN_DEF 16 -+#define MT9V032_ANALOG_GAIN_MAX 64 -+#define MT9V032_MAX_ANALOG_GAIN 0x36 -+#define MT9V032_MAX_ANALOG_GAIN_MAX 127 -+#define MT9V032_FRAME_DARK_AVERAGE 0x42 -+#define MT9V032_DARK_AVG_THRESH 0x46 -+#define MT9V032_DARK_AVG_LOW_THRESH_MASK (255 << 0) -+#define MT9V032_DARK_AVG_LOW_THRESH_SHIFT 0 -+#define MT9V032_DARK_AVG_HIGH_THRESH_MASK (255 << 8) -+#define MT9V032_DARK_AVG_HIGH_THRESH_SHIFT 8 -+#define MT9V032_ROW_NOISE_CORR_CONTROL 0x70 -+#define MT9V032_ROW_NOISE_CORR_ENABLE (1 << 5) -+#define MT9V032_ROW_NOISE_CORR_USE_BLK_AVG (1 << 7) -+#define MT9V032_PIXEL_CLOCK 0x74 -+#define MT9V032_PIXEL_CLOCK_INV_LINE (1 << 0) -+#define MT9V032_PIXEL_CLOCK_INV_FRAME (1 << 1) -+#define MT9V032_PIXEL_CLOCK_XOR_LINE (1 << 2) -+#define MT9V032_PIXEL_CLOCK_CONT_LINE (1 << 3) -+#define MT9V032_PIXEL_CLOCK_INV_PXL_CLK (1 << 4) -+#define MT9V032_TEST_PATTERN 0x7f -+#define MT9V032_TEST_PATTERN_DATA_MASK (1023 << 0) -+#define MT9V032_TEST_PATTERN_DATA_SHIFT 0 -+#define MT9V032_TEST_PATTERN_USE_DATA (1 << 10) -+#define MT9V032_TEST_PATTERN_GRAY_MASK (3 << 11) -+#define MT9V032_TEST_PATTERN_GRAY_NONE (0 << 11) -+#define MT9V032_TEST_PATTERN_GRAY_VERTICAL (1 << 11) -+#define MT9V032_TEST_PATTERN_GRAY_HORIZONTAL (2 << 11) -+#define MT9V032_TEST_PATTERN_GRAY_DIAGONAL (3 << 11) -+#define MT9V032_TEST_PATTERN_ENABLE (1 << 13) -+#define MT9V032_TEST_PATTERN_FLIP (1 << 14) -+#define MT9V032_AEC_AGC_ENABLE 0xaf -+#define MT9V032_AEC_ENABLE (1 << 0) -+#define MT9V032_AGC_ENABLE (1 << 1) -+#define MT9V032_THERMAL_INFO 0xc1 -+ -+struct mt9v032 { -+ struct v4l2_subdev subdev; -+ struct media_pad pad; -+ -+ struct v4l2_mbus_framefmt format; -+ struct v4l2_rect crop; -+ -+ struct v4l2_ctrl_handler ctrls; -+ -+ struct mutex power_lock; -+ int power_count; -+ -+ struct mt9v032_platform_data *pdata; -+ u16 chip_control; -+ u16 aec_agc; -+}; -+ -+static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd) -+{ -+ return container_of(sd, struct mt9v032, subdev); -+} -+ -+static int mt9v032_read(struct i2c_client *client, const u8 reg) -+{ -+ s32 data = i2c_smbus_read_word_data(client, reg); -+ dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__, -+ swab16(data), reg); -+ return data < 0 ? data : swab16(data); -+} -+ -+static int mt9v032_write(struct i2c_client *client, const u8 reg, -+ const u16 data) -+{ -+ dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__, -+ data, reg); -+ return i2c_smbus_write_word_data(client, reg, swab16(data)); -+} -+ -+static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set) -+{ -+ struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); -+ u16 value = (mt9v032->chip_control & ~clear) | set; -+ int ret; -+ -+ ret = mt9v032_write(client, MT9V032_CHIP_CONTROL, value); -+ if (ret < 0) -+ return ret; -+ -+ mt9v032->chip_control = value; -+ return 0; -+} -+ -+static int -+mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable) -+{ -+ struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); -+ u16 value = mt9v032->aec_agc; -+ int ret; -+ -+ if (enable) -+ value |= which; -+ else -+ value &= ~which; -+ -+ ret = mt9v032_write(client, MT9V032_AEC_AGC_ENABLE, value); -+ if (ret < 0) -+ return ret; -+ -+ mt9v032->aec_agc = value; -+ return 0; -+} -+ -+static int mt9v032_power_on(struct mt9v032 *mt9v032) -+{ -+ struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); -+ int ret; -+ -+ if (mt9v032->pdata->set_clock) { -+ mt9v032->pdata->set_clock(&mt9v032->subdev, 25000000); -+ udelay(1); -+ } -+ -+ /* Reset the chip and stop data read out */ -+ ret = mt9v032_write(client, MT9V032_RESET, 1); -+ if (ret < 0) -+ return ret; -+ -+ ret = mt9v032_write(client, MT9V032_RESET, 0); -+ if (ret < 0) -+ return ret; -+ -+ return mt9v032_write(client, MT9V032_CHIP_CONTROL, 0); -+} -+ -+static void mt9v032_power_off(struct mt9v032 *mt9v032) -+{ -+ if (mt9v032->pdata->set_clock) -+ mt9v032->pdata->set_clock(&mt9v032->subdev, 0); -+} -+ -+static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on) -+{ -+ struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); -+ int ret; -+ -+ if (!on) { -+ mt9v032_power_off(mt9v032); -+ return 0; -+ } -+ -+ ret = mt9v032_power_on(mt9v032); -+ if (ret < 0) -+ return ret; -+ -+ /* Configure the pixel clock polarity */ -+ if (mt9v032->pdata && mt9v032->pdata->clk_pol) { -+ ret = mt9v032_write(client, MT9V032_PIXEL_CLOCK, -+ MT9V032_PIXEL_CLOCK_INV_PXL_CLK); -+ if (ret < 0) -+ return ret; -+ } -+ -+ /* Disable the noise correction algorithm and restore the controls. */ -+ ret = mt9v032_write(client, MT9V032_ROW_NOISE_CORR_CONTROL, 0); -+ if (ret < 0) -+ return ret; -+ -+ return v4l2_ctrl_handler_setup(&mt9v032->ctrls); -+} -+ -+/* ----------------------------------------------------------------------------- -+ * V4L2 subdev video operations -+ */ -+ -+static struct v4l2_mbus_framefmt * -+__mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh, -+ unsigned int pad, enum v4l2_subdev_format_whence which) -+{ -+ switch (which) { -+ case V4L2_SUBDEV_FORMAT_TRY: -+ return v4l2_subdev_get_try_format(fh, pad); -+ case V4L2_SUBDEV_FORMAT_ACTIVE: -+ return &mt9v032->format; -+ default: -+ return NULL; -+ } -+} -+ -+static struct v4l2_rect * -+__mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh, -+ unsigned int pad, enum v4l2_subdev_format_whence which) -+{ -+ switch (which) { -+ case V4L2_SUBDEV_FORMAT_TRY: -+ return v4l2_subdev_get_try_crop(fh, pad); -+ case V4L2_SUBDEV_FORMAT_ACTIVE: -+ return &mt9v032->crop; -+ default: -+ return NULL; -+ } -+} -+ -+static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable) -+{ -+ const u16 mode = MT9V032_CHIP_CONTROL_MASTER_MODE -+ | MT9V032_CHIP_CONTROL_DOUT_ENABLE -+ | MT9V032_CHIP_CONTROL_SEQUENTIAL; -+ struct i2c_client *client = v4l2_get_subdevdata(subdev); -+ struct mt9v032 *mt9v032 = to_mt9v032(subdev); -+ struct v4l2_mbus_framefmt *format = &mt9v032->format; -+ struct v4l2_rect *crop = &mt9v032->crop; -+ unsigned int hratio; -+ unsigned int vratio; -+ int ret; -+ -+ if (!enable) -+ return mt9v032_set_chip_control(mt9v032, mode, 0); -+ -+ /* Configure the window size and row/column bin */ -+ hratio = DIV_ROUND_CLOSEST(crop->width, format->width); -+ vratio = DIV_ROUND_CLOSEST(crop->height, format->height); -+ -+ ret = mt9v032_write(client, MT9V032_READ_MODE, -+ (hratio - 1) << MT9V032_READ_MODE_ROW_BIN_SHIFT | -+ (vratio - 1) << MT9V032_READ_MODE_COLUMN_BIN_SHIFT); -+ if (ret < 0) -+ return ret; -+ -+ ret = mt9v032_write(client, MT9V032_COLUMN_START, crop->left); -+ if (ret < 0) -+ return ret; -+ -+ ret = mt9v032_write(client, MT9V032_ROW_START, crop->top); -+ if (ret < 0) -+ return ret; -+ -+ ret = mt9v032_write(client, MT9V032_WINDOW_WIDTH, crop->width); -+ if (ret < 0) -+ return ret; -+ -+ ret = mt9v032_write(client, MT9V032_WINDOW_HEIGHT, crop->height); -+ if (ret < 0) -+ return ret; -+ -+ ret = mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING, -+ max(43, 660 - crop->width)); -+ if (ret < 0) -+ return ret; -+ -+ /* Switch to master "normal" mode */ -+ return mt9v032_set_chip_control(mt9v032, 0, mode); -+} -+ -+static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_mbus_code_enum *code) -+{ -+ if (code->index > 0) -+ return -EINVAL; -+ -+ code->code = V4L2_MBUS_FMT_SGRBG10_1X10; -+ return 0; -+} -+ -+static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_frame_size_enum *fse) -+{ -+ if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10) -+ return -EINVAL; -+ -+ fse->min_width = MT9V032_WINDOW_WIDTH_DEF / fse->index; -+ fse->max_width = fse->min_width; -+ fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / fse->index; -+ fse->max_height = fse->min_height; -+ -+ return 0; -+} -+ -+static int mt9v032_get_format(struct v4l2_subdev *subdev, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_format *format) -+{ -+ struct mt9v032 *mt9v032 = to_mt9v032(subdev); -+ -+ format->format = *__mt9v032_get_pad_format(mt9v032, fh, format->pad, -+ format->which); -+ return 0; -+} -+ -+static int mt9v032_set_format(struct v4l2_subdev *subdev, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_format *format) -+{ -+ struct mt9v032 *mt9v032 = to_mt9v032(subdev); -+ struct v4l2_mbus_framefmt *__format; -+ struct v4l2_rect *__crop; -+ unsigned int width; -+ unsigned int height; -+ unsigned int hratio; -+ unsigned int vratio; -+ -+ __crop = __mt9v032_get_pad_crop(mt9v032, fh, format->pad, -+ format->which); -+ -+ /* Clamp the width and height to avoid dividing by zero. */ -+ width = clamp_t(unsigned int, ALIGN(format->format.width, 2), -+ max(__crop->width / 8, MT9V032_WINDOW_WIDTH_MIN), -+ __crop->width); -+ height = clamp_t(unsigned int, ALIGN(format->format.height, 2), -+ max(__crop->height / 8, MT9V032_WINDOW_HEIGHT_MIN), -+ __crop->height); -+ -+ hratio = DIV_ROUND_CLOSEST(__crop->width, width); -+ vratio = DIV_ROUND_CLOSEST(__crop->height, height); -+ -+ __format = __mt9v032_get_pad_format(mt9v032, fh, format->pad, -+ format->which); -+ __format->width = __crop->width / hratio; -+ __format->height = __crop->height / vratio; -+ -+ format->format = *__format; -+ -+ return 0; -+} -+ -+static int mt9v032_get_crop(struct v4l2_subdev *subdev, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_crop *crop) -+{ -+ struct mt9v032 *mt9v032 = to_mt9v032(subdev); -+ -+ crop->rect = *__mt9v032_get_pad_crop(mt9v032, fh, crop->pad, -+ crop->which); -+ return 0; -+} -+ -+static int mt9v032_set_crop(struct v4l2_subdev *subdev, -+ struct v4l2_subdev_fh *fh, -+ struct v4l2_subdev_crop *crop) -+{ -+ struct mt9v032 *mt9v032 = to_mt9v032(subdev); -+ struct v4l2_mbus_framefmt *__format; -+ struct v4l2_rect *__crop; -+ struct v4l2_rect rect; -+ -+ /* Clamp the crop rectangle boundaries and align them to a non multiple -+ * of 2 pixels to ensure a GRBG Bayer pattern. -+ */ -+ rect.left = clamp(ALIGN(crop->rect.left + 1, 2) - 1, -+ MT9V032_COLUMN_START_MIN, -+ MT9V032_COLUMN_START_MAX); -+ rect.top = clamp(ALIGN(crop->rect.top + 1, 2) - 1, -+ MT9V032_ROW_START_MIN, -+ MT9V032_ROW_START_MAX); -+ rect.width = clamp(ALIGN(crop->rect.width, 2), -+ MT9V032_WINDOW_WIDTH_MIN, -+ MT9V032_WINDOW_WIDTH_MAX); -+ rect.height = clamp(ALIGN(crop->rect.height, 2), -+ MT9V032_WINDOW_HEIGHT_MIN, -+ MT9V032_WINDOW_HEIGHT_MAX); -+ -+ rect.width = min(rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left); -+ rect.height = min(rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top); -+ -+ __crop = __mt9v032_get_pad_crop(mt9v032, fh, crop->pad, crop->which); -+ -+ if (rect.width != __crop->width || rect.height != __crop->height) { -+ /* Reset the output image size if the crop rectangle size has -+ * been modified. -+ */ -+ __format = __mt9v032_get_pad_format(mt9v032, fh, crop->pad, -+ crop->which); -+ __format->width = rect.width; -+ __format->height = rect.height; -+ } -+ -+ *__crop = rect; -+ crop->rect = rect; -+ -+ return 0; -+} -+ -+/* ----------------------------------------------------------------------------- -+ * V4L2 subdev control operations -+ */ -+ -+#define V4L2_CID_TEST_PATTERN (V4L2_CID_USER_BASE | 0x1001) -+ -+static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl) -+{ -+ struct mt9v032 *mt9v032 = -+ container_of(ctrl->handler, struct mt9v032, ctrls); -+ struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev); -+ u16 data; -+ -+ switch (ctrl->id) { -+ case V4L2_CID_AUTOGAIN: -+ return mt9v032_update_aec_agc(mt9v032, MT9V032_AGC_ENABLE, -+ ctrl->val); -+ -+ case V4L2_CID_GAIN: -+ return mt9v032_write(client, MT9V032_ANALOG_GAIN, ctrl->val); -+ -+ case V4L2_CID_EXPOSURE_AUTO: -+ return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE, -+ ctrl->val); -+ -+ case V4L2_CID_EXPOSURE: -+ return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH, -+ ctrl->val); -+ -+ case V4L2_CID_TEST_PATTERN: -+ switch (ctrl->val) { -+ case 0: -+ data = 0; -+ break; -+ case 1: -+ data = MT9V032_TEST_PATTERN_GRAY_VERTICAL -+ | MT9V032_TEST_PATTERN_ENABLE; -+ break; -+ case 2: -+ data = MT9V032_TEST_PATTERN_GRAY_HORIZONTAL -+ | MT9V032_TEST_PATTERN_ENABLE; -+ break; -+ case 3: -+ data = MT9V032_TEST_PATTERN_GRAY_DIAGONAL -+ | MT9V032_TEST_PATTERN_ENABLE; -+ break; -+ default: -+ data = (ctrl->val << MT9V032_TEST_PATTERN_DATA_SHIFT) -+ | MT9V032_TEST_PATTERN_USE_DATA -+ | MT9V032_TEST_PATTERN_ENABLE -+ | MT9V032_TEST_PATTERN_FLIP; -+ break; -+ } -+ -+ return mt9v032_write(client, MT9V032_TEST_PATTERN, data); -+ } -+ -+ return 0; -+} -+ -+static struct v4l2_ctrl_ops mt9v032_ctrl_ops = { -+ .s_ctrl = mt9v032_s_ctrl, -+}; -+ -+static const struct v4l2_ctrl_config mt9v032_ctrls[] = { -+ { -+ .ops = &mt9v032_ctrl_ops, -+ .id = V4L2_CID_TEST_PATTERN, -+ .type = V4L2_CTRL_TYPE_INTEGER, -+ .name = "Test pattern", -+ .min = 0, -+ .max = 1023, -+ .step = 1, -+ .def = 0, -+ .flags = 0, -+ } -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * V4L2 subdev core operations -+ */ -+ -+static int mt9v032_set_power(struct v4l2_subdev *subdev, int on) -+{ -+ struct mt9v032 *mt9v032 = to_mt9v032(subdev); -+ int ret = 0; -+ -+ mutex_lock(&mt9v032->power_lock); -+ -+ /* If the power count is modified from 0 to != 0 or from != 0 to 0, -+ * update the power state. -+ */ -+ if (mt9v032->power_count == !on) { -+ ret = __mt9v032_set_power(mt9v032, !!on); -+ if (ret < 0) -+ goto done; -+ } -+ -+ /* Update the power count. */ -+ mt9v032->power_count += on ? 1 : -1; -+ WARN_ON(mt9v032->power_count < 0); -+ -+done: -+ mutex_unlock(&mt9v032->power_lock); -+ return ret; -+} -+ -+/* ----------------------------------------------------------------------------- -+ * V4L2 subdev internal operations -+ */ -+ -+static int mt9v032_registered(struct v4l2_subdev *subdev) -+{ -+ struct i2c_client *client = v4l2_get_subdevdata(subdev); -+ struct mt9v032 *mt9v032 = to_mt9v032(subdev); -+ s32 data; -+ int ret; -+ -+ dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n", -+ client->addr); -+ -+ ret = mt9v032_power_on(mt9v032); -+ if (ret < 0) { -+ dev_err(&client->dev, "MT9V032 power up failed\n"); -+ return ret; -+ } -+ -+ /* Read and check the sensor version */ -+ data = mt9v032_read(client, MT9V032_CHIP_VERSION); -+ if (data != MT9V032_CHIP_ID_REV1 && data != MT9V032_CHIP_ID_REV3) { -+ dev_err(&client->dev, "MT9V032 not detected, wrong version " -+ "0x%04x\n", data); -+ return -ENODEV; -+ } -+ -+ mt9v032_power_off(mt9v032); -+ -+ dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n", -+ client->addr); -+ -+ return ret; -+} -+ -+static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) -+{ -+ struct v4l2_mbus_framefmt *format; -+ struct v4l2_rect *crop; -+ -+ crop = v4l2_subdev_get_try_crop(fh, 0); -+ crop->left = MT9V032_COLUMN_START_DEF; -+ crop->top = MT9V032_ROW_START_DEF; -+ crop->width = MT9V032_WINDOW_WIDTH_DEF; -+ crop->height = MT9V032_WINDOW_HEIGHT_DEF; -+ -+ format = v4l2_subdev_get_try_format(fh, 0); -+ format->code = V4L2_MBUS_FMT_SGRBG10_1X10; -+ format->width = MT9V032_WINDOW_WIDTH_DEF; -+ format->height = MT9V032_WINDOW_HEIGHT_DEF; -+ format->field = V4L2_FIELD_NONE; -+ format->colorspace = V4L2_COLORSPACE_SRGB; -+ -+ return mt9v032_set_power(subdev, 1); -+} -+ -+static int mt9v032_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) -+{ -+ return mt9v032_set_power(subdev, 0); -+} -+ -+static struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = { -+ .s_power = mt9v032_set_power, -+}; -+ -+static struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = { -+ .s_stream = mt9v032_s_stream, -+}; -+ -+static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = { -+ .enum_mbus_code = mt9v032_enum_mbus_code, -+ .enum_frame_size = mt9v032_enum_frame_size, -+ .get_fmt = mt9v032_get_format, -+ .set_fmt = mt9v032_set_format, -+ .get_crop = mt9v032_get_crop, -+ .set_crop = mt9v032_set_crop, -+}; -+ -+static struct v4l2_subdev_ops mt9v032_subdev_ops = { -+ .core = &mt9v032_subdev_core_ops, -+ .video = &mt9v032_subdev_video_ops, -+ .pad = &mt9v032_subdev_pad_ops, -+}; -+ -+static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = { -+ .registered = mt9v032_registered, -+ .open = mt9v032_open, -+ .close = mt9v032_close, -+}; -+ -+/* ----------------------------------------------------------------------------- -+ * Driver initialization and probing -+ */ -+ -+static int mt9v032_probe(struct i2c_client *client, -+ const struct i2c_device_id *did) -+{ -+ struct mt9v032 *mt9v032; -+ unsigned int i; -+ int ret; -+ -+ if (!i2c_check_functionality(client->adapter, -+ I2C_FUNC_SMBUS_WORD_DATA)) { -+ dev_warn(&client->adapter->dev, -+ "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); -+ return -EIO; -+ } -+ -+ mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL); -+ if (!mt9v032) -+ return -ENOMEM; -+ -+ mutex_init(&mt9v032->power_lock); -+ mt9v032->pdata = client->dev.platform_data; -+ -+ v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 4); -+ -+ v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, -+ V4L2_CID_AUTOGAIN, 0, 1, 1, 1); -+ v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, -+ V4L2_CID_GAIN, MT9V032_ANALOG_GAIN_MIN, -+ MT9V032_ANALOG_GAIN_MAX, 1, MT9V032_ANALOG_GAIN_DEF); -+ v4l2_ctrl_new_std_menu(&mt9v032->ctrls, &mt9v032_ctrl_ops, -+ V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0, -+ V4L2_EXPOSURE_AUTO); -+ v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops, -+ V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN, -+ MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1, -+ MT9V032_TOTAL_SHUTTER_WIDTH_DEF); -+ -+ for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i) -+ v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL); -+ -+ mt9v032->subdev.ctrl_handler = &mt9v032->ctrls; -+ -+ if (mt9v032->ctrls.error) -+ printk(KERN_INFO "%s: control initialization error %d\n", -+ __func__, mt9v032->ctrls.error); -+ -+ mt9v032->crop.left = MT9V032_COLUMN_START_DEF; -+ mt9v032->crop.top = MT9V032_ROW_START_DEF; -+ mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF; -+ mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF; -+ -+ mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10; -+ mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF; -+ mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF; -+ mt9v032->format.field = V4L2_FIELD_NONE; -+ mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB; -+ -+ mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE; -+ -+ v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops); -+ mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops; -+ mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; -+ -+ mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE; -+ ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0); -+ if (ret < 0) -+ kfree(mt9v032); -+ -+ return ret; -+} -+ -+static int mt9v032_remove(struct i2c_client *client) -+{ -+ struct v4l2_subdev *subdev = i2c_get_clientdata(client); -+ struct mt9v032 *mt9v032 = to_mt9v032(subdev); -+ -+ v4l2_device_unregister_subdev(subdev); -+ media_entity_cleanup(&subdev->entity); -+ kfree(mt9v032); -+ return 0; -+} -+ -+static const struct i2c_device_id mt9v032_id[] = { -+ { "mt9v032", 0 }, -+ { } -+}; -+MODULE_DEVICE_TABLE(i2c, mt9v032_id); -+ -+static struct i2c_driver mt9v032_driver = { -+ .driver = { -+ .name = "mt9v032", -+ }, -+ .probe = mt9v032_probe, -+ .remove = mt9v032_remove, -+ .id_table = mt9v032_id, -+}; -+ -+static int __init mt9v032_init(void) -+{ -+ return i2c_add_driver(&mt9v032_driver); -+} -+ -+static void __exit mt9v032_exit(void) -+{ -+ i2c_del_driver(&mt9v032_driver); -+} -+ -+module_init(mt9v032_init); -+module_exit(mt9v032_exit); -+ -+MODULE_DESCRIPTION("Aptina MT9V032 Camera driver"); -+MODULE_AUTHOR("Laurent Pinchart "); -+MODULE_LICENSE("GPL"); -diff --git a/include/media/mt9v032.h b/include/media/mt9v032.h -new file mode 100644 -index 0000000..5e27f9b ---- /dev/null -+++ b/include/media/mt9v032.h -@@ -0,0 +1,12 @@ -+#ifndef _MEDIA_MT9V032_H -+#define _MEDIA_MT9V032_H -+ -+struct v4l2_subdev; -+ -+struct mt9v032_platform_data { -+ unsigned int clk_pol:1; -+ -+ void (*set_clock)(struct v4l2_subdev *subdev, unsigned int rate); -+}; -+ -+#endif --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/camera/0003-Add-support-for-mt9p031-LI-5M03-module-in-Beagleboar.patch b/recipes-kernel/linux/linux-omap-2.6.39/camera/0003-Add-support-for-mt9p031-LI-5M03-module-in-Beagleboar.patch deleted file mode 100644 index a1807e73..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/camera/0003-Add-support-for-mt9p031-LI-5M03-module-in-Beagleboar.patch +++ /dev/null @@ -1,162 +0,0 @@ -From f662a8a2b9794121568903f5cc969e50eb151892 Mon Sep 17 00:00:00 2001 -From: Javier Martin -Date: Mon, 30 May 2011 10:37:17 +0200 -Subject: [PATCH 3/3] Add support for mt9p031 (LI-5M03 module) in Beagleboard xM. - -Since isp clocks have not been exposed yet, this patch -includes a temporal solution for testing mt9p031 driver -in Beagleboard xM. - -Signed-off-by: Javier Martin ---- - arch/arm/mach-omap2/Makefile | 1 + - arch/arm/mach-omap2/board-omap3beagle-camera.c | 95 ++++++++++++++++++++++++ - arch/arm/mach-omap2/board-omap3beagle.c | 5 + - 3 files changed, 101 insertions(+), 0 deletions(-) - create mode 100644 arch/arm/mach-omap2/board-omap3beagle-camera.c - -diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile -index 512b152..05cd983 100644 ---- a/arch/arm/mach-omap2/Makefile -+++ b/arch/arm/mach-omap2/Makefile -@@ -179,6 +179,7 @@ obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \ - hsmmc.o - obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o - obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \ -+ board-omap3beagle-camera.o \ - hsmmc.o - obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o \ - hsmmc.o -diff --git a/arch/arm/mach-omap2/board-omap3beagle-camera.c b/arch/arm/mach-omap2/board-omap3beagle-camera.c -new file mode 100644 -index 0000000..2632557 ---- /dev/null -+++ b/arch/arm/mach-omap2/board-omap3beagle-camera.c -@@ -0,0 +1,95 @@ -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include "devices.h" -+#include "../../../drivers/media/video/omap3isp/isp.h" -+ -+#define MT9P031_RESET_GPIO 98 -+#define MT9P031_XCLK ISP_XCLK_A -+ -+static struct regulator *reg_1v8, *reg_2v8; -+ -+static int beagle_cam_set_xclk(struct v4l2_subdev *subdev, int hz) -+{ -+ struct isp_device *isp = v4l2_dev_to_isp_device(subdev->v4l2_dev); -+ int ret; -+ -+ ret = isp->platform_cb.set_xclk(isp, hz, MT9P031_XCLK); -+ return 0; -+} -+ -+static int beagle_cam_reset(struct v4l2_subdev *subdev, int active) -+{ -+ /* Set RESET_BAR to !active */ -+ gpio_set_value(MT9P031_RESET_GPIO, !active); -+ -+ return 0; -+} -+ -+static struct mt9p031_platform_data beagle_mt9p031_platform_data = { -+ .set_xclk = beagle_cam_set_xclk, -+ .reset = beagle_cam_reset, -+ .vdd_io = MT9P031_VDD_IO_1V8, -+ .version = MT9P031_COLOR_VERSION, -+}; -+ -+static struct i2c_board_info mt9p031_camera_i2c_device = { -+ I2C_BOARD_INFO("mt9p031", 0x48), -+ .platform_data = &beagle_mt9p031_platform_data, -+}; -+ -+static struct isp_subdev_i2c_board_info mt9p031_camera_subdevs[] = { -+ { -+ .board_info = &mt9p031_camera_i2c_device, -+ .i2c_adapter_id = 2, -+ }, -+ { NULL, 0, }, -+}; -+ -+static struct isp_v4l2_subdevs_group beagle_camera_subdevs[] = { -+ { -+ .subdevs = mt9p031_camera_subdevs, -+ .interface = ISP_INTERFACE_PARALLEL, -+ .bus = { -+ .parallel = { -+ .data_lane_shift = 0, -+ .clk_pol = 1, -+ .bridge = ISPCTRL_PAR_BRIDGE_DISABLE, -+ } -+ }, -+ }, -+ { }, -+}; -+ -+static struct isp_platform_data beagle_isp_platform_data = { -+ .subdevs = beagle_camera_subdevs, -+}; -+ -+static int __init beagle_camera_init(void) -+{ -+ if (!machine_is_omap3_beagle() || !cpu_is_omap3630()) -+ return 0; -+ -+ reg_1v8 = regulator_get(NULL, "cam_1v8"); -+ if (IS_ERR(reg_1v8)) -+ pr_err("%s: cannot get cam_1v8 regulator\n", __func__); -+ else -+ regulator_enable(reg_1v8); -+ -+ reg_2v8 = regulator_get(NULL, "cam_2v8"); -+ if (IS_ERR(reg_2v8)) -+ pr_err("%s: cannot get cam_2v8 regulator\n", __func__); -+ else -+ regulator_enable(reg_2v8); -+ -+ omap_register_i2c_bus(2, 100, NULL, 0); -+ gpio_request(MT9P031_RESET_GPIO, "cam_rst"); -+ gpio_direction_output(MT9P031_RESET_GPIO, 0); -+ omap3_init_camera(&beagle_isp_platform_data); -+ return 0; -+} -+late_initcall(beagle_camera_init); -diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c -index 221bfda..dd6e31f 100644 ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -25,12 +25,16 @@ - #include - #include - #include -+#include -+#include -+#include - - #include - #include - #include - #include - -+#include - #include - #include - -@@ -48,6 +52,7 @@ - #include - #include - #include -+#include - - #include "mux.h" - #include "hsmmc.h" --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0001-mfd-Fix-omap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0001-mfd-Fix-omap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch deleted file mode 100644 index c9f1e6a9..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0001-mfd-Fix-omap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 46be90d202c36db19e27c2991cbff401c6c3ee81 Mon Sep 17 00:00:00 2001 -From: Keshava Munegowda -Date: Mon, 16 May 2011 14:24:58 +0530 -Subject: [PATCH 01/13] mfd: Fix omap usbhs crash when rmmoding ehci or ohci - -The disabling of clocks and freeing GPIO are changed -to fix the occurrence of the crash of rmmod of ehci and ohci -drivers. The GPIOs should be freed after the spin locks are -unlocked. - -Signed-off-by: Keshava Munegowda -Acked-by: Felipe Balbi -Cc: stable@kernel.org -Signed-off-by: Samuel Ortiz ---- - drivers/mfd/omap-usb-host.c | 27 +++++++++++++++++++-------- - 1 files changed, 19 insertions(+), 8 deletions(-) - -diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c -index 3ab9ffa..55c5d47 100644 ---- a/drivers/mfd/omap-usb-host.c -+++ b/drivers/mfd/omap-usb-host.c -@@ -994,22 +994,33 @@ static void usbhs_disable(struct device *dev) - dev_dbg(dev, "operation timed out\n"); - } - -- if (pdata->ehci_data->phy_reset) { -- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) -- gpio_free(pdata->ehci_data->reset_gpio_port[0]); -- -- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) -- gpio_free(pdata->ehci_data->reset_gpio_port[1]); -+ if (is_omap_usbhs_rev2(omap)) { -+ if (is_ehci_tll_mode(pdata->port_mode[0])) -+ clk_enable(omap->usbtll_p1_fck); -+ if (is_ehci_tll_mode(pdata->port_mode[1])) -+ clk_enable(omap->usbtll_p2_fck); -+ clk_disable(omap->utmi_p2_fck); -+ clk_disable(omap->utmi_p1_fck); - } - -- clk_disable(omap->utmi_p2_fck); -- clk_disable(omap->utmi_p1_fck); - clk_disable(omap->usbtll_ick); - clk_disable(omap->usbtll_fck); - clk_disable(omap->usbhost_fs_fck); - clk_disable(omap->usbhost_hs_fck); - clk_disable(omap->usbhost_ick); - -+ /* The gpio_free migh sleep; so unlock the spinlock */ -+ spin_unlock_irqrestore(&omap->lock, flags); -+ -+ if (pdata->ehci_data->phy_reset) { -+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) -+ gpio_free(pdata->ehci_data->reset_gpio_port[0]); -+ -+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) -+ gpio_free(pdata->ehci_data->reset_gpio_port[1]); -+ } -+ return; -+ - end_disble: - spin_unlock_irqrestore(&omap->lock, flags); - } --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0002-mfd-Fix-omap_usbhs_alloc_children-error-handling.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0002-mfd-Fix-omap_usbhs_alloc_children-error-handling.patch deleted file mode 100644 index 380dd82a..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0002-mfd-Fix-omap_usbhs_alloc_children-error-handling.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 89a903aca8fda3dcf1a6f9a424247e772afdd44e Mon Sep 17 00:00:00 2001 -From: Axel Lin -Date: Sat, 14 May 2011 14:15:36 +0800 -Subject: [PATCH 02/13] mfd: Fix omap_usbhs_alloc_children error handling - -1. Return proper error if omap_usbhs_alloc_child fails -2. In the case of goto err_ehci, we should call platform_device_unregister(ehci) - instead of platform_device_put(ehci) because we have already added the - platform device to device hierarchy. - -Signed-off-by: Axel Lin -Signed-off-by: Axel Lin -Tested-by: Keshava Munegowda -Acked-by: Felipe Balbi -Signed-off-by: Samuel Ortiz ---- - drivers/mfd/omap-usb-host.c | 4 +++- - 1 files changed, 3 insertions(+), 1 deletions(-) - -diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c -index 55c5d47..1717144 100644 ---- a/drivers/mfd/omap-usb-host.c -+++ b/drivers/mfd/omap-usb-host.c -@@ -281,6 +281,7 @@ static int omap_usbhs_alloc_children(struct platform_device *pdev) - - if (!ehci) { - dev_err(dev, "omap_usbhs_alloc_child failed\n"); -+ ret = -ENOMEM; - goto err_end; - } - -@@ -304,13 +305,14 @@ static int omap_usbhs_alloc_children(struct platform_device *pdev) - sizeof(*ohci_data), dev); - if (!ohci) { - dev_err(dev, "omap_usbhs_alloc_child failed\n"); -+ ret = -ENOMEM; - goto err_ehci; - } - - return 0; - - err_ehci: -- platform_device_put(ehci); -+ platform_device_unregister(ehci); - - err_end: - return ret; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0003-mfd-Add-omap-usbhs-runtime-PM-support.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0003-mfd-Add-omap-usbhs-runtime-PM-support.patch deleted file mode 100644 index b47deb2c..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0003-mfd-Add-omap-usbhs-runtime-PM-support.patch +++ /dev/null @@ -1,245 +0,0 @@ -From edc881f9c4897fab11542cd5c36a33b288f702be Mon Sep 17 00:00:00 2001 -From: Keshava Munegowda -Date: Sun, 22 May 2011 22:51:26 +0200 -Subject: [PATCH 03/13] mfd: Add omap-usbhs runtime PM support - -The usbhs core driver does not enable/disable the interface and -functional clocks; These clocks are handled by hwmod and runtime pm, -hence insted of the clock enable/disable, the runtime pm APIS are -used. however,the port clocks and tll clocks are handled -by the usbhs core. - -Signed-off-by: Keshava Munegowda -Signed-off-by: Samuel Ortiz ---- - drivers/mfd/omap-usb-host.c | 131 +++---------------------------------------- - 1 files changed, 9 insertions(+), 122 deletions(-) - -diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c -index 1717144..8552195 100644 ---- a/drivers/mfd/omap-usb-host.c -+++ b/drivers/mfd/omap-usb-host.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #define USBHS_DRIVER_NAME "usbhs-omap" - #define OMAP_EHCI_DEVICE "ehci-omap" -@@ -146,9 +147,6 @@ - - - struct usbhs_hcd_omap { -- struct clk *usbhost_ick; -- struct clk *usbhost_hs_fck; -- struct clk *usbhost_fs_fck; - struct clk *xclk60mhsp1_ck; - struct clk *xclk60mhsp2_ck; - struct clk *utmi_p1_fck; -@@ -158,8 +156,6 @@ struct usbhs_hcd_omap { - struct clk *usbhost_p2_fck; - struct clk *usbtll_p2_fck; - struct clk *init_60m_fclk; -- struct clk *usbtll_fck; -- struct clk *usbtll_ick; - - void __iomem *uhh_base; - void __iomem *tll_base; -@@ -353,46 +349,13 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev) - omap->platdata.ehci_data = pdata->ehci_data; - omap->platdata.ohci_data = pdata->ohci_data; - -- omap->usbhost_ick = clk_get(dev, "usbhost_ick"); -- if (IS_ERR(omap->usbhost_ick)) { -- ret = PTR_ERR(omap->usbhost_ick); -- dev_err(dev, "usbhost_ick failed error:%d\n", ret); -- goto err_end; -- } -- -- omap->usbhost_hs_fck = clk_get(dev, "hs_fck"); -- if (IS_ERR(omap->usbhost_hs_fck)) { -- ret = PTR_ERR(omap->usbhost_hs_fck); -- dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret); -- goto err_usbhost_ick; -- } -- -- omap->usbhost_fs_fck = clk_get(dev, "fs_fck"); -- if (IS_ERR(omap->usbhost_fs_fck)) { -- ret = PTR_ERR(omap->usbhost_fs_fck); -- dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret); -- goto err_usbhost_hs_fck; -- } -- -- omap->usbtll_fck = clk_get(dev, "usbtll_fck"); -- if (IS_ERR(omap->usbtll_fck)) { -- ret = PTR_ERR(omap->usbtll_fck); -- dev_err(dev, "usbtll_fck failed error:%d\n", ret); -- goto err_usbhost_fs_fck; -- } -- -- omap->usbtll_ick = clk_get(dev, "usbtll_ick"); -- if (IS_ERR(omap->usbtll_ick)) { -- ret = PTR_ERR(omap->usbtll_ick); -- dev_err(dev, "usbtll_ick failed error:%d\n", ret); -- goto err_usbtll_fck; -- } -+ pm_runtime_enable(&pdev->dev); - - omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); - if (IS_ERR(omap->utmi_p1_fck)) { - ret = PTR_ERR(omap->utmi_p1_fck); - dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); -- goto err_usbtll_ick; -+ goto err_end; - } - - omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); -@@ -522,22 +485,8 @@ err_xclk60mhsp1_ck: - err_utmi_p1_fck: - clk_put(omap->utmi_p1_fck); - --err_usbtll_ick: -- clk_put(omap->usbtll_ick); -- --err_usbtll_fck: -- clk_put(omap->usbtll_fck); -- --err_usbhost_fs_fck: -- clk_put(omap->usbhost_fs_fck); -- --err_usbhost_hs_fck: -- clk_put(omap->usbhost_hs_fck); -- --err_usbhost_ick: -- clk_put(omap->usbhost_ick); -- - err_end: -+ pm_runtime_disable(&pdev->dev); - kfree(omap); - - end_probe: -@@ -571,11 +520,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev) - clk_put(omap->utmi_p2_fck); - clk_put(omap->xclk60mhsp1_ck); - clk_put(omap->utmi_p1_fck); -- clk_put(omap->usbtll_ick); -- clk_put(omap->usbtll_fck); -- clk_put(omap->usbhost_fs_fck); -- clk_put(omap->usbhost_hs_fck); -- clk_put(omap->usbhost_ick); -+ pm_runtime_disable(&pdev->dev); - kfree(omap); - - return 0; -@@ -695,7 +640,6 @@ static int usbhs_enable(struct device *dev) - struct usbhs_omap_platform_data *pdata = &omap->platdata; - unsigned long flags = 0; - int ret = 0; -- unsigned long timeout; - unsigned reg; - - dev_dbg(dev, "starting TI HSUSB Controller\n"); -@@ -708,11 +652,7 @@ static int usbhs_enable(struct device *dev) - if (omap->count > 0) - goto end_count; - -- clk_enable(omap->usbhost_ick); -- clk_enable(omap->usbhost_hs_fck); -- clk_enable(omap->usbhost_fs_fck); -- clk_enable(omap->usbtll_fck); -- clk_enable(omap->usbtll_ick); -+ pm_runtime_get_sync(dev); - - if (pdata->ehci_data->phy_reset) { - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { -@@ -736,50 +676,6 @@ static int usbhs_enable(struct device *dev) - omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); - dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); - -- /* perform TLL soft reset, and wait until reset is complete */ -- usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, -- OMAP_USBTLL_SYSCONFIG_SOFTRESET); -- -- /* Wait for TLL reset to complete */ -- timeout = jiffies + msecs_to_jiffies(1000); -- while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) -- & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { -- cpu_relax(); -- -- if (time_after(jiffies, timeout)) { -- dev_dbg(dev, "operation timed out\n"); -- ret = -EINVAL; -- goto err_tll; -- } -- } -- -- dev_dbg(dev, "TLL RESET DONE\n"); -- -- /* (1<<3) = no idle mode only for initial debugging */ -- usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, -- OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | -- OMAP_USBTLL_SYSCONFIG_SIDLEMODE | -- OMAP_USBTLL_SYSCONFIG_AUTOIDLE); -- -- /* Put UHH in NoIdle/NoStandby mode */ -- reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG); -- if (is_omap_usbhs_rev1(omap)) { -- reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP -- | OMAP_UHH_SYSCONFIG_SIDLEMODE -- | OMAP_UHH_SYSCONFIG_CACTIVITY -- | OMAP_UHH_SYSCONFIG_MIDLEMODE); -- reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; -- -- -- } else if (is_omap_usbhs_rev2(omap)) { -- reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; -- reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; -- reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; -- reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; -- } -- -- usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); -- - reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); - /* setup ULPI bypass and burst configurations */ - reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN -@@ -919,6 +815,8 @@ end_count: - return 0; - - err_tll: -+ pm_runtime_put_sync(dev); -+ spin_unlock_irqrestore(&omap->lock, flags); - if (pdata->ehci_data->phy_reset) { - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) - gpio_free(pdata->ehci_data->reset_gpio_port[0]); -@@ -926,13 +824,6 @@ err_tll: - if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) - gpio_free(pdata->ehci_data->reset_gpio_port[1]); - } -- -- clk_disable(omap->usbtll_ick); -- clk_disable(omap->usbtll_fck); -- clk_disable(omap->usbhost_fs_fck); -- clk_disable(omap->usbhost_hs_fck); -- clk_disable(omap->usbhost_ick); -- spin_unlock_irqrestore(&omap->lock, flags); - return ret; - } - -@@ -1005,11 +896,7 @@ static void usbhs_disable(struct device *dev) - clk_disable(omap->utmi_p1_fck); - } - -- clk_disable(omap->usbtll_ick); -- clk_disable(omap->usbtll_fck); -- clk_disable(omap->usbhost_fs_fck); -- clk_disable(omap->usbhost_hs_fck); -- clk_disable(omap->usbhost_ick); -+ pm_runtime_put_sync(dev); - - /* The gpio_free migh sleep; so unlock the spinlock */ - spin_unlock_irqrestore(&omap->lock, flags); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0004-arm-omap-usb-ehci-and-ohci-hwmod-structures-for-omap.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0004-arm-omap-usb-ehci-and-ohci-hwmod-structures-for-omap.patch deleted file mode 100644 index 3d4d8a2d..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0004-arm-omap-usb-ehci-and-ohci-hwmod-structures-for-omap.patch +++ /dev/null @@ -1,406 +0,0 @@ -From 339b167f6f76707a2d6ae3a7c0b921b8278564af Mon Sep 17 00:00:00 2001 -From: Keshava Munegowda -Date: Wed, 1 Jun 2011 11:02:49 -0700 -Subject: [PATCH 04/13] arm: omap: usb: ehci and ohci hwmod structures for omap3 and omap4 - -Following 2 hwmod strcuture are added: -UHH hwmod of usbhs with uhh base address and -EHCI , OHCI irq and base addresses. -TLL hwmod of usbhs with the TLL base address and irq. - -Signed-off-by: Keshava Munegowda ---- - arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 184 ++++++++++++++++++++++++++++ - arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 153 +++++++++++++++++++++++ - 2 files changed, 337 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c -index 909a84d..fe9a176 100644 ---- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c -+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c -@@ -84,6 +84,8 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod; - static struct omap_hwmod omap3xxx_mcbsp5_hwmod; - static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod; - static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod; -+static struct omap_hwmod omap34xx_usb_host_hs_hwmod; -+static struct omap_hwmod omap34xx_usb_tll_hs_hwmod; - - /* L3 -> L4_CORE interface */ - static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = { -@@ -3574,6 +3576,185 @@ static struct omap_hwmod omap3xxx_mmc3_hwmod = { - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - }; - -+/* -+ * 'usb_host_hs' class -+ * high-speed multi-port usb host controller -+ */ -+static struct omap_hwmod_ocp_if omap34xx_usb_host_hs__l3_main_2 = { -+ .master = &omap34xx_usb_host_hs_hwmod, -+ .slave = &omap3xxx_l3_main_hwmod, -+ .clk = "core_l3_ick", -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_class_sysconfig omap34xx_usb_host_hs_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap34xx_usb_host_hs_hwmod_class = { -+ .name = "usbhs_uhh", -+ .sysc = &omap34xx_usb_host_hs_sysc, -+}; -+ -+static struct omap_hwmod_ocp_if *omap34xx_usb_host_hs_masters[] = { -+ &omap34xx_usb_host_hs__l3_main_2, -+}; -+ -+static struct omap_hwmod_irq_info omap34xx_usb_host_hs_irqs[] = { -+ { .name = "ohci-irq", .irq = 76 }, -+ { .name = "ehci-irq", .irq = 77 }, -+}; -+ -+static struct omap_hwmod_addr_space omap34xx_usb_host_hs_addrs[] = { -+ { -+ .name = "uhh", -+ .pa_start = 0x48064000, -+ .pa_end = 0x480643ff, -+ .flags = ADDR_TYPE_RT -+ }, -+ { -+ .name = "ohci", -+ .pa_start = 0x48064400, -+ .pa_end = 0x480647FF, -+ .flags = ADDR_MAP_ON_INIT -+ }, -+ { -+ .name = "ehci", -+ .pa_start = 0x48064800, -+ .pa_end = 0x48064CFF, -+ .flags = ADDR_MAP_ON_INIT -+ } -+}; -+ -+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usb_host_hs = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap34xx_usb_host_hs_hwmod, -+ .clk = "l4_ick", -+ .addr = omap34xx_usb_host_hs_addrs, -+ .addr_cnt = ARRAY_SIZE(omap34xx_usb_host_hs_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_ocp_if omap34xx_f128m_cfg__usb_host_hs = { -+ .clk = "usbhost_120m_fck", -+ .user = OCP_USER_MPU, -+ .flags = OCPIF_SWSUP_IDLE, -+}; -+ -+static struct omap_hwmod_ocp_if omap34xx_f48m_cfg__usb_host_hs = { -+ .clk = "usbhost_48m_fck", -+ .user = OCP_USER_MPU, -+ .flags = OCPIF_SWSUP_IDLE, -+}; -+ -+static struct omap_hwmod_ocp_if *omap34xx_usb_host_hs_slaves[] = { -+ &omap34xx_l4_cfg__usb_host_hs, -+ &omap34xx_f128m_cfg__usb_host_hs, -+ &omap34xx_f48m_cfg__usb_host_hs, -+}; -+ -+static struct omap_hwmod omap34xx_usb_host_hs_hwmod = { -+ .name = "usbhs_uhh", -+ .class = &omap34xx_usb_host_hs_hwmod_class, -+ .mpu_irqs = omap34xx_usb_host_hs_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_usb_host_hs_irqs), -+ .main_clk = "usbhost_ick", -+ .prcm = { -+ .omap2 = { -+ .module_offs = OMAP3430ES2_USBHOST_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = 0, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = 1, -+ .idlest_stdby_bit = 0, -+ }, -+ }, -+ .slaves = omap34xx_usb_host_hs_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap34xx_usb_host_hs_slaves), -+ .masters = omap34xx_usb_host_hs_masters, -+ .masters_cnt = ARRAY_SIZE(omap34xx_usb_host_hs_masters), -+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* -+ * 'usb_tll_hs' class -+ * usb_tll_hs module is the adapter on the usb_host_hs ports -+ */ -+static struct omap_hwmod_class_sysconfig omap34xx_usb_tll_hs_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap34xx_usb_tll_hs_hwmod_class = { -+ .name = "usbhs_tll", -+ .sysc = &omap34xx_usb_tll_hs_sysc, -+}; -+ -+static struct omap_hwmod_irq_info omap34xx_usb_tll_hs_irqs[] = { -+ { .name = "tll-irq", .irq = 78 }, -+}; -+ -+static struct omap_hwmod_addr_space omap34xx_usb_tll_hs_addrs[] = { -+ { -+ .name = "tll", -+ .pa_start = 0x48062000, -+ .pa_end = 0x48062fff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap34xx_f_cfg__usb_tll_hs = { -+ .clk = "usbtll_fck", -+ .user = OCP_USER_MPU, -+ .flags = OCPIF_SWSUP_IDLE, -+}; -+ -+static struct omap_hwmod_ocp_if omap34xx_l4_cfg__usb_tll_hs = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap34xx_usb_tll_hs_hwmod, -+ .clk = "l4_ick", -+ .addr = omap34xx_usb_tll_hs_addrs, -+ .addr_cnt = ARRAY_SIZE(omap34xx_usb_tll_hs_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_ocp_if *omap34xx_usb_tll_hs_slaves[] = { -+ &omap34xx_l4_cfg__usb_tll_hs, -+ &omap34xx_f_cfg__usb_tll_hs, -+}; -+ -+static struct omap_hwmod omap34xx_usb_tll_hs_hwmod = { -+ .name = "usbhs_tll", -+ .class = &omap34xx_usb_tll_hs_hwmod_class, -+ .mpu_irqs = omap34xx_usb_tll_hs_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_usb_tll_hs_irqs), -+ .main_clk = "usbtll_ick", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 3, -+ .module_bit = 2, -+ .idlest_reg_id = 3, -+ .idlest_idle_bit = 2, -+ }, -+ }, -+ .slaves = omap34xx_usb_tll_hs_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap34xx_usb_tll_hs_slaves), -+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ - static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { - &omap3xxx_l3_main_hwmod, - &omap3xxx_l4_core_hwmod, -@@ -3656,6 +3837,9 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { - /* usbotg for am35x */ - &am35xx_usbhsotg_hwmod, - -+ &omap34xx_usb_host_hs_hwmod, -+ &omap34xx_usb_tll_hs_hwmod, -+ - NULL, - }; - -diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c -index abc548a..d7112b0 100644 ---- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c -+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c -@@ -66,6 +66,8 @@ static struct omap_hwmod omap44xx_mmc2_hwmod; - static struct omap_hwmod omap44xx_mpu_hwmod; - static struct omap_hwmod omap44xx_mpu_private_hwmod; - static struct omap_hwmod omap44xx_usb_otg_hs_hwmod; -+static struct omap_hwmod omap44xx_usb_host_hs_hwmod; -+static struct omap_hwmod omap44xx_usb_tll_hs_hwmod; - - /* - * Interconnects omap_hwmod structures -@@ -5027,6 +5029,155 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = { - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - -+/* -+ * 'usb_host_hs' class -+ * high-speed multi-port usb host controller -+ */ -+static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = { -+ .master = &omap44xx_usb_host_hs_hwmod, -+ .slave = &omap44xx_l3_main_2_hwmod, -+ .clk = "l3_div_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_class_sysconfig omap44xx_usb_host_hs_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap44xx_usb_host_hs_hwmod_class = { -+ .name = "usbhs_uhh", -+ .sysc = &omap44xx_usb_host_hs_sysc, -+}; -+ -+static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_masters[] = { -+ &omap44xx_usb_host_hs__l3_main_2, -+}; -+ -+static struct omap_hwmod_irq_info omap44xx_usb_host_hs_irqs[] = { -+ { .name = "ohci-irq", .irq = 76 + OMAP44XX_IRQ_GIC_START }, -+ { .name = "ehci-irq", .irq = 77 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = { -+ { -+ .name = "uhh", -+ .pa_start = 0x4a064000, -+ .pa_end = 0x4a0647ff, -+ .flags = ADDR_TYPE_RT -+ }, -+ { -+ .name = "ohci", -+ .pa_start = 0x4A064800, -+ .pa_end = 0x4A064BFF, -+ .flags = ADDR_MAP_ON_INIT -+ }, -+ { -+ .name = "ehci", -+ .pa_start = 0x4A064C00, -+ .pa_end = 0x4A064FFF, -+ .flags = ADDR_MAP_ON_INIT -+ } -+}; -+ -+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_hs = { -+ .master = &omap44xx_l4_cfg_hwmod, -+ .slave = &omap44xx_usb_host_hs_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_usb_host_hs_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_ocp_if *omap44xx_usb_host_hs_slaves[] = { -+ &omap44xx_l4_cfg__usb_host_hs, -+}; -+ -+static struct omap_hwmod omap44xx_usb_host_hs_hwmod = { -+ .name = "usbhs_uhh", -+ .class = &omap44xx_usb_host_hs_hwmod_class, -+ .mpu_irqs = omap44xx_usb_host_hs_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_irqs), -+ .main_clk = "usb_host_hs_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L3INIT_USB_HOST_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_usb_host_hs_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_slaves), -+ .masters = omap44xx_usb_host_hs_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_usb_host_hs_masters), -+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'usb_tll_hs' class -+ * usb_tll_hs module is the adapter on the usb_host_hs ports -+ */ -+static struct omap_hwmod_class_sysconfig omap44xx_usb_tll_hs_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_usb_tll_hs_hwmod_class = { -+ .name = "usbhs_tll", -+ .sysc = &omap44xx_usb_tll_hs_sysc, -+}; -+ -+static struct omap_hwmod_irq_info omap44xx_usb_tll_hs_irqs[] = { -+ { .name = "tll-irq", .irq = 78 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_usb_tll_hs_addrs[] = { -+ { -+ .name = "tll", -+ .pa_start = 0x4a062000, -+ .pa_end = 0x4a063fff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_tll_hs = { -+ .master = &omap44xx_l4_cfg_hwmod, -+ .slave = &omap44xx_usb_tll_hs_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_usb_tll_hs_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_usb_tll_hs_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_ocp_if *omap44xx_usb_tll_hs_slaves[] = { -+ &omap44xx_l4_cfg__usb_tll_hs, -+}; -+ -+static struct omap_hwmod omap44xx_usb_tll_hs_hwmod = { -+ .name = "usbhs_tll", -+ .class = &omap44xx_usb_tll_hs_hwmod_class, -+ .mpu_irqs = omap44xx_usb_tll_hs_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_usb_tll_hs_irqs), -+ .main_clk = "usb_tll_hs_ick", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L3INIT_USB_TLL_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_usb_tll_hs_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_usb_tll_hs_slaves), -+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ - static __initdata struct omap_hwmod *omap44xx_hwmods[] = { - - /* dmm class */ -@@ -5173,6 +5324,8 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { - &omap44xx_wd_timer2_hwmod, - &omap44xx_wd_timer3_hwmod, - -+ &omap44xx_usb_host_hs_hwmod, -+ &omap44xx_usb_tll_hs_hwmod, - NULL, - }; - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0005-arm-omap-usb-register-hwmods-of-usbhs.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0005-arm-omap-usb-register-hwmods-of-usbhs.patch deleted file mode 100644 index 8e9a4ba4..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0005-arm-omap-usb-register-hwmods-of-usbhs.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 70f5e1a0e6639710503a9ffb9008ddcd2bb3f06e Mon Sep 17 00:00:00 2001 -From: Keshava Munegowda -Date: Wed, 1 Jun 2011 11:02:54 -0700 -Subject: [PATCH 05/13] arm: omap: usb: register hwmods of usbhs - -The hwmod structure of uhh and tll are retrived -and registered with omap device - -Signed-off-by: Keshava Munegowda ---- - arch/arm/mach-omap2/usb-host.c | 99 ++++++++++++++-------------------------- - 1 files changed, 35 insertions(+), 64 deletions(-) - -diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c -index 89ae298..9d762c4 100644 ---- a/arch/arm/mach-omap2/usb-host.c -+++ b/arch/arm/mach-omap2/usb-host.c -@@ -28,51 +28,28 @@ - #include - #include - #include -+#include - - #include "mux.h" - - #ifdef CONFIG_MFD_OMAP_USB_HOST - --#define OMAP_USBHS_DEVICE "usbhs-omap" -- --static struct resource usbhs_resources[] = { -- { -- .name = "uhh", -- .flags = IORESOURCE_MEM, -- }, -- { -- .name = "tll", -- .flags = IORESOURCE_MEM, -- }, -- { -- .name = "ehci", -- .flags = IORESOURCE_MEM, -- }, -- { -- .name = "ehci-irq", -- .flags = IORESOURCE_IRQ, -- }, -- { -- .name = "ohci", -- .flags = IORESOURCE_MEM, -- }, -- { -- .name = "ohci-irq", -- .flags = IORESOURCE_IRQ, -- } --}; -- --static struct platform_device usbhs_device = { -- .name = OMAP_USBHS_DEVICE, -- .id = 0, -- .num_resources = ARRAY_SIZE(usbhs_resources), -- .resource = usbhs_resources, --}; -+#define OMAP_USBHS_DEVICE "usbhs_omap" -+#define USBHS_UHH_HWMODNAME "usbhs_uhh" -+#define USBHS_TLL_HWMODNAME "usbhs_tll" - - static struct usbhs_omap_platform_data usbhs_data; - static struct ehci_hcd_omap_platform_data ehci_data; - static struct ohci_hcd_omap_platform_data ohci_data; - -+static struct omap_device_pm_latency omap_uhhtll_latency[] = { -+ { -+ .deactivate_func = omap_device_idle_hwmods, -+ .activate_func = omap_device_enable_hwmods, -+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, -+ }, -+}; -+ - /* MUX settings for EHCI pins */ - /* - * setup_ehci_io_mux - initialize IO pad mux for USBHOST -@@ -508,7 +485,10 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode) - - void __init usbhs_init(const struct usbhs_omap_board_data *pdata) - { -- int i; -+ struct omap_hwmod *oh[2]; -+ struct omap_device *od; -+ int bus_id = -1; -+ int i; - - for (i = 0; i < OMAP3_HS_USB_PORTS; i++) { - usbhs_data.port_mode[i] = pdata->port_mode[i]; -@@ -523,44 +503,35 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) - usbhs_data.ohci_data = &ohci_data; - - if (cpu_is_omap34xx()) { -- usbhs_resources[0].start = OMAP34XX_UHH_CONFIG_BASE; -- usbhs_resources[0].end = OMAP34XX_UHH_CONFIG_BASE + SZ_1K - 1; -- usbhs_resources[1].start = OMAP34XX_USBTLL_BASE; -- usbhs_resources[1].end = OMAP34XX_USBTLL_BASE + SZ_4K - 1; -- usbhs_resources[2].start = OMAP34XX_EHCI_BASE; -- usbhs_resources[2].end = OMAP34XX_EHCI_BASE + SZ_1K - 1; -- usbhs_resources[3].start = INT_34XX_EHCI_IRQ; -- usbhs_resources[4].start = OMAP34XX_OHCI_BASE; -- usbhs_resources[4].end = OMAP34XX_OHCI_BASE + SZ_1K - 1; -- usbhs_resources[5].start = INT_34XX_OHCI_IRQ; - setup_ehci_io_mux(pdata->port_mode); - setup_ohci_io_mux(pdata->port_mode); - } else if (cpu_is_omap44xx()) { -- usbhs_resources[0].start = OMAP44XX_UHH_CONFIG_BASE; -- usbhs_resources[0].end = OMAP44XX_UHH_CONFIG_BASE + SZ_1K - 1; -- usbhs_resources[1].start = OMAP44XX_USBTLL_BASE; -- usbhs_resources[1].end = OMAP44XX_USBTLL_BASE + SZ_4K - 1; -- usbhs_resources[2].start = OMAP44XX_HSUSB_EHCI_BASE; -- usbhs_resources[2].end = OMAP44XX_HSUSB_EHCI_BASE + SZ_1K - 1; -- usbhs_resources[3].start = OMAP44XX_IRQ_EHCI; -- usbhs_resources[4].start = OMAP44XX_HSUSB_OHCI_BASE; -- usbhs_resources[4].end = OMAP44XX_HSUSB_OHCI_BASE + SZ_1K - 1; -- usbhs_resources[5].start = OMAP44XX_IRQ_OHCI; - setup_4430ehci_io_mux(pdata->port_mode); - setup_4430ohci_io_mux(pdata->port_mode); - } - -- if (platform_device_add_data(&usbhs_device, -- &usbhs_data, sizeof(usbhs_data)) < 0) { -- printk(KERN_ERR "USBHS platform_device_add_data failed\n"); -- goto init_end; -+ oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME); -+ if (!oh[0]) { -+ pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME); -+ return; - } - -- if (platform_device_register(&usbhs_device) < 0) -- printk(KERN_ERR "USBHS platform_device_register failed\n"); -+ oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME); -+ if (!oh[1]) { -+ pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME); -+ return; -+ } - --init_end: -- return; -+ od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2, -+ (void *)&usbhs_data, sizeof(usbhs_data), -+ omap_uhhtll_latency, -+ ARRAY_SIZE(omap_uhhtll_latency), false); -+ -+ if (IS_ERR(od)) { -+ pr_err("Could not build hwmod devices %s, %s\n", -+ USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME); -+ return; -+ } - } - - #else --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0006-arm-omap-usb-device-name-change-for-the-clk-names-of.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0006-arm-omap-usb-device-name-change-for-the-clk-names-of.patch deleted file mode 100644 index c0ac58bf..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0006-arm-omap-usb-device-name-change-for-the-clk-names-of.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 64bc651bb56435e4cd86d2ebfa4f301abdbac6e5 Mon Sep 17 00:00:00 2001 -From: Keshava Munegowda -Date: Wed, 1 Jun 2011 11:02:58 -0700 -Subject: [PATCH 06/13] arm: omap: usb: device name change for the clk names of usbhs - -device name usbhs clocks are changed from -usbhs-omap.0 to usbhs_omap; this is because -in the hwmod registration the device name is set -as usbhs_omap - -Signed-off-by: Keshava Munegowda ---- - arch/arm/mach-omap2/clock3xxx_data.c | 28 ++++++++++++++-------------- - arch/arm/mach-omap2/clock44xx_data.c | 10 +++++----- - drivers/mfd/omap-usb-host.c | 2 +- - 3 files changed, 20 insertions(+), 20 deletions(-) - -diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c -index 75b119b..fabe482 100644 ---- a/arch/arm/mach-omap2/clock3xxx_data.c -+++ b/arch/arm/mach-omap2/clock3xxx_data.c -@@ -3285,7 +3285,7 @@ static struct omap_clk omap3xxx_clks[] = { - CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -- CLK("usbhs-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -+ CLK("usbhs_omap", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), - CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), - CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), -@@ -3321,7 +3321,7 @@ static struct omap_clk omap3xxx_clks[] = { - CLK(NULL, "pka_ick", &pka_ick, CK_34XX | CK_36XX), - CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX), - CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -- CLK("usbhs-omap.0", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -+ CLK("usbhs_omap", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX), - CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX), -@@ -3367,20 +3367,20 @@ static struct omap_clk omap3xxx_clks[] = { - CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), - CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), - CLK(NULL, "usbhost_120m_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -- CLK("usbhs-omap.0", "hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -+ CLK("usbhs_omap", "hs_fck", &usbhost_120m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK(NULL, "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -- CLK("usbhs-omap.0", "fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -+ CLK("usbhs_omap", "fs_fck", &usbhost_48m_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK(NULL, "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -- CLK("usbhs-omap.0", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -- CLK("usbhs-omap.0", "utmi_p1_gfclk", &dummy_ck, CK_3XXX), -- CLK("usbhs-omap.0", "utmi_p2_gfclk", &dummy_ck, CK_3XXX), -- CLK("usbhs-omap.0", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), -- CLK("usbhs-omap.0", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), -- CLK("usbhs-omap.0", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), -- CLK("usbhs-omap.0", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), -- CLK("usbhs-omap.0", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), -- CLK("usbhs-omap.0", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), -- CLK("usbhs-omap.0", "init_60m_fclk", &dummy_ck, CK_3XXX), -+ CLK("usbhs_omap", "usbhost_ick", &usbhost_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -+ CLK("usbhs_omap", "utmi_p1_gfclk", &dummy_ck, CK_3XXX), -+ CLK("usbhs_omap", "utmi_p2_gfclk", &dummy_ck, CK_3XXX), -+ CLK("usbhs_omap", "xclk60mhsp1_ck", &dummy_ck, CK_3XXX), -+ CLK("usbhs_omap", "xclk60mhsp2_ck", &dummy_ck, CK_3XXX), -+ CLK("usbhs_omap", "usb_host_hs_utmi_p1_clk", &dummy_ck, CK_3XXX), -+ CLK("usbhs_omap", "usb_host_hs_utmi_p2_clk", &dummy_ck, CK_3XXX), -+ CLK("usbhs_omap", "usb_tll_hs_usb_ch0_clk", &dummy_ck, CK_3XXX), -+ CLK("usbhs_omap", "usb_tll_hs_usb_ch1_clk", &dummy_ck, CK_3XXX), -+ CLK("usbhs_omap", "init_60m_fclk", &dummy_ck, CK_3XXX), - CLK(NULL, "usim_fck", &usim_fck, CK_3430ES2PLUS | CK_36XX), - CLK(NULL, "gpt1_fck", &gpt1_fck, CK_3XXX), - CLK(NULL, "wkup_32k_fck", &wkup_32k_fck, CK_3XXX), -diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c -index 8c96567..34e91eb 100644 ---- a/arch/arm/mach-omap2/clock44xx_data.c -+++ b/arch/arm/mach-omap2/clock44xx_data.c -@@ -3205,7 +3205,7 @@ static struct omap_clk omap44xx_clks[] = { - CLK(NULL, "uart3_fck", &uart3_fck, CK_443X), - CLK(NULL, "uart4_fck", &uart4_fck, CK_443X), - CLK(NULL, "usb_host_fs_fck", &usb_host_fs_fck, CK_443X), -- CLK("usbhs-omap.0", "fs_fck", &usb_host_fs_fck, CK_443X), -+ CLK("usbhs_omap", "fs_fck", &usb_host_fs_fck, CK_443X), - CLK(NULL, "utmi_p1_gfclk", &utmi_p1_gfclk, CK_443X), - CLK(NULL, "usb_host_hs_utmi_p1_clk", &usb_host_hs_utmi_p1_clk, CK_443X), - CLK(NULL, "utmi_p2_gfclk", &utmi_p2_gfclk, CK_443X), -@@ -3217,8 +3217,8 @@ static struct omap_clk omap44xx_clks[] = { - CLK(NULL, "usb_host_hs_hsic480m_p2_clk", &usb_host_hs_hsic480m_p2_clk, CK_443X), - CLK(NULL, "usb_host_hs_func48mclk", &usb_host_hs_func48mclk, CK_443X), - CLK(NULL, "usb_host_hs_fck", &usb_host_hs_fck, CK_443X), -- CLK("usbhs-omap.0", "hs_fck", &usb_host_hs_fck, CK_443X), -- CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_443X), -+ CLK("usbhs_omap", "hs_fck", &usb_host_hs_fck, CK_443X), -+ CLK("usbhs_omap", "usbhost_ick", &dummy_ck, CK_443X), - CLK(NULL, "otg_60m_gfclk", &otg_60m_gfclk, CK_443X), - CLK(NULL, "usb_otg_hs_xclk", &usb_otg_hs_xclk, CK_443X), - CLK("musb-omap2430", "ick", &usb_otg_hs_ick, CK_443X), -@@ -3227,8 +3227,8 @@ static struct omap_clk omap44xx_clks[] = { - CLK(NULL, "usb_tll_hs_usb_ch0_clk", &usb_tll_hs_usb_ch0_clk, CK_443X), - CLK(NULL, "usb_tll_hs_usb_ch1_clk", &usb_tll_hs_usb_ch1_clk, CK_443X), - CLK(NULL, "usb_tll_hs_ick", &usb_tll_hs_ick, CK_443X), -- CLK("usbhs-omap.0", "usbtll_ick", &usb_tll_hs_ick, CK_443X), -- CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_443X), -+ CLK("usbhs_omap", "usbtll_ick", &usb_tll_hs_ick, CK_443X), -+ CLK("usbhs_omap", "usbtll_fck", &dummy_ck, CK_443X), - CLK(NULL, "usim_ck", &usim_ck, CK_443X), - CLK(NULL, "usim_fclk", &usim_fclk, CK_443X), - CLK(NULL, "usim_fck", &usim_fck, CK_443X), -diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c -index 8552195..43de12a 100644 ---- a/drivers/mfd/omap-usb-host.c -+++ b/drivers/mfd/omap-usb-host.c -@@ -28,7 +28,7 @@ - #include - #include - --#define USBHS_DRIVER_NAME "usbhs-omap" -+#define USBHS_DRIVER_NAME "usbhs_omap" - #define OMAP_EHCI_DEVICE "ehci-omap" - #define OMAP_OHCI_DEVICE "ohci-omap3" - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch deleted file mode 100644 index 94d5f591..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch +++ /dev/null @@ -1,165 +0,0 @@ -From bf583f2924fd9b2f0356cbd0bbfd58c48d98ef15 Mon Sep 17 00:00:00 2001 -From: Keshava Munegowda -Date: Wed, 1 Jun 2011 11:03:03 -0700 -Subject: [PATCH 07/13] mfd: global Suspend and resume support of ehci and ohci - -The global suspend and resume functions for usbhs core driver -are implemented.These routine are called when the global suspend -and resume occurs. Before calling these functions, the -bus suspend and resume of ehci and ohci drivers are called -from runtime pm. - -Signed-off-by: Keshava Munegowda ---- - drivers/mfd/omap-usb-host.c | 103 +++++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 103 insertions(+), 0 deletions(-) - -diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c -index 43de12a..32d19e2 100644 ---- a/drivers/mfd/omap-usb-host.c -+++ b/drivers/mfd/omap-usb-host.c -@@ -146,6 +146,10 @@ - #define is_ehci_hsic_mode(x) (x == OMAP_EHCI_PORT_MODE_HSIC) - - -+/* USBHS state bits */ -+#define OMAP_USBHS_INIT 0 -+#define OMAP_USBHS_SUSPEND 4 -+ - struct usbhs_hcd_omap { - struct clk *xclk60mhsp1_ck; - struct clk *xclk60mhsp2_ck; -@@ -165,6 +169,7 @@ struct usbhs_hcd_omap { - u32 usbhs_rev; - spinlock_t lock; - int count; -+ unsigned long state; - }; - /*-------------------------------------------------------------------------*/ - -@@ -809,6 +814,8 @@ static int usbhs_enable(struct device *dev) - (pdata->ehci_data->reset_gpio_port[1], 1); - } - -+ set_bit(OMAP_USBHS_INIT, &omap->state); -+ - end_count: - omap->count++; - spin_unlock_irqrestore(&omap->lock, flags); -@@ -897,6 +904,7 @@ static void usbhs_disable(struct device *dev) - } - - pm_runtime_put_sync(dev); -+ clear_bit(OMAP_USBHS_INIT, &omap->state); - - /* The gpio_free migh sleep; so unlock the spinlock */ - spin_unlock_irqrestore(&omap->lock, flags); -@@ -926,10 +934,105 @@ void omap_usbhs_disable(struct device *dev) - } - EXPORT_SYMBOL_GPL(omap_usbhs_disable); - -+#ifdef CONFIG_PM -+ -+static int usbhs_resume(struct device *dev) -+{ -+ struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); -+ struct usbhs_omap_platform_data *pdata = &omap->platdata; -+ unsigned long flags = 0; -+ -+ dev_dbg(dev, "Resuming TI HSUSB Controller\n"); -+ -+ if (!pdata) { -+ dev_dbg(dev, "missing platform_data\n"); -+ return -ENODEV; -+ } -+ -+ spin_lock_irqsave(&omap->lock, flags); -+ -+ if (!test_bit(OMAP_USBHS_INIT, &omap->state) || -+ !test_bit(OMAP_USBHS_SUSPEND, &omap->state)) -+ goto end_resume; -+ -+ pm_runtime_get_sync(dev); -+ -+ if (is_omap_usbhs_rev2(omap)) { -+ if (is_ehci_tll_mode(pdata->port_mode[0])) { -+ clk_enable(omap->usbhost_p1_fck); -+ clk_enable(omap->usbtll_p1_fck); -+ } -+ if (is_ehci_tll_mode(pdata->port_mode[1])) { -+ clk_enable(omap->usbhost_p2_fck); -+ clk_enable(omap->usbtll_p2_fck); -+ } -+ clk_enable(omap->utmi_p1_fck); -+ clk_enable(omap->utmi_p2_fck); -+ } -+ clear_bit(OMAP_USBHS_SUSPEND, &omap->state); -+ -+end_resume: -+ spin_unlock_irqrestore(&omap->lock, flags); -+ return 0; -+} -+ -+ -+static int usbhs_suspend(struct device *dev) -+{ -+ struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); -+ struct usbhs_omap_platform_data *pdata = &omap->platdata; -+ unsigned long flags = 0; -+ -+ dev_dbg(dev, "Suspending TI HSUSB Controller\n"); -+ -+ if (!pdata) { -+ dev_dbg(dev, "missing platform_data\n"); -+ return -ENODEV; -+ } -+ -+ spin_lock_irqsave(&omap->lock, flags); -+ -+ if (!test_bit(OMAP_USBHS_INIT, &omap->state) || -+ test_bit(OMAP_USBHS_SUSPEND, &omap->state)) -+ goto end_suspend; -+ -+ if (is_omap_usbhs_rev2(omap)) { -+ if (is_ehci_tll_mode(pdata->port_mode[0])) { -+ clk_disable(omap->usbhost_p1_fck); -+ clk_disable(omap->usbtll_p1_fck); -+ } -+ if (is_ehci_tll_mode(pdata->port_mode[1])) { -+ clk_disable(omap->usbhost_p2_fck); -+ clk_disable(omap->usbtll_p2_fck); -+ } -+ clk_disable(omap->utmi_p2_fck); -+ clk_disable(omap->utmi_p1_fck); -+ } -+ -+ set_bit(OMAP_USBHS_SUSPEND, &omap->state); -+ pm_runtime_put_sync(dev); -+ -+end_suspend: -+ spin_unlock_irqrestore(&omap->lock, flags); -+ return 0; -+} -+ -+ -+static const struct dev_pm_ops usbhsomap_dev_pm_ops = { -+ .suspend = usbhs_suspend, -+ .resume = usbhs_resume, -+}; -+ -+#define USBHS_OMAP_DEV_PM_OPS (&usbhsomap_dev_pm_ops) -+#else -+#define USBHS_OMAP_DEV_PM_OPS NULL -+#endif -+ - static struct platform_driver usbhs_omap_driver = { - .driver = { - .name = (char *)usbhs_driver_name, - .owner = THIS_MODULE, -+ .pm = USBHS_OMAP_DEV_PM_OPS, - }, - .remove = __exit_p(usbhs_omap_remove), - }; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0008-MFD-TWL4030-Correct-the-warning-print-during-script-.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0008-MFD-TWL4030-Correct-the-warning-print-during-script-.patch deleted file mode 100644 index e3de4672..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0008-MFD-TWL4030-Correct-the-warning-print-during-script-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 1f2e639755b920398d6592775e0e31f7fb1ca955 Mon Sep 17 00:00:00 2001 -From: Lesly A M -Date: Wed, 1 Jun 2011 14:56:38 -0700 -Subject: [PATCH 08/13] MFD: TWL4030: Correct the warning print during script loading - -Correcting the if condition check for printing the warning, -if wakeup script is not updated before updating the sleep script. - -Since the flag 'order' is set to '1' while updating the wakeup script for P1P2, -the condition checking for printing the warning should be if(!order) -(ie: print the warning if wakeup script is not updated before updating the sleep script) - -Signed-off-by: Lesly A M -Cc: Nishanth Menon -Cc: David Derrick -Cc: Samuel Ortiz ---- - drivers/mfd/twl4030-power.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c -index 2c0d4d1..8373d79 100644 ---- a/drivers/mfd/twl4030-power.c -+++ b/drivers/mfd/twl4030-power.c -@@ -448,7 +448,7 @@ static int __init load_twl4030_script(struct twl4030_script *tscript, - goto out; - } - if (tscript->flags & TWL4030_SLEEP_SCRIPT) { -- if (order) -+ if (!order) - pr_warning("TWL4030: Bad order of scripts (sleep "\ - "script before wakeup) Leads to boot"\ - "failure on some boards\n"); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0009-MFD-TWL4030-Modifying-the-macro-name-Main_Ref-to-all.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0009-MFD-TWL4030-Modifying-the-macro-name-Main_Ref-to-all.patch deleted file mode 100644 index 6be454aa..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0009-MFD-TWL4030-Modifying-the-macro-name-Main_Ref-to-all.patch +++ /dev/null @@ -1,61 +0,0 @@ -From ea9acebfe2d3ca8fb3969eaf327665632142b85d Mon Sep 17 00:00:00 2001 -From: Lesly A M -Date: Wed, 1 Jun 2011 14:56:45 -0700 -Subject: [PATCH 09/13] MFD: TWL4030: Modifying the macro name Main_Ref to all caps - -Modifying the macro name Main_Ref to all caps(MAIN_REF). - -Suggested by Nishanth Menon - -Signed-off-by: Lesly A M -Cc: Nishanth Menon -Cc: David Derrick -Cc: Samuel Ortiz ---- - arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +- - drivers/mfd/twl4030-power.c | 2 +- - include/linux/i2c/twl.h | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c -index bbcb677..01ee0a1 100644 ---- a/arch/arm/mach-omap2/board-rx51-peripherals.c -+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c -@@ -730,7 +730,7 @@ static struct twl4030_resconfig twl4030_rconfig[] __initdata = { - { .resource = RES_RESET, .devgroup = -1, - .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 - }, -- { .resource = RES_Main_Ref, .devgroup = -1, -+ { .resource = RES_MAIN_REF, .devgroup = -1, - .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1 - }, - { 0, 0}, -diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c -index 8373d79..8162e43 100644 ---- a/drivers/mfd/twl4030-power.c -+++ b/drivers/mfd/twl4030-power.c -@@ -120,7 +120,7 @@ static u8 res_config_addrs[] = { - [RES_HFCLKOUT] = 0x8b, - [RES_32KCLKOUT] = 0x8e, - [RES_RESET] = 0x91, -- [RES_Main_Ref] = 0x94, -+ [RES_MAIN_REF] = 0x94, - }; - - static int __init twl4030_write_script_byte(u8 address, u8 byte) -diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h -index cbbf3b3..aee3a22 100644 ---- a/include/linux/i2c/twl.h -+++ b/include/linux/i2c/twl.h -@@ -502,7 +502,7 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) - #define RES_32KCLKOUT 26 - #define RES_RESET 27 - /* Power Reference */ --#define RES_Main_Ref 28 -+#define RES_MAIN_REF 28 - - #define TOTAL_RESOURCES 28 - /* --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0010-MFD-TWL4030-power-scripts-for-OMAP3-boards.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0010-MFD-TWL4030-power-scripts-for-OMAP3-boards.patch deleted file mode 100644 index 84e1ae7e..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0010-MFD-TWL4030-power-scripts-for-OMAP3-boards.patch +++ /dev/null @@ -1,705 +0,0 @@ -From 0b29e1f61b85dd2d04f035088b70dc287d15b9f0 Mon Sep 17 00:00:00 2001 -From: Lesly A M -Date: Wed, 1 Jun 2011 14:56:49 -0700 -Subject: [PATCH 10/13] MFD: TWL4030: power scripts for OMAP3 boards - -Power bus message sequence for TWL4030 to enter sleep/wakeup/warm_reset. - -TWL4030 power scripts which can be used by different OMAP3 boards -with the power companion chip (TWL4030 series). - -The twl4030 generic script can be used by any board file to update -the power data in twl4030_platform_data. - -Since the TWL4030 power script has dependency with APIs in twl4030-power.c -removing the __init for these APIs. - -For more information please see: - http://omapedia.org/wiki/TWL4030_power_scripts - -Signed-off-by: Lesly A M -Cc: Nishanth Menon -Cc: David Derrick -Cc: Samuel Ortiz ---- - arch/arm/configs/omap2plus_defconfig | 1 + - arch/arm/mach-omap2/devices.c | 15 ++ - drivers/mfd/Kconfig | 11 + - drivers/mfd/Makefile | 1 + - drivers/mfd/twl4030-power.c | 31 ++-- - drivers/mfd/twl4030-script-omap.c | 373 ++++++++++++++++++++++++++++++++++ - include/linux/i2c/twl.h | 41 ++++- - 7 files changed, 454 insertions(+), 19 deletions(-) - create mode 100644 drivers/mfd/twl4030-script-omap.c - -diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig -index 076db52..d9b9858 100644 ---- a/arch/arm/configs/omap2plus_defconfig -+++ b/arch/arm/configs/omap2plus_defconfig -@@ -184,6 +184,7 @@ CONFIG_TWL4030_WATCHDOG=y - CONFIG_MENELAUS=y - CONFIG_TWL4030_CORE=y - CONFIG_TWL4030_POWER=y -+CONFIG_TWL4030_SCRIPT=m - CONFIG_REGULATOR=y - CONFIG_REGULATOR_TWL4030=y - CONFIG_REGULATOR_TPS65023=y -diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c -index 7b85585..7653329 100644 ---- a/arch/arm/mach-omap2/devices.c -+++ b/arch/arm/mach-omap2/devices.c -@@ -329,6 +329,20 @@ static void omap_init_audio(void) - static inline void omap_init_audio(void) {} - #endif - -+#ifdef CONFIG_ARCH_OMAP3 -+static struct platform_device omap_twl4030_script = { -+ .name = "twl4030_script", -+ .id = -1, -+}; -+ -+static void omap_init_twl4030_script(void) -+{ -+ platform_device_register(&omap_twl4030_script); -+} -+#else -+static inline void omap_init_twl4030_script(void) {} -+#endif -+ - #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) - - #include -@@ -691,6 +705,7 @@ static int __init omap2_init_devices(void) - omap_init_sham(); - omap_init_aes(); - omap_init_vout(); -+ omap_init_twl4030_script(); - - return 0; - } -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index fe2370a..ea25d93 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -204,6 +204,17 @@ config TWL4030_POWER - and load scripts controlling which resources are switched off/on - or reset when a sleep, wakeup or warm reset event occurs. - -+config TWL4030_SCRIPT -+ tristate "Support TWL4030 script for OMAP3 boards" -+ depends on TWL4030_CORE && TWL4030_POWER -+ help -+ Say yes here if you want to use the twl4030 power scripts -+ for OMAP3 boards. Power bus message sequence for -+ TWL4030 to enter sleep/wakeup/warm_reset. -+ -+ TWL4030 power scripts which can be used by different -+ OMAP3 boards with the power companion chip (TWL4030 series). -+ - config TWL4030_CODEC - bool - depends on TWL4030_CORE -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index 419caa9..53ada21 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -42,6 +42,7 @@ obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o - obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o - obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o - obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o -+obj-$(CONFIG_TWL4030_SCRIPT) += twl4030-script-omap.o - - obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o - -diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c -index 8162e43..91d5bc8 100644 ---- a/drivers/mfd/twl4030-power.c -+++ b/drivers/mfd/twl4030-power.c -@@ -123,7 +123,7 @@ static u8 res_config_addrs[] = { - [RES_MAIN_REF] = 0x94, - }; - --static int __init twl4030_write_script_byte(u8 address, u8 byte) -+static int twl4030_write_script_byte(u8 address, u8 byte) - { - int err; - -@@ -137,7 +137,7 @@ out: - return err; - } - --static int __init twl4030_write_script_ins(u8 address, u16 pmb_message, -+static int twl4030_write_script_ins(u8 address, u16 pmb_message, - u8 delay, u8 next) - { - int err; -@@ -157,7 +157,7 @@ out: - return err; - } - --static int __init twl4030_write_script(u8 address, struct twl4030_ins *script, -+static int twl4030_write_script(u8 address, struct twl4030_ins *script, - int len) - { - int err; -@@ -182,7 +182,7 @@ static int __init twl4030_write_script(u8 address, struct twl4030_ins *script, - return err; - } - --static int __init twl4030_config_wakeup3_sequence(u8 address) -+static int twl4030_config_wakeup3_sequence(u8 address) - { - int err; - u8 data; -@@ -207,7 +207,7 @@ out: - return err; - } - --static int __init twl4030_config_wakeup12_sequence(u8 address) -+static int twl4030_config_wakeup12_sequence(u8 address) - { - int err = 0; - u8 data; -@@ -261,7 +261,7 @@ out: - return err; - } - --static int __init twl4030_config_sleep_sequence(u8 address) -+static int twl4030_config_sleep_sequence(u8 address) - { - int err; - -@@ -275,7 +275,7 @@ static int __init twl4030_config_sleep_sequence(u8 address) - return err; - } - --static int __init twl4030_config_warmreset_sequence(u8 address) -+static int twl4030_config_warmreset_sequence(u8 address) - { - int err; - u8 rd_data; -@@ -323,7 +323,7 @@ out: - return err; - } - --static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig) -+static int twl4030_configure_resource(struct twl4030_resconfig *rconfig) - { - int rconfig_addr; - int err; -@@ -415,7 +415,7 @@ static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig) - return 0; - } - --static int __init load_twl4030_script(struct twl4030_script *tscript, -+static int load_twl4030_script(struct twl4030_script *tscript, - u8 address) - { - int err; -@@ -510,8 +510,9 @@ int twl4030_remove_script(u8 flags) - - return err; - } -+EXPORT_SYMBOL_GPL(twl4030_remove_script); - --void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts) -+int twl4030_power_init(struct twl4030_power_data *twl4030_scripts) - { - int err = 0; - int i; -@@ -529,7 +530,6 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts) - TWL4030_PM_MASTER_PROTECT_KEY); - if (err) - goto unlock; -- - for (i = 0; i < twl4030_scripts->num; i++) { - err = load_twl4030_script(twl4030_scripts->scripts[i], address); - if (err) -@@ -552,18 +552,19 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts) - TWL4030_PM_MASTER_PROTECT_KEY); - if (err) - pr_err("TWL4030 Unable to relock registers\n"); -- return; -+ return err; - - unlock: - if (err) - pr_err("TWL4030 Unable to unlock registers\n"); -- return; -+ return err; - load: - if (err) - pr_err("TWL4030 failed to load scripts\n"); -- return; -+ return err; - resource: - if (err) - pr_err("TWL4030 failed to configure resource\n"); -- return; -+ return err; - } -+EXPORT_SYMBOL_GPL(twl4030_power_init); -diff --git a/drivers/mfd/twl4030-script-omap.c b/drivers/mfd/twl4030-script-omap.c -new file mode 100644 -index 0000000..867a442 ---- /dev/null -+++ b/drivers/mfd/twl4030-script-omap.c -@@ -0,0 +1,373 @@ -+/* -+ * OMAP power script for PMIC TWL4030 -+ * -+ * Author: Lesly A M -+ * -+ * Copyright (C) 2010 Texas Instruments, Inc. -+ * Lesly A M -+ * -+ * 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 -+#include -+#include -+ -+#include -+ -+/* -+ * power management signal connections for OMAP3430 with TWL5030 -+ * -+ * TWL5030 OMAP3430 -+ * ______________________ _____________________ -+ * | | | | -+ * | (P1) NSLEEP1|<----------|SYS_OFFMODE | -+ * | NRESWARM|<----------|NWARMRESET | -+ * | (P2) NSLEEP2|---| | | -+ * | | === | | -+ * | | - | | -+ * | | | | -+ * | VDD1 |---------->| VDD1 | -+ * | VDD2 |---------->| VDD2 | -+ * | VIO |---------->| VDDS | -+ * ________ | VAUX1 | | | -+ * | | | ... | | | -+ * | ENABLE|<--------|CLKEN CLKREQ|<----------|SYS_CLKREQ | -+ * | CLKOUT|-------->|HFCLKIN (P3) HFCLKOUT|---------->|XTALIN | -+ * |________| |______________________| |_____________________| -+ * -+ * -+ * Signal descriptions: -+ * -+ * SYS_OFFMODE - OMAP drives this signal low only when the OMAP is in the -+ * OFF idle mode. It is driven high when a wake up event is detected. -+ * This signal should control the P1 device group in the PMIC. -+ * -+ * SYS_CLKREQ - OMAP should drive this signal low when the OMAP goes into -+ * any idle mode. This signal should control the P3 device group -+ * in the PMIC. It is used to notify PMIC when XTALIN is no longer needed. -+ * -+ * NSLEEP1(P1) - When this signal goes low the P1 sleep sequence is executed -+ * in the PMIC turning off certain resources. When this signal goes high -+ * the P1 active sequence is executed turning back on certain resources. -+ * -+ * NSLEEP2(P2) - This signal controls the P2 device group of the PMIC. -+ * It is not used in this setup and should be tied to ground. -+ * This can be used for connecting a different processor or MODEM chip. -+ * -+ * CLKREQ(P3) - When this signal goes low the P3 sleep sequence is executed -+ * in the PMIC turning off HFCLKOUT. When this signal goes high -+ * the P3 active sequence is executed turning back on HFCLKOUT and other -+ * resources. -+ * -+ * CLKEN - Enable signal for oscillator. Should only go low when OMAP is -+ * in the OFF idle mode due to long oscillator startup times. -+ * -+ * HFCLKIN - Oscillator output clock into PMIC. -+ * -+ * HFCLKOUT - System clock output from PMIC to OMAP. -+ * -+ * XTALIN - OMAP system clock input(HFCLKOUT). -+ */ -+ -+/* -+ * Recommended sleep and active sequences for TWL5030 when connected to OMAP3 -+ * -+ * WARNING: If the board is using NSLEEP2(P2), should modify this script and -+ * setuptime values accordingly. -+ * -+ * Chip Retention/Off (using i2c for scaling voltage): -+ * When OMAP de-assert the SYS_CLKREQ signal, only HFCLKOUT is affected -+ * since it is the only resource assigned to P3 only. -+ * -+ * Sysoff (using sys_off signal): -+ * When OMAP de-assert the SYS_OFFMODE signal A2S(active to sleep sequence) -+ * on the PMIC is executed. This will put resources of TYPE2=1 and TYPE2=2 -+ * into sleep. At this point only resources assigned to P1 only will be -+ * affected (VDD1, VDD2 & VPLL1). -+ * -+ * Next the OMAP will lower SYS_CLKREQ which will allow the A2S sequence -+ * in PMIC to execute again. This will put resources of TYPE2=1 and TYPE2=2 -+ * into sleep but will affect resources that are assigned to P3(HFCLKOUT) -+ * only or assigned to P1 and P3. -+ * -+ * On wakeup event OMAP goes active and pulls the SYS_CLKREQ high, -+ * which will execute the P3 S2A sequence on the PMIC. This will turn on -+ * resources assigned to P3 or assigned to P1 and P3 and of TYPE2=2. -+ * -+ * Next the OMAP will wait the PRM_VOLTOFFSET time and then de-assert -+ * the SYS_OFFMODE pin allowing the PMIC to execute the P1 S2A active -+ * sequence. This will turn on resources assigned to P1 or assigned to -+ * P1 and P3 and of TYPE2=1. -+ * -+ * Timing diagram for OMAP wakeup from OFFMODE using sys_off signal -+ * _____________________________________________________________ -+ * OMAP active __/ -+ * |<--------------------PRM_CLKSETP-------------------->| -+ * ______________________________________________________ -+ * SYS_CLKREQ _________/ -+ * ___________________________________________________ -+ * CLKEN ____________/ -+ * -+ * HFCLKIN _______________________________________________///////////////// -+ * -+ * HFCLKOUT __________________________________________________////////////// -+ * |<---PRM_VOLTOFFSET-->| -+ * ________________________________ -+ * SYS_OFFMODE _______________________________/ -+ * |<--------PRM_VOLTSETUP2------->| -+ * ___________ -+ * VPLL1 ____________________________________________________/ -+ * __ -+ * VDD1 _____________________________________________________________/ -+ * __ -+ * VDD2 _____________________________________________________________/ -+ * -+ * Other resources which are not handled by this script should be -+ * controlled by the respective drivers using them (VAUX1, VAUX2, VAUX3, -+ * VAUX4, VMMC1, VMMC2, VPLL2, VSIM, VDAC, VUSB1V5, VUSB1V8 & VUSB3V1). -+ * -+ * More info: -+ * http://omapedia.org/wiki/TWL4030_power_scripts -+ */ -+ -+/** -+ * DOC: Sleep to active sequence for P1/P2 -+ * -+ * Sequence to control the TWL4030 Power resources, -+ * when the system wakeup from sleep. -+ * Executed upon P1_P2 transition for wakeup -+ * (sys_offmode signal de-asserted on OMAP). -+ */ -+static struct twl4030_ins wakeup_p12_seq[] __initdata = { -+ /* -+ * Broadcast message to put resources to active -+ * -+ * Since we are not using TYPE, resources which have TYPE2 configured -+ * as 1 will be targeted (VPLL1, VDD1, VDD2, REGEN, NRES_PWRON, SYSEN). -+ */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1, -+ RES_STATE_ACTIVE), 2}, -+}; -+ -+static struct twl4030_script wakeup_p12_script __initdata = { -+ .script = wakeup_p12_seq, -+ .size = ARRAY_SIZE(wakeup_p12_seq), -+ .flags = TWL4030_WAKEUP12_SCRIPT, -+}; -+ -+/** -+ * DOC: Sleep to active sequence for P3 -+ * -+ * Sequence to control the TWL4030 Power resources, -+ * when the system wakeup from sleep. -+ * Executed upon P3 transition for wakeup -+ * (clkreq signal asserted on OMAP). -+ */ -+static struct twl4030_ins wakeup_p3_seq[] __initdata = { -+ /* -+ * Broadcast message to put resources to active -+ * -+ * Since we are not using TYPE, resources which have TYPE2 configured -+ * as 2 will be targeted -+ * (VINTANA1, VINTANA2, VINTDIG, VIO, CLKEN, HFCLKOUT). -+ */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, -+ RES_STATE_ACTIVE), 2}, -+}; -+ -+static struct twl4030_script wakeup_p3_script __initdata = { -+ .script = wakeup_p3_seq, -+ .size = ARRAY_SIZE(wakeup_p3_seq), -+ .flags = TWL4030_WAKEUP3_SCRIPT, -+}; -+ -+/** -+ * DOC: Active to sleep sequence for P1/P2/P3 -+ * -+ * Sequence to control the TWL4030 Power resources, -+ * when the system goes into sleep. -+ * Executed upon P1_P2/P3 transition for sleep. -+ * (sys_offmode signal asserted/clkreq de-asserted on OMAP). -+ */ -+static struct twl4030_ins sleep_on_seq[] __initdata = { -+ /* Broadcast message to put res to sleep (TYPE2 = 1, 2) */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1, -+ RES_STATE_SLEEP), 2}, -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, -+ RES_STATE_SLEEP), 2}, -+}; -+ -+static struct twl4030_script sleep_on_script __initdata = { -+ .script = sleep_on_seq, -+ .size = ARRAY_SIZE(sleep_on_seq), -+ .flags = TWL4030_SLEEP_SCRIPT, -+}; -+ -+/** -+ * DOC: Warm reset sequence -+ * -+ * Sequence to reset the TWL4030 Power resources, -+ * when the system gets warm reset. -+ * Executed upon warm reset signal. -+ * -+ * First the device is put in reset, then the system clock is requested to -+ * the external oscillator, and default ON power reference and power providers -+ * are enabled. Next some additional resources which are software controlled -+ * are enabled. Finally sequence is ended by the release of TWL5030 reset. -+ */ -+static struct twl4030_ins wrst_seq[] __initdata = { -+ /* -+ * As a workaround for OMAP Erratum (ID: i537 - OMAP HS devices are -+ * not recovering from warm reset while in OFF mode) -+ * NRESPWRON is toggled to force a power on reset condition to OMAP -+ */ -+ /* Trun OFF NRES_PWRON */ -+ {MSG_SINGULAR(DEV_GRP_NULL, RES_NRES_PWRON, RES_STATE_OFF), 2}, -+ /* Reset twl4030 */ -+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_OFF), 2}, -+ /* Reset MAIN_REF */ -+ {MSG_SINGULAR(DEV_GRP_NULL, RES_MAIN_REF, RES_STATE_WRST), 2}, -+ /* Reset All type2_group2 */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, -+ RES_STATE_WRST), 2}, -+ /* Reset VUSB_3v1 */ -+ {MSG_SINGULAR(DEV_GRP_NULL, RES_VUSB_3V1, RES_STATE_WRST), 2}, -+ /* Reset All type2_group1 */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1, -+ RES_STATE_WRST), 2}, -+ /* Reset the Reset & Contorl_signals */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0, -+ RES_STATE_WRST), 2}, -+ /* Re-enable twl4030 */ -+ {MSG_SINGULAR(DEV_GRP_NULL, RES_RESET, RES_STATE_ACTIVE), 2}, -+ /* Trun ON NRES_PWRON */ -+ {MSG_SINGULAR(DEV_GRP_NULL, RES_NRES_PWRON, RES_STATE_ACTIVE), 2}, -+}; -+ -+static struct twl4030_script wrst_script __initdata = { -+ .script = wrst_seq, -+ .size = ARRAY_SIZE(wrst_seq), -+ .flags = TWL4030_WRST_SCRIPT, -+}; -+ -+/* TWL4030 script for sleep, wakeup & warm_reset */ -+static struct twl4030_script *twl4030_scripts[] __initdata = { -+ &wakeup_p12_script, -+ &wakeup_p3_script, -+ &sleep_on_script, -+ &wrst_script, -+}; -+ -+/** -+ * DOC: TWL4030 resource configuration -+ * -+ * Resource which are attached to P1 device group alone -+ * will go to sleep state, when sys_off signal from OMAP is de-asserted. -+ * (VPLL1, VDD1, VDD2) -+ * -+ * None of the resources are attached to P2 device group alone. -+ * (WARNING: If MODEM or connectivity chip is connected to NSLEEP2 PIN on -+ * TWL4030, should modify the resource configuration accordingly). -+ * -+ * Resource which are attached to P3 device group alone -+ * will go to sleep state, when clk_req signal from OMAP is de-asserted. -+ * (HFCLKOUT) -+ * -+ * Resource which are attached to more than one device group -+ * will go to sleep state, when corresponding signals are de-asserted. -+ * (VINTANA1, VINTANA2, VINTDIG, VIO, REGEN, NRESPWRON, CLKEN, SYSEN) -+ * -+ * REGEN is an output of the device which can be connected to slave power ICs -+ * or external LDOs that power on before voltage for the IO interface (VIO). -+ * -+ * SYSEN is a bidirectional signal of the device that controls slave power ICs. -+ * In master mode, the device sets SYSEN high to enable the slave power ICs. -+ * In slave mode, when one of the power ICs drives the SYSEN signal low, -+ * all devices of the platform stay in the wait-on state. -+ * -+ * Resource which are attached to none of the device group by default -+ * will be in sleep state. These resource should be controlled by -+ * the respective drivers using them. -+ * Resource which are controlled by drivers are not modified here. -+ * (VAUX1, VAUX2, VAUX3, VAUX4, VMMC1, VMMC2, VPLL2, VSIM, VDAC, -+ * VUSB1V5, VUSB1V8, VUSB3V1) -+ * -+ * Resource using reset values. -+ * (32KCLKOUT, TRITON_RESET, MAINREF) -+ */ -+static struct twl4030_resconfig twl4030_rconfig[] __initdata = { -+ { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1, .type = 3, -+ .type2 = 1, .remap_sleep = RES_STATE_OFF }, -+ { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_VDD1, .devgroup = DEV_GRP_P1, -+ .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF }, -+ { .resource = RES_VDD2, .devgroup = DEV_GRP_P1, -+ .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF }, -+ { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2, -+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0, -+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6, -+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P3, -+ .type = 0, .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { 0, 0}, -+}; -+ -+struct twl4030_power_data twl4030_generic_script __initdata = { -+ .scripts = twl4030_scripts, -+ .num = ARRAY_SIZE(twl4030_scripts), -+ .resource_config = twl4030_rconfig, -+}; -+ -+static int __init twl4030_script_probe(struct platform_device *pdev) -+{ -+ return twl4030_power_init(&twl4030_generic_script); -+} -+ -+static int twl4030_script_remove(struct platform_device *pdev) -+{ -+ return twl4030_remove_script(TWL4030_SLEEP_SCRIPT | -+ TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT | -+ TWL4030_WRST_SCRIPT); -+} -+ -+static struct platform_driver twl4030_script_driver = { -+ .remove = twl4030_script_remove, -+ .driver = { -+ .name = "twl4030_script", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init twl4030_script_init(void) -+{ -+ /* Register the TWL4030 script driver */ -+ return platform_driver_probe(&twl4030_script_driver, -+ twl4030_script_probe); -+} -+ -+static void __exit twl4030_script_cleanup(void) -+{ -+ /* Unregister TWL4030 script driver */ -+ platform_driver_unregister(&twl4030_script_driver); -+} -+ -+module_init(twl4030_script_init); -+module_exit(twl4030_script_cleanup); -+ -+MODULE_DESCRIPTION("OMAP TWL4030 script driver"); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Texas Instruments Inc"); -diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h -index aee3a22..f343974 100644 ---- a/include/linux/i2c/twl.h -+++ b/include/linux/i2c/twl.h -@@ -205,6 +205,12 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) - return -EIO; - } - #endif -+ -+#ifdef CONFIG_TWL4030_POWER -+extern struct twl4030_power_data twl4030_generic_script; -+#else -+#define twl4030_generic_script NULL; -+#endif - /*----------------------------------------------------------------------*/ - - /* -@@ -437,9 +443,23 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) - - /* Power bus message definitions */ - --/* The TWL4030/5030 splits its power-management resources (the various -- * regulators, clock and reset lines) into 3 processor groups - P1, P2 and -- * P3. These groups can then be configured to transition between sleep, wait-on -+/* -+ * The TWL4030/5030 splits its power-management resources (the various -+ * regulators, clock and reset lines) into 3 processor groups - P1, P2 and P3. -+ * -+ * Resources attached to device group P1 is managed depending on the state of -+ * NSLEEP1 pin of TWL4030, which is connected to sys_off signal from OMAP -+ * -+ * Resources attached to device group P2 is managed depending on the state of -+ * NSLEEP2 pin of TWL4030, which is can be connected to a modem or -+ * connectivity chip -+ * -+ * Resources attached to device group P3 is managed depending on the state of -+ * CLKREQ pin of TWL4030, which is connected to clk request signal from OMAP -+ * -+ * If required these resources can be attached to combination of P1/P2/P3. -+ * -+ * These groups can then be configured to transition between sleep, wait-on - * and active states by sending messages to the power bus. See Section 5.4.2 - * Power Resources of TWL4030 TRM - */ -@@ -449,7 +469,17 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) - #define DEV_GRP_P1 0x1 /* P1: all OMAP devices */ - #define DEV_GRP_P2 0x2 /* P2: all Modem devices */ - #define DEV_GRP_P3 0x4 /* P3: all peripheral devices */ -+#define DEV_GRP_ALL 0x7 /* P1/P2/P3: all devices */ - -+/* -+ * The 27 power resources in TWL4030 is again divided into -+ * analog resources: -+ * Power Providers - LDO regulators, dc-to-dc regulators -+ * Power Reference - analog reference -+ * -+ * and digital resources: -+ * Reset & Clock - reset and clock signals. -+ */ - /* Resource groups */ - #define RES_GRP_RES 0x0 /* Reserved */ - #define RES_GRP_PP 0x1 /* Power providers */ -@@ -461,7 +491,10 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) - #define RES_GRP_ALL 0x7 /* All resource groups */ - - #define RES_TYPE2_R0 0x0 -+#define RES_TYPE2_R1 0x1 -+#define RES_TYPE2_R2 0x2 - -+#define RES_TYPE_R0 0x0 - #define RES_TYPE_ALL 0x7 - - /* Resource states */ -@@ -636,7 +669,7 @@ struct twl4030_power_data { - #define TWL4030_RESCONFIG_UNDEF ((u8)-1) - }; - --extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts); -+extern int twl4030_power_init(struct twl4030_power_data *triton2_scripts); - extern int twl4030_remove_script(u8 flags); - - struct twl4030_codec_audio_data { --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0011-MFD-TWL4030-TWL-version-checking.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0011-MFD-TWL4030-TWL-version-checking.patch deleted file mode 100644 index 6de2193d..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0011-MFD-TWL4030-TWL-version-checking.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 3ceb224732230934aba7d082f3e2ca96c14a9ca0 Mon Sep 17 00:00:00 2001 -From: Lesly A M -Date: Wed, 1 Jun 2011 14:56:56 -0700 -Subject: [PATCH 11/13] MFD: TWL4030: TWL version checking - -Added API to get the TWL5030 Si version from the IDCODE register. -It is used for enabling the workaround for TWL erratum 27. - -Signed-off-by: Lesly A M -Cc: Nishanth Menon -Cc: David Derrick -Cc: Samuel Ortiz ---- - drivers/mfd/twl-core.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/i2c/twl.h | 17 ++++++++++++- - 2 files changed, 78 insertions(+), 1 deletions(-) - -diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c -index 9096d7d..a60601d 100644 ---- a/drivers/mfd/twl-core.c -+++ b/drivers/mfd/twl-core.c -@@ -251,6 +251,9 @@ - /* is driver active, bound to a chip? */ - static bool inuse; - -+/* TWL IDCODE Register value */ -+static u32 twl_idcode; -+ - static unsigned int twl_id; - unsigned int twl_rev(void) - { -@@ -509,6 +512,58 @@ EXPORT_SYMBOL(twl_i2c_read_u8); - - /*----------------------------------------------------------------------*/ - -+/** -+ * twl_read_idcode_register - API to read the IDCODE register. -+ * -+ * Unlocks the IDCODE register and read the 32 bit value. -+ */ -+static int twl_read_idcode_register(void) -+{ -+ int err; -+ -+ err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK, -+ REG_UNLOCK_TEST_REG); -+ if (err) { -+ pr_err("TWL4030 Unable to unlock IDCODE registers -%d\n", err); -+ goto fail; -+ } -+ -+ err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_idcode), -+ REG_IDCODE_7_0, 4); -+ if (err) { -+ pr_err("TWL4030: unable to read IDCODE -%d\n", err); -+ goto fail; -+ } -+ -+ err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, REG_UNLOCK_TEST_REG); -+ if (err) -+ pr_err("TWL4030 Unable to relock IDCODE registers -%d\n", err); -+fail: -+ return err; -+} -+ -+/** -+ * twl_get_type - API to get TWL Si type. -+ * -+ * Api to get the TWL Si type from IDCODE value. -+ */ -+int twl_get_type(void) -+{ -+ return TWL_SIL_TYPE(twl_idcode); -+} -+EXPORT_SYMBOL_GPL(twl_get_type); -+ -+/** -+ * twl_get_version - API to get TWL Si version. -+ * -+ * Api to get the TWL Si version from IDCODE value. -+ */ -+int twl_get_version(void) -+{ -+ return TWL_SIL_REV(twl_idcode); -+} -+EXPORT_SYMBOL_GPL(twl_get_version); -+ - static struct device * - add_numbered_child(unsigned chip, const char *name, int num, - void *pdata, unsigned pdata_len, -@@ -1071,6 +1126,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) - unsigned i; - struct twl4030_platform_data *pdata = client->dev.platform_data; - u8 temp; -+ int ret = 0; - - if (!pdata) { - dev_dbg(&client->dev, "no platform data?\n"); -@@ -1117,6 +1173,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) - /* setup clock framework */ - clocks_init(&client->dev, pdata->clock); - -+ /* read TWL IDCODE Register */ -+ if (twl_id == TWL4030_CLASS_ID) { -+ ret = twl_read_idcode_register(); -+ WARN(ret < 0, "Error: reading twl_idcode register value\n"); -+ } -+ - /* load power event scripts */ - if (twl_has_power() && pdata->power) - twl4030_power_init(pdata->power); -diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h -index f343974..23ec058 100644 ---- a/include/linux/i2c/twl.h -+++ b/include/linux/i2c/twl.h -@@ -151,7 +151,12 @@ - #define MMC_PU (0x1 << 3) - #define MMC_PD (0x1 << 2) - -- -+#define TWL_SIL_TYPE(rev) ((rev) & 0x00FFFFFF) -+#define TWL_SIL_REV(rev) ((rev) >> 24) -+#define TWL_SIL_5030 0x09002F -+#define TWL5030_REV_1_0 0x00 -+#define TWL5030_REV_1_1 0x10 -+#define TWL5030_REV_1_2 0x30 - - #define TWL4030_CLASS_ID 0x4030 - #define TWL6030_CLASS_ID 0x6030 -@@ -181,6 +186,9 @@ int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg); - int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); - int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes); - -+int twl_get_type(void); -+int twl_get_version(void); -+ - int twl6030_interrupt_unmask(u8 bit_mask, u8 offset); - int twl6030_interrupt_mask(u8 bit_mask, u8 offset); - -@@ -286,7 +294,12 @@ extern struct twl4030_power_data twl4030_generic_script; - *(Use TWL_4030_MODULE_INTBR) - */ - -+#define REG_IDCODE_7_0 0x00 -+#define REG_IDCODE_15_8 0x01 -+#define REG_IDCODE_16_23 0x02 -+#define REG_IDCODE_31_24 0x03 - #define REG_GPPUPDCTR1 0x0F -+#define REG_UNLOCK_TEST_REG 0x12 - - /*I2C1 and I2C4(SR) SDA/SCL pull-up control bits */ - -@@ -295,6 +308,8 @@ extern struct twl4030_power_data twl4030_generic_script; - #define SR_I2C_SCL_CTRL_PU BIT(4) - #define SR_I2C_SDA_CTRL_PU BIT(6) - -+#define TWL_EEPROM_R_UNLOCK 0x49 -+ - /*----------------------------------------------------------------------*/ - - /* --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0012-MFD-TWL4030-workaround-changes-for-Erratum-27.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0012-MFD-TWL4030-workaround-changes-for-Erratum-27.patch deleted file mode 100644 index 6fe9dbfb..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0012-MFD-TWL4030-workaround-changes-for-Erratum-27.patch +++ /dev/null @@ -1,341 +0,0 @@ -From 0bec9f7b20e7c61e0bab93195ec39cf94f1f8e25 Mon Sep 17 00:00:00 2001 -From: Lesly A M -Date: Wed, 1 Jun 2011 14:57:01 -0700 -Subject: [PATCH 12/13] MFD: TWL4030: workaround changes for Erratum 27 - -Workaround for TWL5030 Silicon Errata 27 & 28: - 27 - VDD1, VDD2, may have glitches when their output value is updated. - 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock - is switched from internal to external. - -Erratum 27: - If the DCDC regulators is running on their internal oscillator, - negative glitches may occur on VDD1, VDD2 output when voltage is changed. - The OMAP device may reboot if the VDD1 or VDD2 go below the - core minimum operating voltage. - - WORKAROUND - Set up the TWL5030 DC-DC power supplies to use the HFCLKIN instead of - the internal oscillator. - -Erratum 28: - VDD1/VDD2 clock system may hang during switching the clock source from - internal oscillator to external. VDD1/VDD2 output voltages may collapse - if clock stops. - - WORKAROUND - If HFCLK is disabled in OFFMODE, modify the sleep/wakeup sequence and - setuptimes to make sure the switching will happen only when HFCLKIN is stable. - Also use the TWL5030 watchdog to safeguard the first switching from - internal oscillator to HFCLKIN during the TWL5030 init. - - IMPACT - power sequence is changed. - sleep/wakeup time values will be changed. - -The workaround changes are called from twl4030_power_init(), since we have to -make some i2c_read calls to check the TWL4030 version & the i2c will not be -initialized in the early stage. - -This workaround is required for TWL5030 Silicon version less than ES1.2 -The power script & setup time changes are recommended by TI HW team. - -For more information please see: - http://omapedia.org/wiki/TWL4030_power_scripts - -Changes taken from TWL4030 Erratum 27 workaround patch by Nishanth Menon. - -Signed-off-by: Lesly A M -Cc: Nishanth Menon -Cc: David Derrick -Cc: Samuel Ortiz ---- - drivers/mfd/twl4030-power.c | 79 +++++++++++++++++++ - drivers/mfd/twl4030-script-omap.c | 150 +++++++++++++++++++++++++++++++++++++ - include/linux/i2c/twl.h | 1 + - 3 files changed, 230 insertions(+), 0 deletions(-) - -diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c -index 91d5bc8..8af3fe3 100644 ---- a/drivers/mfd/twl4030-power.c -+++ b/drivers/mfd/twl4030-power.c -@@ -63,6 +63,14 @@ static u8 twl4030_start_script_address = 0x2b; - #define R_MEMORY_ADDRESS PHY_TO_OFF_PM_MASTER(0x59) - #define R_MEMORY_DATA PHY_TO_OFF_PM_MASTER(0x5a) - -+#define R_VDD1_OSC 0x5C -+#define R_VDD2_OSC 0x6A -+#define R_VIO_OSC 0x52 -+#define EXT_FS_CLK_EN BIT(6) -+ -+#define R_WDT_CFG 0x03 -+#define WDT_WRK_TIMEOUT 0x03 -+ - /* resource configuration registers - _DEV_GRP at address 'n+0' - _TYPE at address 'n+1' -@@ -512,6 +520,67 @@ int twl4030_remove_script(u8 flags) - } - EXPORT_SYMBOL_GPL(twl4030_remove_script); - -+/** -+ * twl_dcdc_use_hfclk - API to use HFCLK for TWL DCDCs -+ * -+ * TWL DCDCs switching to HFCLK instead of using internal RC oscillator. -+ */ -+static int twl_dcdc_use_hfclk(void) -+{ -+ u8 val; -+ u8 smps_osc_reg[] = {R_VDD1_OSC, R_VDD2_OSC, R_VIO_OSC}; -+ int i; -+ int err; -+ -+ for (i = 0; i < sizeof(smps_osc_reg); i++) { -+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &val, -+ smps_osc_reg[i]); -+ val |= EXT_FS_CLK_EN; -+ err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, val, -+ smps_osc_reg[i]); -+ } -+ return err; -+} -+ -+/** -+ * twl_erratum27_workaround - Workaround for TWL5030 Silicon Erratum 27 -+ * 27 - VDD1, VDD2, may have glitches when their output value is updated. -+ * 28 - VDD1 and / or VDD2 DCDC clock may stop working when internal clock is -+ * switched from internal to external. -+ * -+ * Workaround requires the TWL DCDCs to use HFCLK instead of -+ * internal oscillator. Also enable TWL watchdog before switching the osc -+ * to recover if the VDD1/VDD2 stop working. -+ */ -+static void twl_erratum27_workaround(void) -+{ -+ u8 wdt_counter_val = 0; -+ int err; -+ -+ /* Setup the twl wdt to take care of borderline failure case */ -+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &wdt_counter_val, -+ R_WDT_CFG); -+ err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, WDT_WRK_TIMEOUT, -+ R_WDT_CFG); -+ -+ /* TWL DCDC switching to HFCLK */ -+ err |= twl_dcdc_use_hfclk(); -+ -+ /* restore the original value */ -+ err |= twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, wdt_counter_val, -+ R_WDT_CFG); -+ if (err) -+ pr_warning("TWL4030: workaround setup failed!\n"); -+} -+ -+static bool is_twl5030_erratum27wa_required(void) -+{ -+ if (twl_get_type() == TWL_SIL_5030) -+ return (twl_get_version() < TWL5030_REV_1_2); -+ -+ return 0; -+} -+ - int twl4030_power_init(struct twl4030_power_data *twl4030_scripts) - { - int err = 0; -@@ -530,6 +599,16 @@ int twl4030_power_init(struct twl4030_power_data *twl4030_scripts) - TWL4030_PM_MASTER_PROTECT_KEY); - if (err) - goto unlock; -+ -+ /* Applying TWL5030 Erratum 27 WA based on Si revision & -+ * flag updated from board file*/ -+ if (is_twl5030_erratum27wa_required()) { -+ pr_info("TWL5030: Enabling workaround for Si Erratum 27\n"); -+ twl_erratum27_workaround(); -+ if (twl4030_scripts->twl5030_erratum27wa_script) -+ twl4030_scripts->twl5030_erratum27wa_script(); -+ } -+ - for (i = 0; i < twl4030_scripts->num; i++) { - err = load_twl4030_script(twl4030_scripts->scripts[i], address); - if (err) -diff --git a/drivers/mfd/twl4030-script-omap.c b/drivers/mfd/twl4030-script-omap.c -index 867a442..ff93fd2 100644 ---- a/drivers/mfd/twl4030-script-omap.c -+++ b/drivers/mfd/twl4030-script-omap.c -@@ -326,10 +326,160 @@ static struct twl4030_resconfig twl4030_rconfig[] __initdata = { - { 0, 0}, - }; - -+/* -+ * Sleep and active sequences with changes for TWL5030 Erratum 27 workaround -+ * -+ * Sysoff (using sys_off signal): -+ * When SYS_CLKREQ goes low during retention no resources will be affected -+ * since no resources are assigned to P3 only. -+ * -+ * Since all resources are assigned to P1 and P3 then all resources -+ * will be affected on the falling edge of P3 (SYS_CLKREQ). -+ * When OMAP lower the SYS_CLKREQ signal PMIC will execute the -+ * A2S sequence in which HFCLKOUT is dissabled first and -+ * after 488.32 usec(PRM_VOLTOFFSET) resources assigned to P1 and P3 -+ * and of TYPE2=1 are put to sleep -+ * (VDD1, VDD2, VPLL1, REGEN, NRESPWRON & SYSEN). -+ * Again after a 61.04 usec resources assigned to P1 and P3 -+ * and of TYPE2=2 are put to sleep -+ * (VINTANA1, VINTANA2, VINTDIG, VIO & CLKEN). -+ * -+ * On wakeup event OMAP goes active and pulls the SYS_CLKREQ high, -+ * and will execute the S2A sequence which is same for P1_P2 & P3. -+ * This will turn on all resources of TYPE2=2 to go to the active state. -+ * Three dummy broadcast messages are added to get a delay of ~10 ms -+ * before enabling the HFCLKOUT resource. And after a 30.52 usec -+ * all resources of TYPE2=1 are put to the active state. -+ * -+ * This 10ms delay can be reduced if the oscillator is having less -+ * stabilization time. A should be taken care if it needs more time -+ * for stabilization. -+ * -+ */ -+ -+/** -+ * DOC: Sleep to Active sequence for P1/P2/P3 -+ * -+ * The wakeup sequence is adjusted to do the VDD1/VDD2 voltage ramp-up -+ * only after HFCLKIN is stabilized and the HFCLKOUT is enabled. -+ */ -+static struct twl4030_ins wakeup_seq_erratum27[] __initdata = { -+ /* -+ * Broadcast message to put res(TYPE2 = 2) to active. -+ * Wait for ~10 mS (ramp-up time for OSC on the board) -+ * after HFCLKIN is enabled -+ */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, -+ RES_STATE_ACTIVE), 55}, -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, -+ RES_STATE_ACTIVE), 55}, -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, -+ RES_STATE_ACTIVE), 54}, -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, -+ RES_STATE_ACTIVE), 1}, -+ /* Singular message to enable HCLKOUT after HFCLKIN is stabilized */ -+ {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_ACTIVE), 1}, -+ /* -+ * Broadcast message to put res(TYPE2 = 1) to active. -+ * VDD1/VDD2 ramp-up after HFCLKIN is stable and HFCLKOUT is enabled. -+ */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1, -+ RES_STATE_ACTIVE), 2}, -+}; -+ -+static struct twl4030_script wakeup_script_erratum27 __initdata = { -+ .script = wakeup_seq_erratum27, -+ .size = ARRAY_SIZE(wakeup_seq_erratum27), -+ .flags = TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT, -+}; -+ -+/** -+ * DOC: Active to Sleep sequence for P1/P2/P3 -+ * -+ * The sleep sequence is adjusted to do the switching of VDD1/VDD2/VIO OSC from -+ * HFCLKIN to internal oscillator when the HFCLKIN is stable. -+ */ -+static struct twl4030_ins sleep_on_seq_erratum27[] __initdata = { -+ /* -+ * Singular message to disable HCLKOUT. -+ * Wait for ~488.32 uS to do the switching of VDD1/VDD2/VIO OSC from -+ * HFCLKIN to internal oscillator before disabling HFCLKIN. -+ */ -+ {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_SLEEP), 20}, -+ /* Broadcast message to put res(TYPE2 = 1) to sleep */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R1, -+ RES_STATE_SLEEP), 2}, -+ /* Broadcast message to put res(TYPE2 = 2) to sleep, disable HFCLKIN */ -+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_R0, RES_TYPE2_R2, -+ RES_STATE_SLEEP), 2}, -+}; -+ -+static struct twl4030_script sleep_on_script_erratum27 __initdata = { -+ .script = sleep_on_seq_erratum27, -+ .size = ARRAY_SIZE(sleep_on_seq_erratum27), -+ .flags = TWL4030_SLEEP_SCRIPT, -+}; -+ -+/* TWL4030 script for sleep, wakeup & warm_reset */ -+static struct twl4030_script *twl4030_scripts_erratum27[] __initdata = { -+ &wakeup_script_erratum27, -+ &sleep_on_script_erratum27, -+ &wrst_script, -+}; -+ -+/** -+ * DOC: TWL4030 resource configuration -+ * -+ * VDD1/VDD2/VPLL are assigned to P1 and P3, to have better control -+ * during OFFMODE. HFCLKOUT is assigned to P1 and P3 (*p2) to turn off -+ * only during OFFMODE. -+ * (*P2 is included if the platform uses it for modem/some other processor) -+ */ -+static struct twl4030_resconfig twl4030_rconfig_erratum27[] __initdata = { -+ { .resource = RES_VPLL1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, -+ .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF }, -+ { .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_VDD1, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, -+ .type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF }, -+ { .resource = RES_VDD2, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, -+ .type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF }, -+ { .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2, -+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0, -+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3, -+ .type2 = 2, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6, -+ .type2 = 1, .remap_sleep = RES_STATE_SLEEP }, -+ { .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P1 | DEV_GRP_P3, -+ .type = 0, .type2 = 1, .remap_sleep = RES_STATE_SLEEP }, -+ { 0, 0}, -+}; -+ -+/** -+ * twl5030_script_erratum27() - API to modify TWL4030 script -+ * -+ * Updating the TWL4030 script & resource configuration -+ */ -+static void __init twl5030_script_erratum27(void) -+{ -+ twl4030_generic_script.scripts = twl4030_scripts_erratum27; -+ twl4030_generic_script.num = ARRAY_SIZE(twl4030_scripts_erratum27); -+ twl4030_generic_script.resource_config = twl4030_rconfig_erratum27; -+} -+ - struct twl4030_power_data twl4030_generic_script __initdata = { - .scripts = twl4030_scripts, - .num = ARRAY_SIZE(twl4030_scripts), - .resource_config = twl4030_rconfig, -+ .twl5030_erratum27wa_script = twl5030_script_erratum27, - }; - - static int __init twl4030_script_probe(struct platform_device *pdev) -diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h -index 23ec058..10cb6e2 100644 ---- a/include/linux/i2c/twl.h -+++ b/include/linux/i2c/twl.h -@@ -681,6 +681,7 @@ struct twl4030_power_data { - struct twl4030_script **scripts; - unsigned num; - struct twl4030_resconfig *resource_config; -+ void (*twl5030_erratum27wa_script)(void); - #define TWL4030_RESCONFIG_UNDEF ((u8)-1) - }; - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0013-MFD-TWL4030-optimizing-resource-configuration.patch b/recipes-kernel/linux/linux-omap-2.6.39/mfd/0013-MFD-TWL4030-optimizing-resource-configuration.patch deleted file mode 100644 index 8904f8de..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/mfd/0013-MFD-TWL4030-optimizing-resource-configuration.patch +++ /dev/null @@ -1,184 +0,0 @@ -From bf171753a162d07753208c6bcfae8ca1e5c94af3 Mon Sep 17 00:00:00 2001 -From: Lesly A M -Date: Wed, 1 Jun 2011 14:57:05 -0700 -Subject: [PATCH 13/13] MFD: TWL4030: optimizing resource configuration - -Skip the i2c register writes in twl4030_configure_resource() if the new value -is same as the old value, for devgrp/type/remap regs. - -Suggested by David Derrick - -Signed-off-by: Lesly A M -Cc: Nishanth Menon -Cc: David Derrick -Cc: Samuel Ortiz ---- - drivers/mfd/twl4030-power.c | 126 ++++++++++++++++++++++++------------------ - 1 files changed, 72 insertions(+), 54 deletions(-) - -diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c -index 8af3fe3..d82632f 100644 ---- a/drivers/mfd/twl4030-power.c -+++ b/drivers/mfd/twl4030-power.c -@@ -335,9 +335,9 @@ static int twl4030_configure_resource(struct twl4030_resconfig *rconfig) - { - int rconfig_addr; - int err; -- u8 type; -- u8 grp; -- u8 remap; -+ u8 type, type_value; -+ u8 grp, grp_value; -+ u8 remap, remap_value; - - if (rconfig->resource > TOTAL_RESOURCES) { - pr_err("TWL4030 Resource %d does not exist\n", -@@ -348,76 +348,94 @@ static int twl4030_configure_resource(struct twl4030_resconfig *rconfig) - rconfig_addr = res_config_addrs[rconfig->resource]; - - /* Set resource group */ -- err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &grp, -+ if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) { -+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &grp, - rconfig_addr + DEV_GRP_OFFSET); -- if (err) { -- pr_err("TWL4030 Resource %d group could not be read\n", -- rconfig->resource); -- return err; -- } -+ if (err) { -+ pr_err("TWL4030 Resource %d group could not be read\n", -+ rconfig->resource); -+ return err; -+ } - -- if (rconfig->devgroup != TWL4030_RESCONFIG_UNDEF) { -- grp &= ~DEV_GRP_MASK; -- grp |= rconfig->devgroup << DEV_GRP_SHIFT; -- err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, -+ grp_value = (grp & DEV_GRP_MASK) >> DEV_GRP_SHIFT; -+ -+ if (rconfig->devgroup != grp_value) { -+ grp &= ~DEV_GRP_MASK; -+ grp |= rconfig->devgroup << DEV_GRP_SHIFT; -+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, - grp, rconfig_addr + DEV_GRP_OFFSET); -- if (err < 0) { -- pr_err("TWL4030 failed to program devgroup\n"); -- return err; -+ if (err < 0) { -+ pr_err("TWL4030 failed to program devgroup\n"); -+ return err; -+ } - } - } - - /* Set resource types */ -- err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &type, -+ if ((rconfig->type != TWL4030_RESCONFIG_UNDEF) || -+ (rconfig->type2 != TWL4030_RESCONFIG_UNDEF)) { -+ -+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &type, - rconfig_addr + TYPE_OFFSET); -- if (err < 0) { -- pr_err("TWL4030 Resource %d type could not be read\n", -- rconfig->resource); -- return err; -- } -+ if (err < 0) { -+ pr_err("TWL4030 Resource %d type could not be read\n", -+ rconfig->resource); -+ return err; -+ } - -- if (rconfig->type != TWL4030_RESCONFIG_UNDEF) { -- type &= ~TYPE_MASK; -- type |= rconfig->type << TYPE_SHIFT; -- } -+ type_value = type; - -- if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) { -- type &= ~TYPE2_MASK; -- type |= rconfig->type2 << TYPE2_SHIFT; -- } -+ if (rconfig->type != TWL4030_RESCONFIG_UNDEF) { -+ type &= ~TYPE_MASK; -+ type |= rconfig->type << TYPE_SHIFT; -+ } - -- err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, -+ if (rconfig->type2 != TWL4030_RESCONFIG_UNDEF) { -+ type &= ~TYPE2_MASK; -+ type |= rconfig->type2 << TYPE2_SHIFT; -+ } -+ -+ if (type != type_value) { -+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, - type, rconfig_addr + TYPE_OFFSET); -- if (err < 0) { -- pr_err("TWL4030 failed to program resource type\n"); -- return err; -+ if (err < 0) { -+ pr_err("TWL4030 failed to program resource type\n"); -+ return err; -+ } -+ } - } - - /* Set remap states */ -- err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &remap, -+ if ((rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) || -+ (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF)) { -+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &remap, - rconfig_addr + REMAP_OFFSET); -- if (err < 0) { -- pr_err("TWL4030 Resource %d remap could not be read\n", -- rconfig->resource); -- return err; -- } -+ if (err < 0) { -+ pr_err("TWL4030 Resource %d remap could not be read\n", -+ rconfig->resource); -+ return err; -+ } - -- if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) { -- remap &= ~OFF_STATE_MASK; -- remap |= rconfig->remap_off << OFF_STATE_SHIFT; -- } -+ remap_value = remap; - -- if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) { -- remap &= ~SLEEP_STATE_MASK; -- remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT; -- } -+ if (rconfig->remap_off != TWL4030_RESCONFIG_UNDEF) { -+ remap &= ~OFF_STATE_MASK; -+ remap |= rconfig->remap_off << OFF_STATE_SHIFT; -+ } - -- err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, -- remap, -- rconfig_addr + REMAP_OFFSET); -- if (err < 0) { -- pr_err("TWL4030 failed to program remap\n"); -- return err; -+ if (rconfig->remap_sleep != TWL4030_RESCONFIG_UNDEF) { -+ remap &= ~SLEEP_STATE_MASK; -+ remap |= rconfig->remap_sleep << SLEEP_STATE_SHIFT; -+ } -+ -+ if (remap != remap_value) { -+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, -+ remap, rconfig_addr + REMAP_OFFSET); -+ if (err < 0) { -+ pr_err("TWL4030 failed to program remap\n"); -+ return err; -+ } -+ } - } - - return 0; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/musb/0001-usb-musb-Enable-DMA-mode1-RX-for-USB-Mass-Storage.patch b/recipes-kernel/linux/linux-omap-2.6.39/musb/0001-usb-musb-Enable-DMA-mode1-RX-for-USB-Mass-Storage.patch deleted file mode 100644 index a98a4da9..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/musb/0001-usb-musb-Enable-DMA-mode1-RX-for-USB-Mass-Storage.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 2adb339e4988632379971febe5696f21d05c71f2 Mon Sep 17 00:00:00 2001 -From: Anand Gadiyar -Date: Tue, 19 Jul 2011 01:52:14 -0700 -Subject: [PATCH] usb: musb: Enable DMA mode1 RX for USB-Mass-Storage - -This patch enables the DMA mode1 RX support. -This feature is enabled based on the short_not_ok flag passed from -gadget drivers. - -This will result in a thruput performance gain of around -40% for USB mass-storage/mtp use cases. - -Signed-off-by: Anand Gadiyar -Signed-off-by: Moiz Sonasath -Tested-by: Vikram Pandita -Signed-off-by: Koen Kooi ---- - drivers/usb/musb/musb_gadget.c | 68 ++++++++++++++++++++++++--------------- - 1 files changed, 42 insertions(+), 26 deletions(-) - -diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c -index f47c201..ca32c63 100644 ---- a/drivers/usb/musb/musb_gadget.c -+++ b/drivers/usb/musb/musb_gadget.c -@@ -630,6 +630,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) - u16 len; - u16 csr = musb_readw(epio, MUSB_RXCSR); - struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; -+ u8 use_mode_1; - - if (hw_ep->is_shared_fifo) - musb_ep = &hw_ep->ep_in; -@@ -679,6 +680,18 @@ static void rxstate(struct musb *musb, struct musb_request *req) - - if (csr & MUSB_RXCSR_RXPKTRDY) { - len = musb_readw(epio, MUSB_RXCOUNT); -+ -+ /* -+ * Enable Mode 1 for RX transfers only for mass-storage -+ * use-case, based on short_not_ok flag which is set only -+ * from file_storage and f_mass_storage drivers -+ */ -+ -+ if (request->short_not_ok && len == musb_ep->packet_sz) -+ use_mode_1 = 1; -+ else -+ use_mode_1 = 0; -+ - if (request->actual < request->length) { - #ifdef CONFIG_USB_INVENTRA_DMA - if (is_buffer_mapped(req)) { -@@ -710,37 +723,40 @@ static void rxstate(struct musb *musb, struct musb_request *req) - * then becomes usable as a runtime "use mode 1" hint... - */ - -- csr |= MUSB_RXCSR_DMAENAB; --#ifdef USE_MODE1 -- csr |= MUSB_RXCSR_AUTOCLEAR; -- /* csr |= MUSB_RXCSR_DMAMODE; */ -- -- /* this special sequence (enabling and then -- * disabling MUSB_RXCSR_DMAMODE) is required -- * to get DMAReq to activate -- */ -- musb_writew(epio, MUSB_RXCSR, -- csr | MUSB_RXCSR_DMAMODE); --#else -- if (!musb_ep->hb_mult && -- musb_ep->hw_ep->rx_double_buffered) -+ /* Experimental: Mode1 works with mass storage use cases */ -+ if (use_mode_1) { - csr |= MUSB_RXCSR_AUTOCLEAR; --#endif -- musb_writew(epio, MUSB_RXCSR, csr); -+ musb_writew(epio, MUSB_RXCSR, csr); -+ csr |= MUSB_RXCSR_DMAENAB; -+ musb_writew(epio, MUSB_RXCSR, csr); -+ -+ /* this special sequence (enabling and then -+ * disabling MUSB_RXCSR_DMAMODE) is required -+ * to get DMAReq to activate -+ */ -+ musb_writew(epio, MUSB_RXCSR, -+ csr | MUSB_RXCSR_DMAMODE); -+ musb_writew(epio, MUSB_RXCSR, csr); -+ -+ } else { -+ if (!musb_ep->hb_mult && -+ musb_ep->hw_ep->rx_double_buffered) -+ csr |= MUSB_RXCSR_AUTOCLEAR; -+ csr |= MUSB_RXCSR_DMAENAB; -+ musb_writew(epio, MUSB_RXCSR, csr); -+ } - - if (request->actual < request->length) { - int transfer_size = 0; --#ifdef USE_MODE1 -- transfer_size = min(request->length - request->actual, -- channel->max_len); --#else -- transfer_size = min(request->length - request->actual, -- (unsigned)len); --#endif -- if (transfer_size <= musb_ep->packet_sz) -- musb_ep->dma->desired_mode = 0; -- else -+ if (use_mode_1) { -+ transfer_size = min(request->length - request->actual, -+ channel->max_len); - musb_ep->dma->desired_mode = 1; -+ } else { -+ transfer_size = min(request->length - request->actual, -+ (unsigned)len); -+ musb_ep->dma->desired_mode = 0; -+ } - - use_dma = c->channel_program( - channel, --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/net/0001-NFS-Revert-NFSROOT-default-mount-options.patch b/recipes-kernel/linux/linux-omap-2.6.39/net/0001-NFS-Revert-NFSROOT-default-mount-options.patch deleted file mode 100644 index 617698da..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/net/0001-NFS-Revert-NFSROOT-default-mount-options.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c -index c541093..c4744e1 100644 ---- a/fs/nfs/nfsroot.c -+++ b/fs/nfs/nfsroot.c -@@ -87,7 +87,7 @@ - #define NFS_ROOT "/tftpboot/%s" - - /* Default NFSROOT mount options. */ --#define NFS_DEF_OPTIONS "udp" -+#define NFS_DEF_OPTIONS "vers=2,udp,rsize=4096,wsize=4096" - - /* Parameters passed from the kernel command line */ - static char nfs_root_parms[256] __initdata = ""; diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0001-OMAP2-cpufreq-free-up-table-on-exit.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0001-OMAP2-cpufreq-free-up-table-on-exit.patch deleted file mode 100644 index 9e9a8a0b..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0001-OMAP2-cpufreq-free-up-table-on-exit.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 38dd5aadc86725f6018d23679e9daa60ca0a8319 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Thu, 12 May 2011 07:59:52 -0500 -Subject: [PATCH 1/6] OMAP2+: cpufreq: free up table on exit - -freq_table allocated by opp_init_cpufreq_table in omap_cpu_init -needs to be freed in omap_cpu_exit. - -Signed-off-by: Nishanth Menon -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/omap2plus-cpufreq.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c -index d53ce23..e38ebb8 100644 ---- a/arch/arm/mach-omap2/omap2plus-cpufreq.c -+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -216,6 +217,8 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - static int omap_cpu_exit(struct cpufreq_policy *policy) - { - clk_exit_cpufreq_table(&freq_table); -+ kfree(freq_table); -+ freq_table = NULL; - clk_put(mpu_clk); - return 0; - } --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0002-OMAP2-cpufreq-handle-invalid-cpufreq-table.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0002-OMAP2-cpufreq-handle-invalid-cpufreq-table.patch deleted file mode 100644 index 087724d1..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0002-OMAP2-cpufreq-handle-invalid-cpufreq-table.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 5febdc0482e545c2a598f035c5e03931e0c3c808 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Thu, 12 May 2011 08:14:41 -0500 -Subject: [PATCH 2/6] OMAP2+: cpufreq: handle invalid cpufreq table - -Handle the case when cpufreq_frequency_table_cpuinfo fails. freq_table -that we passed failed the internal test of cpufreq generic driver, -so we should'nt be using the freq_table as such. Instead, warn and -fallback to clock functions for validation and operation. - -Signed-off-by: Nishanth Menon -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/omap2plus-cpufreq.c | 12 ++++++++++-- - 1 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c -index e38ebb8..6e3666a 100644 ---- a/arch/arm/mach-omap2/omap2plus-cpufreq.c -+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c -@@ -182,10 +182,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - - if (freq_table) { - result = cpufreq_frequency_table_cpuinfo(policy, freq_table); -- if (!result) -+ if (!result) { - cpufreq_frequency_table_get_attr(freq_table, - policy->cpu); -- } else { -+ } else { -+ WARN(true, "%s: fallback to clk_round(freq_table=%d)\n", -+ __func__, result); -+ kfree(freq_table); -+ freq_table = NULL; -+ } -+ } -+ -+ if (!freq_table) { - policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; - policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, - VERY_HI_RATE) / 1000; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0003-OMAP2-cpufreq-minor-comment-cleanup.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0003-OMAP2-cpufreq-minor-comment-cleanup.patch deleted file mode 100644 index 4f4cdb14..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0003-OMAP2-cpufreq-minor-comment-cleanup.patch +++ /dev/null @@ -1,33 +0,0 @@ -From aef7e862873e6125159a18d22a2e37b1fbab2153 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Thu, 12 May 2011 16:27:45 -0700 -Subject: [PATCH 3/6] OMAP2+: cpufreq: minor comment cleanup - -this should probably get squashed in.. - -Signed-off-by: Nishanth Menon -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/omap2plus-cpufreq.c | 6 ++++-- - 1 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c -index 6e3666a..45f1e9e 100644 ---- a/arch/arm/mach-omap2/omap2plus-cpufreq.c -+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c -@@ -84,8 +84,10 @@ static int omap_target(struct cpufreq_policy *policy, - if (is_smp() && (num_online_cpus() < NR_CPUS)) - return ret; - -- /* Ensure desired rate is within allowed range. Some govenors -- * (ondemand) will just pass target_freq=0 to get the minimum. */ -+ /* -+ * Ensure desired rate is within allowed range. Some govenors -+ * (ondemand) will just pass target_freq=0 to get the minimum. -+ */ - if (target_freq < policy->min) - target_freq = policy->min; - if (target_freq > policy->max) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0004-OMAP2-cpufreq-use-clk_init_cpufreq_table-if-OPPs-not.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0004-OMAP2-cpufreq-use-clk_init_cpufreq_table-if-OPPs-not.patch deleted file mode 100644 index dd23c082..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0004-OMAP2-cpufreq-use-clk_init_cpufreq_table-if-OPPs-not.patch +++ /dev/null @@ -1,48 +0,0 @@ -From f231980dbd0f05229f2020e59b7242872576416f Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Fri, 13 May 2011 05:34:35 -0700 -Subject: [PATCH 4/6] OMAP2: cpufreq: use clk_init_cpufreq_table if OPPs not available - -OMAP2 does not use OPP tables at the moment for DVFS. Currently, -we depend on opp table initialization to give us the freq_table, -which makes sense for OMAP3+. for OMAP2, we should be using -clk_init_cpufreq_table - so if the opp based frequency table -initilization fails, fall back to clk_init_cpufreq_table to give -us the table. - -Signed-off-by: Nishanth Menon -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/omap2plus-cpufreq.c | 9 ++++++++- - 1 files changed, 8 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c -index 45f1e9e..854f4b3 100644 ---- a/arch/arm/mach-omap2/omap2plus-cpufreq.c -+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c -@@ -180,7 +180,13 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - pr_warning("%s: unable to get the mpu device\n", __func__); - return -EINVAL; - } -- opp_init_cpufreq_table(mpu_dev, &freq_table); -+ -+ /* -+ * if we dont get cpufreq table using opp, use traditional omap2 lookup -+ * as a fallback -+ */ -+ if (opp_init_cpufreq_table(mpu_dev, &freq_table)) -+ clk_init_cpufreq_table(&freq_table); - - if (freq_table) { - result = cpufreq_frequency_table_cpuinfo(policy, freq_table); -@@ -188,6 +194,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - cpufreq_frequency_table_get_attr(freq_table, - policy->cpu); - } else { -+ clk_exit_cpufreq_table(&freq_table); - WARN(true, "%s: fallback to clk_round(freq_table=%d)\n", - __func__, result); - kfree(freq_table); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0005-OMAP2-cpufreq-use-cpufreq_frequency_table_target.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0005-OMAP2-cpufreq-use-cpufreq_frequency_table_target.patch deleted file mode 100644 index 504d1916..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0005-OMAP2-cpufreq-use-cpufreq_frequency_table_target.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 272d76bcb22b9509ccc1b59d3a62e3930d902d17 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Fri, 13 May 2011 05:43:49 -0700 -Subject: [PATCH 5/6] OMAP2+: cpufreq: use cpufreq_frequency_table_target - -Use cpufreq_frequency_table_target for finding the proper target -instead of seeing if the frequency requested is divisible alone. -if we have a frequency table, we should restrict ourselves to -selecting the "approved" frequencies alone and only in the case -where the frequency table is not available should we attempt at -closest roundable clock frequency. - -Signed-off-by: Nishanth Menon -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/omap2plus-cpufreq.c | 38 ++++++++++++++++++++++-------- - 1 files changed, 28 insertions(+), 10 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c -index 854f4b3..d0b4f97 100644 ---- a/arch/arm/mach-omap2/omap2plus-cpufreq.c -+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c -@@ -77,24 +77,42 @@ static int omap_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) - { -- int i, ret = 0; -+ unsigned int i; -+ int ret = 0; - struct cpufreq_freqs freqs; - - /* Changes not allowed until all CPUs are online */ - if (is_smp() && (num_online_cpus() < NR_CPUS)) - return ret; - -- /* -- * Ensure desired rate is within allowed range. Some govenors -- * (ondemand) will just pass target_freq=0 to get the minimum. -- */ -- if (target_freq < policy->min) -- target_freq = policy->min; -- if (target_freq > policy->max) -- target_freq = policy->max; -+ if (freq_table) { -+ ret = cpufreq_frequency_table_target(policy, freq_table, -+ target_freq, relation, &i); -+ if (ret) { -+ pr_debug("%s: cpu%d: no freq match for %d(ret=%d)\n", -+ __func__, policy->cpu, target_freq, ret); -+ return ret; -+ } -+ freqs.new = freq_table[i].frequency; -+ } else { -+ /* -+ * Ensure desired rate is within allowed range. Some govenors -+ * (ondemand) will just pass target_freq=0 to get the minimum. -+ */ -+ if (target_freq < policy->min) -+ target_freq = policy->min; -+ if (target_freq > policy->max) -+ target_freq = policy->max; -+ -+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; -+ } -+ if (!freqs.new) { -+ pr_err("%s: cpu%d: no match for freq %d\n", __func__, -+ policy->cpu, target_freq); -+ return -EINVAL; -+ } - - freqs.old = omap_getspeed(policy->cpu); -- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; - freqs.cpu = policy->cpu; - - if (freqs.old == freqs.new) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch deleted file mode 100644 index 0cb4c91f..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 42a384af80e07534913d9002ec8d9caf5d4d305c Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Wed, 18 May 2011 01:48:23 -0500 -Subject: [PATCH 6/6] OMAP2+: cpufreq: fix freq_table leak - -Since we have two cpus the cpuinit call for cpu1 causes -freq_table of cpu0 to be overwritten. instead, we maintain -a counter to keep track of cpus who use the cpufreq table -allocate it once(one freq table for all CPUs) and free them -once the last user is done with it. - -Signed-off-by: Nishanth Menon -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/omap2plus-cpufreq.c | 33 ++++++++++++++++++++++++------ - 1 files changed, 26 insertions(+), 7 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c -index d0b4f97..fc3d0fb 100644 ---- a/arch/arm/mach-omap2/omap2plus-cpufreq.c -+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c -@@ -42,6 +42,9 @@ - #define VERY_HI_RATE 900000000 - - static struct cpufreq_frequency_table *freq_table; -+static int freq_table_users; -+static DEFINE_MUTEX(freq_table_lock); -+ - static struct clk *mpu_clk; - - static int omap_verify_speed(struct cpufreq_policy *policy) -@@ -172,6 +175,18 @@ skip_lpj: - return ret; - } - -+static void freq_table_free(void) -+{ -+ if (!freq_table_users) -+ return; -+ freq_table_users--; -+ if (freq_table_users) -+ return; -+ clk_exit_cpufreq_table(&freq_table); -+ kfree(freq_table); -+ freq_table = NULL; -+} -+ - static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - { - int result = 0; -@@ -199,14 +214,18 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - return -EINVAL; - } - -+ mutex_lock(&freq_table_lock); - /* - * if we dont get cpufreq table using opp, use traditional omap2 lookup - * as a fallback - */ -- if (opp_init_cpufreq_table(mpu_dev, &freq_table)) -- clk_init_cpufreq_table(&freq_table); -+ if (!freq_table) { -+ if (opp_init_cpufreq_table(mpu_dev, &freq_table)) -+ clk_init_cpufreq_table(&freq_table); -+ } - - if (freq_table) { -+ freq_table_users++; - result = cpufreq_frequency_table_cpuinfo(policy, freq_table); - if (!result) { - cpufreq_frequency_table_get_attr(freq_table, -@@ -215,10 +234,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - clk_exit_cpufreq_table(&freq_table); - WARN(true, "%s: fallback to clk_round(freq_table=%d)\n", - __func__, result); -- kfree(freq_table); -- freq_table = NULL; -+ freq_table_free(); - } - } -+ mutex_unlock(&freq_table_lock); - - if (!freq_table) { - policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; -@@ -251,9 +270,9 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - - static int omap_cpu_exit(struct cpufreq_policy *policy) - { -- clk_exit_cpufreq_table(&freq_table); -- kfree(freq_table); -- freq_table = NULL; -+ mutex_lock(&freq_table_lock); -+ freq_table_free(); -+ mutex_unlock(&freq_table_lock); - clk_put(mpu_clk); - return 0; - } --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch deleted file mode 100644 index 576cd08f..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 8726f3a7218b72a1003904a24bb000b3e4f9b4d1 Mon Sep 17 00:00:00 2001 -From: Mike Turquette -Date: Tue, 17 May 2011 09:35:54 -0500 -Subject: [PATCH 1/2] cpufreq: helpers for walking the frequency table - -Two new functions for getting the next higher and next lower frequencies -in the cpufreq table, based upon a frequency supplied in kHz. - -This is useful for cpufreq governors that do not target frequencies -based upon a percentage or a pre-determined value, but instead access -the cpufreq table directly. - -Signed-off-by: Mike Turquette -Signed-off-by: Santosh Shilimkar -Signed-off-by: Koen Kooi ---- - drivers/cpufreq/freq_table.c | 73 ++++++++++++++++++++++++++++++++++++++++++ - include/linux/cpufreq.h | 9 +++++ - 2 files changed, 82 insertions(+), 0 deletions(-) - -diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c -index 0543221..11a307b 100644 ---- a/drivers/cpufreq/freq_table.c -+++ b/drivers/cpufreq/freq_table.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - #define dprintk(msg...) \ - cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg) -@@ -174,6 +175,78 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, - } - EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target); - -+int cpufreq_frequency_table_next_lowest(struct cpufreq_policy *policy, -+ struct cpufreq_frequency_table *table, int *index) -+{ -+ unsigned int cur_freq; -+ unsigned int next_lowest_freq; -+ int optimal_index = -1; -+ int i = 0; -+ -+ if (!policy || IS_ERR(policy) || !table || IS_ERR(table) || -+ !index || IS_ERR(index)) -+ return -ENOMEM; -+ -+ cur_freq = policy->cur; -+ next_lowest_freq = policy->min; -+ -+ /* we're at the lowest frequency in the table already, bail out */ -+ if (cur_freq == policy->min) -+ return -EINVAL; -+ -+ /* walk the list, find closest freq to cur_freq that is below it */ -+ while(table[i].frequency != CPUFREQ_TABLE_END) { -+ if (table[i].frequency < cur_freq && -+ table[i].frequency >= next_lowest_freq) { -+ next_lowest_freq = table[i].frequency; -+ optimal_index = table[i].index; -+ } -+ -+ i++; -+ } -+ -+ *index = optimal_index; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_next_lowest); -+ -+int cpufreq_frequency_table_next_highest(struct cpufreq_policy *policy, -+ struct cpufreq_frequency_table *table, int *index) -+{ -+ unsigned int cur_freq; -+ unsigned int next_higher_freq; -+ int optimal_index = -1; -+ int i = 0; -+ -+ if (!policy || IS_ERR(policy) || !table || IS_ERR(table) || -+ !index || IS_ERR(index)) -+ return -ENOMEM; -+ -+ cur_freq = policy->cur; -+ next_higher_freq = policy->max; -+ -+ /* we're at the highest frequency in the table already, bail out */ -+ if (cur_freq == policy->max) -+ return -EINVAL; -+ -+ /* walk the list, find closest freq to cur_freq that is above it */ -+ while(table[i].frequency != CPUFREQ_TABLE_END) { -+ if (table[i].frequency > cur_freq && -+ table[i].frequency <= next_higher_freq) { -+ next_higher_freq = table[i].frequency; -+ optimal_index = table[i].index; -+ } -+ -+ i++; -+ } -+ -+ *index = optimal_index; -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_next_highest); -+ - static DEFINE_PER_CPU(struct cpufreq_frequency_table *, cpufreq_show_table); - /** - * show_available_freqs - show available frequencies for the specified CPU -diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h -index 9343dd3..a38fca8 100644 ---- a/include/linux/cpufreq.h -+++ b/include/linux/cpufreq.h -@@ -396,6 +396,15 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, - - void cpufreq_frequency_table_put_attr(unsigned int cpu); - -+/* the following are for use in governors, or anywhere else */ -+extern int cpufreq_frequency_table_next_lowest(struct cpufreq_policy *policy, -+ struct cpufreq_frequency_table *table, -+ int *index); -+ -+extern int cpufreq_frequency_table_next_highest(struct cpufreq_policy *policy, -+ struct cpufreq_frequency_table *table, -+ int *index); -+ - - /********************************************************************* - * UNIFIED DEBUG HELPERS * --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0002-cpufreq-introduce-hotplug-governor.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0002-cpufreq-introduce-hotplug-governor.patch deleted file mode 100644 index 731906cc..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0002-cpufreq-introduce-hotplug-governor.patch +++ /dev/null @@ -1,879 +0,0 @@ -From e4c777d8314d7925e4895f00b3a7ebd64a4d830b Mon Sep 17 00:00:00 2001 -From: Mike Turquette -Date: Tue, 17 May 2011 09:43:09 -0500 -Subject: [PATCH 2/2] cpufreq: introduce hotplug governor - -The "hotplug" governor scales CPU frequency based on load, similar to -"ondemand". It scales up to the highest frequency when "up_threshold" -is crossed and scales down one frequency at a time when "down_threshold" -is crossed. Unlike those governors, target frequencies are determined -by directly accessing the CPUfreq frequency table, instead of taking -some percentage of maximum available frequency. - -The key difference in the "hotplug" governor is that it will disable -auxillary CPUs when the system is very idle, and enable them again once -the system becomes busy. This is achieved by averaging load over -multiple sampling periods; if CPUs were online or offlined based on a -single sampling period then thrashing will occur. - -Sysfs entries exist for "hotplug_in_sampling_periods" and for -"hotplug_out_sampling_periods" which determine how many consecutive -periods get averaged to determine if auxillery CPUs should be onlined or -offlined. Defaults are 5 periods and 20 periods respectively. -Otherwise the standard sysfs entries you might find for "ondemand" and -"conservative" governors are there. - -To use this governor it is assumed that your CPUfreq driver has -populated the CPUfreq table, CONFIG_NO_HZ is enabled and -CONFIG_HOTPLUG_CPU is enabled. - -Changes in V2: - Corrected default sampling periods - Optimized load history array resizing - Maintain load history when resizing array - Add locking to dbs_check_cpu - Switch from enable_nonboot_cpus to cpu_up - Switch from disable_nonboot_cpus to down_cpu - Fix some printks - Coding style around for-loops - -Signed-off-by: Mike Turquette -Signed-off-by: Santosh Shilimkar -Signed-off-by: Koen Kooi ---- - Documentation/cpu-freq/governors.txt | 28 ++ - drivers/cpufreq/Kconfig | 33 ++ - drivers/cpufreq/Makefile | 1 + - drivers/cpufreq/cpufreq_hotplug.c | 705 ++++++++++++++++++++++++++++++++++ - include/linux/cpufreq.h | 3 + - 5 files changed, 770 insertions(+), 0 deletions(-) - create mode 100644 drivers/cpufreq/cpufreq_hotplug.c - -diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt -index e74d0a2..c2e3d3d 100644 ---- a/Documentation/cpu-freq/governors.txt -+++ b/Documentation/cpu-freq/governors.txt -@@ -193,6 +193,34 @@ governor but for the opposite direction. For example when set to its - default value of '20' it means that if the CPU usage needs to be below - 20% between samples to have the frequency decreased. - -+ -+2.6 Hotplug -+----------- -+ -+The CPUfreq governor "hotplug" operates similary to "ondemand" and -+"conservative". It's decisions are based primarily on CPU load. Like -+"ondemand" the "hotplug" governor will ramp up to the highest frequency -+once the run-time tunable "up_threshold" parameter is crossed. Like -+"conservative", the "hotplug" governor exports a "down_threshold" -+parameter that is also tunable at run-time. When the "down_threshold" -+is crossed the CPU transitions to the next lowest frequency in the -+CPUfreq frequency table instead of decrementing the frequency based on a -+percentage of maximum load. -+ -+The main reason "hotplug" governor exists is for architectures requiring -+that only the master CPU be online in order to hit low-power states -+(C-states). OMAP4 is one such example of this. The "hotplug" governor -+is also helpful in reducing thermal output in devices with tight thermal -+constraints. -+ -+Auxillary CPUs are onlined/offline based on CPU load, but the decision -+to do so is made after averaging several sampling windows. This is to -+reduce CPU hotplug "thrashing", which can be caused by normal system -+entropy and leads to lots of spurious plug-in and plug-out transitions. -+The number of sampling periods averaged together is tunable via the -+"hotplug_in_sampling_periods" and "hotplug_out_sampling_periods" -+run-time tunable parameters. -+ - 3. The Governor Interface in the CPUfreq Core - ============================================= - -diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig -index ca8ee80..c716a0e 100644 ---- a/drivers/cpufreq/Kconfig -+++ b/drivers/cpufreq/Kconfig -@@ -110,6 +110,19 @@ 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_HOTPLUG -+ bool "hotplug" -+ select CPU_FREQ_GOV_HOTPLUG -+ select CPU_FREQ_GOV_PERFORMANCE -+ help -+ Use the CPUFreq governor 'hotplug' as default. This allows you -+ to get a full dynamic frequency capable system with CPU -+ hotplug support by simply loading your cpufreq low-level -+ hardware driver. Be aware that not all cpufreq drivers -+ support the hotplug 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 -@@ -190,4 +203,24 @@ config CPU_FREQ_GOV_CONSERVATIVE - - If in doubt, say N. - -+config CPU_FREQ_GOV_HOTPLUG -+ tristate "'hotplug' cpufreq governor" -+ depends on CPU_FREQ && NO_HZ && HOTPLUG_CPU -+ help -+ 'hotplug' - this driver mimics the frequency scaling behavior -+ in 'ondemand', but with several key differences. First is -+ that frequency transitions use the CPUFreq table directly, -+ instead of incrementing in a percentage of the maximum -+ available frequency. Second 'hotplug' will offline auxillary -+ CPUs when the system is idle, and online those CPUs once the -+ system becomes busy again. This last feature is needed for -+ architectures which transition to low power states when only -+ the "master" CPU is online, or for thermally constrained -+ devices. -+ -+ If you don't have one of these architectures or devices, use -+ 'ondemand' instead. -+ -+ If in doubt, say N. -+ - endif # CPU_FREQ -diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile -index 71fc3b4..05d564c 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_HOTPLUG) += cpufreq_hotplug.o - - # CPUfreq cross-arch helpers - obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o -diff --git a/drivers/cpufreq/cpufreq_hotplug.c b/drivers/cpufreq/cpufreq_hotplug.c -new file mode 100644 -index 0000000..85aa6d2 ---- /dev/null -+++ b/drivers/cpufreq/cpufreq_hotplug.c -@@ -0,0 +1,705 @@ -+/* -+ * CPUFreq hotplug governor -+ * -+ * Copyright (C) 2010 Texas Instruments, Inc. -+ * Mike Turquette -+ * Santosh Shilimkar -+ * -+ * Based on ondemand governor -+ * Copyright (C) 2001 Russell King -+ * (C) 2003 Venkatesh Pallipadi , -+ * Jun Nakajima -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* greater than 80% avg load across online CPUs increases frequency */ -+#define DEFAULT_UP_FREQ_MIN_LOAD (80) -+ -+/* less than 20% avg load across online CPUs decreases frequency */ -+#define DEFAULT_DOWN_FREQ_MAX_LOAD (20) -+ -+/* default sampling period (uSec) is bogus; 10x ondemand's default for x86 */ -+#define DEFAULT_SAMPLING_PERIOD (100000) -+ -+/* default number of sampling periods to average before hotplug-in decision */ -+#define DEFAULT_HOTPLUG_IN_SAMPLING_PERIODS (5) -+ -+/* default number of sampling periods to average before hotplug-out decision */ -+#define DEFAULT_HOTPLUG_OUT_SAMPLING_PERIODS (20) -+ -+static void do_dbs_timer(struct work_struct *work); -+static int cpufreq_governor_dbs(struct cpufreq_policy *policy, -+ unsigned int event); -+ -+#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG -+static -+#endif -+struct cpufreq_governor cpufreq_gov_hotplug = { -+ .name = "hotplug", -+ .governor = cpufreq_governor_dbs, -+ .owner = THIS_MODULE, -+}; -+ -+struct cpu_dbs_info_s { -+ cputime64_t prev_cpu_idle; -+ cputime64_t prev_cpu_wall; -+ cputime64_t prev_cpu_nice; -+ struct cpufreq_policy *cur_policy; -+ struct delayed_work work; -+ struct cpufreq_frequency_table *freq_table; -+ int cpu; -+ /* -+ * percpu mutex that serializes governor limit change with -+ * do_dbs_timer invocation. We do not want do_dbs_timer to run -+ * when user is changing the governor or limits. -+ */ -+ struct mutex timer_mutex; -+}; -+static DEFINE_PER_CPU(struct cpu_dbs_info_s, hp_cpu_dbs_info); -+ -+static unsigned int dbs_enable; /* number of CPUs using this policy */ -+ -+/* -+ * dbs_mutex protects data in dbs_tuners_ins from concurrent changes on -+ * different CPUs. It protects dbs_enable in governor start/stop. -+ */ -+static DEFINE_MUTEX(dbs_mutex); -+ -+static struct workqueue_struct *khotplug_wq; -+ -+static struct dbs_tuners { -+ unsigned int sampling_rate; -+ unsigned int up_threshold; -+ unsigned int down_threshold; -+ unsigned int hotplug_in_sampling_periods; -+ unsigned int hotplug_out_sampling_periods; -+ unsigned int hotplug_load_index; -+ unsigned int *hotplug_load_history; -+ unsigned int ignore_nice; -+ unsigned int io_is_busy; -+} dbs_tuners_ins = { -+ .sampling_rate = DEFAULT_SAMPLING_PERIOD, -+ .up_threshold = DEFAULT_UP_FREQ_MIN_LOAD, -+ .down_threshold = DEFAULT_DOWN_FREQ_MAX_LOAD, -+ .hotplug_in_sampling_periods = DEFAULT_HOTPLUG_IN_SAMPLING_PERIODS, -+ .hotplug_out_sampling_periods = DEFAULT_HOTPLUG_OUT_SAMPLING_PERIODS, -+ .hotplug_load_index = 0, -+ .ignore_nice = 0, -+ .io_is_busy = 0, -+}; -+ -+/* -+ * A corner case exists when switching io_is_busy at run-time: comparing idle -+ * times from a non-io_is_busy period to an io_is_busy period (or vice-versa) -+ * will misrepresent the actual change in system idleness. We ignore this -+ * corner case: enabling io_is_busy might cause freq increase and disabling -+ * might cause freq decrease, which probably matches the original intent. -+ */ -+static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) -+{ -+ u64 idle_time; -+ u64 iowait_time; -+ -+ /* cpufreq-hotplug always assumes CONFIG_NO_HZ */ -+ idle_time = get_cpu_idle_time_us(cpu, wall); -+ -+ /* add time spent doing I/O to idle time */ -+ if (dbs_tuners_ins.io_is_busy) { -+ iowait_time = get_cpu_iowait_time_us(cpu, wall); -+ /* cpufreq-hotplug always assumes CONFIG_NO_HZ */ -+ if (iowait_time != -1ULL && idle_time >= iowait_time) -+ idle_time -= iowait_time; -+ } -+ -+ return idle_time; -+} -+ -+/************************** sysfs interface ************************/ -+ -+/* XXX look at global sysfs macros in cpufreq.h, can those be used here? */ -+ -+/* cpufreq_hotplug Governor Tunables */ -+#define show_one(file_name, object) \ -+static ssize_t show_##file_name \ -+(struct kobject *kobj, struct attribute *attr, char *buf) \ -+{ \ -+ return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ -+} -+show_one(sampling_rate, sampling_rate); -+show_one(up_threshold, up_threshold); -+show_one(down_threshold, down_threshold); -+show_one(hotplug_in_sampling_periods, hotplug_in_sampling_periods); -+show_one(hotplug_out_sampling_periods, hotplug_out_sampling_periods); -+show_one(ignore_nice_load, ignore_nice); -+show_one(io_is_busy, io_is_busy); -+ -+static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b, -+ const char *buf, size_t count) -+{ -+ unsigned int input; -+ int ret; -+ ret = sscanf(buf, "%u", &input); -+ if (ret != 1) -+ return -EINVAL; -+ -+ mutex_lock(&dbs_mutex); -+ dbs_tuners_ins.sampling_rate = input; -+ mutex_unlock(&dbs_mutex); -+ -+ return count; -+} -+ -+static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, -+ const char *buf, size_t count) -+{ -+ unsigned int input; -+ int ret; -+ ret = sscanf(buf, "%u", &input); -+ -+ if (ret != 1 || input <= dbs_tuners_ins.down_threshold) { -+ return -EINVAL; -+ } -+ -+ mutex_lock(&dbs_mutex); -+ dbs_tuners_ins.up_threshold = input; -+ mutex_unlock(&dbs_mutex); -+ -+ return count; -+} -+ -+static ssize_t store_down_threshold(struct kobject *a, struct attribute *b, -+ const char *buf, size_t count) -+{ -+ unsigned int input; -+ int ret; -+ ret = sscanf(buf, "%u", &input); -+ -+ if (ret != 1 || input >= dbs_tuners_ins.up_threshold) { -+ return -EINVAL; -+ } -+ -+ mutex_lock(&dbs_mutex); -+ dbs_tuners_ins.down_threshold = input; -+ mutex_unlock(&dbs_mutex); -+ -+ return count; -+} -+ -+static ssize_t store_hotplug_in_sampling_periods(struct kobject *a, -+ struct attribute *b, const char *buf, size_t count) -+{ -+ unsigned int input; -+ unsigned int *temp; -+ unsigned int max_windows; -+ int ret; -+ ret = sscanf(buf, "%u", &input); -+ -+ if (ret != 1) -+ return -EINVAL; -+ -+ /* already using this value, bail out */ -+ if (input == dbs_tuners_ins.hotplug_in_sampling_periods) -+ return count; -+ -+ mutex_lock(&dbs_mutex); -+ ret = count; -+ max_windows = max(dbs_tuners_ins.hotplug_in_sampling_periods, -+ dbs_tuners_ins.hotplug_out_sampling_periods); -+ -+ /* no need to resize array */ -+ if (input <= max_windows) { -+ dbs_tuners_ins.hotplug_in_sampling_periods = input; -+ goto out; -+ } -+ -+ /* resize array */ -+ temp = kmalloc((sizeof(unsigned int) * input), GFP_KERNEL); -+ -+ if (!temp || IS_ERR(temp)) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ memcpy(temp, dbs_tuners_ins.hotplug_load_history, -+ (max_windows * sizeof(unsigned int))); -+ kfree(dbs_tuners_ins.hotplug_load_history); -+ -+ /* replace old buffer, old number of sampling periods & old index */ -+ dbs_tuners_ins.hotplug_load_history = temp; -+ dbs_tuners_ins.hotplug_in_sampling_periods = input; -+ dbs_tuners_ins.hotplug_load_index = max_windows; -+out: -+ mutex_unlock(&dbs_mutex); -+ -+ return ret; -+} -+ -+static ssize_t store_hotplug_out_sampling_periods(struct kobject *a, -+ struct attribute *b, const char *buf, size_t count) -+{ -+ unsigned int input; -+ unsigned int *temp; -+ unsigned int max_windows; -+ int ret; -+ ret = sscanf(buf, "%u", &input); -+ -+ if (ret != 1) -+ return -EINVAL; -+ -+ /* already using this value, bail out */ -+ if (input == dbs_tuners_ins.hotplug_out_sampling_periods) -+ return count; -+ -+ mutex_lock(&dbs_mutex); -+ ret = count; -+ max_windows = max(dbs_tuners_ins.hotplug_in_sampling_periods, -+ dbs_tuners_ins.hotplug_out_sampling_periods); -+ -+ /* no need to resize array */ -+ if (input <= max_windows) { -+ dbs_tuners_ins.hotplug_out_sampling_periods = input; -+ goto out; -+ } -+ -+ /* resize array */ -+ temp = kmalloc((sizeof(unsigned int) * input), GFP_KERNEL); -+ -+ if (!temp || IS_ERR(temp)) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ memcpy(temp, dbs_tuners_ins.hotplug_load_history, -+ (max_windows * sizeof(unsigned int))); -+ kfree(dbs_tuners_ins.hotplug_load_history); -+ -+ /* replace old buffer, old number of sampling periods & old index */ -+ dbs_tuners_ins.hotplug_load_history = temp; -+ dbs_tuners_ins.hotplug_out_sampling_periods = input; -+ dbs_tuners_ins.hotplug_load_index = max_windows; -+out: -+ mutex_unlock(&dbs_mutex); -+ -+ return ret; -+} -+ -+static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b, -+ const char *buf, size_t count) -+{ -+ unsigned int input; -+ int ret; -+ -+ unsigned int j; -+ -+ ret = sscanf(buf, "%u", &input); -+ if (ret != 1) -+ return -EINVAL; -+ -+ if (input > 1) -+ input = 1; -+ -+ mutex_lock(&dbs_mutex); -+ if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */ -+ mutex_unlock(&dbs_mutex); -+ return count; -+ } -+ dbs_tuners_ins.ignore_nice = input; -+ -+ /* we need to re-evaluate prev_cpu_idle */ -+ for_each_online_cpu(j) { -+ struct cpu_dbs_info_s *dbs_info; -+ dbs_info = &per_cpu(hp_cpu_dbs_info, j); -+ dbs_info->prev_cpu_idle = get_cpu_idle_time(j, -+ &dbs_info->prev_cpu_wall); -+ if (dbs_tuners_ins.ignore_nice) -+ dbs_info->prev_cpu_nice = kstat_cpu(j).cpustat.nice; -+ -+ } -+ mutex_unlock(&dbs_mutex); -+ -+ return count; -+} -+ -+static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, -+ const char *buf, size_t count) -+{ -+ unsigned int input; -+ int ret; -+ -+ ret = sscanf(buf, "%u", &input); -+ if (ret != 1) -+ return -EINVAL; -+ -+ mutex_lock(&dbs_mutex); -+ dbs_tuners_ins.io_is_busy = !!input; -+ mutex_unlock(&dbs_mutex); -+ -+ return count; -+} -+ -+define_one_global_rw(sampling_rate); -+define_one_global_rw(up_threshold); -+define_one_global_rw(down_threshold); -+define_one_global_rw(hotplug_in_sampling_periods); -+define_one_global_rw(hotplug_out_sampling_periods); -+define_one_global_rw(ignore_nice_load); -+define_one_global_rw(io_is_busy); -+ -+static struct attribute *dbs_attributes[] = { -+ &sampling_rate.attr, -+ &up_threshold.attr, -+ &down_threshold.attr, -+ &hotplug_in_sampling_periods.attr, -+ &hotplug_out_sampling_periods.attr, -+ &ignore_nice_load.attr, -+ &io_is_busy.attr, -+ NULL -+}; -+ -+static struct attribute_group dbs_attr_group = { -+ .attrs = dbs_attributes, -+ .name = "hotplug", -+}; -+ -+/************************** sysfs end ************************/ -+ -+static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) -+{ -+ /* combined load of all enabled CPUs */ -+ unsigned int total_load = 0; -+ /* single largest CPU load */ -+ unsigned int max_load = 0; -+ /* average load across all enabled CPUs */ -+ unsigned int avg_load = 0; -+ /* average load across multiple sampling periods for hotplug events */ -+ unsigned int hotplug_in_avg_load = 0; -+ unsigned int hotplug_out_avg_load = 0; -+ /* number of sampling periods averaged for hotplug decisions */ -+ unsigned int periods; -+ -+ struct cpufreq_policy *policy; -+ unsigned int index = 0; -+ unsigned int i, j; -+ -+ policy = this_dbs_info->cur_policy; -+ -+ /* -+ * cpu load accounting -+ * get highest load, total load and average load across all CPUs -+ */ -+ for_each_cpu(j, policy->cpus) { -+ unsigned int load; -+ unsigned int idle_time, wall_time; -+ cputime64_t cur_wall_time, cur_idle_time; -+ struct cpu_dbs_info_s *j_dbs_info; -+ -+ j_dbs_info = &per_cpu(hp_cpu_dbs_info, j); -+ -+ /* update both cur_idle_time and cur_wall_time */ -+ cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); -+ -+ /* how much wall time has passed since last iteration? */ -+ wall_time = (unsigned int) cputime64_sub(cur_wall_time, -+ j_dbs_info->prev_cpu_wall); -+ j_dbs_info->prev_cpu_wall = cur_wall_time; -+ -+ /* how much idle time has passed since last iteration? */ -+ idle_time = (unsigned int) cputime64_sub(cur_idle_time, -+ j_dbs_info->prev_cpu_idle); -+ j_dbs_info->prev_cpu_idle = cur_idle_time; -+ -+ if (unlikely(!wall_time || wall_time < idle_time)) -+ continue; -+ -+ /* load is the percentage of time not spent in idle */ -+ load = 100 * (wall_time - idle_time) / wall_time; -+ -+ /* keep track of combined load across all CPUs */ -+ total_load += load; -+ -+ /* keep track of highest single load across all CPUs */ -+ if (load > max_load) -+ max_load = load; -+ } -+ -+ /* calculate the average load across all related CPUs */ -+ avg_load = total_load / num_online_cpus(); -+ -+ -+ /* -+ * hotplug load accounting -+ * average load over multiple sampling periods -+ */ -+ -+ /* how many sampling periods do we use for hotplug decisions? */ -+ periods = max(dbs_tuners_ins.hotplug_in_sampling_periods, -+ dbs_tuners_ins.hotplug_out_sampling_periods); -+ -+ /* store avg_load in the circular buffer */ -+ dbs_tuners_ins.hotplug_load_history[dbs_tuners_ins.hotplug_load_index] -+ = avg_load; -+ -+ /* compute average load across in & out sampling periods */ -+ for (i = 0, j = dbs_tuners_ins.hotplug_load_index; -+ i < periods; i++, j--) { -+ if (i < dbs_tuners_ins.hotplug_in_sampling_periods) -+ hotplug_in_avg_load += -+ dbs_tuners_ins.hotplug_load_history[j]; -+ if (i < dbs_tuners_ins.hotplug_out_sampling_periods) -+ hotplug_out_avg_load += -+ dbs_tuners_ins.hotplug_load_history[j]; -+ -+ if (j == 0) -+ j = periods; -+ } -+ -+ hotplug_in_avg_load = hotplug_in_avg_load / -+ dbs_tuners_ins.hotplug_in_sampling_periods; -+ -+ hotplug_out_avg_load = hotplug_out_avg_load / -+ dbs_tuners_ins.hotplug_out_sampling_periods; -+ -+ /* return to first element if we're at the circular buffer's end */ -+ if (++dbs_tuners_ins.hotplug_load_index == periods) -+ dbs_tuners_ins.hotplug_load_index = 0; -+ -+ /* check for frequency increase */ -+ if (avg_load > dbs_tuners_ins.up_threshold) { -+ /* should we enable auxillary CPUs? */ -+ if (num_online_cpus() < 2 && hotplug_in_avg_load > -+ dbs_tuners_ins.up_threshold) { -+ /* hotplug with cpufreq is nasty -+ * a call to cpufreq_governor_dbs may cause a lockup. -+ * wq is not running here so its safe. -+ */ -+ mutex_unlock(&this_dbs_info->timer_mutex); -+ cpu_up(1); -+ mutex_lock(&this_dbs_info->timer_mutex); -+ goto out; -+ } -+ -+ /* increase to highest frequency supported */ -+ if (policy->cur < policy->max) -+ __cpufreq_driver_target(policy, policy->max, -+ CPUFREQ_RELATION_H); -+ -+ goto out; -+ } -+ -+ /* check for frequency decrease */ -+ if (avg_load < dbs_tuners_ins.down_threshold) { -+ /* are we at the minimum frequency already? */ -+ if (policy->cur == policy->min) { -+ /* should we disable auxillary CPUs? */ -+ if (num_online_cpus() > 1 && hotplug_out_avg_load < -+ dbs_tuners_ins.down_threshold) { -+ mutex_unlock(&this_dbs_info->timer_mutex); -+ cpu_down(1); -+ mutex_lock(&this_dbs_info->timer_mutex); -+ } -+ goto out; -+ } -+ -+ /* bump down to the next lowest frequency in the table */ -+ if (cpufreq_frequency_table_next_lowest(policy, -+ this_dbs_info->freq_table, &index)) { -+ pr_err("%s: failed to get next lowest frequency\n", -+ __func__); -+ goto out; -+ } -+ -+ __cpufreq_driver_target(policy, -+ this_dbs_info->freq_table[index].frequency, -+ CPUFREQ_RELATION_L); -+ } -+out: -+ return; -+} -+ -+static void do_dbs_timer(struct work_struct *work) -+{ -+ struct cpu_dbs_info_s *dbs_info = -+ container_of(work, struct cpu_dbs_info_s, work.work); -+ unsigned int cpu = dbs_info->cpu; -+ -+ /* We want all related CPUs to do sampling nearly on same jiffy */ -+ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); -+ -+ mutex_lock(&dbs_info->timer_mutex); -+ dbs_check_cpu(dbs_info); -+ queue_delayed_work_on(cpu, khotplug_wq, &dbs_info->work, delay); -+ mutex_unlock(&dbs_info->timer_mutex); -+} -+ -+static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) -+{ -+ /* We want all related CPUs to do sampling nearly on same jiffy */ -+ int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); -+ delay -= jiffies % delay; -+ -+ INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); -+ queue_delayed_work_on(dbs_info->cpu, khotplug_wq, &dbs_info->work, -+ delay); -+} -+ -+static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) -+{ -+ cancel_delayed_work_sync(&dbs_info->work); -+} -+ -+static int cpufreq_governor_dbs(struct cpufreq_policy *policy, -+ unsigned int event) -+{ -+ unsigned int cpu = policy->cpu; -+ struct cpu_dbs_info_s *this_dbs_info; -+ unsigned int i, j, max_periods; -+ int rc; -+ -+ this_dbs_info = &per_cpu(hp_cpu_dbs_info, cpu); -+ -+ switch (event) { -+ case CPUFREQ_GOV_START: -+ if ((!cpu_online(cpu)) || (!policy->cur)) -+ return -EINVAL; -+ -+ mutex_lock(&dbs_mutex); -+ dbs_enable++; -+ for_each_cpu(j, policy->cpus) { -+ struct cpu_dbs_info_s *j_dbs_info; -+ j_dbs_info = &per_cpu(hp_cpu_dbs_info, j); -+ j_dbs_info->cur_policy = policy; -+ -+ j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j, -+ &j_dbs_info->prev_cpu_wall); -+ if (dbs_tuners_ins.ignore_nice) { -+ j_dbs_info->prev_cpu_nice = -+ kstat_cpu(j).cpustat.nice; -+ } -+ -+ max_periods = max(DEFAULT_HOTPLUG_IN_SAMPLING_PERIODS, -+ DEFAULT_HOTPLUG_OUT_SAMPLING_PERIODS); -+ dbs_tuners_ins.hotplug_load_history = kmalloc( -+ (sizeof(unsigned int) * max_periods), -+ GFP_KERNEL); -+ if (!dbs_tuners_ins.hotplug_load_history) { -+ WARN_ON(1); -+ return -ENOMEM; -+ } -+ for (i = 0; i < max_periods; i++) -+ dbs_tuners_ins.hotplug_load_history[i] = 50; -+ } -+ this_dbs_info->cpu = cpu; -+ this_dbs_info->freq_table = cpufreq_frequency_get_table(cpu); -+ /* -+ * Start the timerschedule work, when this governor -+ * is used for first time -+ */ -+ if (dbs_enable == 1) { -+ rc = sysfs_create_group(cpufreq_global_kobject, -+ &dbs_attr_group); -+ if (rc) { -+ mutex_unlock(&dbs_mutex); -+ return rc; -+ } -+ } -+ mutex_unlock(&dbs_mutex); -+ -+ mutex_init(&this_dbs_info->timer_mutex); -+ dbs_timer_init(this_dbs_info); -+ break; -+ -+ case CPUFREQ_GOV_STOP: -+ dbs_timer_exit(this_dbs_info); -+ -+ mutex_lock(&dbs_mutex); -+ mutex_destroy(&this_dbs_info->timer_mutex); -+ dbs_enable--; -+ mutex_unlock(&dbs_mutex); -+ if (!dbs_enable) -+ sysfs_remove_group(cpufreq_global_kobject, -+ &dbs_attr_group); -+ kfree(dbs_tuners_ins.hotplug_load_history); -+ /* -+ * XXX BIG CAVEAT: Stopping the governor with CPU1 offline -+ * will result in it remaining offline until the user onlines -+ * it again. It is up to the user to do this (for now). -+ */ -+ break; -+ -+ case CPUFREQ_GOV_LIMITS: -+ mutex_lock(&this_dbs_info->timer_mutex); -+ if (policy->max < this_dbs_info->cur_policy->cur) -+ __cpufreq_driver_target(this_dbs_info->cur_policy, -+ policy->max, CPUFREQ_RELATION_H); -+ else if (policy->min > this_dbs_info->cur_policy->cur) -+ __cpufreq_driver_target(this_dbs_info->cur_policy, -+ policy->min, CPUFREQ_RELATION_L); -+ mutex_unlock(&this_dbs_info->timer_mutex); -+ break; -+ } -+ return 0; -+} -+ -+static int __init cpufreq_gov_dbs_init(void) -+{ -+ int err; -+ cputime64_t wall; -+ u64 idle_time; -+ int cpu = get_cpu(); -+ -+ idle_time = get_cpu_idle_time_us(cpu, &wall); -+ put_cpu(); -+ if (idle_time != -1ULL) { -+ dbs_tuners_ins.up_threshold = DEFAULT_UP_FREQ_MIN_LOAD; -+ } else { -+ pr_err("cpufreq-hotplug: %s: assumes CONFIG_NO_HZ\n", -+ __func__); -+ return -EINVAL; -+ } -+ -+ khotplug_wq = create_workqueue("khotplug"); -+ if (!khotplug_wq) { -+ pr_err("Creation of khotplug failed\n"); -+ return -EFAULT; -+ } -+ err = cpufreq_register_governor(&cpufreq_gov_hotplug); -+ if (err) -+ destroy_workqueue(khotplug_wq); -+ -+ return err; -+} -+ -+static void __exit cpufreq_gov_dbs_exit(void) -+{ -+ cpufreq_unregister_governor(&cpufreq_gov_hotplug); -+ destroy_workqueue(khotplug_wq); -+} -+ -+MODULE_AUTHOR("Mike Turquette "); -+MODULE_DESCRIPTION("'cpufreq_hotplug' - cpufreq governor for dynamic frequency scaling and CPU hotplugging"); -+MODULE_LICENSE("GPL"); -+ -+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_HOTPLUG -+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 a38fca8..6cbc3df 100644 ---- a/include/linux/cpufreq.h -+++ b/include/linux/cpufreq.h -@@ -355,6 +355,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_HOTPLUG) -+extern struct cpufreq_governor cpufreq_gov_hotplug; -+#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_hotplug) - #endif - - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0001-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0001-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch deleted file mode 100644 index d150dfc6..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0001-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 33668b07abd5e66a263cc8b4b88587646f38bed0 Mon Sep 17 00:00:00 2001 -From: Peter 'p2' De Schrijver -Date: Wed, 11 Aug 2010 17:02:43 -0700 -Subject: [PATCH 1/8] OMAP: CPUfreq: ensure driver initializes after cpufreq framework and governors - -Signed-off-by: Peter 'p2' De Schrijver -Signed-off-by: Kevin Hilman ---- - arch/arm/plat-omap/cpu-omap.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c -index da4f68d..cd09d4b 100644 ---- a/arch/arm/plat-omap/cpu-omap.c -+++ b/arch/arm/plat-omap/cpu-omap.c -@@ -160,7 +160,7 @@ static int __init omap_cpufreq_init(void) - return cpufreq_register_driver(&omap_driver); - } - --arch_initcall(omap_cpufreq_init); -+late_initcall(omap_cpufreq_init); - - /* - * if ever we want to remove this, upon cleanup call: --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0002-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0002-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch deleted file mode 100644 index d62e04d1..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0002-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch +++ /dev/null @@ -1,31 +0,0 @@ -From e89b1544450fb8410a44004e48d6b330bc39f0ce Mon Sep 17 00:00:00 2001 -From: Kevin Hilman -Date: Wed, 11 Aug 2010 17:05:38 -0700 -Subject: [PATCH 2/8] OMAP: CPUfreq: ensure policy is fully initialized - -Ensure policy min/max/cur values are initialized when OMAP -CPUfreq driver starts. - -Signed-off-by: Kevin Hilman ---- - arch/arm/plat-omap/cpu-omap.c | 4 ++++ - 1 files changed, 4 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c -index cd09d4b..1b36664 100644 ---- a/arch/arm/plat-omap/cpu-omap.c -+++ b/arch/arm/plat-omap/cpu-omap.c -@@ -126,6 +126,10 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - VERY_HI_RATE) / 1000; - } - -+ policy->min = policy->cpuinfo.min_freq; -+ policy->max = policy->cpuinfo.max_freq; -+ policy->cur = omap_getspeed(0); -+ - /* FIXME: what's the actual transition time? */ - policy->cpuinfo.transition_latency = 300 * 1000; - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch deleted file mode 100644 index fbe16213..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch +++ /dev/null @@ -1,263 +0,0 @@ -From 948b868e4a83b054e8a58362238bc6cd61c0aeab Mon Sep 17 00:00:00 2001 -From: Rajendra Nayak -Date: Mon, 10 Nov 2008 17:00:25 +0530 -Subject: [PATCH 3/8] OMAP3 PM: CPUFreq driver for OMAP3 - -CPUFreq driver for OMAP3 - -With additional fixes and cleanups from Tero Kristo: -- Fix rate calculation bug in omap3_select_table_rate -- Refreshed DVFS VDD1 control against latest clock fw - -Signed-off-by: Tero Kristo -Signed-off-by: Rajendra Nayak - -OMAP3: PM: CPUFreq: Fix omap_getspeed. - -Signed-off-by: Peter 'p2' De Schrijver - -Make sure omap cpufreq driver initializes after cpufreq framework and governors - -Signed-off-by: Peter 'p2' De Schrijver - -merge: CPUFreq: remove obsolete funcs - -OMAP3 clock: Update cpufreq driver - -This patch removes all refrences to virtual clock -nodes in CPUFreq driver. - -Signed-off-by: Rajendra Nayak -Signed-off-by: Tero Kristo -Signed-off-by: Jean Pihet - -PM: Prevent direct cpufreq scaling during initialization - -It is seen that the OMAP specific cpufreq initialization code tries to -scale the MPU frequency to the highest possible without taking care of -the voltage level. On power on reset the power IC does not provide the -necessary voltage for the highest available MPU frequency (that would -satisfy all Si families). This potentially is an window of opportunity -for things to go wrong. - -Signed-off-by: Romit Dasgupta -Signed-off-by: Kevin Hilman - -OMAP3: PM: enable 600MHz (overdrive) OPP - -Signed-off-by: Kevin Hilman - -omap3: introduce cpufreq - -OMAP OPP layer functions now have dependencies of CONFIG_CPU_FREQ only. - -With this patch, omap opp layer now has its compilation flags -bound to CONFIG_CPU_FREQ. Also its code has been removed from pm34xx.c. - -A new file has been created to contain cpu freq code related to -OMAP3: cpufreq34xx.c - -OMAP34xx and OMAP36xx family OPPs are made available - -Signed-off-by: Eduardo Valentin -Signed-off-by: Paul Walmsley -Signed-off-by: Nishanth Menon -Signed-off-by: Vishwanath BS -Signed-off-by: Kevin Hilman -Signed-off-by: Romit Dasgupta -Signed-off-by: Rajendra Nayak - -omap3: cpufreq: allow default opp table init - -For board files which choose to override the defaults, the existing -mechanism will work, for boards that would like to work with defaults, -allow init_common_hw to call init_opp_table to initialize if not -already initialized. this will allow all omap boards which have opp -tables predefined for a silicon to use the same. - -Originally reported for overo: -http://marc.info/?t=127265269400004&r=1&w=2 - -Signed-off-by: Nishanth Menon -Reported-by: Peter Tseng -Cc: Cliff Brake -Cc: Kevin Hilman - -OMAP2: update OPP data to be device based - -Cc: Nishanth Menon -Signed-off-by: Kevin Hilman - -OMAP3: CPUfreq: update to device-based OPP API - -Update usage of OPP API to use new device-based API. This requires -getting the 'struct device' for the MPU and using that with the OPP -API. - -Signed-off-by: Kevin Hilman - -omap3: opp: make independent of cpufreq - -Make opp3xx data which is registered with the opp layer -dependent purely on CONFIG_PM as opp layer and pm.c users -are CONFIG_PM dependent not cpufreq dependent. -so we rename the data definition to opp3xxx_data.c (inline with what -we have for omap2), also move the build definition to be under -the existing CONFIG_PM build instead of CPUFREQ. - -Cc: Eduardo Valentin -Cc: Kevin Hilman -Cc: Paul Walmsley -Cc: Rajendra Nayak -Cc: Sanjeev Premi -Cc: Thara Gopinath -Cc: Tony Lindgren - -Signed-off-by: Nishanth Menon ---- - arch/arm/mach-omap2/clock.h | 14 +++++++++++++- - arch/arm/mach-omap2/clock34xx.c | 2 ++ - arch/arm/plat-omap/cpu-omap.c | 34 +++++++++++++++++++++++++++++++--- - 3 files changed, 46 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h -index e10ff2b..0a07e50 100644 ---- a/arch/arm/mach-omap2/clock.h -+++ b/arch/arm/mach-omap2/clock.h -@@ -141,7 +141,9 @@ extern const struct clksel_rate gpt_sys_rates[]; - extern const struct clksel_rate gfx_l3_rates[]; - extern const struct clksel_rate dsp_ick_rates[]; - --#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_CPU_FREQ) -+#ifdef CONFIG_CPU_FREQ -+ -+#ifdef CONFIG_ARCH_OMAP2 - extern void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); - extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); - #else -@@ -149,6 +151,16 @@ extern void omap2_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table) - #define omap2_clk_exit_cpufreq_table 0 - #endif - -+#ifdef CONFIG_ARCH_OMAP3 -+extern void omap3_clk_init_cpufreq_table(struct cpufreq_frequency_table **table); -+extern void omap3_clk_exit_cpufreq_table(struct cpufreq_frequency_table **table); -+#else -+#define omap3_clk_init_cpufreq_table 0 -+#define omap3_clk_exit_cpufreq_table 0 -+#endif -+ -+#endif /* CONFIG_CPU_FREQ */ -+ - extern const struct clkops clkops_omap2_iclk_dflt_wait; - extern const struct clkops clkops_omap2_iclk_dflt; - extern const struct clkops clkops_omap2_iclk_idle_only; -diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c -index 1fc96b9..119e135 100644 ---- a/arch/arm/mach-omap2/clock34xx.c -+++ b/arch/arm/mach-omap2/clock34xx.c -@@ -20,6 +20,8 @@ - #include - #include - #include -+#include -+#include - - #include - -diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c -index 1b36664..f0f9430 100644 ---- a/arch/arm/plat-omap/cpu-omap.c -+++ b/arch/arm/plat-omap/cpu-omap.c -@@ -8,6 +8,10 @@ - * - * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King - * -+ * Copyright (C) 2007-2008 Texas Instruments, Inc. -+ * Updated to support OMAP3 -+ * Rajendra Nayak -+ * - * 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. -@@ -26,12 +30,19 @@ - #include - #include - -+#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) -+#include -+#include -+#endif -+ - #define VERY_HI_RATE 900000000 - - static struct cpufreq_frequency_table *freq_table; - - #ifdef CONFIG_ARCH_OMAP1 - #define MPU_CLK "mpu" -+#elif CONFIG_ARCH_OMAP3 -+#define MPU_CLK "arm_fck" - #else - #define MPU_CLK "virt_prcm_set" - #endif -@@ -73,7 +84,13 @@ static int omap_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) - { -+#ifdef CONFIG_ARCH_OMAP1 - struct cpufreq_freqs freqs; -+#endif -+#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) -+ unsigned long freq; -+ struct device *mpu_dev = omap2_get_mpuss_device(); -+#endif - int ret = 0; - - /* Ensure desired rate is within allowed range. Some govenors -@@ -83,13 +100,13 @@ static int omap_target(struct cpufreq_policy *policy, - if (target_freq > policy->max) - target_freq = policy->max; - -+#ifdef CONFIG_ARCH_OMAP1 - freqs.old = omap_getspeed(0); - freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; - freqs.cpu = 0; - - if (freqs.old == freqs.new) - return ret; -- - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - #ifdef CONFIG_CPU_FREQ_DEBUG - printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n", -@@ -97,7 +114,11 @@ static int omap_target(struct cpufreq_policy *policy, - #endif - ret = clk_set_rate(mpu_clk, freqs.new * 1000); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -- -+#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) -+ freq = target_freq * 1000; -+ if (opp_find_freq_ceil(mpu_dev, &freq)) -+ omap_pm_cpu_set_freq(freq); -+#endif - return ret; - } - -@@ -114,7 +135,14 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - - policy->cur = policy->min = policy->max = omap_getspeed(0); - -- clk_init_cpufreq_table(&freq_table); -+ if (!cpu_is_omap34xx()) { -+ clk_init_cpufreq_table(&freq_table); -+ } else { -+ struct device *mpu_dev = omap2_get_mpuss_device(); -+ -+ opp_init_cpufreq_table(mpu_dev, &freq_table); -+ } -+ - if (freq_table) { - result = cpufreq_frequency_table_cpuinfo(policy, freq_table); - if (!result) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0004-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0004-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch deleted file mode 100644 index 36742e43..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0004-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 86227f1eb341e571163464cb0a412ed2179f2541 Mon Sep 17 00:00:00 2001 -From: Silesh C V -Date: Wed, 29 Sep 2010 14:52:54 +0530 -Subject: [PATCH 4/8] OMAP: PM: CPUFREQ: Fix conditional compilation - -Fix conditional compilation. A conditional expresiion -should follow "#elif", in this case #elif clause should -check whether CONFIG_ARCH_OMAP3 is defined or not -(ie. defined(CONFIG_ARCH_OMAP3)) rather than checking for -the value of the macro. - -Signed-off-by: Silesh C V ---- - arch/arm/plat-omap/cpu-omap.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c -index f0f9430..c3ac065 100644 ---- a/arch/arm/plat-omap/cpu-omap.c -+++ b/arch/arm/plat-omap/cpu-omap.c -@@ -41,7 +41,7 @@ static struct cpufreq_frequency_table *freq_table; - - #ifdef CONFIG_ARCH_OMAP1 - #define MPU_CLK "mpu" --#elif CONFIG_ARCH_OMAP3 -+#elif defined(CONFIG_ARCH_OMAP3) - #define MPU_CLK "arm_fck" - #else - #define MPU_CLK "virt_prcm_set" --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0005-cpufreq-fixup-after-new-OPP-layer-merged.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0005-cpufreq-fixup-after-new-OPP-layer-merged.patch deleted file mode 100644 index 7cf69325..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0005-cpufreq-fixup-after-new-OPP-layer-merged.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 4764137dd613362656726a15cb8184724aeb99bb Mon Sep 17 00:00:00 2001 -From: Kevin Hilman -Date: Tue, 16 Nov 2010 11:48:41 -0800 -Subject: [PATCH 5/8] cpufreq: fixup after new OPP layer merged - ---- - arch/arm/plat-omap/cpu-omap.c | 3 ++- - 1 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c -index c3ac065..9cd2709 100644 ---- a/arch/arm/plat-omap/cpu-omap.c -+++ b/arch/arm/plat-omap/cpu-omap.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -32,7 +33,7 @@ - - #if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) - #include --#include -+#include - #endif - - #define VERY_HI_RATE 900000000 --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0006-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0006-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch deleted file mode 100644 index cfc257e0..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0006-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch +++ /dev/null @@ -1,669 +0,0 @@ -From e16548716c5cbc3c9885d05f1654d83d5411a3a7 Mon Sep 17 00:00:00 2001 -From: Santosh Shilimkar -Date: Mon, 14 Mar 2011 17:08:48 +0530 -Subject: [PATCH 6/8] OMAP: cpufreq: Split OMAP1 and OMAP2PLUS CPUfreq drivers. - -This patch is an attempt to cleanup the #ifdeferry in the -omap CPUfreq drivers. - -The split betwenn OMAP1 and OMAP2PLUS is logical because - - OMAP1 doesn't support opp layer. - - OMAP1 build is seperate from omap2plus. - -Signed-off-by: Santosh Shilimkar -Cc: Kevin Hilman -Cc: Vishwanath BS ---- - arch/arm/mach-omap1/Makefile | 3 + - arch/arm/mach-omap1/omap1-cpufreq.c | 176 ++++++++++++++++++++++++++ - arch/arm/mach-omap2/Makefile | 3 + - arch/arm/mach-omap2/omap2plus-cpufreq.c | 201 ++++++++++++++++++++++++++++++ - arch/arm/plat-omap/Makefile | 1 - - arch/arm/plat-omap/cpu-omap.c | 204 ------------------------------- - 6 files changed, 383 insertions(+), 205 deletions(-) - create mode 100644 arch/arm/mach-omap1/omap1-cpufreq.c - create mode 100644 arch/arm/mach-omap2/omap2plus-cpufreq.c - delete mode 100644 arch/arm/plat-omap/cpu-omap.c - -diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile -index af98117..e5082b0 100644 ---- a/arch/arm/mach-omap1/Makefile -+++ b/arch/arm/mach-omap1/Makefile -@@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o - - obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o - -+# CPUFREQ driver -+obj-$(CONFIG_CPU_FREQ) += omap1-cpufreq.o -+ - # Power Management - obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o - -diff --git a/arch/arm/mach-omap1/omap1-cpufreq.c b/arch/arm/mach-omap1/omap1-cpufreq.c -new file mode 100644 -index 0000000..682cdc8 ---- /dev/null -+++ b/arch/arm/mach-omap1/omap1-cpufreq.c -@@ -0,0 +1,176 @@ -+/* -+ * OMAP1 cpufreq driver -+ * -+ * CPU frequency scaling for OMAP -+ * -+ * Copyright (C) 2005 Nokia Corporation -+ * Written by Tony Lindgren -+ * -+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King -+ * -+ * Copyright (C) 2007-2008 Texas Instruments, Inc. -+ * Updated to support OMAP3 -+ * Rajendra Nayak -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include -+ -+#define VERY_HI_RATE 900000000 -+ -+static struct cpufreq_frequency_table *freq_table; -+static struct clk *mpu_clk; -+ -+static int omap_verify_speed(struct cpufreq_policy *policy) -+{ -+ if (freq_table) -+ return cpufreq_frequency_table_verify(policy, freq_table); -+ -+ if (policy->cpu) -+ return -EINVAL; -+ -+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, -+ policy->cpuinfo.max_freq); -+ -+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; -+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; -+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, -+ policy->cpuinfo.max_freq); -+ return 0; -+} -+ -+static unsigned int omap_getspeed(unsigned int cpu) -+{ -+ unsigned long rate; -+ -+ if (cpu) -+ return 0; -+ -+ rate = clk_get_rate(mpu_clk) / 1000; -+ return rate; -+} -+ -+static int omap_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, -+ unsigned int relation) -+{ -+ struct cpufreq_freqs freqs; -+ int ret = 0; -+ -+ /* Ensure desired rate is within allowed range. Some govenors -+ * (ondemand) will just pass target_freq=0 to get the minimum. */ -+ if (target_freq < policy->min) -+ target_freq = policy->min; -+ if (target_freq > policy->max) -+ target_freq = policy->max; -+ -+ freqs.old = omap_getspeed(0); -+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; -+ freqs.cpu = 0; -+ -+ if (freqs.old == freqs.new) -+ return ret; -+ -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ -+#ifdef CONFIG_CPU_FREQ_DEBUG -+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new); -+#endif -+ ret = clk_set_rate(mpu_clk, freqs.new * 1000); -+ -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+ -+ return ret; -+} -+ -+static int __init omap_cpu_init(struct cpufreq_policy *policy) -+{ -+ int result = 0; -+ -+ mpu_clk = clk_get(NULL, "mpu"); -+ if (IS_ERR(mpu_clk)) -+ return PTR_ERR(mpu_clk); -+ -+ if (policy->cpu != 0) -+ return -EINVAL; -+ -+ policy->cur = policy->min = policy->max = omap_getspeed(0); -+ -+ clk_init_cpufreq_table(&freq_table); -+ -+ if (freq_table) { -+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table); -+ if (!result) -+ cpufreq_frequency_table_get_attr(freq_table, -+ policy->cpu); -+ } else { -+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; -+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, -+ VERY_HI_RATE) / 1000; -+ } -+ -+ policy->min = policy->cpuinfo.min_freq; -+ policy->max = policy->cpuinfo.max_freq; -+ policy->cur = omap_getspeed(0); -+ -+ /* FIXME: what's the actual transition time? */ -+ policy->cpuinfo.transition_latency = 300 * 1000; -+ -+ return 0; -+} -+ -+static int omap_cpu_exit(struct cpufreq_policy *policy) -+{ -+ clk_exit_cpufreq_table(&freq_table); -+ clk_put(mpu_clk); -+ return 0; -+} -+ -+static struct freq_attr *omap_cpufreq_attr[] = { -+ &cpufreq_freq_attr_scaling_available_freqs, -+ NULL, -+}; -+ -+static struct cpufreq_driver omap_driver = { -+ .flags = CPUFREQ_STICKY, -+ .verify = omap_verify_speed, -+ .target = omap_target, -+ .get = omap_getspeed, -+ .init = omap_cpu_init, -+ .exit = omap_cpu_exit, -+ .name = "omap1", -+ .attr = omap_cpufreq_attr, -+}; -+ -+static int __init omap_cpufreq_init(void) -+{ -+ return cpufreq_register_driver(&omap_driver); -+} -+ -+static void __exit omap_cpufreq_exit(void) -+{ -+ cpufreq_unregister_driver(&omap_driver); -+} -+ -+MODULE_DESCRIPTION("cpufreq driver for OMAP1 SOCs"); -+MODULE_LICENSE("GPL"); -+module_init(omap_cpufreq_init); -+module_exit(omap_cpufreq_exit); -diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile -index 05cd983..e9c2445 100644 ---- a/arch/arm/mach-omap2/Makefile -+++ b/arch/arm/mach-omap2/Makefile -@@ -56,6 +56,9 @@ obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o - obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o - endif - -+# CPUFREQ driver -+obj-$(CONFIG_CPU_FREQ) += omap2plus-cpufreq.o -+ - # Power Management - ifeq ($(CONFIG_PM),y) - obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o -diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c -new file mode 100644 -index 0000000..14f84cc ---- /dev/null -+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c -@@ -0,0 +1,201 @@ -+/* -+ * OMAP2PLUS cpufreq driver -+ * -+ * CPU frequency scaling for OMAP -+ * -+ * Copyright (C) 2005 Nokia Corporation -+ * Written by Tony Lindgren -+ * -+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King -+ * -+ * Copyright (C) 2007-2008 Texas Instruments, Inc. -+ * Updated to support OMAP3 -+ * Rajendra Nayak -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+ -+#define VERY_HI_RATE 900000000 -+ -+static struct cpufreq_frequency_table *freq_table; -+static struct clk *mpu_clk; -+ -+static int omap_verify_speed(struct cpufreq_policy *policy) -+{ -+ if (freq_table) -+ return cpufreq_frequency_table_verify(policy, freq_table); -+ -+ if (policy->cpu) -+ return -EINVAL; -+ -+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, -+ policy->cpuinfo.max_freq); -+ -+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; -+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; -+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, -+ policy->cpuinfo.max_freq); -+ return 0; -+} -+ -+static unsigned int omap_getspeed(unsigned int cpu) -+{ -+ unsigned long rate; -+ -+ if (cpu) -+ return 0; -+ -+ rate = clk_get_rate(mpu_clk) / 1000; -+ return rate; -+} -+ -+static int omap_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, -+ unsigned int relation) -+{ -+ int ret = 0; -+ struct cpufreq_freqs freqs; -+ -+ /* Ensure desired rate is within allowed range. Some govenors -+ * (ondemand) will just pass target_freq=0 to get the minimum. */ -+ if (target_freq < policy->min) -+ target_freq = policy->min; -+ if (target_freq > policy->max) -+ target_freq = policy->max; -+ -+ freqs.old = omap_getspeed(0); -+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; -+ freqs.cpu = 0; -+ -+ if (freqs.old == freqs.new) -+ return ret; -+ -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ -+#ifdef CONFIG_CPU_FREQ_DEBUG -+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new); -+#endif -+ -+ ret = clk_set_rate(mpu_clk, freqs.new * 1000); -+ -+ /* -+ * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies -+ * won't get updated when UP machine cpufreq build with -+ * CONFIG_SMP enabled. Below code is added only to manage that -+ * scenario -+ */ -+ if (!is_smp()) -+ loops_per_jiffy = -+ cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new); -+ -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+ -+ return ret; -+} -+ -+static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) -+{ -+ int result = 0; -+ struct device *mpu_dev; -+ -+ if (cpu_is_omap24xx()) -+ mpu_clk = clk_get(NULL, "virt_prcm_set"); -+ else if (cpu_is_omap34xx()) -+ mpu_clk = clk_get(NULL, "dpll1_ck"); -+ else if (cpu_is_omap34xx()) -+ mpu_clk = clk_get(NULL, "dpll_mpu_ck"); -+ -+ if (IS_ERR(mpu_clk)) -+ return PTR_ERR(mpu_clk); -+ -+ if (policy->cpu != 0) -+ return -EINVAL; -+ -+ policy->cur = policy->min = policy->max = omap_getspeed(0); -+ -+ mpu_dev = omap2_get_mpuss_device(); -+ if (!mpu_dev) { -+ pr_warning("%s: unable to get the mpu device\n", __func__); -+ return -EINVAL; -+ } -+ opp_init_cpufreq_table(mpu_dev, &freq_table); -+ -+ if (freq_table) { -+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table); -+ if (!result) -+ cpufreq_frequency_table_get_attr(freq_table, -+ policy->cpu); -+ } else { -+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; -+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, -+ VERY_HI_RATE) / 1000; -+ } -+ -+ policy->min = policy->cpuinfo.min_freq; -+ policy->max = policy->cpuinfo.max_freq; -+ policy->cur = omap_getspeed(0); -+ -+ /* FIXME: what's the actual transition time? */ -+ policy->cpuinfo.transition_latency = 300 * 1000; -+ -+ return 0; -+} -+ -+static int omap_cpu_exit(struct cpufreq_policy *policy) -+{ -+ clk_exit_cpufreq_table(&freq_table); -+ clk_put(mpu_clk); -+ return 0; -+} -+ -+static struct freq_attr *omap_cpufreq_attr[] = { -+ &cpufreq_freq_attr_scaling_available_freqs, -+ NULL, -+}; -+ -+static struct cpufreq_driver omap_driver = { -+ .flags = CPUFREQ_STICKY, -+ .verify = omap_verify_speed, -+ .target = omap_target, -+ .get = omap_getspeed, -+ .init = omap_cpu_init, -+ .exit = omap_cpu_exit, -+ .name = "omap2plus", -+ .attr = omap_cpufreq_attr, -+}; -+ -+static int __init omap_cpufreq_init(void) -+{ -+ return cpufreq_register_driver(&omap_driver); -+} -+ -+static void __exit omap_cpufreq_exit(void) -+{ -+ cpufreq_unregister_driver(&omap_driver); -+} -+ -+MODULE_DESCRIPTION("cpufreq driver for OMAP2PLUS SOCs"); -+MODULE_LICENSE("GPL"); -+module_init(omap_cpufreq_init); -+module_exit(omap_cpufreq_exit); -diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile -index a4a1285..ec7862e 100644 ---- a/arch/arm/plat-omap/Makefile -+++ b/arch/arm/plat-omap/Makefile -@@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o - obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o - obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o - --obj-$(CONFIG_CPU_FREQ) += cpu-omap.o - obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o - obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o - obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o -diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c -deleted file mode 100644 -index 9cd2709..0000000 ---- a/arch/arm/plat-omap/cpu-omap.c -+++ /dev/null -@@ -1,204 +0,0 @@ --/* -- * linux/arch/arm/plat-omap/cpu-omap.c -- * -- * CPU frequency scaling for OMAP -- * -- * Copyright (C) 2005 Nokia Corporation -- * Written by Tony Lindgren -- * -- * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King -- * -- * Copyright (C) 2007-2008 Texas Instruments, Inc. -- * Updated to support OMAP3 -- * Rajendra Nayak -- * -- * 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 --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include -- --#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) --#include --#include --#endif -- --#define VERY_HI_RATE 900000000 -- --static struct cpufreq_frequency_table *freq_table; -- --#ifdef CONFIG_ARCH_OMAP1 --#define MPU_CLK "mpu" --#elif defined(CONFIG_ARCH_OMAP3) --#define MPU_CLK "arm_fck" --#else --#define MPU_CLK "virt_prcm_set" --#endif -- --static struct clk *mpu_clk; -- --/* TODO: Add support for SDRAM timing changes */ -- --static int omap_verify_speed(struct cpufreq_policy *policy) --{ -- if (freq_table) -- return cpufreq_frequency_table_verify(policy, freq_table); -- -- if (policy->cpu) -- return -EINVAL; -- -- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, -- policy->cpuinfo.max_freq); -- -- policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; -- policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; -- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, -- policy->cpuinfo.max_freq); -- return 0; --} -- --static unsigned int omap_getspeed(unsigned int cpu) --{ -- unsigned long rate; -- -- if (cpu) -- return 0; -- -- rate = clk_get_rate(mpu_clk) / 1000; -- return rate; --} -- --static int omap_target(struct cpufreq_policy *policy, -- unsigned int target_freq, -- unsigned int relation) --{ --#ifdef CONFIG_ARCH_OMAP1 -- struct cpufreq_freqs freqs; --#endif --#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) -- unsigned long freq; -- struct device *mpu_dev = omap2_get_mpuss_device(); --#endif -- int ret = 0; -- -- /* Ensure desired rate is within allowed range. Some govenors -- * (ondemand) will just pass target_freq=0 to get the minimum. */ -- if (target_freq < policy->min) -- target_freq = policy->min; -- if (target_freq > policy->max) -- target_freq = policy->max; -- --#ifdef CONFIG_ARCH_OMAP1 -- freqs.old = omap_getspeed(0); -- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; -- freqs.cpu = 0; -- -- if (freqs.old == freqs.new) -- return ret; -- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); --#ifdef CONFIG_CPU_FREQ_DEBUG -- printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n", -- freqs.old, freqs.new); --#endif -- ret = clk_set_rate(mpu_clk, freqs.new * 1000); -- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); --#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE) -- freq = target_freq * 1000; -- if (opp_find_freq_ceil(mpu_dev, &freq)) -- omap_pm_cpu_set_freq(freq); --#endif -- return ret; --} -- --static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) --{ -- int result = 0; -- -- mpu_clk = clk_get(NULL, MPU_CLK); -- if (IS_ERR(mpu_clk)) -- return PTR_ERR(mpu_clk); -- -- if (policy->cpu != 0) -- return -EINVAL; -- -- policy->cur = policy->min = policy->max = omap_getspeed(0); -- -- if (!cpu_is_omap34xx()) { -- clk_init_cpufreq_table(&freq_table); -- } else { -- struct device *mpu_dev = omap2_get_mpuss_device(); -- -- opp_init_cpufreq_table(mpu_dev, &freq_table); -- } -- -- if (freq_table) { -- result = cpufreq_frequency_table_cpuinfo(policy, freq_table); -- if (!result) -- cpufreq_frequency_table_get_attr(freq_table, -- policy->cpu); -- } else { -- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; -- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, -- VERY_HI_RATE) / 1000; -- } -- -- policy->min = policy->cpuinfo.min_freq; -- policy->max = policy->cpuinfo.max_freq; -- policy->cur = omap_getspeed(0); -- -- /* FIXME: what's the actual transition time? */ -- policy->cpuinfo.transition_latency = 300 * 1000; -- -- return 0; --} -- --static int omap_cpu_exit(struct cpufreq_policy *policy) --{ -- clk_exit_cpufreq_table(&freq_table); -- clk_put(mpu_clk); -- return 0; --} -- --static struct freq_attr *omap_cpufreq_attr[] = { -- &cpufreq_freq_attr_scaling_available_freqs, -- NULL, --}; -- --static struct cpufreq_driver omap_driver = { -- .flags = CPUFREQ_STICKY, -- .verify = omap_verify_speed, -- .target = omap_target, -- .get = omap_getspeed, -- .init = omap_cpu_init, -- .exit = omap_cpu_exit, -- .name = "omap", -- .attr = omap_cpufreq_attr, --}; -- --static int __init omap_cpufreq_init(void) --{ -- return cpufreq_register_driver(&omap_driver); --} -- --late_initcall(omap_cpufreq_init); -- --/* -- * if ever we want to remove this, upon cleanup call: -- * -- * cpufreq_unregister_driver() -- * cpufreq_frequency_table_put_attr() -- */ -- --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch deleted file mode 100644 index 6624d1ec..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch +++ /dev/null @@ -1,170 +0,0 @@ -From f375d3c39d2835929d34c2a046b8c43cea6d1467 Mon Sep 17 00:00:00 2001 -From: Santosh Shilimkar -Date: Mon, 14 Mar 2011 17:08:49 +0530 -Subject: [PATCH 7/8] OMAP2PLUS: cpufreq: Add SMP support to cater OMAP4430 - -On OMAP SMP configuartion, both processors share the voltage -and clock. So both CPUs needs to be scaled together and hence -needs software co-ordination. - -Signed-off-by: Santosh Shilimkar -Cc: Kevin Hilman -cc: Vishwanath BS ---- - arch/arm/mach-omap2/omap2plus-cpufreq.c | 73 ++++++++++++++++++++++++++----- - 1 files changed, 62 insertions(+), 11 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c -index 14f84cc..8d472f6 100644 ---- a/arch/arm/mach-omap2/omap2plus-cpufreq.c -+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c -@@ -26,9 +26,11 @@ - #include - #include - #include -+#include - - #include - #include -+#include - - #include - #include -@@ -63,7 +65,7 @@ static unsigned int omap_getspeed(unsigned int cpu) - { - unsigned long rate; - -- if (cpu) -+ if (cpu >= NR_CPUS) - return 0; - - rate = clk_get_rate(mpu_clk) / 1000; -@@ -74,9 +76,13 @@ static int omap_target(struct cpufreq_policy *policy, - unsigned int target_freq, - unsigned int relation) - { -- int ret = 0; -+ int i, ret = 0; - struct cpufreq_freqs freqs; - -+ /* Changes not allowed until all CPUs are online */ -+ if (is_smp() && (num_online_cpus() < NR_CPUS)) -+ return ret; -+ - /* Ensure desired rate is within allowed range. Some govenors - * (ondemand) will just pass target_freq=0 to get the minimum. */ - if (target_freq < policy->min) -@@ -84,15 +90,25 @@ static int omap_target(struct cpufreq_policy *policy, - if (target_freq > policy->max) - target_freq = policy->max; - -- freqs.old = omap_getspeed(0); -+ freqs.old = omap_getspeed(policy->cpu); - freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; -- freqs.cpu = 0; -+ freqs.cpu = policy->cpu; - - if (freqs.old == freqs.new) - return ret; - -- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ if (!is_smp()) { -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ goto set_freq; -+ } -+ -+ /* notifiers */ -+ for_each_cpu(i, policy->cpus) { -+ freqs.cpu = i; -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ } - -+set_freq: - #ifdef CONFIG_CPU_FREQ_DEBUG - pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new); - #endif -@@ -105,12 +121,33 @@ static int omap_target(struct cpufreq_policy *policy, - * CONFIG_SMP enabled. Below code is added only to manage that - * scenario - */ -- if (!is_smp()) -+ freqs.new = omap_getspeed(policy->cpu); -+ if (!is_smp()) { - loops_per_jiffy = - cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new); -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+ goto skip_lpj; -+ } - -- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+#ifdef CONFIG_SMP -+ /* -+ * Note that loops_per_jiffy is not updated on SMP systems in -+ * cpufreq driver. So, update the per-CPU loops_per_jiffy value -+ * on frequency transition. We need to update all dependent CPUs. -+ */ -+ for_each_cpu(i, policy->cpus) -+ per_cpu(cpu_data, i).loops_per_jiffy = -+ cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy, -+ freqs.old, freqs.new); -+#endif - -+ /* notifiers */ -+ for_each_cpu(i, policy->cpus) { -+ freqs.cpu = i; -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+ } -+ -+skip_lpj: - return ret; - } - -@@ -118,6 +155,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - { - int result = 0; - struct device *mpu_dev; -+ static cpumask_var_t cpumask; - - if (cpu_is_omap24xx()) - mpu_clk = clk_get(NULL, "virt_prcm_set"); -@@ -129,12 +167,12 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - if (IS_ERR(mpu_clk)) - return PTR_ERR(mpu_clk); - -- if (policy->cpu != 0) -+ if (policy->cpu >= NR_CPUS) - return -EINVAL; - -- policy->cur = policy->min = policy->max = omap_getspeed(0); -- -+ policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu); - mpu_dev = omap2_get_mpuss_device(); -+ - if (!mpu_dev) { - pr_warning("%s: unable to get the mpu device\n", __func__); - return -EINVAL; -@@ -154,7 +192,20 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - - policy->min = policy->cpuinfo.min_freq; - policy->max = policy->cpuinfo.max_freq; -- policy->cur = omap_getspeed(0); -+ policy->cur = omap_getspeed(policy->cpu); -+ -+ /* -+ * On OMAP SMP configuartion, both processors share the voltage -+ * and clock. So both CPUs needs to be scaled together and hence -+ * needs software co-ordination. Use cpufreq affected_cpus -+ * interface to handle this scenario. Additional is_smp() check -+ * is to keep SMP_ON_UP build working. -+ */ -+ if (is_smp()) { -+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY; -+ cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask); -+ cpumask_copy(policy->cpus, cpumask); -+ } - - /* FIXME: what's the actual transition time? */ - policy->cpuinfo.transition_latency = 300 * 1000; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0008-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0008-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch deleted file mode 100644 index 3797443c..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0008-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 6e101764a47cb6975a555e2237843ad391a542a4 Mon Sep 17 00:00:00 2001 -From: Jarkko Nikula -Date: Thu, 14 Apr 2011 16:21:58 +0300 -Subject: [PATCH 8/8] OMAP2PLUS: cpufreq: Fix typo when attempting to set mpu_clk for OMAP4 - -Fix this typo as there is no dpll_mpu_ck for OMAP3 and code flow is clearly -trying to set mpu_clk for OMAP4 for which this dpll_mpu_ck is available. - -Signed-off-by: Jarkko Nikula ---- - arch/arm/mach-omap2/omap2plus-cpufreq.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c -index 8d472f6..d53ce23 100644 ---- a/arch/arm/mach-omap2/omap2plus-cpufreq.c -+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c -@@ -161,7 +161,7 @@ static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - mpu_clk = clk_get(NULL, "virt_prcm_set"); - else if (cpu_is_omap34xx()) - mpu_clk = clk_get(NULL, "dpll1_ck"); -- else if (cpu_is_omap34xx()) -+ else if (cpu_is_omap44xx()) - mpu_clk = clk_get(NULL, "dpll_mpu_ck"); - - if (IS_ERR(mpu_clk)) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0001-OMAP2-clockdomain-Add-an-api-to-read-idle-mode.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0001-OMAP2-clockdomain-Add-an-api-to-read-idle-mode.patch deleted file mode 100644 index d9b05173..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0001-OMAP2-clockdomain-Add-an-api-to-read-idle-mode.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 988f50cb51d18e81ed2f7673a09694d28c9d086a Mon Sep 17 00:00:00 2001 -From: Rajendra Nayak -Date: Tue, 5 Apr 2011 15:22:31 +0530 -Subject: [PATCH 1/6] OMAP2+: clockdomain: Add an api to read idle mode - -Add a clockdomain api to check if hardware supervised -idle transitions are enabled on a clockdomain. - -Signed-off-by: Rajendra Nayak ---- - arch/arm/mach-omap2/clockdomain.c | 21 +++++++++++++++++++++ - arch/arm/mach-omap2/clockdomain.h | 3 +++ - 2 files changed, 24 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c -index 6cb6c03..2ab3686 100644 ---- a/arch/arm/mach-omap2/clockdomain.c -+++ b/arch/arm/mach-omap2/clockdomain.c -@@ -795,6 +795,27 @@ void clkdm_deny_idle(struct clockdomain *clkdm) - arch_clkdm->clkdm_deny_idle(clkdm); - } - -+/** -+ * clkdm_is_idle - Check if the clkdm hwsup/autoidle is enabled -+ * @clkdm: struct clockdomain * -+ * -+ * Returns true if the clockdomain is in hardware-supervised -+ * idle mode, or 0 otherwise. -+ * -+ */ -+int clkdm_is_idle(struct clockdomain *clkdm) -+{ -+ if (!clkdm) -+ return -EINVAL; -+ -+ if (!arch_clkdm || !arch_clkdm->clkdm_is_idle) -+ return -EINVAL; -+ -+ pr_debug("clockdomain: reading idle state for %s\n", clkdm->name); -+ -+ return arch_clkdm->clkdm_is_idle(clkdm); -+} -+ - - /* Clockdomain-to-clock framework interface code */ - -diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h -index 5823584..085ed82 100644 ---- a/arch/arm/mach-omap2/clockdomain.h -+++ b/arch/arm/mach-omap2/clockdomain.h -@@ -138,6 +138,7 @@ struct clockdomain { - * @clkdm_wakeup: Force a clockdomain to wakeup - * @clkdm_allow_idle: Enable hw supervised idle transitions for clock domain - * @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain -+ * @clkdm_is_idle: Check if hw supervised idle transitions are enabled - * @clkdm_clk_enable: Put the clkdm in right state for a clock enable - * @clkdm_clk_disable: Put the clkdm in right state for a clock disable - */ -@@ -154,6 +155,7 @@ struct clkdm_ops { - int (*clkdm_wakeup)(struct clockdomain *clkdm); - void (*clkdm_allow_idle)(struct clockdomain *clkdm); - void (*clkdm_deny_idle)(struct clockdomain *clkdm); -+ int (*clkdm_is_idle)(struct clockdomain *clkdm); - int (*clkdm_clk_enable)(struct clockdomain *clkdm); - int (*clkdm_clk_disable)(struct clockdomain *clkdm); - }; -@@ -177,6 +179,7 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); - - void clkdm_allow_idle(struct clockdomain *clkdm); - void clkdm_deny_idle(struct clockdomain *clkdm); -+int clkdm_is_idle(struct clockdomain *clkdm); - - int clkdm_wakeup(struct clockdomain *clkdm); - int clkdm_sleep(struct clockdomain *clkdm); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0002-OMAP2-clockdomain-Add-SoC-support-for-clkdm_is_idle.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0002-OMAP2-clockdomain-Add-SoC-support-for-clkdm_is_idle.patch deleted file mode 100644 index c7c1ea0b..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0002-OMAP2-clockdomain-Add-SoC-support-for-clkdm_is_idle.patch +++ /dev/null @@ -1,86 +0,0 @@ -From e3ba8d41bfafd782f3ee7f8930d9bf393986c662 Mon Sep 17 00:00:00 2001 -From: Rajendra Nayak -Date: Tue, 5 Apr 2011 15:22:36 +0530 -Subject: [PATCH 2/6] OMAP2+: clockdomain: Add SoC support for clkdm_is_idle - -Add the SoC specific implemenation for clkdm_is_idle -for OMAP2/3 and OMAP4. - -Signed-off-by: Rajendra Nayak ---- - arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 12 ++++++++++++ - arch/arm/mach-omap2/clockdomain44xx.c | 7 +++++++ - 2 files changed, 19 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c -index 48d0db7..db49baa 100644 ---- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c -+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c -@@ -13,6 +13,7 @@ - */ - - #include -+#include - #include - #include "prm.h" - #include "prm2xxx_3xxx.h" -@@ -146,6 +147,15 @@ static void omap2_clkdm_deny_idle(struct clockdomain *clkdm) - _clkdm_del_autodeps(clkdm); - } - -+static int omap2_clkdm_is_idle(struct clockdomain *clkdm) -+{ -+ if (!clkdm->clktrctrl_mask) -+ return -1; -+ -+ return omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, -+ clkdm->clktrctrl_mask); -+} -+ - static void _enable_hwsup(struct clockdomain *clkdm) - { - if (cpu_is_omap24xx()) -@@ -252,6 +262,7 @@ struct clkdm_ops omap2_clkdm_operations = { - .clkdm_wakeup = omap2_clkdm_wakeup, - .clkdm_allow_idle = omap2_clkdm_allow_idle, - .clkdm_deny_idle = omap2_clkdm_deny_idle, -+ .clkdm_is_idle = omap2_clkdm_is_idle, - .clkdm_clk_enable = omap2_clkdm_clk_enable, - .clkdm_clk_disable = omap2_clkdm_clk_disable, - }; -@@ -269,6 +280,7 @@ struct clkdm_ops omap3_clkdm_operations = { - .clkdm_wakeup = omap3_clkdm_wakeup, - .clkdm_allow_idle = omap3_clkdm_allow_idle, - .clkdm_deny_idle = omap3_clkdm_deny_idle, -+ .clkdm_is_idle = omap2_clkdm_is_idle, - .clkdm_clk_enable = omap2_clkdm_clk_enable, - .clkdm_clk_disable = omap2_clkdm_clk_disable, - }; -diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c -index a1a4ecd..4b10727 100644 ---- a/arch/arm/mach-omap2/clockdomain44xx.c -+++ b/arch/arm/mach-omap2/clockdomain44xx.c -@@ -93,6 +93,12 @@ static void omap4_clkdm_deny_idle(struct clockdomain *clkdm) - clkdm->cm_inst, clkdm->clkdm_offs); - } - -+static int omap4_clkdm_is_idle(struct clockdomain *clkdm) -+{ -+ return omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, -+ clkdm->cm_inst, clkdm->clkdm_offs); -+} -+ - static int omap4_clkdm_clk_enable(struct clockdomain *clkdm) - { - bool hwsup = false; -@@ -132,6 +138,7 @@ struct clkdm_ops omap4_clkdm_operations = { - .clkdm_wakeup = omap4_clkdm_wakeup, - .clkdm_allow_idle = omap4_clkdm_allow_idle, - .clkdm_deny_idle = omap4_clkdm_deny_idle, -+ .clkdm_is_idle = omap4_clkdm_is_idle, - .clkdm_clk_enable = omap4_clkdm_clk_enable, - .clkdm_clk_disable = omap4_clkdm_clk_disable, - }; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0003-OMAP2-PM-Initialise-sleep_switch-to-a-non-valid-valu.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0003-OMAP2-PM-Initialise-sleep_switch-to-a-non-valid-valu.patch deleted file mode 100644 index cbe5ca20..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0003-OMAP2-PM-Initialise-sleep_switch-to-a-non-valid-valu.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 7cdc87071a4bb390ad5d7ddea210bd2b4d662114 Mon Sep 17 00:00:00 2001 -From: Rajendra Nayak -Date: Tue, 5 Apr 2011 15:22:41 +0530 -Subject: [PATCH 3/6] OMAP2+: PM: Initialise sleep_switch to a non-valid value - -sleep_switch which is initialised to 0 in omap_set_pwrdm_state -happens to be a valid sleep_switch type (FORCEWAKEUP_SWITCH) -which are defined as -#define FORCEWAKEUP_SWITCH 0 -#define LOWPOWERSTATE_SWITCH 1 - -This causes the function to wrongly program some clock domains -even when the Powerdomain is in ON state. - -Signed-off-by: Rajendra Nayak ---- - arch/arm/mach-omap2/pm.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c -index 49486f5..d48813f 100644 ---- a/arch/arm/mach-omap2/pm.c -+++ b/arch/arm/mach-omap2/pm.c -@@ -106,7 +106,7 @@ static void omap2_init_processor_devices(void) - int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) - { - u32 cur_state; -- int sleep_switch = 0; -+ int sleep_switch = -1; - int ret = 0; - - if (pwrdm == NULL || IS_ERR(pwrdm)) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0004-OMAP2-PM-idle-clkdms-only-if-already-in-idle.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0004-OMAP2-PM-idle-clkdms-only-if-already-in-idle.patch deleted file mode 100644 index 16eedf9a..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0004-OMAP2-PM-idle-clkdms-only-if-already-in-idle.patch +++ /dev/null @@ -1,50 +0,0 @@ -From cec133850aa42c03d912c764aaa441677e782eca Mon Sep 17 00:00:00 2001 -From: Rajendra Nayak -Date: Tue, 5 Apr 2011 15:22:48 +0530 -Subject: [PATCH 4/6] OMAP2+: PM: idle clkdms only if already in idle - -The omap_set_pwrdm_state function forces clockdomains -to idle, without checking the existing idle state -programmed, instead based solely on the HW capability -of the clockdomain to support idle. -This is wrong and the clockdomains should be idled -post a state_switch *only* if idle transitions on the -clockdomain were already enabled. - -Signed-off-by: Rajendra Nayak ---- - arch/arm/mach-omap2/pm.c | 4 +++- - 1 files changed, 3 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c -index d48813f..840b0e1 100644 ---- a/arch/arm/mach-omap2/pm.c -+++ b/arch/arm/mach-omap2/pm.c -@@ -108,6 +108,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) - u32 cur_state; - int sleep_switch = -1; - int ret = 0; -+ int hwsup = 0; - - if (pwrdm == NULL || IS_ERR(pwrdm)) - return -EINVAL; -@@ -127,6 +128,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) - (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) { - sleep_switch = LOWPOWERSTATE_SWITCH; - } else { -+ hwsup = clkdm_is_idle(pwrdm->pwrdm_clkdms[0]); - clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); - pwrdm_wait_transition(pwrdm); - sleep_switch = FORCEWAKEUP_SWITCH; -@@ -142,7 +144,7 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state) - - switch (sleep_switch) { - case FORCEWAKEUP_SWITCH: -- if (pwrdm->pwrdm_clkdms[0]->flags & CLKDM_CAN_ENABLE_AUTO) -+ if (hwsup) - clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); - else - clkdm_sleep(pwrdm->pwrdm_clkdms[0]); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0005-OMAP2-hwmod-Follow-the-recomended-PRCM-sequence.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0005-OMAP2-hwmod-Follow-the-recomended-PRCM-sequence.patch deleted file mode 100644 index b0af9e7f..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0005-OMAP2-hwmod-Follow-the-recomended-PRCM-sequence.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 8fb6b7c488b31fbff5b81bdeea5dbb236342458b Mon Sep 17 00:00:00 2001 -From: Rajendra Nayak -Date: Tue, 29 Mar 2011 22:37:43 +0530 -Subject: [PATCH 5/6] OMAP2+: hwmod: Follow the recomended PRCM sequence - -Follow the recomended PRCM sequence. -This still does not take care of Optional clocks. - -Signed-off-by: Rajendra Nayak ---- - arch/arm/mach-omap2/omap_hwmod.c | 9 ++++++++- - 1 files changed, 8 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c -index e034294..fc0db0c 100644 ---- a/arch/arm/mach-omap2/omap_hwmod.c -+++ b/arch/arm/mach-omap2/omap_hwmod.c -@@ -1223,6 +1223,7 @@ static int _reset(struct omap_hwmod *oh) - static int _enable(struct omap_hwmod *oh) - { - int r; -+ int hwsup = 0; - - if (oh->_state != _HWMOD_STATE_INITIALIZED && - oh->_state != _HWMOD_STATE_IDLE && -@@ -1250,10 +1251,16 @@ static int _enable(struct omap_hwmod *oh) - omap_hwmod_mux(oh->mux, _HWMOD_STATE_ENABLED); - - _add_initiator_dep(oh, mpu_oh); -+ if (oh->_clk && oh->_clk->clkdm) { -+ hwsup = clkdm_is_idle(oh->_clk->clkdm); -+ clkdm_wakeup(oh->_clk->clkdm); -+ } - _enable_clocks(oh); -- - r = _wait_target_ready(oh); - if (!r) { -+ if (oh->_clk && oh->_clk->clkdm && hwsup) -+ clkdm_allow_idle(oh->_clk->clkdm); -+ - oh->_state = _HWMOD_STATE_ENABLED; - - /* Access the sysconfig only if the target is ready */ --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0006-OMAP-Serial-Check-wk_st-only-if-present.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0006-OMAP-Serial-Check-wk_st-only-if-present.patch deleted file mode 100644 index a8fc0c07..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0006-OMAP-Serial-Check-wk_st-only-if-present.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 7b74888d198c260992349fab214cad3adf853ef9 Mon Sep 17 00:00:00 2001 -From: Rajendra Nayak -Date: Tue, 2 Mar 2010 17:25:30 +0530 -Subject: [PATCH 6/6] OMAP: Serial: Check wk_st only if present - -Uart on the resume path tries to read wk_st registers, even -on architectures were its not present/populated. -This patch fixes the issue. - -Signed-off-by: Rajendra Nayak ---- - arch/arm/mach-omap2/serial.c | 5 +++-- - 1 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c -index 1ac361b..a0046ce 100644 ---- a/arch/arm/mach-omap2/serial.c -+++ b/arch/arm/mach-omap2/serial.c -@@ -418,8 +418,9 @@ void omap_uart_resume_idle(int num) - } - - /* Check for normal UART wakeup */ -- if (__raw_readl(uart->wk_st) & uart->wk_mask) -- omap_uart_block_sleep(uart); -+ if (uart->wk_st && uart->wk_mask) -+ if (__raw_readl(uart->wk_st) & uart->wk_mask) -+ omap_uart_block_sleep(uart); - return; - } - } --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0001-OMAP3-voltage-remove-spurious-pr_notice-for-debugfs.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0001-OMAP3-voltage-remove-spurious-pr_notice-for-debugfs.patch deleted file mode 100644 index 0d1cbce6..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0001-OMAP3-voltage-remove-spurious-pr_notice-for-debugfs.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 4af697edf9d1d85d2735e86e86e1203c3509dcba Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Sat, 12 Feb 2011 17:27:14 +0530 -Subject: [PATCH 01/12] OMAP3+: voltage: remove spurious pr_notice for debugfs - -cat of debugfs entry for vp_volt provides voltage. The additional pr_notice -is just spam on console and provides no additional information. - -Signed-off-by: Nishanth Menon -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/voltage.c | 1 - - 1 files changed, 0 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c -index 0c1552d..9ef3789 100644 ---- a/arch/arm/mach-omap2/voltage.c -+++ b/arch/arm/mach-omap2/voltage.c -@@ -148,7 +148,6 @@ static int vp_volt_debug_get(void *data, u64 *val) - } - - vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage); -- pr_notice("curr_vsel = %x\n", vsel); - - if (!vdd->pmic_info->vsel_to_uv) { - pr_warning("PMIC function to convert vsel to voltage" --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0002-OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0002-OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch deleted file mode 100644 index 7b137925..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0002-OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 37fb1c8eeecd39542716d3d0c7c5e3ca0eb198f8 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Sun, 13 Mar 2011 09:07:23 +0530 -Subject: [PATCH 02/12] OMAP4: PM: remove redundant #ifdef CONFIG_PM - -pm44xx.c is built only when CONFIG_PM is setup, -remove redundant CONFIG_PM check. - -This also fixes: -https://bugzilla.kernel.org/show_bug.cgi?id=25022 - -Reported-by: Martin Etti - -Signed-off-by: Nishanth Menon -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/pm44xx.c | 2 -- - 1 files changed, 0 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c -index 76cfff2..59a870b 100644 ---- a/arch/arm/mach-omap2/pm44xx.c -+++ b/arch/arm/mach-omap2/pm44xx.c -@@ -105,13 +105,11 @@ static int __init omap4_pm_init(void) - - pr_err("Power Management for TI OMAP4.\n"); - --#ifdef CONFIG_PM - ret = pwrdm_for_each(pwrdms_setup, NULL); - if (ret) { - pr_err("Failed to setup powerdomains\n"); - goto err2; - } --#endif - - #ifdef CONFIG_SUSPEND - suspend_set_ops(&omap_pm_ops); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0003-OMAP3-smartreflex-fix-sr_late_init-error-path-in-pro.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0003-OMAP3-smartreflex-fix-sr_late_init-error-path-in-pro.patch deleted file mode 100644 index 6c37b622..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0003-OMAP3-smartreflex-fix-sr_late_init-error-path-in-pro.patch +++ /dev/null @@ -1,30 +0,0 @@ -From a22a0dcefe99c8ee260e0c489bc44e6e14bb1ccb Mon Sep 17 00:00:00 2001 -From: Aaro Koskinen -Date: Thu, 24 Mar 2011 18:35:31 +0200 -Subject: [PATCH 03/12] OMAP3+: smartreflex: fix sr_late_init() error path in probe - -sr_late_init() will take care of freeing the resources. - -Signed-off-by: Aaro Koskinen -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/smartreflex.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c -index 13e24f9..dbc4b6f 100644 ---- a/arch/arm/mach-omap2/smartreflex.c -+++ b/arch/arm/mach-omap2/smartreflex.c -@@ -883,7 +883,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) - ret = sr_late_init(sr_info); - if (ret) { - pr_warning("%s: Error in SR late init\n", __func__); -- goto err_release_region; -+ return ret; - } - } - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0004-OMAP3-smartreflex-request-the-memory-region.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0004-OMAP3-smartreflex-request-the-memory-region.patch deleted file mode 100644 index 263094d5..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0004-OMAP3-smartreflex-request-the-memory-region.patch +++ /dev/null @@ -1,36 +0,0 @@ -From db9c7da6a78be8584c96c83a3a2d1c8aeb623da8 Mon Sep 17 00:00:00 2001 -From: Aaro Koskinen -Date: Thu, 24 Mar 2011 18:35:32 +0200 -Subject: [PATCH 04/12] OMAP3+: smartreflex: request the memory region - -We are releasing the memory region, but never actually request it. - -Signed-off-by: Aaro Koskinen -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/smartreflex.c | 8 ++++++++ - 1 files changed, 8 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c -index dbc4b6f..703143a 100644 ---- a/arch/arm/mach-omap2/smartreflex.c -+++ b/arch/arm/mach-omap2/smartreflex.c -@@ -847,6 +847,14 @@ static int __init omap_sr_probe(struct platform_device *pdev) - goto err_free_devinfo; - } - -+ mem = request_mem_region(mem->start, resource_size(mem), -+ dev_name(&pdev->dev)); -+ if (!mem) { -+ dev_err(&pdev->dev, "%s: no mem region\n", __func__); -+ ret = -EBUSY; -+ goto err_free_devinfo; -+ } -+ - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - - pm_runtime_enable(&pdev->dev); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0005-OMAP3-smartreflex-fix-ioremap-leak-on-probe-error.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0005-OMAP3-smartreflex-fix-ioremap-leak-on-probe-error.patch deleted file mode 100644 index ea1e5673..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0005-OMAP3-smartreflex-fix-ioremap-leak-on-probe-error.patch +++ /dev/null @@ -1,66 +0,0 @@ -From b3ca51ac09da7c260c28df396d4c830814697ff0 Mon Sep 17 00:00:00 2001 -From: Aaro Koskinen -Date: Thu, 24 Mar 2011 18:35:33 +0200 -Subject: [PATCH 05/12] OMAP3+: smartreflex: fix ioremap leak on probe error - -Add missing iounmap() to error paths. - -Signed-off-by: Aaro Koskinen -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/smartreflex.c | 10 ++++++---- - 1 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c -index 703143a..156807e 100644 ---- a/arch/arm/mach-omap2/smartreflex.c -+++ b/arch/arm/mach-omap2/smartreflex.c -@@ -904,7 +904,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) - vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm); - if (!vdd_dbg_dir) { - ret = -EINVAL; -- goto err_release_region; -+ goto err_iounmap; - } - - sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir); -@@ -912,7 +912,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) - dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n", - __func__); - ret = PTR_ERR(sr_info->dbg_dir); -- goto err_release_region; -+ goto err_iounmap; - } - - (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR, -@@ -929,7 +929,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) - dev_err(&pdev->dev, "%s: Unable to create debugfs directory" - "for n-values\n", __func__); - ret = PTR_ERR(nvalue_dir); -- goto err_release_region; -+ goto err_iounmap; - } - - omap_voltage_get_volttable(sr_info->voltdm, &volt_data); -@@ -939,7 +939,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) - "entries for n-values\n", - __func__, sr_info->voltdm->name); - ret = -ENODATA; -- goto err_release_region; -+ goto err_iounmap; - } - - for (i = 0; i < sr_info->nvalue_count; i++) { -@@ -953,6 +953,8 @@ static int __init omap_sr_probe(struct platform_device *pdev) - - return ret; - -+err_iounmap: -+ iounmap(sr_info->base); - err_release_region: - release_mem_region(mem->start, resource_size(mem)); - err_free_devinfo: --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0006-OMAP3-smartreflex-delete-instance-from-sr_list-on-pr.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0006-OMAP3-smartreflex-delete-instance-from-sr_list-on-pr.patch deleted file mode 100644 index cda6da63..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0006-OMAP3-smartreflex-delete-instance-from-sr_list-on-pr.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 92e63a2f098ce344cfc51ec9a7420e1a5cf85c3e Mon Sep 17 00:00:00 2001 -From: Aaro Koskinen -Date: Thu, 24 Mar 2011 18:35:34 +0200 -Subject: [PATCH 06/12] OMAP3+: smartreflex: delete instance from sr_list on probe error - -If the probe fails, the node should be deleted from sr_list. - -Signed-off-by: Aaro Koskinen -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/smartreflex.c | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c -index 156807e..f0a488a 100644 ---- a/arch/arm/mach-omap2/smartreflex.c -+++ b/arch/arm/mach-omap2/smartreflex.c -@@ -954,6 +954,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) - return ret; - - err_iounmap: -+ list_del(&sr_info->node); - iounmap(sr_info->base); - err_release_region: - release_mem_region(mem->start, resource_size(mem)); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0007-OMAP3-smartreflex-delete-debugfs-entries-on-probe-er.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0007-OMAP3-smartreflex-delete-debugfs-entries-on-probe-er.patch deleted file mode 100644 index d4543a46..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0007-OMAP3-smartreflex-delete-debugfs-entries-on-probe-er.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c194377152df812bcb29fff8f217ffbde59089be Mon Sep 17 00:00:00 2001 -From: Aaro Koskinen -Date: Thu, 24 Mar 2011 18:35:35 +0200 -Subject: [PATCH 07/12] OMAP3+: smartreflex: delete debugfs entries on probe error - -Delete created debugfs entries if probe fails. - -Signed-off-by: Aaro Koskinen -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/smartreflex.c | 6 ++++-- - 1 files changed, 4 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c -index f0a488a..fb7dc52 100644 ---- a/arch/arm/mach-omap2/smartreflex.c -+++ b/arch/arm/mach-omap2/smartreflex.c -@@ -929,7 +929,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) - dev_err(&pdev->dev, "%s: Unable to create debugfs directory" - "for n-values\n", __func__); - ret = PTR_ERR(nvalue_dir); -- goto err_iounmap; -+ goto err_debugfs; - } - - omap_voltage_get_volttable(sr_info->voltdm, &volt_data); -@@ -939,7 +939,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) - "entries for n-values\n", - __func__, sr_info->voltdm->name); - ret = -ENODATA; -- goto err_iounmap; -+ goto err_debugfs; - } - - for (i = 0; i < sr_info->nvalue_count; i++) { -@@ -953,6 +953,8 @@ static int __init omap_sr_probe(struct platform_device *pdev) - - return ret; - -+err_debugfs: -+ debugfs_remove_recursive(sr_info->dbg_dir); - err_iounmap: - list_del(&sr_info->node); - iounmap(sr_info->base); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0008-OMAP3-cpuidle-remove-useless-SDP-specific-timings.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0008-OMAP3-cpuidle-remove-useless-SDP-specific-timings.patch deleted file mode 100644 index e3ee0412..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0008-OMAP3-cpuidle-remove-useless-SDP-specific-timings.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 2b9e07516cc3853340b5e06e9ae7244ca5681466 Mon Sep 17 00:00:00 2001 -From: Jean Pihet -Date: Fri, 29 Apr 2011 11:26:22 +0200 -Subject: [PATCH 08/12] OMAP3 cpuidle: remove useless SDP specific timings - -The cpuidle states settings can be overriden by some board- -specific settings, by calling omap3_pm_init_cpuidle. -Remove the 3430SDP specific states settings registration -since the figures are identical to the default ones (in cpuidle34xx.c). - -Signed-off-by: Jean Pihet -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/board-3430sdp.c | 19 ------------------- - 1 files changed, 0 insertions(+), 19 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c -index 9afd087..7ffad7b 100644 ---- a/arch/arm/mach-omap2/board-3430sdp.c -+++ b/arch/arm/mach-omap2/board-3430sdp.c -@@ -59,24 +59,6 @@ - - #define TWL4030_MSECURE_GPIO 22 - --/* FIXME: These values need to be updated based on more profiling on 3430sdp*/ --static struct cpuidle_params omap3_cpuidle_params_table[] = { -- /* C1 */ -- {1, 2, 2, 5}, -- /* C2 */ -- {1, 10, 10, 30}, -- /* C3 */ -- {1, 50, 50, 300}, -- /* C4 */ -- {1, 1500, 1800, 4000}, -- /* C5 */ -- {1, 2500, 7500, 12000}, -- /* C6 */ -- {1, 3000, 8500, 15000}, -- /* C7 */ -- {1, 10000, 30000, 300000}, --}; -- - static uint32_t board_keymap[] = { - KEY(0, 0, KEY_LEFT), - KEY(0, 1, KEY_RIGHT), -@@ -883,7 +865,6 @@ static void __init omap_3430sdp_init(void) - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - omap_board_config = sdp3430_config; - omap_board_config_size = ARRAY_SIZE(sdp3430_config); -- omap3_pm_init_cpuidle(omap3_cpuidle_params_table); - omap3430_i2c_init(); - omap_display_init(&sdp3430_dss_data); - if (omap_rev() > OMAP3430_REV_ES1_0) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0009-OMAP3-SR-make-notify-independent-of-class.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0009-OMAP3-SR-make-notify-independent-of-class.patch deleted file mode 100644 index c44371df..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0009-OMAP3-SR-make-notify-independent-of-class.patch +++ /dev/null @@ -1,48 +0,0 @@ -From a0f28097b944930e479998780863b9e5a39e30b3 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Mon, 14 Feb 2011 12:16:36 +0530 -Subject: [PATCH 09/12] OMAP3+: SR: make notify independent of class - -Interrupt notification mechanism of SmartReflex can be used by the -choice of implementation of the class driver. For example, Class 2 and -Class 1.5 of SmartReflex can both use the interrupt notification to -identify the transition of voltage or other events. - -Hence, the actual class does not matter for notifier. Let the class -driver's handling decide how it should be used. SmartReflex driver -should provide just the primitives. - -Signed-off-by: Nishanth Menon -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/smartreflex.c | 6 ++---- - 1 files changed, 2 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c -index fb7dc52..3ee7261 100644 ---- a/arch/arm/mach-omap2/smartreflex.c -+++ b/arch/arm/mach-omap2/smartreflex.c -@@ -143,7 +143,7 @@ static irqreturn_t sr_interrupt(int irq, void *data) - sr_write_reg(sr_info, IRQSTATUS, status); - } - -- if (sr_class->class_type == SR_CLASS2 && sr_class->notify) -+ if (sr_class->notify) - sr_class->notify(sr_info->voltdm, status); - - return IRQ_HANDLED; -@@ -258,9 +258,7 @@ static int sr_late_init(struct omap_sr *sr_info) - struct resource *mem; - int ret = 0; - -- if (sr_class->class_type == SR_CLASS2 && -- sr_class->notify_flags && sr_info->irq) { -- -+ if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { - name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name); - if (name == NULL) { - ret = -ENOMEM; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0010-OMAP3-SR-disable-interrupt-by-default.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0010-OMAP3-SR-disable-interrupt-by-default.patch deleted file mode 100644 index e25c3e86..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0010-OMAP3-SR-disable-interrupt-by-default.patch +++ /dev/null @@ -1,37 +0,0 @@ -From ca5dc57538a566681731102e09a9d1865a4a7020 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Mon, 14 Feb 2011 12:41:10 +0530 -Subject: [PATCH 10/12] OMAP3+: SR: disable interrupt by default - -We will enable and disable interrupt on a need basis in the class -driver. We need to keep the IRQ disabled by default else the -forceupdate or vcbypass events could trigger events that we don't -need/expect to handle. - -This is a preparation for SmartReflex AVS class drivers such as -class 2 and class 1.5 which would need to use interrupts. Existing -SmartReflex AVS class 3 driver does not require to use interrupts -and is not impacted by this change. - -Signed-off-by: Nishanth Menon -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/smartreflex.c | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c -index 3ee7261..616ef62 100644 ---- a/arch/arm/mach-omap2/smartreflex.c -+++ b/arch/arm/mach-omap2/smartreflex.c -@@ -268,6 +268,7 @@ static int sr_late_init(struct omap_sr *sr_info) - 0, name, (void *)sr_info); - if (ret) - goto error; -+ disable_irq(sr_info->irq); - } - - if (pdata && pdata->enable_on_init) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0011-OMAP3-SR-enable-disable-SR-only-on-need.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0011-OMAP3-SR-enable-disable-SR-only-on-need.patch deleted file mode 100644 index b96682ea..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0011-OMAP3-SR-enable-disable-SR-only-on-need.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 4aa67e94d6b13905abcf3e95cb66ea7be9c2e8dd Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Mon, 14 Feb 2011 21:14:17 +0530 -Subject: [PATCH 11/12] OMAP3+: SR: enable/disable SR only on need - -Since we already know the state of the autocomp enablement, we can -see if the requested state is different from the current state and -enable/disable SR only on the need basis. - -Signed-off-by: Nishanth Menon -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/smartreflex.c | 11 +++++++---- - 1 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c -index 616ef62..3bd9fac 100644 ---- a/arch/arm/mach-omap2/smartreflex.c -+++ b/arch/arm/mach-omap2/smartreflex.c -@@ -807,10 +807,13 @@ static int omap_sr_autocomp_store(void *data, u64 val) - return -EINVAL; - } - -- if (!val) -- sr_stop_vddautocomp(sr_info); -- else -- sr_start_vddautocomp(sr_info); -+ /* control enable/disable only if there is a delta in value */ -+ if (sr_info->autocomp_active != val) { -+ if (!val) -+ sr_stop_vddautocomp(sr_info); -+ else -+ sr_start_vddautocomp(sr_info); -+ } - - return 0; - } --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0012-OMAP3-SR-fix-cosmetic-indentation.patch b/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0012-OMAP3-SR-fix-cosmetic-indentation.patch deleted file mode 100644 index eda76a0d..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/pm/linux-omap-2.6.39-ti-pm/0012-OMAP3-SR-fix-cosmetic-indentation.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0c2089eecdfc3a85a376eddf9c77857f3d575be6 Mon Sep 17 00:00:00 2001 -From: Nishanth Menon -Date: Mon, 14 Feb 2011 12:33:13 +0530 -Subject: [PATCH 12/12] OMAP3+: SR: fix cosmetic indentation - -Error label case seems to have a 2 tab indentation when just 1 is -necessary. - -Signed-off-by: Nishanth Menon -Signed-off-by: Kevin Hilman -Signed-off-by: Koen Kooi ---- - arch/arm/mach-omap2/smartreflex.c | 20 ++++++++++---------- - 1 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c -index 3bd9fac..2ce2fb7 100644 ---- a/arch/arm/mach-omap2/smartreflex.c -+++ b/arch/arm/mach-omap2/smartreflex.c -@@ -277,16 +277,16 @@ static int sr_late_init(struct omap_sr *sr_info) - return ret; - - error: -- iounmap(sr_info->base); -- mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0); -- release_mem_region(mem->start, resource_size(mem)); -- list_del(&sr_info->node); -- dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" -- "interrupt handler. Smartreflex will" -- "not function as desired\n", __func__); -- kfree(name); -- kfree(sr_info); -- return ret; -+ iounmap(sr_info->base); -+ mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0); -+ release_mem_region(mem->start, resource_size(mem)); -+ list_del(&sr_info->node); -+ dev_err(&sr_info->pdev->dev, "%s: ERROR in registering" -+ "interrupt handler. Smartreflex will" -+ "not function as desired\n", __func__); -+ kfree(name); -+ kfree(sr_info); -+ return ret; - } - - static void sr_v1_disable(struct omap_sr *sr) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0001-OMAP-DSS2-DSI-fix-use_sys_clk-highfreq.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0001-OMAP-DSS2-DSI-fix-use_sys_clk-highfreq.patch deleted file mode 100644 index a66407b3..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0001-OMAP-DSS2-DSI-fix-use_sys_clk-highfreq.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 6aae34d56ba8fef140b60631536272f6b39c1f61 Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen -Date: Thu, 7 Apr 2011 15:28:47 +0300 -Subject: [PATCH 01/32] OMAP: DSS2: DSI: fix use_sys_clk & highfreq - -use_sys_clk and highfreq fields in dsi.current_cinfo were never set. -Luckily they weren't used anywhere so it didn't cause any problems. - -This patch fixes those fields and they are now set at the same time as -the rest of the fields. - -Signed-off-by: Tomi Valkeinen ---- - drivers/video/omap2/dss/dsi.c | 3 +++ - 1 files changed, 3 insertions(+), 0 deletions(-) - -diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c -index 0a7f1a4..8604153 100644 ---- a/drivers/video/omap2/dss/dsi.c -+++ b/drivers/video/omap2/dss/dsi.c -@@ -1276,6 +1276,9 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) - - DSSDBGF(); - -+ dsi.current_cinfo.use_sys_clk = cinfo->use_sys_clk; -+ dsi.current_cinfo.highfreq = cinfo->highfreq; -+ - dsi.current_cinfo.fint = cinfo->fint; - dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; - dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk = --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0002-OMAP-DSS2-DSI-fix-dsi_dump_clocks.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0002-OMAP-DSS2-DSI-fix-dsi_dump_clocks.patch deleted file mode 100644 index 9d5ab617..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0002-OMAP-DSS2-DSI-fix-dsi_dump_clocks.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 5275654d2e873ca5bdbbd8be61dbb2d63c0e04cb Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen -Date: Mon, 4 Apr 2011 10:02:53 +0300 -Subject: [PATCH 02/32] OMAP: DSS2: DSI: fix dsi_dump_clocks() - -On OMAP4, reading DSI_PLL_CONFIGURATION2 register requires the L3 clock -(CIO_CLK_ICG) to PLL. Currently dsi_dump_clocks() tries to read that -register without enabling the L3 clock, leading to crash if DSI is not -in use. - -The status of the bit being read from DSI_PLL_CONFIGURATION2 is -available from dsi_clock_info->use_sys_clk, so we can avoid the whole -problem by just using that. - -Signed-off-by: Tomi Valkeinen ---- - drivers/video/omap2/dss/dsi.c | 6 +----- - 1 files changed, 1 insertions(+), 5 deletions(-) - -diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c -index 8604153..1464ac4 100644 ---- a/drivers/video/omap2/dss/dsi.c -+++ b/drivers/video/omap2/dss/dsi.c -@@ -1491,7 +1491,6 @@ void dsi_pll_uninit(void) - - void dsi_dump_clocks(struct seq_file *s) - { -- int clksel; - struct dsi_clock_info *cinfo = &dsi.current_cinfo; - enum dss_clk_source dispc_clk_src, dsi_clk_src; - -@@ -1500,13 +1499,10 @@ void dsi_dump_clocks(struct seq_file *s) - - enable_clocks(1); - -- clksel = REG_GET(DSI_PLL_CONFIGURATION2, 11, 11); -- - seq_printf(s, "- DSI PLL -\n"); - - seq_printf(s, "dsi pll source = %s\n", -- clksel == 0 ? -- "dss_sys_clk" : "pclkfree"); -+ cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree"); - - seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0003-OMAP2PLUS-DSS2-Fix-Return-correct-lcd-clock-source-f.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0003-OMAP2PLUS-DSS2-Fix-Return-correct-lcd-clock-source-f.patch deleted file mode 100644 index 14239fad..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0003-OMAP2PLUS-DSS2-Fix-Return-correct-lcd-clock-source-f.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 9ddb3aafff5f7f6b7eaad32f9b1eea249c0dce8b Mon Sep 17 00:00:00 2001 -From: Archit Taneja -Date: Thu, 31 Mar 2011 13:23:35 +0530 -Subject: [PATCH 03/32] OMAP2PLUS: DSS2: Fix: Return correct lcd clock source for OMAP2/3 - -dss.lcd_clk_source is set to the default value DSS_CLK_SRC_FCK at dss_init. -For OMAP2 and OMAP3, the dss.lcd_clk_source should always be the same as -dss.dispc_clk_source. The function dss_get_lcd_clk_source() always returns the -default value DSS_CLK_SRC_FCK for OMAP2/3. This leads to wrong clock dumps when -dispc_clk_source is not DSS_CLK_SRC_FCK. - -Correct this function to always return dss.dispc_clk_source for OMAP2/3. - -Signed-off-by: Archit Taneja -Signed-off-by: Tomi Valkeinen ---- - drivers/video/omap2/dss/dss.c | 10 ++++++++-- - 1 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c -index 3f1fee6..c3b48a0 100644 ---- a/drivers/video/omap2/dss/dss.c -+++ b/drivers/video/omap2/dss/dss.c -@@ -385,8 +385,14 @@ enum dss_clk_source dss_get_dsi_clk_source(void) - - enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) - { -- int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; -- return dss.lcd_clk_source[ix]; -+ if (dss_has_feature(FEAT_LCD_CLK_SRC)) { -+ int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; -+ return dss.lcd_clk_source[ix]; -+ } else { -+ /* LCD_CLK source is the same as DISPC_FCLK source for -+ * OMAP2 and OMAP3 */ -+ return dss.dispc_clk_source; -+ } - } - - /* calculate clock rates using dividers in cinfo */ --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0004-OMAP-DSS-DSI-Fix-DSI-PLL-power-bug.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0004-OMAP-DSS-DSI-Fix-DSI-PLL-power-bug.patch deleted file mode 100644 index 8c2d6e6c..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0004-OMAP-DSS-DSI-Fix-DSI-PLL-power-bug.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 4a56fbcabd128dbd07895e5167fd131299a1391c Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen -Date: Fri, 15 Apr 2011 10:42:59 +0300 -Subject: [PATCH 04/32] OMAP: DSS: DSI: Fix DSI PLL power bug - -OMAP3630 has a HW bug causing DSI PLL power command POWER_ON_DIV (0x3) -to not work properly. The bug prevents us from enabling DSI PLL power -only to HS divider block. - -This patch adds a dss feature for the bug and converts POWER_ON_DIV -requests to POWER_ON_ALL (0x2). - -Signed-off-by: Tomi Valkeinen ---- - drivers/video/omap2/dss/dsi.c | 5 +++++ - drivers/video/omap2/dss/dss_features.c | 2 +- - drivers/video/omap2/dss/dss_features.h | 2 ++ - 3 files changed, 8 insertions(+), 1 deletions(-) - -diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c -index 1464ac4..cbd9ca4 100644 ---- a/drivers/video/omap2/dss/dsi.c -+++ b/drivers/video/omap2/dss/dsi.c -@@ -1059,6 +1059,11 @@ static int dsi_pll_power(enum dsi_pll_power_state state) - { - int t = 0; - -+ /* DSI-PLL power command 0x3 is not working */ -+ if (dss_has_feature(FEAT_DSI_PLL_PWR_BUG) && -+ state == DSI_PLL_POWER_ON_DIV) -+ state = DSI_PLL_POWER_ON_ALL; -+ - REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_CMD */ - - /* PLL_PWR_STATUS */ -diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c -index aa16222..8c50e18 100644 ---- a/drivers/video/omap2/dss/dss_features.c -+++ b/drivers/video/omap2/dss/dss_features.c -@@ -271,7 +271,7 @@ static struct omap_dss_features omap3630_dss_features = { - FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | - FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED | - FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | -- FEAT_RESIZECONF, -+ FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG, - - .num_mgrs = 2, - .num_ovls = 3, -diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h -index 12e9c4e..37922ce 100644 ---- a/drivers/video/omap2/dss/dss_features.h -+++ b/drivers/video/omap2/dss/dss_features.h -@@ -40,6 +40,8 @@ enum dss_feat_id { - /* Independent core clk divider */ - FEAT_CORE_CLK_DIV = 1 << 11, - FEAT_LCD_CLK_SRC = 1 << 12, -+ /* DSI-PLL power command 0x3 is not working */ -+ FEAT_DSI_PLL_PWR_BUG = 1 << 13, - }; - - /* DSS register field id */ --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0005-OMAP-DSS2-fix-panel-Kconfig-dependencies.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0005-OMAP-DSS2-fix-panel-Kconfig-dependencies.patch deleted file mode 100644 index a8279242..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0005-OMAP-DSS2-fix-panel-Kconfig-dependencies.patch +++ /dev/null @@ -1,61 +0,0 @@ -From fcb26a06fe1badfaaf7aaa68140c8b3370dd503e Mon Sep 17 00:00:00 2001 -From: Tomi Valkeinen -Date: Fri, 8 Apr 2011 09:30:27 +0300 -Subject: [PATCH 05/32] OMAP: DSS2: fix panel Kconfig dependencies - -All DPI panels were missing dependency to OMAP2_DSS_DPI. Add the -dependency. - -Signed-off-by: Tomi Valkeinen ---- - drivers/video/omap2/displays/Kconfig | 9 +++++---- - 1 files changed, 5 insertions(+), 4 deletions(-) - -diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig -index d18ad6b..609a280 100644 ---- a/drivers/video/omap2/displays/Kconfig -+++ b/drivers/video/omap2/displays/Kconfig -@@ -3,6 +3,7 @@ menu "OMAP2/3 Display Device Drivers" - - config PANEL_GENERIC_DPI - tristate "Generic DPI Panel" -+ depends on OMAP2_DSS_DPI - help - Generic DPI panel driver. - Supports DVI output for Beagle and OMAP3 SDP. -@@ -11,20 +12,20 @@ config PANEL_GENERIC_DPI - - config PANEL_LGPHILIPS_LB035Q02 - tristate "LG.Philips LB035Q02 LCD Panel" -- depends on OMAP2_DSS && SPI -+ depends on OMAP2_DSS_DPI && SPI - help - LCD Panel used on the Gumstix Overo Palo35 - - config PANEL_SHARP_LS037V7DW01 - tristate "Sharp LS037V7DW01 LCD Panel" -- depends on OMAP2_DSS -+ depends on OMAP2_DSS_DPI - select BACKLIGHT_CLASS_DEVICE - help - LCD Panel used in TI's SDP3430 and EVM boards - - config PANEL_NEC_NL8048HL11_01B - tristate "NEC NL8048HL11-01B Panel" -- depends on OMAP2_DSS -+ depends on OMAP2_DSS_DPI - help - This NEC NL8048HL11-01B panel is TFT LCD - used in the Zoom2/3/3630 sdp boards. -@@ -37,7 +38,7 @@ config PANEL_TAAL - - config PANEL_TPO_TD043MTEA1 - tristate "TPO TD043MTEA1 LCD Panel" -- depends on OMAP2_DSS && SPI -+ depends on OMAP2_DSS_DPI && SPI - help - LCD Panel used in OMAP3 Pandora - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0006-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0006-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch deleted file mode 100644 index d899cb0b..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0006-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 4bd1d52fff974f5a5d0582f4fa4eae6e03e36fc1 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Tue, 19 Jan 2010 21:19:15 -0800 -Subject: [PATCH 06/32] OMAP: DSS2: add bootarg for selecting svideo or composite for tv output - -also add pal-16 and ntsc-16 omapfb.mode settings for 16bpp ---- - drivers/video/omap2/dss/venc.c | 22 ++++++++++++++++++++++ - drivers/video/omap2/omapfb/omapfb-main.c | 10 +++++++++- - 2 files changed, 31 insertions(+), 1 deletions(-) - -diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c -index 8e35a5b..827723f 100644 ---- a/drivers/video/omap2/dss/venc.c -+++ b/drivers/video/omap2/dss/venc.c -@@ -85,6 +85,11 @@ - #define VENC_OUTPUT_TEST 0xC8 - #define VENC_DAC_B__DAC_C 0xC8 - -+static char *tv_connection; -+ -+module_param_named(tvcable, tv_connection, charp, 0); -+MODULE_PARM_DESC(tvcable, "TV connection type (svideo, composite)"); -+ - struct venc_config { - u32 f_control; - u32 vidout_ctrl; -@@ -458,6 +463,23 @@ static int venc_panel_probe(struct omap_dss_device *dssdev) - { - dssdev->panel.timings = omap_dss_pal_timings; - -+ /* Allow the TV output to be overriden */ -+ if (tv_connection) { -+ if (strcmp(tv_connection, "svideo") == 0) { -+ printk(KERN_INFO -+ "omapdss: tv output is svideo.\n"); -+ dssdev->phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO; -+ } else if (strcmp(tv_connection, "composite") == 0) { -+ printk(KERN_INFO -+ "omapdss: tv output is composite.\n"); -+ dssdev->phy.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE; -+ } else { -+ printk(KERN_INFO -+ "omapdss: unsupported output type'%s'.\n", -+ tv_connection); -+ } -+ } -+ - return 0; - } - -diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c -index 505ec66..eaeded5 100644 ---- a/drivers/video/omap2/omapfb/omapfb-main.c -+++ b/drivers/video/omap2/omapfb/omapfb-main.c -@@ -2036,7 +2036,15 @@ static int omapfb_mode_to_timings(const char *mode_str, - int r; - - #ifdef CONFIG_OMAP2_DSS_VENC -- if (strcmp(mode_str, "pal") == 0) { -+ if (strcmp(mode_str, "pal-16") == 0) { -+ *timings = omap_dss_pal_timings; -+ *bpp = 16; -+ return 0; -+ } else if (strcmp(mode_str, "ntsc-16") == 0) { -+ *timings = omap_dss_ntsc_timings; -+ *bpp = 16; -+ return 0; -+ } else if (strcmp(mode_str, "pal") == 0) { - *timings = omap_dss_pal_timings; - *bpp = 24; - return 0; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0007-video-add-timings-for-hd720.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0007-video-add-timings-for-hd720.patch deleted file mode 100644 index b653e6c4..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0007-video-add-timings-for-hd720.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 6d87a3f85ac36205111b4fe71ad06976239cdbe7 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Sat, 19 Dec 2009 06:52:43 -0800 -Subject: [PATCH 07/32] video: add timings for hd720 - ---- - drivers/video/modedb.c | 4 ++++ - 1 files changed, 4 insertions(+), 0 deletions(-) - -diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c -index 48c3ea8..b320a30 100644 ---- a/drivers/video/modedb.c -+++ b/drivers/video/modedb.c -@@ -103,6 +103,10 @@ static const struct fb_videomode modedb[] = { - { NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, 0, - FB_VMODE_NONINTERLACED }, - -+ /* 1280x720 @ 60 Hz, 45 kHz hsync, CEA 681-E Format 4 */ -+ { "hd720", 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5, 0, -+ FB_VMODE_NONINTERLACED }, -+ - /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ - { NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, 0, - FB_VMODE_INTERLACED }, --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0008-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0008-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch deleted file mode 100644 index 1e0e0579..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0008-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 1e3fcfd74686fa8b02f93bb592cca458942058e4 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Tue, 15 Dec 2009 15:17:44 -0800 -Subject: [PATCH 08/32] drivers: net: smsc911x: return ENODEV if device is not found - -Signed-off-by: Steve Sakoman ---- - drivers/net/smsc911x.c | 4 +++- - 1 files changed, 3 insertions(+), 1 deletions(-) - -diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c -index 4b42ecc..5c1202b 100644 ---- a/drivers/net/smsc911x.c -+++ b/drivers/net/smsc911x.c -@@ -2028,8 +2028,10 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) - } - - retval = smsc911x_init(dev); -- if (retval < 0) -+ if (retval < 0) { -+ retval = -ENODEV; - goto out_unmap_io_3; -+ } - - /* configure irq polarity and type before connecting isr */ - if (pdata->config.irq_polarity == SMSC911X_IRQ_POLARITY_ACTIVE_HIGH) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0009-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0009-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch deleted file mode 100644 index f753684a..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0009-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 078005a9c8b5913ed5eb7a7a9508e4b0a5b18c30 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Tue, 15 Dec 2009 15:24:10 -0800 -Subject: [PATCH 09/32] drivers: input: touchscreen: ads7846: return ENODEV if device is not found - -Signed-off-by: Steve Sakoman ---- - drivers/input/touchscreen/ads7846.c | 13 ++++++++++--- - 1 files changed, 10 insertions(+), 3 deletions(-) - -diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c -index 1de1c19..097db10 100644 ---- a/drivers/input/touchscreen/ads7846.c -+++ b/drivers/input/touchscreen/ads7846.c -@@ -1338,11 +1338,18 @@ static int __devinit ads7846_probe(struct spi_device *spi) - * the touchscreen, in case it's not connected. - */ - if (ts->model == 7845) -- ads7845_read12_ser(&spi->dev, PWRDOWN); -+ err = ads7845_read12_ser(&spi->dev, PWRDOWN); - else -- (void) ads7846_read12_ser(&spi->dev, -+ err = ads7846_read12_ser(&spi->dev, - READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); - -+ /* if sample is all 0's or all 1's then there is no device on spi */ -+ if ( (err == 0x000) || (err == 0xfff)) { -+ dev_info(&spi->dev, "no device detected, test read result was 0x%08X\n", err); -+ err = -ENODEV; -+ goto err_free_irq; -+ } -+ - err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); - if (err) - goto err_remove_hwmon; -@@ -1366,7 +1373,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) - err_put_regulator: - regulator_put(ts->reg); - err_free_gpio: -- if (!ts->get_pendown_state) -+ if (!ts->get_pendown_state && ts->gpio_pendown != -1) - gpio_free(ts->gpio_pendown); - err_cleanup_filter: - if (ts->filter_cleanup) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0010-Revert-omap2_mcspi-Flush-posted-writes.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0010-Revert-omap2_mcspi-Flush-posted-writes.patch deleted file mode 100644 index 6c76843d..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0010-Revert-omap2_mcspi-Flush-posted-writes.patch +++ /dev/null @@ -1,25 +0,0 @@ -From ae16b19238b8d0609612d0e1f1a419d293f17c80 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Thu, 3 Mar 2011 13:29:30 -0800 -Subject: [PATCH 10/32] Revert "omap2_mcspi: Flush posted writes" - -This reverts commit a330ce2001b290c59fe98c37e981683ef0a75fdf. ---- - drivers/spi/omap2_mcspi.c | 1 - - 1 files changed, 0 insertions(+), 1 deletions(-) - -diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c -index 6f86ba0..6094be7 100644 ---- a/drivers/spi/omap2_mcspi.c -+++ b/drivers/spi/omap2_mcspi.c -@@ -195,7 +195,6 @@ static inline void mcspi_write_chconf0(const struct spi_device *spi, u32 val) - - cs->chconf0 = val; - mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, val); -- mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); - } - - static void omap2_mcspi_set_dma_req(const struct spi_device *spi, --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0011-Revert-omap_hsmmc-improve-interrupt-synchronisation.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0011-Revert-omap_hsmmc-improve-interrupt-synchronisation.patch deleted file mode 100644 index 78381e9e..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0011-Revert-omap_hsmmc-improve-interrupt-synchronisation.patch +++ /dev/null @@ -1,482 +0,0 @@ -From 3a66cefdf60033381c623b0425345c41e8c078fe Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Fri, 19 Nov 2010 15:11:19 -0800 -Subject: [PATCH 11/32] Revert "omap_hsmmc: improve interrupt synchronisation" - -This reverts commit b417577d3b9bbb06a4ddc9aa955af9bd503f7242. - -Conflicts: - - drivers/mmc/host/omap_hsmmc.c ---- - drivers/mmc/host/omap_hsmmc.c | 267 ++++++++++++++++++++--------------------- - 1 files changed, 128 insertions(+), 139 deletions(-) - -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index 259ece0..15a023b 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -159,10 +159,12 @@ struct omap_hsmmc_host { - */ - struct regulator *vcc; - struct regulator *vcc_aux; -+ struct semaphore sem; - struct work_struct mmc_carddetect_work; - void __iomem *base; - resource_size_t mapbase; - spinlock_t irq_lock; /* Prevent races with irq handler */ -+ unsigned long flags; - unsigned int id; - unsigned int dma_len; - unsigned int dma_sg_idx; -@@ -183,7 +185,6 @@ struct omap_hsmmc_host { - int protect_card; - int reqs_blocked; - int use_reg; -- int req_in_progress; - - struct omap_mmc_platform_data *pdata; - }; -@@ -556,32 +557,6 @@ static void omap_hsmmc_stop_clock(struct omap_hsmmc_host *host) - dev_dbg(mmc_dev(host->mmc), "MMC Clock is not stoped\n"); - } - --static void omap_hsmmc_enable_irq(struct omap_hsmmc_host *host, -- struct mmc_command *cmd) --{ -- unsigned int irq_mask; -- -- if (host->use_dma) -- irq_mask = INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE); -- else -- irq_mask = INT_EN_MASK; -- -- /* Disable timeout for erases */ -- if (cmd->opcode == MMC_ERASE) -- irq_mask &= ~DTO_ENABLE; -- -- OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); -- OMAP_HSMMC_WRITE(host->base, ISE, irq_mask); -- OMAP_HSMMC_WRITE(host->base, IE, irq_mask); --} -- --static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host) --{ -- OMAP_HSMMC_WRITE(host->base, ISE, 0); -- OMAP_HSMMC_WRITE(host->base, IE, 0); -- OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); --} -- - #ifdef CONFIG_PM - - /* -@@ -650,7 +625,9 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) - && time_before(jiffies, timeout)) - ; - -- omap_hsmmc_disable_irq(host); -+ OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); -+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); -+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); - - /* Do not initialize card-specific things if the power is off */ - if (host->power_mode == MMC_POWER_OFF) -@@ -753,8 +730,6 @@ static void send_init_stream(struct omap_hsmmc_host *host) - return; - - disable_irq(host->irq); -- -- OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); - OMAP_HSMMC_WRITE(host->base, CON, - OMAP_HSMMC_READ(host->base, CON) | INIT_STREAM); - OMAP_HSMMC_WRITE(host->base, CMD, INIT_STREAM_CMD); -@@ -820,7 +795,17 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, - mmc_hostname(host->mmc), cmd->opcode, cmd->arg); - host->cmd = cmd; - -- omap_hsmmc_enable_irq(host, cmd); -+ /* -+ * Clear status bits and enable interrupts -+ */ -+ OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); -+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); -+ -+ if (host->use_dma) -+ OMAP_HSMMC_WRITE(host->base, IE, -+ INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE)); -+ else -+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); - - host->response_busy = 0; - if (cmd->flags & MMC_RSP_PRESENT) { -@@ -854,7 +839,13 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, - if (host->use_dma) - cmdreg |= DMA_EN; - -- host->req_in_progress = 1; -+ /* -+ * In an interrupt context (i.e. STOP command), the spinlock is unlocked -+ * by the interrupt handler, otherwise (i.e. for a new request) it is -+ * unlocked here. -+ */ -+ if (!in_interrupt()) -+ spin_unlock_irqrestore(&host->irq_lock, host->flags); - - OMAP_HSMMC_WRITE(host->base, ARG, cmd->arg); - OMAP_HSMMC_WRITE(host->base, CMD, cmdreg); -@@ -869,23 +860,6 @@ omap_hsmmc_get_dma_dir(struct omap_hsmmc_host *host, struct mmc_data *data) - return DMA_FROM_DEVICE; - } - --static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_request *mrq) --{ -- int dma_ch; -- -- spin_lock(&host->irq_lock); -- host->req_in_progress = 0; -- dma_ch = host->dma_ch; -- spin_unlock(&host->irq_lock); -- -- omap_hsmmc_disable_irq(host); -- /* Do not complete the request if DMA is still in progress */ -- if (mrq->data && host->use_dma && dma_ch != -1) -- return; -- host->mrq = NULL; -- mmc_request_done(host->mmc, mrq); --} -- - /* - * Notify the transfer complete to MMC core - */ -@@ -902,19 +876,25 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) - return; - } - -- omap_hsmmc_request_done(host, mrq); -+ host->mrq = NULL; -+ mmc_request_done(host->mmc, mrq); - return; - } - - host->data = NULL; - -+ if (host->use_dma && host->dma_ch != -1) -+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, -+ omap_hsmmc_get_dma_dir(host, data)); -+ - if (!data->error) - data->bytes_xfered += data->blocks * (data->blksz); - else - data->bytes_xfered = 0; - - if (!data->stop) { -- omap_hsmmc_request_done(host, data->mrq); -+ host->mrq = NULL; -+ mmc_request_done(host->mmc, data->mrq); - return; - } - omap_hsmmc_start_command(host, data->stop, NULL); -@@ -940,8 +920,10 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) - cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10); - } - } -- if ((host->data == NULL && !host->response_busy) || cmd->error) -- omap_hsmmc_request_done(host, cmd->mrq); -+ if ((host->data == NULL && !host->response_busy) || cmd->error) { -+ host->mrq = NULL; -+ mmc_request_done(host->mmc, cmd->mrq); -+ } - } - - /* -@@ -949,19 +931,14 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct mmc_command *cmd) - */ - static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) - { -- int dma_ch; -- - host->data->error = errno; - -- spin_lock(&host->irq_lock); -- dma_ch = host->dma_ch; -- host->dma_ch = -1; -- spin_unlock(&host->irq_lock); -- -- if (host->use_dma && dma_ch != -1) { -+ if (host->use_dma && host->dma_ch != -1) { - dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len, - omap_hsmmc_get_dma_dir(host, host->data)); -- omap_free_dma(dma_ch); -+ omap_free_dma(host->dma_ch); -+ host->dma_ch = -1; -+ up(&host->sem); - } - host->data = NULL; - } -@@ -1034,21 +1011,28 @@ static inline void omap_hsmmc_reset_controller_fsm(struct omap_hsmmc_host *host, - __func__); - } - --static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) -+/* -+ * MMC controller IRQ handler -+ */ -+static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) - { -+ struct omap_hsmmc_host *host = dev_id; - struct mmc_data *data; -- int end_cmd = 0, end_trans = 0; -- -- if (!host->req_in_progress) { -- do { -- OMAP_HSMMC_WRITE(host->base, STAT, status); -- /* Flush posted write */ -- status = OMAP_HSMMC_READ(host->base, STAT); -- } while (status & INT_EN_MASK); -- return; -+ int end_cmd = 0, end_trans = 0, status; -+ -+ spin_lock(&host->irq_lock); -+ -+ if (host->mrq == NULL) { -+ OMAP_HSMMC_WRITE(host->base, STAT, -+ OMAP_HSMMC_READ(host->base, STAT)); -+ /* Flush posted write */ -+ OMAP_HSMMC_READ(host->base, STAT); -+ spin_unlock(&host->irq_lock); -+ return IRQ_HANDLED; - } - - data = host->data; -+ status = OMAP_HSMMC_READ(host->base, STAT); - dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); - - if (status & ERR) { -@@ -1101,27 +1085,15 @@ static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status) - } - - OMAP_HSMMC_WRITE(host->base, STAT, status); -+ /* Flush posted write */ -+ OMAP_HSMMC_READ(host->base, STAT); - - if (end_cmd || ((status & CC) && host->cmd)) - omap_hsmmc_cmd_done(host, host->cmd); - if ((end_trans || (status & TC)) && host->mrq) - omap_hsmmc_xfer_done(host, data); --} -- --/* -- * MMC controller IRQ handler -- */ --static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) --{ -- struct omap_hsmmc_host *host = dev_id; -- int status; - -- status = OMAP_HSMMC_READ(host->base, STAT); -- do { -- omap_hsmmc_do_irq(host, status); -- /* Flush posted write */ -- status = OMAP_HSMMC_READ(host->base, STAT); -- } while (status & INT_EN_MASK); -+ spin_unlock(&host->irq_lock); - - return IRQ_HANDLED; - } -@@ -1316,11 +1288,9 @@ static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host, - /* - * DMA call back function - */ --static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) -+static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *data) - { -- struct omap_hsmmc_host *host = cb_data; -- struct mmc_data *data = host->mrq->data; -- int dma_ch, req_in_progress; -+ struct omap_hsmmc_host *host = data; - - if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) { - dev_warn(mmc_dev(host->mmc), "unexpected dma status %x\n", -@@ -1328,38 +1298,24 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) - return; - } - -- spin_lock(&host->irq_lock); -- if (host->dma_ch < 0) { -- spin_unlock(&host->irq_lock); -+ if (host->dma_ch < 0) - return; -- } - - host->dma_sg_idx++; - if (host->dma_sg_idx < host->dma_len) { - /* Fire up the next transfer. */ -- omap_hsmmc_config_dma_params(host, data, -- data->sg + host->dma_sg_idx); -- spin_unlock(&host->irq_lock); -+ omap_hsmmc_config_dma_params(host, host->data, -+ host->data->sg + host->dma_sg_idx); - return; - } - -- dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, -- omap_hsmmc_get_dma_dir(host, data)); -- -- req_in_progress = host->req_in_progress; -- dma_ch = host->dma_ch; -+ omap_free_dma(host->dma_ch); - host->dma_ch = -1; -- spin_unlock(&host->irq_lock); -- -- omap_free_dma(dma_ch); -- -- /* If DMA has finished after TC, complete the request */ -- if (!req_in_progress) { -- struct mmc_request *mrq = host->mrq; -- -- host->mrq = NULL; -- mmc_request_done(host->mmc, mrq); -- } -+ /* -+ * DMA Callback: run in interrupt context. -+ * mutex_unlock will throw a kernel warning if used. -+ */ -+ up(&host->sem); - } - - /* -@@ -1368,7 +1324,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) - static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, - struct mmc_request *req) - { -- int dma_ch = 0, ret = 0, i; -+ int dma_ch = 0, ret = 0, err = 1, i; - struct mmc_data *data = req->data; - - /* Sanity check: all the SG entries must be aligned by block size. */ -@@ -1385,7 +1341,23 @@ static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host, - */ - return -EINVAL; - -- BUG_ON(host->dma_ch != -1); -+ /* -+ * If for some reason the DMA transfer is still active, -+ * we wait for timeout period and free the dma -+ */ -+ if (host->dma_ch != -1) { -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_timeout(100); -+ if (down_trylock(&host->sem)) { -+ omap_free_dma(host->dma_ch); -+ host->dma_ch = -1; -+ up(&host->sem); -+ return err; -+ } -+ } else { -+ if (down_trylock(&host->sem)) -+ return err; -+ } - - ret = omap_request_dma(omap_hsmmc_get_dma_sync_dev(host, data), - "MMC/SD", omap_hsmmc_dma_cb, host, &dma_ch); -@@ -1485,27 +1457,37 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) - struct omap_hsmmc_host *host = mmc_priv(mmc); - int err; - -- BUG_ON(host->req_in_progress); -- BUG_ON(host->dma_ch != -1); -- if (host->protect_card) { -- if (host->reqs_blocked < 3) { -- /* -- * Ensure the controller is left in a consistent -- * state by resetting the command and data state -- * machines. -- */ -- omap_hsmmc_reset_controller_fsm(host, SRD); -- omap_hsmmc_reset_controller_fsm(host, SRC); -- host->reqs_blocked += 1; -- } -- req->cmd->error = -EBADF; -- if (req->data) -- req->data->error = -EBADF; -- req->cmd->retries = 0; -- mmc_request_done(mmc, req); -- return; -- } else if (host->reqs_blocked) -- host->reqs_blocked = 0; -+ /* -+ * Prevent races with the interrupt handler because of unexpected -+ * interrupts, but not if we are already in interrupt context i.e. -+ * retries. -+ */ -+ if (!in_interrupt()) { -+ spin_lock_irqsave(&host->irq_lock, host->flags); -+ /* -+ * Protect the card from I/O if there is a possibility -+ * it can be removed. -+ */ -+ if (host->protect_card) { -+ if (host->reqs_blocked < 3) { -+ /* -+ * Ensure the controller is left in a consistent -+ * state by resetting the command and data state -+ * machines. -+ */ -+ omap_hsmmc_reset_controller_fsm(host, SRD); -+ omap_hsmmc_reset_controller_fsm(host, SRC); -+ host->reqs_blocked += 1; -+ } -+ req->cmd->error = -EBADF; -+ if (req->data) -+ req->data->error = -EBADF; -+ spin_unlock_irqrestore(&host->irq_lock, host->flags); -+ mmc_request_done(mmc, req); -+ return; -+ } else if (host->reqs_blocked) -+ host->reqs_blocked = 0; -+ } - WARN_ON(host->mrq != NULL); - host->mrq = req; - err = omap_hsmmc_prepare_data(host, req); -@@ -1514,6 +1496,8 @@ static void omap_hsmmc_request(struct mmc_host *mmc, struct mmc_request *req) - if (req->data) - req->data->error = err; - host->mrq = NULL; -+ if (!in_interrupt()) -+ spin_unlock_irqrestore(&host->irq_lock, host->flags); - mmc_request_done(mmc, req); - return; - } -@@ -2093,6 +2077,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) - mmc->f_min = 400000; - mmc->f_max = 52000000; - -+ sema_init(&host->sem, 1); - spin_lock_init(&host->irq_lock); - - host->iclk = clk_get(&pdev->dev, "ick"); -@@ -2235,7 +2220,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) - pdata->resume = omap_hsmmc_resume_cdirq; - } - -- omap_hsmmc_disable_irq(host); -+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); -+ OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); - - mmc_host_lazy_disable(host->mmc); - -@@ -2356,7 +2342,10 @@ static int omap_hsmmc_suspend(struct device *dev) - ret = mmc_suspend_host(host->mmc); - mmc_host_enable(host->mmc); - if (ret == 0) { -- omap_hsmmc_disable_irq(host); -+ OMAP_HSMMC_WRITE(host->base, ISE, 0); -+ OMAP_HSMMC_WRITE(host->base, IE, 0); -+ -+ - OMAP_HSMMC_WRITE(host->base, HCTL, - OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP); - mmc_host_disable(host->mmc); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0012-Don-t-turn-SDIO-cards-off-to-save-power.-Doing-so-wi.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0012-Don-t-turn-SDIO-cards-off-to-save-power.-Doing-so-wi.patch deleted file mode 100644 index 1c86b22d..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0012-Don-t-turn-SDIO-cards-off-to-save-power.-Doing-so-wi.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 75d9413d575f724e1f7c006fdef374fb1c200346 Mon Sep 17 00:00:00 2001 -From: David Vrabel -Date: Fri, 2 Apr 2010 08:41:47 -0700 -Subject: [PATCH 12/32] Don't turn SDIO cards off to save power. Doing so will lose all internal state in the card. - -Signed-off-by: David Vrabel ---- - drivers/mmc/host/omap_hsmmc.c | 12 ++++++++---- - 1 files changed, 8 insertions(+), 4 deletions(-) - -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index 15a023b..83f93ab 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1760,8 +1761,12 @@ static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host *host) - mmc_slot(host).card_detect || - (mmc_slot(host).get_cover_state && - mmc_slot(host).get_cover_state(host->dev, host->slot_id)))) { -- mmc_release_host(host->mmc); -- return 0; -+ goto out; -+ } -+ -+ /* Don't turn SDIO cards off. */ -+ if (host->mmc->card && mmc_card_sdio(host->mmc->card)) { -+ goto out; - } - - mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0); -@@ -1772,9 +1777,8 @@ static int omap_hsmmc_sleep_to_off(struct omap_hsmmc_host *host) - host->dpm_state == CARDSLEEP ? "CARDSLEEP" : "REGSLEEP"); - - host->dpm_state = OFF; -- -+out: - mmc_release_host(host->mmc); -- - return 0; - } - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch deleted file mode 100644 index 59d5ec47..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0013-Enable-the-use-of-SDIO-card-interrupts.patch +++ /dev/null @@ -1,288 +0,0 @@ -From 948eeb1f03da5fca0f6734c10efbc35ad63a1d08 Mon Sep 17 00:00:00 2001 -From: David Vrabel -Date: Fri, 2 Apr 2010 08:42:22 -0700 -Subject: [PATCH 13/32] Enable the use of SDIO card interrupts. - -FCLK must be enabled while SDIO interrupts are enabled or the MMC -module won't wake-up (even though ENAWAKEUP in SYSCONFIG and IWE in -HTCL have been set). Enabling the MMC module to wake-up would require -configuring the MMC module (and the mmci_dat[1] GPIO when the CORE -power domain is OFF) as wake-up sources in the PRCM. - -The writes to STAT and ISE when starting a command are unnecessary and -have been removed. - -Signed-off-by: David Vrabel ---- - drivers/mmc/host/omap_hsmmc.c | 118 +++++++++++++++++++++++++++++------------ - 1 files changed, 83 insertions(+), 35 deletions(-) - -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index 83f93ab..d57686c 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -67,6 +67,7 @@ - #define SDVS_MASK 0x00000E00 - #define SDVSCLR 0xFFFFF1FF - #define SDVSDET 0x00000400 -+#define ENAWAKEUP (1 << 2) - #define AUTOIDLE 0x1 - #define SDBP (1 << 8) - #define DTO 0xe -@@ -77,10 +78,13 @@ - #define CLKD_SHIFT 6 - #define DTO_MASK 0x000F0000 - #define DTO_SHIFT 16 -+#define CIRQ_ENABLE (1 << 8) - #define INT_EN_MASK 0x307F0033 - #define BWR_ENABLE (1 << 4) - #define BRR_ENABLE (1 << 5) - #define DTO_ENABLE (1 << 20) -+#define CTPL (1 << 11) -+#define CLKEXTFREE (1 << 16) - #define INIT_STREAM (1 << 1) - #define DP_SELECT (1 << 21) - #define DDIR (1 << 4) -@@ -88,10 +92,12 @@ - #define MSBS (1 << 5) - #define BCE (1 << 1) - #define FOUR_BIT (1 << 1) -+#define IWE (1 << 24) - #define DW8 (1 << 5) - #define CC 0x1 - #define TC 0x02 - #define OD 0x1 -+#define CIRQ (1 << 8) - #define ERR (1 << 15) - #define CMD_TIMEOUT (1 << 16) - #define DATA_TIMEOUT (1 << 20) -@@ -186,6 +192,7 @@ struct omap_hsmmc_host { - int protect_card; - int reqs_blocked; - int use_reg; -+ int sdio_int; - - struct omap_mmc_platform_data *pdata; - }; -@@ -598,7 +605,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) - ; - - OMAP_HSMMC_WRITE(host->base, SYSCONFIG, -- OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE); -+ OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE | ENAWAKEUP); - - if (host->id == OMAP_MMC1_DEVID) { - if (host->power_mode != MMC_POWER_OFF && -@@ -613,7 +620,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) - } - - OMAP_HSMMC_WRITE(host->base, HCTL, -- OMAP_HSMMC_READ(host->base, HCTL) | hctl); -+ OMAP_HSMMC_READ(host->base, HCTL) | hctl | IWE); - - OMAP_HSMMC_WRITE(host->base, CAPA, - OMAP_HSMMC_READ(host->base, CAPA) | capa); -@@ -627,7 +634,7 @@ static int omap_hsmmc_context_restore(struct omap_hsmmc_host *host) - ; - - OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); -- OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); -+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK | CIRQ); - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); - - /* Do not initialize card-specific things if the power is off */ -@@ -791,22 +798,19 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, - struct mmc_data *data) - { - int cmdreg = 0, resptype = 0, cmdtype = 0; -+ int int_en_mask = INT_EN_MASK; - - dev_dbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n", - mmc_hostname(host->mmc), cmd->opcode, cmd->arg); - host->cmd = cmd; - -- /* -- * Clear status bits and enable interrupts -- */ -- OMAP_HSMMC_WRITE(host->base, STAT, STAT_CLEAR); -- OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); -- - if (host->use_dma) -- OMAP_HSMMC_WRITE(host->base, IE, -- INT_EN_MASK & ~(BRR_ENABLE | BWR_ENABLE)); -- else -- OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); -+ int_en_mask &= ~(BRR_ENABLE | BWR_ENABLE); -+ -+ if (host->sdio_int) -+ int_en_mask |= CIRQ; -+ -+ OMAP_HSMMC_WRITE(host->base, IE, int_en_mask); - - host->response_busy = 0; - if (cmd->flags & MMC_RSP_PRESENT) { -@@ -1019,23 +1023,26 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) - { - struct omap_hsmmc_host *host = dev_id; - struct mmc_data *data; -- int end_cmd = 0, end_trans = 0, status; -+ u32 status; -+ int end_cmd = 0, end_trans = 0; -+ bool card_irq = false; - - spin_lock(&host->irq_lock); - -- if (host->mrq == NULL) { -- OMAP_HSMMC_WRITE(host->base, STAT, -- OMAP_HSMMC_READ(host->base, STAT)); -- /* Flush posted write */ -- OMAP_HSMMC_READ(host->base, STAT); -- spin_unlock(&host->irq_lock); -- return IRQ_HANDLED; -- } -- -- data = host->data; - status = OMAP_HSMMC_READ(host->base, STAT); -+ OMAP_HSMMC_WRITE(host->base, STAT, status); -+ OMAP_HSMMC_READ(host->base, STAT); /* Flush posted write. */ -+ - dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status); - -+ if (status & CIRQ) -+ card_irq = true; -+ -+ if (host->mrq == NULL) -+ goto out; -+ -+ data = host->data; -+ - if (status & ERR) { - #ifdef CONFIG_MMC_DEBUG - omap_hsmmc_report_irq(host, status); -@@ -1085,17 +1092,16 @@ static irqreturn_t omap_hsmmc_irq(int irq, void *dev_id) - } - } - -- OMAP_HSMMC_WRITE(host->base, STAT, status); -- /* Flush posted write */ -- OMAP_HSMMC_READ(host->base, STAT); -- - if (end_cmd || ((status & CC) && host->cmd)) - omap_hsmmc_cmd_done(host, host->cmd); - if ((end_trans || (status & TC)) && host->mrq) - omap_hsmmc_xfer_done(host, data); -- -+out: - spin_unlock(&host->irq_lock); - -+ if (card_irq) -+ mmc_signal_sdio_irq(host->mmc); -+ - return IRQ_HANDLED; - } - -@@ -1643,6 +1649,47 @@ static void omap_hsmmc_init_card(struct mmc_host *mmc, struct mmc_card *card) - mmc_slot(host).init_card(card); - } - -+static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable) -+{ -+ struct omap_hsmmc_host *host = mmc_priv(mmc); -+ u32 ie, con; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&host->irq_lock, flags); -+ -+ /* -+ * When interrupts are enabled, CTPL must be set to enable -+ * DAT1 input buffer (or the card interrupt is always -+ * asserted) and FCLK must be enabled as wake-up does not -+ * work. Take care to disable FCLK after all the register -+ * accesses as they might not complete if FCLK is off. -+ * -+ * FIXME: if the MMC module (and the mmci_dat[1] GPIO when the -+ * CORE power domain is OFF) are configured as a wake-up -+ * sources in the PRCM, then FCLK could be switched off. This -+ * might add too much latency. -+ */ -+ con = OMAP_HSMMC_READ(host->base, CON); -+ ie = OMAP_HSMMC_READ(host->base, IE); -+ if (enable) { -+ clk_enable(host->fclk); -+ ie |= CIRQ_ENABLE; -+ con |= CTPL | CLKEXTFREE; -+ host->sdio_int = 1; -+ } else { -+ ie &= ~CIRQ_ENABLE; -+ con &= ~(CTPL | CLKEXTFREE); -+ host->sdio_int = 0; -+ } -+ OMAP_HSMMC_WRITE(host->base, CON, con); -+ OMAP_HSMMC_WRITE(host->base, IE, ie); -+ OMAP_HSMMC_READ(host->base, IE); /* flush posted write */ -+ if (!enable) -+ clk_disable(host->fclk); -+ -+ spin_unlock_irqrestore(&host->irq_lock, flags); -+} -+ - static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) - { - u32 hctl, capa, value; -@@ -1657,14 +1704,14 @@ static void omap_hsmmc_conf_bus_power(struct omap_hsmmc_host *host) - } - - value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK; -- OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl); -+ OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl | IWE); - - value = OMAP_HSMMC_READ(host->base, CAPA); - OMAP_HSMMC_WRITE(host->base, CAPA, value | capa); - - /* Set the controller to AUTO IDLE mode */ - value = OMAP_HSMMC_READ(host->base, SYSCONFIG); -- OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE); -+ OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE | ENAWAKEUP); - - /* Set SD bus power bit */ - set_sd_bus_power(host); -@@ -1918,7 +1965,7 @@ static const struct mmc_host_ops omap_hsmmc_ops = { - .get_cd = omap_hsmmc_get_cd, - .get_ro = omap_hsmmc_get_ro, - .init_card = omap_hsmmc_init_card, -- /* NYET -- enable_sdio_irq */ -+ .enable_sdio_irq = omap_hsmmc_enable_sdio_irq, - }; - - static const struct mmc_host_ops omap_hsmmc_ps_ops = { -@@ -1929,7 +1976,7 @@ static const struct mmc_host_ops omap_hsmmc_ps_ops = { - .get_cd = omap_hsmmc_get_cd, - .get_ro = omap_hsmmc_get_ro, - .init_card = omap_hsmmc_init_card, -- /* NYET -- enable_sdio_irq */ -+ .enable_sdio_irq = omap_hsmmc_enable_sdio_irq, - }; - - #ifdef CONFIG_DEBUG_FS -@@ -2145,7 +2192,8 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) - mmc->max_seg_size = mmc->max_req_size; - - mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | -- MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE; -+ MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_ERASE | -+ MMC_CAP_SDIO_IRQ; - - mmc->caps |= mmc_slot(host).caps; - if (mmc->caps & MMC_CAP_8_BIT_DATA) -@@ -2224,7 +2272,7 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) - pdata->resume = omap_hsmmc_resume_cdirq; - } - -- OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK); -+ OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK | CIRQ); - OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK); - - mmc_host_lazy_disable(host->mmc); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0014-soc-codecs-Enable-audio-capture-by-default-for-twl40.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0014-soc-codecs-Enable-audio-capture-by-default-for-twl40.patch deleted file mode 100644 index d6e82879..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0014-soc-codecs-Enable-audio-capture-by-default-for-twl40.patch +++ /dev/null @@ -1,27 +0,0 @@ -From f646d3df7a7160fd80f20416c4a0fce55946f527 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Thu, 17 Dec 2009 12:45:20 -0800 -Subject: [PATCH 14/32] soc: codecs: Enable audio capture by default for twl4030 - ---- - sound/soc/codecs/twl4030.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c -index 575238d..bd51f72 100644 ---- a/sound/soc/codecs/twl4030.c -+++ b/sound/soc/codecs/twl4030.c -@@ -56,8 +56,8 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { - 0x00, /* REG_OPTION (0x2) */ - 0x00, /* REG_UNKNOWN (0x3) */ - 0x00, /* REG_MICBIAS_CTL (0x4) */ -- 0x00, /* REG_ANAMICL (0x5) */ -- 0x00, /* REG_ANAMICR (0x6) */ -+ 0x34, /* REG_ANAMICL (0x5) */ -+ 0x14, /* REG_ANAMICR (0x6) */ - 0x00, /* REG_AVADC_CTL (0x7) */ - 0x00, /* REG_ADCMICSEL (0x8) */ - 0x00, /* REG_DIGMIXING (0x9) */ --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0015-soc-codecs-twl4030-Turn-on-mic-bias-by-default.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0015-soc-codecs-twl4030-Turn-on-mic-bias-by-default.patch deleted file mode 100644 index 04d91685..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0015-soc-codecs-twl4030-Turn-on-mic-bias-by-default.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 00adf70cb5f8706ac5e7b1ec6f5a94f7e490b606 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Wed, 29 Dec 2010 11:39:16 -0800 -Subject: [PATCH 15/32] soc: codecs: twl4030: Turn on mic bias by default - ---- - sound/soc/codecs/twl4030.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c -index bd51f72..8949773 100644 ---- a/sound/soc/codecs/twl4030.c -+++ b/sound/soc/codecs/twl4030.c -@@ -55,7 +55,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { - 0x00, /* REG_CODEC_MODE (0x1) */ - 0x00, /* REG_OPTION (0x2) */ - 0x00, /* REG_UNKNOWN (0x3) */ -- 0x00, /* REG_MICBIAS_CTL (0x4) */ -+ 0x03, /* REG_MICBIAS_CTL (0x4) */ - 0x34, /* REG_ANAMICL (0x5) */ - 0x14, /* REG_ANAMICR (0x6) */ - 0x00, /* REG_AVADC_CTL (0x7) */ --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0016-RTC-add-support-for-backup-battery-recharge.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0016-RTC-add-support-for-backup-battery-recharge.patch deleted file mode 100644 index cb685cc2..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0016-RTC-add-support-for-backup-battery-recharge.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 6f432e1e39f276a41d600d1cc9cd17fc088877d8 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Thu, 4 Feb 2010 12:26:22 -0800 -Subject: [PATCH 16/32] RTC: add support for backup battery recharge - ---- - drivers/rtc/rtc-twl.c | 25 +++++++++++++++++++++++++ - 1 files changed, 25 insertions(+), 0 deletions(-) - -diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c -index f9a2799..713b8ea 100644 ---- a/drivers/rtc/rtc-twl.c -+++ b/drivers/rtc/rtc-twl.c -@@ -30,6 +30,23 @@ - - #include - -+/* -+ * PM_RECEIVER block register offsets (use TWL4030_MODULE_PM_RECEIVER) -+ */ -+#define REG_BB_CFG 0x12 -+ -+/* PM_RECEIVER BB_CFG bitfields */ -+#define BIT_PM_RECEIVER_BB_CFG_BBCHEN 0x10 -+#define BIT_PM_RECEIVER_BB_CFG_BBSEL 0x0C -+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_2V5 0x00 -+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3V0 0x04 -+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3V1 0x08 -+#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3v2 0x0c -+#define BIT_PM_RECEIVER_BB_CFG_BBISEL 0x03 -+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_25UA 0x00 -+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_150UA 0x01 -+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_500UA 0x02 -+#define BIT_PM_RECEIVER_BB_CFG_BBISEL_1MA 0x03 - - /* - * RTC block register offsets (use TWL_MODULE_RTC) -@@ -495,6 +512,14 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) - if (ret < 0) - goto out2; - -+ /* enable backup battery charging */ -+ /* use a conservative 25uA @ 3.1V */ -+ ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, -+ BIT_PM_RECEIVER_BB_CFG_BBCHEN | -+ BIT_PM_RECEIVER_BB_CFG_BBSEL_3V1 | -+ BIT_PM_RECEIVER_BB_CFG_BBISEL_25UA, -+ REG_BB_CFG); -+ - return ret; - - out2: --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0017-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0017-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch deleted file mode 100644 index 1e6ba8db..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0017-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 56dc96df8ff5e3db6afde96d64d74200f85e59c2 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Sun, 24 Jan 2010 09:33:56 -0800 -Subject: [PATCH 17/32] ARM: OMAP2: mmc-twl4030: move clock input selection prior to vcc test - -otherwise it is not executed on systems that use non-twl regulators ---- - arch/arm/mach-omap2/hsmmc.c | 14 ++++++-------- - 1 files changed, 6 insertions(+), 8 deletions(-) - -diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c -index b2f30be..84d5ef6 100644 ---- a/arch/arm/mach-omap2/hsmmc.c -+++ b/arch/arm/mach-omap2/hsmmc.c -@@ -185,15 +185,13 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot, - if (mmc->slots[0].remux) - mmc->slots[0].remux(dev, slot, power_on); - -- if (power_on) { -- /* Only MMC2 supports a CLKIN */ -- if (mmc->slots[0].internal_clock) { -- u32 reg; -+ /* Only MMC2 supports a CLKIN */ -+ if (mmc->slots[0].internal_clock) { -+ u32 reg; - -- reg = omap_ctrl_readl(control_devconf1_offset); -- reg |= OMAP2_MMCSDIO2ADPCLKISEL; -- omap_ctrl_writel(reg, control_devconf1_offset); -- } -+ reg = omap_ctrl_readl(control_devconf1_offset); -+ reg |= OMAP2_MMCSDIO2ADPCLKISEL; -+ omap_ctrl_writel(reg, control_devconf1_offset); - } - } - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0018-Add-power-off-support-for-the-TWL4030-companion.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0018-Add-power-off-support-for-the-TWL4030-companion.patch deleted file mode 100644 index 30860275..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0018-Add-power-off-support-for-the-TWL4030-companion.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 8c257a6e7460ceb8c899980f7dad701ceb619adc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Bernhard=20W=C3=B6rndl-Aichriedler?= -Date: Sat, 15 May 2010 16:34:05 +0200 -Subject: [PATCH 18/32] Add power-off support for the TWL4030 companion - -This patch adds support for the power-off on shutdown feature of the TWL4030 ---- - drivers/mfd/Kconfig | 6 ++++++ - drivers/mfd/twl-core.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 46 insertions(+), 0 deletions(-) - -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index 3ed3ff0..fe2370a 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -210,6 +210,12 @@ config TWL4030_CODEC - select MFD_CORE - default n - -+config TWL4030_POWEROFF -+ bool "TWL4030 Allow power-off on shutdown" -+ depends on TWL4030_CORE -+ help -+ Enables the CPU to power-off the system on shutdown -+ - config TWL6030_PWM - tristate "TWL6030 PWM (Pulse Width Modulator) Support" - depends on TWL4030_CORE -diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c -index 960b5be..8804550 100644 ---- a/drivers/mfd/twl-core.c -+++ b/drivers/mfd/twl-core.c -@@ -122,6 +122,12 @@ - #define twl_has_bci() false - #endif - -+#if defined (CONFIG_TWL4030_POWEROFF) -+#define twl_has_poweroff() true -+#else -+#define twl_has_poweroff() false -+#endif -+ - /* Triton Core internal information (BEGIN) */ - - /* Last - for index max*/ -@@ -224,6 +230,10 @@ - #define TWL5031 BIT(2) /* twl5031 has different registers */ - #define TWL6030_CLASS BIT(3) /* TWL6030 class */ - -+/* for pm_power_off */ -+#define PWR_P1_SW_EVENTS 0x10 -+#define PWR_DEVOFF (1 << 0) -+ - /*----------------------------------------------------------------------*/ - - /* is driver active, bound to a chip? */ -@@ -1006,6 +1016,30 @@ static int twl_remove(struct i2c_client *client) - return 0; - } - -+static void twl_poweroff(void) -+{ -+ int err; -+ u8 val; -+ -+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &val, -+ PWR_P1_SW_EVENTS); -+ if (err) { -+ pr_err("%s: i2c error %d while reading TWL4030" -+ "PM_MASTER P1_SW_EVENTS\n", -+ DRIVER_NAME, err); -+ return; -+ } -+ -+ val |= PWR_DEVOFF; -+ -+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, val, -+ PWR_P1_SW_EVENTS); -+ if (err) -+ pr_err("%s: i2c error %d while writing TWL4030" -+ "PM_MASTER P1_SW_EVENTS\n", -+ DRIVER_NAME, err); -+} -+ - /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ - static int __devinit - twl_probe(struct i2c_client *client, const struct i2c_device_id *id) -@@ -1093,6 +1127,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) - twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); - } - -+ if(twl_has_poweroff()) -+ { -+ /* initialize pm_power_off routine */ -+ pm_power_off = twl_poweroff; -+ } -+ - status = add_children(pdata, id->driver_data); - fail: - if (status < 0) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch deleted file mode 100644 index 1f139f1c..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 46ea520a3c80914ae5ad3e35be7b8650706da3e6 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Thu, 17 Dec 2009 14:27:15 -0800 -Subject: [PATCH 19/32] ARM: OMAP: Add twl4030 madc support to Overo - -Signed-off-by: Steve Sakoman ---- - arch/arm/mach-omap2/board-overo.c | 5 +++++ - 1 files changed, 5 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c -index 59ca333..86f76e9 100644 ---- a/arch/arm/mach-omap2/board-overo.c -+++ b/arch/arm/mach-omap2/board-overo.c -@@ -637,10 +637,15 @@ static struct twl4030_codec_data overo_codec_data = { - .audio = &overo_audio_data, - }; - -+static struct twl4030_madc_platform_data overo_madc_data = { -+ .irq_line = 1, -+}; -+ - static struct twl4030_platform_data overo_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, - .gpio = &overo_gpio_data, -+ .madc = &overo_madc_data, - .usb = &overo_usb_data, - .codec = &overo_codec_data, - .vmmc1 = &overo_vmmc1, --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0020-Enabling-Hwmon-driver-for-twl4030-madc.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0020-Enabling-Hwmon-driver-for-twl4030-madc.patch deleted file mode 100644 index c80aef9a..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0020-Enabling-Hwmon-driver-for-twl4030-madc.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 931bd787effbd6f1f00468c89c647c66c0bbc164 Mon Sep 17 00:00:00 2001 -From: Keerthy -Date: Wed, 4 May 2011 01:14:50 +0530 -Subject: [PATCH 20/32] Enabling Hwmon driver for twl4030-madc - -Signed-off-by: Keerthy ---- - drivers/mfd/twl-core.c | 15 +++++++++++++++ - 1 files changed, 15 insertions(+), 0 deletions(-) - -diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c -index 8804550..d9435e4 100644 ---- a/drivers/mfd/twl-core.c -+++ b/drivers/mfd/twl-core.c -@@ -83,6 +83,13 @@ - #define twl_has_madc() false - #endif - -+#if defined(CONFIG_SENSORS_TWL4030_MADC) ||\ -+ defined(CONFIG_SENSORS_TWL4030_MADC_MODULE) -+#define twl_has_madc_hwmon() true -+#else -+#define twl_has_madc_hwmon() false -+#endif -+ - #ifdef CONFIG_TWL4030_POWER - #define twl_has_power() true - #else -@@ -619,6 +626,14 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) - return PTR_ERR(child); - } - -+if (twl_has_madc_hwmon()) { -+ child = add_child(2, "twl4030_madc_hwmon", -+ NULL, 0, -+ true, pdata->irq_base + MADC_INTR_OFFSET, 0); -+ if (IS_ERR(child)) -+ return PTR_ERR(child); -+ } -+ - if (twl_has_rtc()) { - /* - * REVISIT platform_data here currently might expose the --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0021-mfd-twl-core-enable-madc-clock.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0021-mfd-twl-core-enable-madc-clock.patch deleted file mode 100644 index 732d306a..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0021-mfd-twl-core-enable-madc-clock.patch +++ /dev/null @@ -1,54 +0,0 @@ -From aee147073ad84a7c81fba36dd475c6d2d17ed728 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Sat, 23 Jan 2010 06:26:54 -0800 -Subject: [PATCH 21/32] mfd: twl-core: enable madc clock - -Now that the madc driver has been merged it is also necessary to enable the clock to the madc block - -Signed-off-by: Steve Sakoman ---- - drivers/mfd/twl-core.c | 8 ++++++++ - include/linux/i2c/twl.h | 1 + - 2 files changed, 9 insertions(+), 0 deletions(-) - -diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c -index d9435e4..9096d7d 100644 ---- a/drivers/mfd/twl-core.c -+++ b/drivers/mfd/twl-core.c -@@ -222,6 +222,11 @@ - - /* Few power values */ - #define R_CFG_BOOT 0x05 -+#define R_GPBR1 0x0C -+ -+/* MADC clock values for R_GPBR1 */ -+#define MADC_HFCLK_EN 0x80 -+#define DEFAULT_MADC_CLK_EN 0x10 - - /* some fields in R_CFG_BOOT */ - #define HFCLK_FREQ_19p2_MHZ (1 << 0) -@@ -992,6 +997,9 @@ static void clocks_init(struct device *dev, - - e |= unprotect_pm_master(); - /* effect->MADC+USB ck en */ -+ if (twl_has_madc()) -+ e |= twl_i2c_write_u8(TWL_MODULE_INTBR, -+ MADC_HFCLK_EN | DEFAULT_MADC_CLK_EN, R_GPBR1); - e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, ctrl, R_CFG_BOOT); - e |= protect_pm_master(); - -diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h -index 0c0d1ae..cbbf3b3 100644 ---- a/include/linux/i2c/twl.h -+++ b/include/linux/i2c/twl.h -@@ -74,6 +74,7 @@ - - #define TWL_MODULE_USB TWL4030_MODULE_USB - #define TWL_MODULE_AUDIO_VOICE TWL4030_MODULE_AUDIO_VOICE -+#define TWL_MODULE_INTBR TWL4030_MODULE_INTBR - #define TWL_MODULE_PIH TWL4030_MODULE_PIH - #define TWL_MODULE_MADC TWL4030_MODULE_MADC - #define TWL_MODULE_MAIN_CHARGE TWL4030_MODULE_MAIN_CHARGE --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0022-rtc-twl-Switch-to-using-threaded-irq.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0022-rtc-twl-Switch-to-using-threaded-irq.patch deleted file mode 100644 index 0306d4b4..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0022-rtc-twl-Switch-to-using-threaded-irq.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 29dd1b5655f60f97a9cee2f4ff1d27d7da1329a1 Mon Sep 17 00:00:00 2001 -From: Ilkka Koskinen -Date: Wed, 16 Mar 2011 16:07:14 +0000 -Subject: [PATCH 22/32] rtc-twl: Switch to using threaded irq - ---- - drivers/rtc/rtc-twl.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c -index 713b8ea..1fe1bc9 100644 ---- a/drivers/rtc/rtc-twl.c -+++ b/drivers/rtc/rtc-twl.c -@@ -479,7 +479,7 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) - if (ret < 0) - goto out1; - -- ret = request_irq(irq, twl_rtc_interrupt, -+ ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt, - IRQF_TRIGGER_RISING, - dev_name(&rtc->dev), rtc); - if (ret < 0) { --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0023-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0023-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch deleted file mode 100644 index a35d7de5..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0023-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 92c06791d4d6b537a9a83b27d71d7d3dd348f93f Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Wed, 24 Feb 2010 10:37:22 -0800 -Subject: [PATCH 23/32] ARM: OMAP: automatically set musb mode in platform data based on CONFIG options - ---- - arch/arm/mach-omap2/board-omap3beagle.c | 6 ++++++ - arch/arm/mach-omap2/board-overo.c | 6 ++++++ - 2 files changed, 12 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c -index 33007fd..2de4b02 100644 ---- a/arch/arm/mach-omap2/board-omap3beagle.c -+++ b/arch/arm/mach-omap2/board-omap3beagle.c -@@ -604,7 +604,13 @@ static struct omap_board_mux board_mux[] __initdata = { - - static struct omap_musb_board_data musb_board_data = { - .interface_type = MUSB_INTERFACE_ULPI, -+#if defined(CONFIG_USB_MUSB_OTG) - .mode = MUSB_OTG, -+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) -+ .mode = MUSB_PERIPHERAL, -+#else -+ .mode = MUSB_HOST, -+#endif - .power = 100, - }; - -diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c -index 86f76e9..61c59fc 100644 ---- a/arch/arm/mach-omap2/board-overo.c -+++ b/arch/arm/mach-omap2/board-overo.c -@@ -729,7 +729,13 @@ static struct omap_board_mux board_mux[] __initdata = { - - static struct omap_musb_board_data musb_board_data = { - .interface_type = MUSB_INTERFACE_ULPI, -+#if defined(CONFIG_USB_MUSB_OTG) - .mode = MUSB_OTG, -+#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) -+ .mode = MUSB_PERIPHERAL, -+#else -+ .mode = MUSB_HOST, -+#endif - .power = 100, - }; - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0024-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0024-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch deleted file mode 100644 index bd1764a5..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0024-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch +++ /dev/null @@ -1,28 +0,0 @@ -From a442a2b9b2f9f51375f8a796ee88784d3754be00 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Wed, 12 Jan 2011 05:54:55 -0800 -Subject: [PATCH 24/32] omap: mmc: Adjust dto to eliminate timeout errors - -A number of SD card types were experiencing timeout errors. This -could also lead to data corruption in some cases. - -This fix proposed by Sukumar Ghoral of TI. ---- - drivers/mmc/host/omap_hsmmc.c | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) - -diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c -index d57686c..7fb03e8 100644 ---- a/drivers/mmc/host/omap_hsmmc.c -+++ b/drivers/mmc/host/omap_hsmmc.c -@@ -1400,6 +1400,7 @@ static void set_data_timeout(struct omap_hsmmc_host *host, - cycle_ns = 1000000000 / (clk_get_rate(host->fclk) / clkd); - timeout = timeout_ns / cycle_ns; - timeout += timeout_clks; -+ timeout *= 2; - if (timeout) { - while ((timeout & 0x80000000) == 0) { - dto += 1; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0025-omap-Fix-mtd-subpage-read-alignment.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0025-omap-Fix-mtd-subpage-read-alignment.patch deleted file mode 100644 index 1508da1a..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0025-omap-Fix-mtd-subpage-read-alignment.patch +++ /dev/null @@ -1,95 +0,0 @@ -From acf75c8b4d0f6775527636bf9d41bb1f74fc2f97 Mon Sep 17 00:00:00 2001 -From: Charles Manning -Date: Tue, 18 Jan 2011 11:25:25 +1300 -Subject: [PATCH 25/32] omap: Fix mtd subpage read alignment - -This allows the omap2 prefetch engine to work properly for subpage -reads. Without this ECC errors will stop UBIFS from working. - -Signed-off-by: Charles Manning ---- - drivers/mtd/nand/nand_base.c | 19 +++++++++++++++++++ - drivers/mtd/nand/omap2.c | 1 + - include/linux/mtd/nand.h | 3 +++ - 3 files changed, 23 insertions(+), 0 deletions(-) - -diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c -index c54a4cb..6ca7098 100644 ---- a/drivers/mtd/nand/nand_base.c -+++ b/drivers/mtd/nand/nand_base.c -@@ -1157,6 +1157,22 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, - } - - /** -+ * nand_align_subpage32 - function to align subpage read to 32-bits -+ * @mtd: mtd info structure -+ * @buf: pointer to offset that needs to be aligned -+ * @len: pointer to length that needs to be aligned. -+ */ -+ -+void nand_align_subpage32(int *offs, int *len) -+{ -+ int diff = *offs & 3; -+ -+ *offs = *offs - diff; -+ *len = (*len + diff + 3) & ~3; -+} -+EXPORT_SYMBOL(nand_align_subpage32); -+ -+/** - * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function - * @mtd: mtd info structure - * @chip: nand chip info structure -@@ -1221,6 +1237,9 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, - if (eccpos[index + (num_steps * chip->ecc.bytes)] & (busw - 1)) - aligned_len++; - -+ if(chip->align_subpage) -+ chip->align_subpage(&aligned_pos, &aligned_len); -+ - chip->cmdfunc(mtd, NAND_CMD_RNDOUT, - mtd->writesize + aligned_pos, -1); - chip->read_buf(mtd, &chip->oob_poi[aligned_pos], aligned_len); -diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c -index da9a351..bb89c65 100644 ---- a/drivers/mtd/nand/omap2.c -+++ b/drivers/mtd/nand/omap2.c -@@ -1069,6 +1069,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) - info->nand.ecc.correct = omap_correct_data; - info->nand.ecc.mode = NAND_ECC_HW; - } -+ info->nand.align_subpage = nand_align_subpage32; - - /* DIP switches on some boards change between 8 and 16 bit - * bus widths for flash. Try the other width if the first try fails. -diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h -index d441927..311f211 100644 ---- a/include/linux/mtd/nand.h -+++ b/include/linux/mtd/nand.h -@@ -479,6 +479,7 @@ struct nand_buffers { - * additional error status checks (determine if errors are - * correctable). - * @write_page: [REPLACEABLE] High-level page write function -+ * @align_subpage: [OPTIONAL] Aligns subpage read buffer. - */ - - struct nand_chip { -@@ -507,6 +508,7 @@ struct nand_chip { - int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, - const uint8_t *buf, int page, int cached, int raw); - -+ void (*align_subpage)(int *offs, int *len); - int chip_delay; - unsigned int options; - -@@ -602,6 +604,7 @@ extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, - int allowbbt); - extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, uint8_t *buf); -+extern void nand_align_subpage32(int *offs, int *len); - - /** - * struct platform_nand_chip - chip level device structure --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0026-mtd-nand-omap2-Force-all-buffer-reads-to-u32-alignme.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0026-mtd-nand-omap2-Force-all-buffer-reads-to-u32-alignme.patch deleted file mode 100644 index 5e060231..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0026-mtd-nand-omap2-Force-all-buffer-reads-to-u32-alignme.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 048c2b85c12ac4aa8cd82201e1ade332557e4380 Mon Sep 17 00:00:00 2001 -From: Charles Manning -Date: Thu, 16 Dec 2010 20:35:56 -0800 -Subject: [PATCH 26/32] mtd: nand: omap2: Force all buffer reads to u32 alignment - ---- - drivers/mtd/nand/omap2.c | 12 ++++++++++++ - 1 files changed, 12 insertions(+), 0 deletions(-) - -diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c -index bb89c65..832f111 100644 ---- a/drivers/mtd/nand/omap2.c -+++ b/drivers/mtd/nand/omap2.c -@@ -247,6 +247,18 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) - int ret = 0; - u32 *p = (u32 *)buf; - -+ /* u32 align the buffer and read */ -+ /* NB: This assumes the buf ptr can be aligned *down* which is a valid. -+ * Assumption when dealing with ecc buffers etc. -+ */ -+ u32 addr = (u32)p; -+ -+ int diff = addr & 3; -+ addr -= diff; -+ len += diff; -+ len = (len + 3) & ~3; -+ p = (u32 *)addr; -+ - /* take care of subpage reads */ - if (len % 4) { - if (info->nand.options & NAND_BUSWIDTH_16) --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0027-omap-nand-fix-subpage-ecc-issue-with-prefetch.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0027-omap-nand-fix-subpage-ecc-issue-with-prefetch.patch deleted file mode 100644 index 21eb1e9f..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0027-omap-nand-fix-subpage-ecc-issue-with-prefetch.patch +++ /dev/null @@ -1,63 +0,0 @@ -From fb4dfff6a6e107e0e526801e7add4a9aaeab1eab Mon Sep 17 00:00:00 2001 -From: kishore kadiyala -Date: Mon, 2 May 2011 11:10:38 +0000 -Subject: [PATCH 27/32] omap : nand : fix subpage ecc issue with prefetch - -For prefetch engine, read and write got broken in commit '2c01946c'. -We never hit a scenario of not getting 'gpmc_prefetch_enable' -call success. -When reading/writing a subpage with a non divisible by 4 ecc number -of bytes, the mis-aligned bytes gets handled first before enabling -the Prefetch engine, then it reads/writes rest of the bytes. - -Signed-off-by: Kishore Kadiyala -Signed-off-by: Vimal Singh -Reported-by: Bryan DE FARIA ---- - drivers/mtd/nand/omap2.c | 12 +++++------- - 1 files changed, 5 insertions(+), 7 deletions(-) - -diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c -index 832f111..471a39b 100644 ---- a/drivers/mtd/nand/omap2.c -+++ b/drivers/mtd/nand/omap2.c -@@ -275,11 +275,10 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) - if (ret) { - /* PFPW engine is busy, use cpu copy method */ - if (info->nand.options & NAND_BUSWIDTH_16) -- omap_read_buf16(mtd, buf, len); -+ omap_read_buf16(mtd, (u_char *)p, len); - else -- omap_read_buf8(mtd, buf, len); -+ omap_read_buf8(mtd, (u_char *)p, len); - } else { -- p = (u32 *) buf; - do { - r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); - r_count = r_count >> 2; -@@ -305,7 +304,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd, - struct omap_nand_info, mtd); - uint32_t w_count = 0; - int i = 0, ret = 0; -- u16 *p; -+ u16 *p = (u16 *)buf; - unsigned long tim, limit; - - /* take care of subpage writes */ -@@ -321,11 +320,10 @@ static void omap_write_buf_pref(struct mtd_info *mtd, - if (ret) { - /* PFPW engine is busy, use cpu copy method */ - if (info->nand.options & NAND_BUSWIDTH_16) -- omap_write_buf16(mtd, buf, len); -+ omap_write_buf16(mtd, (u_char *)p, len); - else -- omap_write_buf8(mtd, buf, len); -+ omap_write_buf8(mtd, (u_char *)p, len); - } else { -- p = (u16 *) buf; - while (len) { - w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); - w_count = w_count >> 1; --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0028-OMAP-Overo-Add-support-for-spidev.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0028-OMAP-Overo-Add-support-for-spidev.patch deleted file mode 100644 index be1f9630..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0028-OMAP-Overo-Add-support-for-spidev.patch +++ /dev/null @@ -1,46 +0,0 @@ -From ee2dcb39e9255fc0aa6b4e267e9553bdbd11e82b Mon Sep 17 00:00:00 2001 -From: Scott Ellis -Date: Sun, 23 Jan 2011 20:39:35 -0800 -Subject: [PATCH 28/32] OMAP: Overo: Add support for spidev - ---- - arch/arm/mach-omap2/board-overo.c | 16 ++++++++++++++++ - 1 files changed, 16 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c -index 61c59fc..05dd3eb 100644 ---- a/arch/arm/mach-omap2/board-overo.c -+++ b/arch/arm/mach-omap2/board-overo.c -@@ -683,6 +683,14 @@ static struct spi_board_info overo_spi_board_info[] __initdata = { - .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN), - .platform_data = &ads7846_config, - }, -+#elif defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) -+ { -+ .modalias = "spidev", -+ .bus_num = 1, -+ .chip_select = 0, -+ .max_speed_hz = 48000000, -+ .mode = SPI_MODE_0, -+ }, - #endif - #if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ - defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) -@@ -693,6 +701,14 @@ static struct spi_board_info overo_spi_board_info[] __initdata = { - .max_speed_hz = 500000, - .mode = SPI_MODE_3, - }, -+#elif defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) -+ { -+ .modalias = "spidev", -+ .bus_num = 1, -+ .chip_select = 1, -+ .max_speed_hz = 48000000, -+ .mode = SPI_MODE_0, -+ }, - #endif - }; - --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0029-unionfs-Add-support-for-unionfs-2.5.9.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0029-unionfs-Add-support-for-unionfs-2.5.9.patch deleted file mode 100644 index c17608b0..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0029-unionfs-Add-support-for-unionfs-2.5.9.patch +++ /dev/null @@ -1,11494 +0,0 @@ -From 0de368979f94e7c51940979c6149d34aec08f13f Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Mon, 2 May 2011 16:14:34 -0700 -Subject: [PATCH 29/32] unionfs: Add support for unionfs 2.5.9 - ---- - Documentation/filesystems/00-INDEX | 2 + - Documentation/filesystems/unionfs/00-INDEX | 10 + - Documentation/filesystems/unionfs/concepts.txt | 287 ++++++ - Documentation/filesystems/unionfs/issues.txt | 28 + - Documentation/filesystems/unionfs/rename.txt | 31 + - Documentation/filesystems/unionfs/usage.txt | 134 +++ - MAINTAINERS | 8 + - fs/Kconfig | 1 + - fs/Makefile | 1 + - fs/namei.c | 38 + - fs/splice.c | 22 +- - fs/stack.c | 14 +- - fs/unionfs/Kconfig | 24 + - fs/unionfs/Makefile | 17 + - fs/unionfs/commonfops.c | 898 +++++++++++++++++++ - fs/unionfs/copyup.c | 896 +++++++++++++++++++ - fs/unionfs/debug.c | 548 ++++++++++++ - fs/unionfs/dentry.c | 406 +++++++++ - fs/unionfs/dirfops.c | 302 +++++++ - fs/unionfs/dirhelper.c | 158 ++++ - fs/unionfs/fanout.h | 407 +++++++++ - fs/unionfs/file.c | 382 ++++++++ - fs/unionfs/inode.c | 1099 ++++++++++++++++++++++++ - fs/unionfs/lookup.c | 569 ++++++++++++ - fs/unionfs/main.c | 763 ++++++++++++++++ - fs/unionfs/mmap.c | 89 ++ - fs/unionfs/rdstate.c | 285 ++++++ - fs/unionfs/rename.c | 522 +++++++++++ - fs/unionfs/sioq.c | 101 +++ - fs/unionfs/sioq.h | 91 ++ - fs/unionfs/subr.c | 95 ++ - fs/unionfs/super.c | 1030 ++++++++++++++++++++++ - fs/unionfs/union.h | 679 +++++++++++++++ - fs/unionfs/unlink.c | 278 ++++++ - fs/unionfs/whiteout.c | 601 +++++++++++++ - fs/unionfs/xattr.c | 173 ++++ - include/linux/fs_stack.h | 14 +- - include/linux/magic.h | 2 + - include/linux/namei.h | 3 + - include/linux/splice.h | 5 + - include/linux/union_fs.h | 22 + - security/security.c | 1 + - 42 files changed, 11024 insertions(+), 12 deletions(-) - create mode 100644 Documentation/filesystems/unionfs/00-INDEX - create mode 100644 Documentation/filesystems/unionfs/concepts.txt - create mode 100644 Documentation/filesystems/unionfs/issues.txt - create mode 100644 Documentation/filesystems/unionfs/rename.txt - create mode 100644 Documentation/filesystems/unionfs/usage.txt - create mode 100644 fs/unionfs/Kconfig - create mode 100644 fs/unionfs/Makefile - create mode 100644 fs/unionfs/commonfops.c - create mode 100644 fs/unionfs/copyup.c - create mode 100644 fs/unionfs/debug.c - create mode 100644 fs/unionfs/dentry.c - create mode 100644 fs/unionfs/dirfops.c - create mode 100644 fs/unionfs/dirhelper.c - create mode 100644 fs/unionfs/fanout.h - create mode 100644 fs/unionfs/file.c - create mode 100644 fs/unionfs/inode.c - create mode 100644 fs/unionfs/lookup.c - create mode 100644 fs/unionfs/main.c - create mode 100644 fs/unionfs/mmap.c - create mode 100644 fs/unionfs/rdstate.c - create mode 100644 fs/unionfs/rename.c - create mode 100644 fs/unionfs/sioq.c - create mode 100644 fs/unionfs/sioq.h - create mode 100644 fs/unionfs/subr.c - create mode 100644 fs/unionfs/super.c - create mode 100644 fs/unionfs/union.h - create mode 100644 fs/unionfs/unlink.c - create mode 100644 fs/unionfs/whiteout.c - create mode 100644 fs/unionfs/xattr.c - create mode 100644 include/linux/union_fs.h - -diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX -index 8c624a1..4aa288b 100644 ---- a/Documentation/filesystems/00-INDEX -+++ b/Documentation/filesystems/00-INDEX -@@ -110,6 +110,8 @@ udf.txt - - info and mount options for the UDF filesystem. - ufs.txt - - info on the ufs filesystem. -+unionfs/ -+ - info on the unionfs filesystem - vfat.txt - - info on using the VFAT filesystem used in Windows NT and Windows 95 - vfs.txt -diff --git a/Documentation/filesystems/unionfs/00-INDEX b/Documentation/filesystems/unionfs/00-INDEX -new file mode 100644 -index 0000000..96fdf67 ---- /dev/null -+++ b/Documentation/filesystems/unionfs/00-INDEX -@@ -0,0 +1,10 @@ -+00-INDEX -+ - this file. -+concepts.txt -+ - A brief introduction of concepts. -+issues.txt -+ - A summary of known issues with unionfs. -+rename.txt -+ - Information regarding rename operations. -+usage.txt -+ - Usage information and examples. -diff --git a/Documentation/filesystems/unionfs/concepts.txt b/Documentation/filesystems/unionfs/concepts.txt -new file mode 100644 -index 0000000..b853788 ---- /dev/null -+++ b/Documentation/filesystems/unionfs/concepts.txt -@@ -0,0 +1,287 @@ -+Unionfs 2.x CONCEPTS: -+===================== -+ -+This file describes the concepts needed by a namespace unification file -+system. -+ -+ -+Branch Priority: -+================ -+ -+Each branch is assigned a unique priority - starting from 0 (highest -+priority). No two branches can have the same priority. -+ -+ -+Branch Mode: -+============ -+ -+Each branch is assigned a mode - read-write or read-only. This allows -+directories on media mounted read-write to be used in a read-only manner. -+ -+ -+Whiteouts: -+========== -+ -+A whiteout removes a file name from the namespace. Whiteouts are needed when -+one attempts to remove a file on a read-only branch. -+ -+Suppose we have a two-branch union, where branch 0 is read-write and branch -+1 is read-only. And a file 'foo' on branch 1: -+ -+./b0/ -+./b1/ -+./b1/foo -+ -+The unified view would simply be: -+ -+./union/ -+./union/foo -+ -+Since 'foo' is stored on a read-only branch, it cannot be removed. A -+whiteout is used to remove the name 'foo' from the unified namespace. Again, -+since branch 1 is read-only, the whiteout cannot be created there. So, we -+try on a higher priority (lower numerically) branch and create the whiteout -+there. -+ -+./b0/ -+./b0/.wh.foo -+./b1/ -+./b1/foo -+ -+Later, when Unionfs traverses branches (due to lookup or readdir), it -+eliminate 'foo' from the namespace (as well as the whiteout itself.) -+ -+ -+Opaque Directories: -+=================== -+ -+Assume we have a unionfs mount comprising of two branches. Branch 0 is -+empty; branch 1 has the directory /a and file /a/f. Let's say we mount a -+union of branch 0 as read-write and branch 1 as read-only. Now, let's say -+we try to perform the following operation in the union: -+ -+ rm -fr a -+ -+Because branch 1 is not writable, we cannot physically remove the file /a/f -+or the directory /a. So instead, we will create a whiteout in branch 0 -+named /.wh.a, masking out the name "a" from branch 1. Next, let's say we -+try to create a directory named "a" as follows: -+ -+ mkdir a -+ -+Because we have a whiteout for "a" already, Unionfs behaves as if "a" -+doesn't exist, and thus will delete the whiteout and replace it with an -+actual directory named "a". -+ -+The problem now is that if you try to "ls" in the union, Unionfs will -+perform is normal directory name unification, for *all* directories named -+"a" in all branches. This will cause the file /a/f from branch 1 to -+re-appear in the union's namespace, which violates Unix semantics. -+ -+To avoid this problem, we have a different form of whiteouts for -+directories, called "opaque directories" (same as BSD Union Mount does). -+Whenever we replace a whiteout with a directory, that directory is marked as -+opaque. In Unionfs 2.x, it means that we create a file named -+/a/.wh.__dir_opaque in branch 0, after having created directory /a there. -+When unionfs notices that a directory is opaque, it stops all namespace -+operations (including merging readdir contents) at that opaque directory. -+This prevents re-exposing names from masked out directories. -+ -+ -+Duplicate Elimination: -+====================== -+ -+It is possible for files on different branches to have the same name. -+Unionfs then has to select which instance of the file to show to the user. -+Given the fact that each branch has a priority associated with it, the -+simplest solution is to take the instance from the highest priority -+(numerically lowest value) and "hide" the others. -+ -+ -+Unlinking: -+========= -+ -+Unlink operation on non-directory instances is optimized to remove the -+maximum possible objects in case multiple underlying branches have the same -+file name. The unlink operation will first try to delete file instances -+from highest priority branch and then move further to delete from remaining -+branches in order of their decreasing priority. Consider a case (F..D..F), -+where F is a file and D is a directory of the same name; here, some -+intermediate branch could have an empty directory instance with the same -+name, so this operation also tries to delete this directory instance and -+proceed further to delete from next possible lower priority branch. The -+unionfs unlink operation will smoothly delete the files with same name from -+all possible underlying branches. In case if some error occurs, it creates -+whiteout in highest priority branch that will hide file instance in rest of -+the branches. An error could occur either if an unlink operations in any of -+the underlying branch failed or if a branch has no write permission. -+ -+This unlinking policy is known as "delete all" and it has the benefit of -+overall reducing the number of inodes used by duplicate files, and further -+reducing the total number of inodes consumed by whiteouts. The cost is of -+extra processing, but testing shows this extra processing is well worth the -+savings. -+ -+ -+Copyup: -+======= -+ -+When a change is made to the contents of a file's data or meta-data, they -+have to be stored somewhere. The best way is to create a copy of the -+original file on a branch that is writable, and then redirect the write -+though to this copy. The copy must be made on a higher priority branch so -+that lookup and readdir return this newer "version" of the file rather than -+the original (see duplicate elimination). -+ -+An entire unionfs mount can be read-only or read-write. If it's read-only, -+then none of the branches will be written to, even if some of the branches -+are physically writeable. If the unionfs mount is read-write, then the -+leftmost (highest priority) branch must be writeable (for copyup to take -+place); the remaining branches can be any mix of read-write and read-only. -+ -+In a writeable mount, unionfs will create new files/dir in the leftmost -+branch. If one tries to modify a file in a read-only branch/media, unionfs -+will copyup the file to the leftmost branch and modify it there. If you try -+to modify a file from a writeable branch which is not the leftmost branch, -+then unionfs will modify it in that branch; this is useful if you, say, -+unify differnet packages (e.g., apache, sendmail, ftpd, etc.) and you want -+changes to specific package files to remain logically in the directory where -+they came from. -+ -+Cache Coherency: -+================ -+ -+Unionfs users often want to be able to modify files and directories directly -+on the lower branches, and have those changes be visible at the Unionfs -+level. This means that data (e.g., pages) and meta-data (dentries, inodes, -+open files, etc.) have to be synchronized between the upper and lower -+layers. In other words, the newest changes from a layer below have to be -+propagated to the Unionfs layer above. If the two layers are not in sync, a -+cache incoherency ensues, which could lead to application failures and even -+oopses. The Linux kernel, however, has a rather limited set of mechanisms -+to ensure this inter-layer cache coherency---so Unionfs has to do most of -+the hard work on its own. -+ -+Maintaining Invariants: -+ -+The way Unionfs ensures cache coherency is as follows. At each entry point -+to a Unionfs file system method, we call a utility function to validate the -+primary objects of this method. Generally, we call unionfs_file_revalidate -+on open files, and __unionfs_d_revalidate_chain on dentries (which also -+validates inodes). These utility functions check to see whether the upper -+Unionfs object is in sync with any of the lower objects that it represents. -+The checks we perform include whether the Unionfs superblock has a newer -+generation number, or if any of the lower objects mtime's or ctime's are -+newer. (Note: generation numbers change when branch-management commands are -+issued, so in a way, maintaining cache coherency is also very important for -+branch-management.) If indeed we determine that any Unionfs object is no -+longer in sync with its lower counterparts, then we rebuild that object -+similarly to how we do so for branch-management. -+ -+While rebuilding Unionfs's objects, we also purge any page mappings and -+truncate inode pages (see fs/unionfs/dentry.c:purge_inode_data). This is to -+ensure that Unionfs will re-get the newer data from the lower branches. We -+perform this purging only if the Unionfs operation in question is a reading -+operation; if Unionfs is performing a data writing operation (e.g., ->write, -+->commit_write, etc.) then we do NOT flush the lower mappings/pages: this is -+because (1) a self-deadlock could occur and (2) the upper Unionfs pages are -+considered more authoritative anyway, as they are newer and will overwrite -+any lower pages. -+ -+Unionfs maintains the following important invariant regarding mtime's, -+ctime's, and atime's: the upper inode object's times are the max() of all of -+the lower ones. For non-directory objects, there's only one object below, -+so the mapping is simple; for directory objects, there could me multiple -+lower objects and we have to sync up with the newest one of all the lower -+ones. This invariant is important to maintain, especially for directories -+(besides, we need this to be POSIX compliant). A union could comprise -+multiple writable branches, each of which could change. If we don't reflect -+the newest possible mtime/ctime, some applications could fail. For example, -+NFSv2/v3 exports check for newer directory mtimes on the server to determine -+if the client-side attribute cache should be purged. -+ -+To maintain these important invariants, of course, Unionfs carefully -+synchronizes upper and lower times in various places. For example, if we -+copy-up a file to a top-level branch, the parent directory where the file -+was copied up to will now have a new mtime: so after a successful copy-up, -+we sync up with the new top-level branch's parent directory mtime. -+ -+Implementation: -+ -+This cache-coherency implementation is efficient because it defers any -+synchronizing between the upper and lower layers until absolutely needed. -+Consider the example a common situation where users perform a lot of lower -+changes, such as untarring a whole package. While these take place, -+typically the user doesn't access the files via Unionfs; only after the -+lower changes are done, does the user try to access the lower files. With -+our cache-coherency implementation, the entirety of the changes to the lower -+branches will not result in a single CPU cycle spent at the Unionfs level -+until the user invokes a system call that goes through Unionfs. -+ -+We have considered two alternate cache-coherency designs. (1) Using the -+dentry/inode notify functionality to register interest in finding out about -+any lower changes. This is a somewhat limited and also a heavy-handed -+approach which could result in many notifications to the Unionfs layer upon -+each small change at the lower layer (imagine a file being modified multiple -+times in rapid succession). (2) Rewriting the VFS to support explicit -+callbacks from lower objects to upper objects. We began exploring such an -+implementation, but found it to be very complicated--it would have resulted -+in massive VFS/MM changes which are unlikely to be accepted by the LKML -+community. We therefore believe that our current cache-coherency design and -+implementation represent the best approach at this time. -+ -+Limitations: -+ -+Our implementation works in that as long as a user process will have caused -+Unionfs to be called, directly or indirectly, even to just do -+->d_revalidate; then we will have purged the current Unionfs data and the -+process will see the new data. For example, a process that continually -+re-reads the same file's data will see the NEW data as soon as the lower -+file had changed, upon the next read(2) syscall (even if the file is still -+open!) However, this doesn't work when the process re-reads the open file's -+data via mmap(2) (unless the user unmaps/closes the file and remaps/reopens -+it). Once we respond to ->readpage(s), then the kernel maps the page into -+the process's address space and there doesn't appear to be a way to force -+the kernel to invalidate those pages/mappings, and force the process to -+re-issue ->readpage. If there's a way to invalidate active mappings and -+force a ->readpage, let us know please (invalidate_inode_pages2 doesn't do -+the trick). -+ -+Our current Unionfs code has to perform many file-revalidation calls. It -+would be really nice if the VFS would export an optional file system hook -+->file_revalidate (similarly to dentry->d_revalidate) that will be called -+before each VFS op that has a "struct file" in it. -+ -+Certain file systems have micro-second granularity (or better) for inode -+times, and asynchronous actions could cause those times to change with some -+small delay. In such cases, Unionfs may see a changed inode time that only -+differs by a tiny fraction of a second: such a change may be a false -+positive indication that the lower object has changed, whereas if unionfs -+waits a little longer, that false indication will not be seen. (These false -+positives are harmless, because they would at most cause unionfs to -+re-validate an object that may need no revalidation, and print a debugging -+message that clutters the console/logs.) Therefore, to minimize the chances -+of these situations, we delay the detection of changed times by a small -+factor of a few seconds, called UNIONFS_MIN_CC_TIME (which defaults to 3 -+seconds, as does NFS). This means that we will detect the change, only a -+couple of seconds later, if indeed the time change persists in the lower -+file object. This delayed detection has an added performance benefit: we -+reduce the number of times that unionfs has to revalidate objects, in case -+there's a lot of concurrent activity on both the upper and lower objects, -+for the same file(s). Lastly, this delayed time attribute detection is -+similar to how NFS clients operate (e.g., acregmin). -+ -+Finally, there is no way currently in Linux to prevent lower directories -+from being moved around (i.e., topology changes); there's no way to prevent -+modifications to directory sub-trees of whole file systems which are mounted -+read-write. It is therefore possible for in-flight operations in unionfs to -+take place, while a lower directory is being moved around. Therefore, if -+you try to, say, create a new file in a directory through unionfs, while the -+directory is being moved around directly, then the new file may get created -+in the new location where that directory was moved to. This is a somewhat -+similar behaviour in NFS: an NFS client could be creating a new file while -+th NFS server is moving th directory around; the file will get successfully -+created in the new location. (The one exception in unionfs is that if the -+branch is marked read-only by unionfs, then a copyup will take place.) -+ -+For more information, see . -diff --git a/Documentation/filesystems/unionfs/issues.txt b/Documentation/filesystems/unionfs/issues.txt -new file mode 100644 -index 0000000..f4b7e7e ---- /dev/null -+++ b/Documentation/filesystems/unionfs/issues.txt -@@ -0,0 +1,28 @@ -+KNOWN Unionfs 2.x ISSUES: -+========================= -+ -+1. Unionfs should not use lookup_one_len() on the underlying f/s as it -+ confuses NFSv4. Currently, unionfs_lookup() passes lookup intents to the -+ lower file-system, this eliminates part of the problem. The remaining -+ calls to lookup_one_len may need to be changed to pass an intent. We are -+ currently introducing VFS changes to fs/namei.c's do_path_lookup() to -+ allow proper file lookup and opening in stackable file systems. -+ -+2. Lockdep (a debugging feature) isn't aware of stacking, and so it -+ incorrectly complains about locking problems. The problem boils down to -+ this: Lockdep considers all objects of a certain type to be in the same -+ class, for example, all inodes. Lockdep doesn't like to see a lock held -+ on two inodes within the same task, and warns that it could lead to a -+ deadlock. However, stackable file systems do precisely that: they lock -+ an upper object, and then a lower object, in a strict order to avoid -+ locking problems; in addition, Unionfs, as a fan-out file system, may -+ have to lock several lower inodes. We are currently looking into Lockdep -+ to see how to make it aware of stackable file systems. For now, we -+ temporarily disable lockdep when calling vfs methods on lower objects, -+ but only for those places where lockdep complained. While this solution -+ may seem unclean, it is not without precedent: other places in the kernel -+ also do similar temporary disabling, of course after carefully having -+ checked that it is the right thing to do. Anyway, you get any warnings -+ from Lockdep, please report them to the Unionfs maintainers. -+ -+For more information, see . -diff --git a/Documentation/filesystems/unionfs/rename.txt b/Documentation/filesystems/unionfs/rename.txt -new file mode 100644 -index 0000000..e20bb82 ---- /dev/null -+++ b/Documentation/filesystems/unionfs/rename.txt -@@ -0,0 +1,31 @@ -+Rename is a complex beast. The following table shows which rename(2) operations -+should succeed and which should fail. -+ -+o: success -+E: error (either unionfs or vfs) -+X: EXDEV -+ -+none = file does not exist -+file = file is a file -+dir = file is a empty directory -+child= file is a non-empty directory -+wh = file is a directory containing only whiteouts; this makes it logically -+ empty -+ -+ none file dir child wh -+file o o E E E -+dir o E o E o -+child X E X E X -+wh o E o E o -+ -+ -+Renaming directories: -+===================== -+ -+Whenever a empty (either physically or logically) directory is being renamed, -+the following sequence of events should take place: -+ -+1) Remove whiteouts from both source and destination directory -+2) Rename source to destination -+3) Make destination opaque to prevent anything under it from showing up -+ -diff --git a/Documentation/filesystems/unionfs/usage.txt b/Documentation/filesystems/unionfs/usage.txt -new file mode 100644 -index 0000000..1adde69 ---- /dev/null -+++ b/Documentation/filesystems/unionfs/usage.txt -@@ -0,0 +1,134 @@ -+Unionfs is a stackable unification file system, which can appear to merge -+the contents of several directories (branches), while keeping their physical -+content separate. Unionfs is useful for unified source tree management, -+merged contents of split CD-ROM, merged separate software package -+directories, data grids, and more. Unionfs allows any mix of read-only and -+read-write branches, as well as insertion and deletion of branches anywhere -+in the fan-out. To maintain Unix semantics, Unionfs handles elimination of -+duplicates, partial-error conditions, and more. -+ -+GENERAL SYNTAX -+============== -+ -+# mount -t unionfs -o , none MOUNTPOINT -+ -+OPTIONS can be any legal combination of: -+ -+- ro # mount file system read-only -+- rw # mount file system read-write -+- remount # remount the file system (see Branch Management below) -+- incgen # increment generation no. (see Cache Consistency below) -+ -+BRANCH-OPTIONS can be either (1) a list of branches given to the "dirs=" -+option, or (2) a list of individual branch manipulation commands, combined -+with the "remount" option, and is further described in the "Branch -+Management" section below. -+ -+The syntax for the "dirs=" mount option is: -+ -+ dirs=branch[=ro|=rw][:...] -+ -+The "dirs=" option takes a colon-delimited list of directories to compose -+the union, with an optional branch mode for each of those directories. -+Directories that come earlier (specified first, on the left) in the list -+have a higher precedence than those which come later. Additionally, -+read-only or read-write permissions of the branch can be specified by -+appending =ro or =rw (default) to each directory. See the Copyup section in -+concepts.txt, for a description of Unionfs's behavior when mixing read-only -+and read-write branches and mounts. -+ -+Syntax: -+ -+ dirs=/branch1[=ro|=rw]:/branch2[=ro|=rw]:...:/branchN[=ro|=rw] -+ -+Example: -+ -+ dirs=/writable_branch=rw:/read-only_branch=ro -+ -+ -+BRANCH MANAGEMENT -+================= -+ -+Once you mount your union for the first time, using the "dirs=" option, you -+can then change the union's overall mode or reconfigure the branches, using -+the remount option, as follows. -+ -+To downgrade a union from read-write to read-only: -+ -+# mount -t unionfs -o remount,ro none MOUNTPOINT -+ -+To upgrade a union from read-only to read-write: -+ -+# mount -t unionfs -o remount,rw none MOUNTPOINT -+ -+To delete a branch /foo, regardless where it is in the current union: -+ -+# mount -t unionfs -o remount,del=/foo none MOUNTPOINT -+ -+To insert (add) a branch /foo before /bar: -+ -+# mount -t unionfs -o remount,add=/bar:/foo none MOUNTPOINT -+ -+To insert (add) a branch /foo (with the "rw" mode flag) before /bar: -+ -+# mount -t unionfs -o remount,add=/bar:/foo=rw none MOUNTPOINT -+ -+To insert (add) a branch /foo (in "rw" mode) at the very beginning (i.e., a -+new highest-priority branch), you can use the above syntax, or use a short -+hand version as follows: -+ -+# mount -t unionfs -o remount,add=/foo none MOUNTPOINT -+ -+To append a branch to the very end (new lowest-priority branch): -+ -+# mount -t unionfs -o remount,add=:/foo none MOUNTPOINT -+ -+To append a branch to the very end (new lowest-priority branch), in -+read-only mode: -+ -+# mount -t unionfs -o remount,add=:/foo=ro none MOUNTPOINT -+ -+Finally, to change the mode of one existing branch, say /foo, from read-only -+to read-write, and change /bar from read-write to read-only: -+ -+# mount -t unionfs -o remount,mode=/foo=rw,mode=/bar=ro none MOUNTPOINT -+ -+Note: in Unionfs 2.x, you cannot set the leftmost branch to readonly because -+then Unionfs won't have any writable place for copyups to take place. -+Moreover, the VFS can get confused when it tries to modify something in a -+file system mounted read-write, but isn't permitted to write to it. -+Instead, you should set the whole union as readonly, as described above. -+If, however, you must set the leftmost branch as readonly, perhaps so you -+can get a snapshot of it at a point in time, then you should insert a new -+writable top-level branch, and mark the one you want as readonly. This can -+be accomplished as follows, assuming that /foo is your current leftmost -+branch: -+ -+# mount -t tmpfs -o size=NNN /new -+# mount -t unionfs -o remount,add=/new,mode=/foo=ro none MOUNTPOINT -+ -+# mount -t unionfs -o remount,del=/new,mode=/foo=rw none MOUNTPOINT -+ -+# umount /new -+ -+CACHE CONSISTENCY -+================= -+ -+If you modify any file on any of the lower branches directly, while there is -+a Unionfs 2.x mounted above any of those branches, you should tell Unionfs -+to purge its caches and re-get the objects. To do that, you have to -+increment the generation number of the superblock using the following -+command: -+ -+# mount -t unionfs -o remount,incgen none MOUNTPOINT -+ -+Note that the older way of incrementing the generation number using an -+ioctl, is no longer supported in Unionfs 2.0 and newer. Ioctls in general -+are not encouraged. Plus, an ioctl is per-file concept, whereas the -+generation number is a per-file-system concept. Worse, such an ioctl -+requires an open file, which then has to be invalidated by the very nature -+of the generation number increase (read: the old generation increase ioctl -+was pretty racy). -+ -+ -+For more information, see . -diff --git a/MAINTAINERS b/MAINTAINERS -index 69f19f1..fd88a30 100644 ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -6319,6 +6319,14 @@ F: Documentation/cdrom/ - F: drivers/cdrom/cdrom.c - F: include/linux/cdrom.h - -+UNIONFS -+P: Erez Zadok -+M: ezk@cs.sunysb.edu -+L: unionfs@filesystems.org -+W: http://unionfs.filesystems.org/ -+T: git git.kernel.org/pub/scm/linux/kernel/git/ezk/unionfs.git -+S: Maintained -+ - UNSORTED BLOCK IMAGES (UBI) - M: Artem Bityutskiy - W: http://www.linux-mtd.infradead.org/ -diff --git a/fs/Kconfig b/fs/Kconfig -index f3aa9b0..0e6182c 100644 ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -170,6 +170,7 @@ if MISC_FILESYSTEMS - source "fs/adfs/Kconfig" - source "fs/affs/Kconfig" - source "fs/ecryptfs/Kconfig" -+source "fs/unionfs/Kconfig" - source "fs/hfs/Kconfig" - source "fs/hfsplus/Kconfig" - source "fs/befs/Kconfig" -diff --git a/fs/Makefile b/fs/Makefile -index fb68c2b..8ca9290 100644 ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -83,6 +83,7 @@ obj-$(CONFIG_ISO9660_FS) += isofs/ - obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+ - obj-$(CONFIG_HFS_FS) += hfs/ - obj-$(CONFIG_ECRYPT_FS) += ecryptfs/ -+obj-$(CONFIG_UNION_FS) += unionfs/ - obj-$(CONFIG_VXFS_FS) += freevxfs/ - obj-$(CONFIG_NFS_FS) += nfs/ - obj-$(CONFIG_EXPORTFS) += exportfs/ -diff --git a/fs/namei.c b/fs/namei.c -index e3c4f11..d9f99a4 100644 ---- a/fs/namei.c -+++ b/fs/namei.c -@@ -578,6 +578,7 @@ void release_open_intent(struct nameidata *nd) - fput(file); - } - } -+EXPORT_SYMBOL_GPL(release_open_intent); - - static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd) - { -@@ -1819,6 +1820,42 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) - return __lookup_hash(&this, base, NULL); - } - -+/* pass nameidata from caller (useful for NFS) */ -+struct dentry *lookup_one_len_nd(const char *name, struct dentry *base, -+ int len, struct nameidata *nd) -+{ -+ struct qstr this; -+ unsigned long hash; -+ unsigned int c; -+ -+ WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex)); -+ -+ this.name = name; -+ this.len = len; -+ if (!len) -+ return ERR_PTR(-EACCES); -+ -+ hash = init_name_hash(); -+ while (len--) { -+ c = *(const unsigned char *)name++; -+ if (c == '/' || c == '\0') -+ return ERR_PTR(-EACCES); -+ hash = partial_name_hash(c, hash); -+ } -+ this.hash = end_name_hash(hash); -+ /* -+ * See if the low-level filesystem might want -+ * to use its own hash.. -+ */ -+ if (base->d_flags & DCACHE_OP_HASH) { -+ int err = base->d_op->d_hash(base, base->d_inode, &this); -+ if (err < 0) -+ return ERR_PTR(err); -+ } -+ -+ return __lookup_hash(&this, base, nd); -+} -+ - int user_path_at(int dfd, const char __user *name, unsigned flags, - struct path *path) - { -@@ -3422,6 +3459,7 @@ EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ - EXPORT_SYMBOL(getname); - EXPORT_SYMBOL(lock_rename); - EXPORT_SYMBOL(lookup_one_len); -+EXPORT_SYMBOL(lookup_one_len_nd); - EXPORT_SYMBOL(page_follow_link_light); - EXPORT_SYMBOL(page_put_link); - EXPORT_SYMBOL(page_readlink); -diff --git a/fs/splice.c b/fs/splice.c -index 50a5d97..a3af841 100644 ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -1081,8 +1081,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); - /* - * Attempt to initiate a splice from pipe to file. - */ --static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, -- loff_t *ppos, size_t len, unsigned int flags) -+long vfs_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags) - { - ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, - loff_t *, size_t, unsigned int); -@@ -1105,13 +1105,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, - - return splice_write(pipe, out, ppos, len, flags); - } -+EXPORT_SYMBOL_GPL(vfs_splice_from); - - /* - * Attempt to initiate a splice from a file to a pipe. - */ --static long do_splice_to(struct file *in, loff_t *ppos, -- struct pipe_inode_info *pipe, size_t len, -- unsigned int flags) -+long vfs_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) - { - ssize_t (*splice_read)(struct file *, loff_t *, - struct pipe_inode_info *, size_t, unsigned int); -@@ -1131,6 +1132,7 @@ static long do_splice_to(struct file *in, loff_t *ppos, - - return splice_read(in, ppos, pipe, len, flags); - } -+EXPORT_SYMBOL_GPL(vfs_splice_to); - - /** - * splice_direct_to_actor - splices data directly between two non-pipes -@@ -1200,7 +1202,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, - size_t read_len; - loff_t pos = sd->pos, prev_pos = pos; - -- ret = do_splice_to(in, &pos, pipe, len, flags); -+ ret = vfs_splice_to(in, &pos, pipe, len, flags); - if (unlikely(ret <= 0)) - goto out_release; - -@@ -1259,8 +1261,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, - { - struct file *file = sd->u.file; - -- return do_splice_from(pipe, file, &file->f_pos, sd->total_len, -- sd->flags); -+ return vfs_splice_from(pipe, file, &file->f_pos, sd->total_len, -+ sd->flags); - } - - /** -@@ -1345,7 +1347,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, - } else - off = &out->f_pos; - -- ret = do_splice_from(ipipe, out, off, len, flags); -+ ret = vfs_splice_from(ipipe, out, off, len, flags); - - if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) - ret = -EFAULT; -@@ -1365,7 +1367,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, - } else - off = &in->f_pos; - -- ret = do_splice_to(in, off, opipe, len, flags); -+ ret = vfs_splice_to(in, off, opipe, len, flags); - - if (off_in && copy_to_user(off_in, off, sizeof(loff_t))) - ret = -EFAULT; -diff --git a/fs/stack.c b/fs/stack.c -index 4a6f7f4..7eeef12 100644 ---- a/fs/stack.c -+++ b/fs/stack.c -@@ -1,8 +1,20 @@ -+/* -+ * Copyright (c) 2006-2009 Erez Zadok -+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2006-2009 Stony Brook University -+ * Copyright (c) 2006-2009 The Research Foundation of SUNY -+ * -+ * 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 - #include - #include - --/* does _NOT_ require i_mutex to be held. -+/* -+ * does _NOT_ require i_mutex to be held. - * - * This function cannot be inlined since i_size_{read,write} is rather - * heavy-weight on 32-bit systems -diff --git a/fs/unionfs/Kconfig b/fs/unionfs/Kconfig -new file mode 100644 -index 0000000..f3c1ac4 ---- /dev/null -+++ b/fs/unionfs/Kconfig -@@ -0,0 +1,24 @@ -+config UNION_FS -+ tristate "Union file system (EXPERIMENTAL)" -+ depends on EXPERIMENTAL -+ help -+ Unionfs is a stackable unification file system, which appears to -+ merge the contents of several directories (branches), while keeping -+ their physical content separate. -+ -+ See for details -+ -+config UNION_FS_XATTR -+ bool "Unionfs extended attributes" -+ depends on UNION_FS -+ help -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page). -+ -+ If unsure, say N. -+ -+config UNION_FS_DEBUG -+ bool "Debug Unionfs" -+ depends on UNION_FS -+ help -+ If you say Y here, you can turn on debugging output from Unionfs. -diff --git a/fs/unionfs/Makefile b/fs/unionfs/Makefile -new file mode 100644 -index 0000000..3e31847 ---- /dev/null -+++ b/fs/unionfs/Makefile -@@ -0,0 +1,17 @@ -+UNIONFS_VERSION="2.5.9 (for 2.6.39-rc5)" -+ -+EXTRA_CFLAGS += -DUNIONFS_VERSION=\"$(UNIONFS_VERSION)\" -+ -+obj-$(CONFIG_UNION_FS) += unionfs.o -+ -+unionfs-y := subr.o dentry.o file.o inode.o main.o super.o \ -+ rdstate.o copyup.o dirhelper.o rename.o unlink.o \ -+ lookup.o commonfops.o dirfops.o sioq.o mmap.o whiteout.o -+ -+unionfs-$(CONFIG_UNION_FS_XATTR) += xattr.o -+ -+unionfs-$(CONFIG_UNION_FS_DEBUG) += debug.o -+ -+ifeq ($(CONFIG_UNION_FS_DEBUG),y) -+EXTRA_CFLAGS += -DDEBUG -+endif -diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c -new file mode 100644 -index 0000000..9f63b1c ---- /dev/null -+++ b/fs/unionfs/commonfops.c -@@ -0,0 +1,898 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * 1) Copyup the file -+ * 2) Rename the file to '.unionfs' - obviously -+ * stolen from NFS's silly rename -+ */ -+static int copyup_deleted_file(struct file *file, struct dentry *dentry, -+ struct dentry *parent, int bstart, int bindex) -+{ -+ static unsigned int counter; -+ const int i_inosize = sizeof(dentry->d_inode->i_ino) * 2; -+ const int countersize = sizeof(counter) * 2; -+ const int nlen = sizeof(".unionfs") + i_inosize + countersize - 1; -+ char name[nlen + 1]; -+ int err; -+ struct dentry *tmp_dentry = NULL; -+ struct dentry *lower_dentry; -+ struct dentry *lower_dir_dentry = NULL; -+ -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bstart); -+ -+ sprintf(name, ".unionfs%*.*lx", -+ i_inosize, i_inosize, lower_dentry->d_inode->i_ino); -+ -+ /* -+ * Loop, looking for an unused temp name to copyup to. -+ * -+ * It's somewhat silly that we look for a free temp tmp name in the -+ * source branch (bstart) instead of the dest branch (bindex), where -+ * the final name will be created. We _will_ catch it if somehow -+ * the name exists in the dest branch, but it'd be nice to catch it -+ * sooner than later. -+ */ -+retry: -+ tmp_dentry = NULL; -+ do { -+ char *suffix = name + nlen - countersize; -+ -+ dput(tmp_dentry); -+ counter++; -+ sprintf(suffix, "%*.*x", countersize, countersize, counter); -+ -+ pr_debug("unionfs: trying to rename %s to %s\n", -+ dentry->d_name.name, name); -+ -+ tmp_dentry = lookup_lck_len(name, lower_dentry->d_parent, -+ nlen); -+ if (IS_ERR(tmp_dentry)) { -+ err = PTR_ERR(tmp_dentry); -+ goto out; -+ } -+ } while (tmp_dentry->d_inode != NULL); /* need negative dentry */ -+ dput(tmp_dentry); -+ -+ err = copyup_named_file(parent->d_inode, file, name, bstart, bindex, -+ i_size_read(file->f_path.dentry->d_inode)); -+ if (err) { -+ if (unlikely(err == -EEXIST)) -+ goto retry; -+ goto out; -+ } -+ -+ /* bring it to the same state as an unlinked file */ -+ lower_dentry = unionfs_lower_dentry_idx(dentry, dbstart(dentry)); -+ if (!unionfs_lower_inode_idx(dentry->d_inode, bindex)) { -+ atomic_inc(&lower_dentry->d_inode->i_count); -+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex, -+ lower_dentry->d_inode); -+ } -+ lower_dir_dentry = lock_parent(lower_dentry); -+ err = vfs_unlink(lower_dir_dentry->d_inode, lower_dentry); -+ unlock_dir(lower_dir_dentry); -+ -+out: -+ if (!err) -+ unionfs_check_dentry(dentry); -+ return err; -+} -+ -+/* -+ * put all references held by upper struct file and free lower file pointer -+ * array -+ */ -+static void cleanup_file(struct file *file) -+{ -+ int bindex, bstart, bend; -+ struct file **lower_files; -+ struct file *lower_file; -+ struct super_block *sb = file->f_path.dentry->d_sb; -+ -+ lower_files = UNIONFS_F(file)->lower_files; -+ bstart = fbstart(file); -+ bend = fbend(file); -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ int i; /* holds (possibly) updated branch index */ -+ int old_bid; -+ -+ lower_file = unionfs_lower_file_idx(file, bindex); -+ if (!lower_file) -+ continue; -+ -+ /* -+ * Find new index of matching branch with an open -+ * file, since branches could have been added or -+ * deleted causing the one with open files to shift. -+ */ -+ old_bid = UNIONFS_F(file)->saved_branch_ids[bindex]; -+ i = branch_id_to_idx(sb, old_bid); -+ if (unlikely(i < 0)) { -+ printk(KERN_ERR "unionfs: no superblock for " -+ "file %p\n", file); -+ continue; -+ } -+ -+ /* decrement count of open files */ -+ branchput(sb, i); -+ /* -+ * fput will perform an mntput for us on the correct branch. -+ * Although we're using the file's old branch configuration, -+ * bindex, which is the old index, correctly points to the -+ * right branch in the file's branch list. In other words, -+ * we're going to mntput the correct branch even if branches -+ * have been added/removed. -+ */ -+ fput(lower_file); -+ UNIONFS_F(file)->lower_files[bindex] = NULL; -+ UNIONFS_F(file)->saved_branch_ids[bindex] = -1; -+ } -+ -+ UNIONFS_F(file)->lower_files = NULL; -+ kfree(lower_files); -+ kfree(UNIONFS_F(file)->saved_branch_ids); -+ /* set to NULL because caller needs to know if to kfree on error */ -+ UNIONFS_F(file)->saved_branch_ids = NULL; -+} -+ -+/* open all lower files for a given file */ -+static int open_all_files(struct file *file) -+{ -+ int bindex, bstart, bend, err = 0; -+ struct file *lower_file; -+ struct dentry *lower_dentry; -+ struct dentry *dentry = file->f_path.dentry; -+ struct super_block *sb = dentry->d_sb; -+ -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry) -+ continue; -+ -+ dget(lower_dentry); -+ unionfs_mntget(dentry, bindex); -+ branchget(sb, bindex); -+ -+ lower_file = -+ dentry_open(lower_dentry, -+ unionfs_lower_mnt_idx(dentry, bindex), -+ file->f_flags, current_cred()); -+ if (IS_ERR(lower_file)) { -+ branchput(sb, bindex); -+ err = PTR_ERR(lower_file); -+ goto out; -+ } else { -+ unionfs_set_lower_file_idx(file, bindex, lower_file); -+ } -+ } -+out: -+ return err; -+} -+ -+/* open the highest priority file for a given upper file */ -+static int open_highest_file(struct file *file, bool willwrite) -+{ -+ int bindex, bstart, bend, err = 0; -+ struct file *lower_file; -+ struct dentry *lower_dentry; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent = dget_parent(dentry); -+ struct inode *parent_inode = parent->d_inode; -+ struct super_block *sb = dentry->d_sb; -+ -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ if (willwrite && IS_WRITE_FLAG(file->f_flags) && is_robranch(dentry)) { -+ for (bindex = bstart - 1; bindex >= 0; bindex--) { -+ err = copyup_file(parent_inode, file, bstart, bindex, -+ i_size_read(dentry->d_inode)); -+ if (!err) -+ break; -+ } -+ atomic_set(&UNIONFS_F(file)->generation, -+ atomic_read(&UNIONFS_I(dentry->d_inode)-> -+ generation)); -+ goto out; -+ } -+ -+ dget(lower_dentry); -+ unionfs_mntget(dentry, bstart); -+ lower_file = dentry_open(lower_dentry, -+ unionfs_lower_mnt_idx(dentry, bstart), -+ file->f_flags, current_cred()); -+ if (IS_ERR(lower_file)) { -+ err = PTR_ERR(lower_file); -+ goto out; -+ } -+ branchget(sb, bstart); -+ unionfs_set_lower_file(file, lower_file); -+ /* Fix up the position. */ -+ lower_file->f_pos = file->f_pos; -+ -+ memcpy(&lower_file->f_ra, &file->f_ra, sizeof(struct file_ra_state)); -+out: -+ dput(parent); -+ return err; -+} -+ -+/* perform a delayed copyup of a read-write file on a read-only branch */ -+static int do_delayed_copyup(struct file *file, struct dentry *parent) -+{ -+ int bindex, bstart, bend, err = 0; -+ struct dentry *dentry = file->f_path.dentry; -+ struct inode *parent_inode = parent->d_inode; -+ -+ bstart = fbstart(file); -+ bend = fbend(file); -+ -+ BUG_ON(!S_ISREG(dentry->d_inode->i_mode)); -+ -+ unionfs_check_file(file); -+ for (bindex = bstart - 1; bindex >= 0; bindex--) { -+ if (!d_deleted(dentry)) -+ err = copyup_file(parent_inode, file, bstart, -+ bindex, -+ i_size_read(dentry->d_inode)); -+ else -+ err = copyup_deleted_file(file, dentry, parent, -+ bstart, bindex); -+ /* if succeeded, set lower open-file flags and break */ -+ if (!err) { -+ struct file *lower_file; -+ lower_file = unionfs_lower_file_idx(file, bindex); -+ lower_file->f_flags = file->f_flags; -+ break; -+ } -+ } -+ if (err || (bstart <= fbstart(file))) -+ goto out; -+ bend = fbend(file); -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ if (unionfs_lower_file_idx(file, bindex)) { -+ branchput(dentry->d_sb, bindex); -+ fput(unionfs_lower_file_idx(file, bindex)); -+ unionfs_set_lower_file_idx(file, bindex, NULL); -+ } -+ } -+ path_put_lowers(dentry, bstart, bend, false); -+ iput_lowers(dentry->d_inode, bstart, bend, false); -+ /* for reg file, we only open it "once" */ -+ fbend(file) = fbstart(file); -+ dbend(dentry) = dbstart(dentry); -+ ibend(dentry->d_inode) = ibstart(dentry->d_inode); -+ -+out: -+ unionfs_check_file(file); -+ return err; -+} -+ -+/* -+ * Helper function for unionfs_file_revalidate/locked. -+ * Expects dentry/parent to be locked already, and revalidated. -+ */ -+static int __unionfs_file_revalidate(struct file *file, struct dentry *dentry, -+ struct dentry *parent, -+ struct super_block *sb, int sbgen, -+ int dgen, bool willwrite) -+{ -+ int fgen; -+ int bstart, bend, orig_brid; -+ int size; -+ int err = 0; -+ -+ fgen = atomic_read(&UNIONFS_F(file)->generation); -+ -+ /* -+ * There are two cases we are interested in. The first is if the -+ * generation is lower than the super-block. The second is if -+ * someone has copied up this file from underneath us, we also need -+ * to refresh things. -+ */ -+ if ((d_deleted(dentry) && dbstart(dentry) >= fbstart(file)) || -+ (sbgen <= fgen && -+ dbstart(dentry) == fbstart(file) && -+ unionfs_lower_file(file))) -+ goto out_may_copyup; -+ -+ /* save orig branch ID */ -+ orig_brid = UNIONFS_F(file)->saved_branch_ids[fbstart(file)]; -+ -+ /* First we throw out the existing files. */ -+ cleanup_file(file); -+ -+ /* Now we reopen the file(s) as in unionfs_open. */ -+ bstart = fbstart(file) = dbstart(dentry); -+ bend = fbend(file) = dbend(dentry); -+ -+ size = sizeof(struct file *) * sbmax(sb); -+ UNIONFS_F(file)->lower_files = kzalloc(size, GFP_KERNEL); -+ if (unlikely(!UNIONFS_F(file)->lower_files)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ size = sizeof(int) * sbmax(sb); -+ UNIONFS_F(file)->saved_branch_ids = kzalloc(size, GFP_KERNEL); -+ if (unlikely(!UNIONFS_F(file)->saved_branch_ids)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ if (S_ISDIR(dentry->d_inode->i_mode)) { -+ /* We need to open all the files. */ -+ err = open_all_files(file); -+ if (err) -+ goto out; -+ } else { -+ int new_brid; -+ /* We only open the highest priority branch. */ -+ err = open_highest_file(file, willwrite); -+ if (err) -+ goto out; -+ new_brid = UNIONFS_F(file)->saved_branch_ids[fbstart(file)]; -+ if (unlikely(new_brid != orig_brid && sbgen > fgen)) { -+ /* -+ * If we re-opened the file on a different branch -+ * than the original one, and this was due to a new -+ * branch inserted, then update the mnt counts of -+ * the old and new branches accordingly. -+ */ -+ unionfs_mntget(dentry, bstart); -+ unionfs_mntput(sb->s_root, -+ branch_id_to_idx(sb, orig_brid)); -+ } -+ /* regular files have only one open lower file */ -+ fbend(file) = fbstart(file); -+ } -+ atomic_set(&UNIONFS_F(file)->generation, -+ atomic_read(&UNIONFS_I(dentry->d_inode)->generation)); -+ -+out_may_copyup: -+ /* Copyup on the first write to a file on a readonly branch. */ -+ if (willwrite && IS_WRITE_FLAG(file->f_flags) && -+ !IS_WRITE_FLAG(unionfs_lower_file(file)->f_flags) && -+ is_robranch(dentry)) { -+ pr_debug("unionfs: do delay copyup of \"%s\"\n", -+ dentry->d_name.name); -+ err = do_delayed_copyup(file, parent); -+ /* regular files have only one open lower file */ -+ if (!err && !S_ISDIR(dentry->d_inode->i_mode)) -+ fbend(file) = fbstart(file); -+ } -+ -+out: -+ if (err) { -+ kfree(UNIONFS_F(file)->lower_files); -+ kfree(UNIONFS_F(file)->saved_branch_ids); -+ } -+ return err; -+} -+ -+/* -+ * Revalidate the struct file -+ * @file: file to revalidate -+ * @parent: parent dentry (locked by caller) -+ * @willwrite: true if caller may cause changes to the file; false otherwise. -+ * Caller must lock/unlock dentry's branch configuration. -+ */ -+int unionfs_file_revalidate(struct file *file, struct dentry *parent, -+ bool willwrite) -+{ -+ struct super_block *sb; -+ struct dentry *dentry; -+ int sbgen, dgen; -+ int err = 0; -+ -+ dentry = file->f_path.dentry; -+ sb = dentry->d_sb; -+ verify_locked(dentry); -+ verify_locked(parent); -+ -+ /* -+ * First revalidate the dentry inside struct file, -+ * but not unhashed dentries. -+ */ -+ if (!d_deleted(dentry) && -+ !__unionfs_d_revalidate(dentry, parent, willwrite)) { -+ err = -ESTALE; -+ goto out; -+ } -+ -+ sbgen = atomic_read(&UNIONFS_SB(sb)->generation); -+ dgen = atomic_read(&UNIONFS_D(dentry)->generation); -+ -+ if (unlikely(sbgen > dgen)) { /* XXX: should never happen */ -+ pr_debug("unionfs: failed to revalidate dentry (%s)\n", -+ dentry->d_name.name); -+ err = -ESTALE; -+ goto out; -+ } -+ -+ err = __unionfs_file_revalidate(file, dentry, parent, sb, -+ sbgen, dgen, willwrite); -+out: -+ return err; -+} -+ -+/* unionfs_open helper function: open a directory */ -+static int __open_dir(struct inode *inode, struct file *file) -+{ -+ struct dentry *lower_dentry; -+ struct file *lower_file; -+ int bindex, bstart, bend; -+ struct vfsmount *mnt; -+ -+ bstart = fbstart(file) = dbstart(file->f_path.dentry); -+ bend = fbend(file) = dbend(file->f_path.dentry); -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_dentry = -+ unionfs_lower_dentry_idx(file->f_path.dentry, bindex); -+ if (!lower_dentry) -+ continue; -+ -+ dget(lower_dentry); -+ unionfs_mntget(file->f_path.dentry, bindex); -+ mnt = unionfs_lower_mnt_idx(file->f_path.dentry, bindex); -+ lower_file = dentry_open(lower_dentry, mnt, file->f_flags, -+ current_cred()); -+ if (IS_ERR(lower_file)) -+ return PTR_ERR(lower_file); -+ -+ unionfs_set_lower_file_idx(file, bindex, lower_file); -+ -+ /* -+ * The branchget goes after the open, because otherwise -+ * we would miss the reference on release. -+ */ -+ branchget(inode->i_sb, bindex); -+ } -+ -+ return 0; -+} -+ -+/* unionfs_open helper function: open a file */ -+static int __open_file(struct inode *inode, struct file *file, -+ struct dentry *parent) -+{ -+ struct dentry *lower_dentry; -+ struct file *lower_file; -+ int lower_flags; -+ int bindex, bstart, bend; -+ -+ lower_dentry = unionfs_lower_dentry(file->f_path.dentry); -+ lower_flags = file->f_flags; -+ -+ bstart = fbstart(file) = dbstart(file->f_path.dentry); -+ bend = fbend(file) = dbend(file->f_path.dentry); -+ -+ /* -+ * check for the permission for lower file. If the error is -+ * COPYUP_ERR, copyup the file. -+ */ -+ if (lower_dentry->d_inode && is_robranch(file->f_path.dentry)) { -+ /* -+ * if the open will change the file, copy it up otherwise -+ * defer it. -+ */ -+ if (lower_flags & O_TRUNC) { -+ int size = 0; -+ int err = -EROFS; -+ -+ /* copyup the file */ -+ for (bindex = bstart - 1; bindex >= 0; bindex--) { -+ err = copyup_file(parent->d_inode, file, -+ bstart, bindex, size); -+ if (!err) { -+ /* only one regular file open */ -+ fbend(file) = fbstart(file); -+ break; -+ } -+ } -+ return err; -+ } else { -+ /* -+ * turn off writeable flags, to force delayed copyup -+ * by caller. -+ */ -+ lower_flags &= ~(OPEN_WRITE_FLAGS); -+ } -+ } -+ -+ dget(lower_dentry); -+ -+ /* -+ * dentry_open will decrement mnt refcnt if err. -+ * otherwise fput() will do an mntput() for us upon file close. -+ */ -+ unionfs_mntget(file->f_path.dentry, bstart); -+ lower_file = -+ dentry_open(lower_dentry, -+ unionfs_lower_mnt_idx(file->f_path.dentry, bstart), -+ lower_flags, current_cred()); -+ if (IS_ERR(lower_file)) -+ return PTR_ERR(lower_file); -+ -+ unionfs_set_lower_file(file, lower_file); -+ branchget(inode->i_sb, bstart); -+ -+ return 0; -+} -+ -+int unionfs_open(struct inode *inode, struct file *file) -+{ -+ int err = 0; -+ struct file *lower_file = NULL; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ int bindex = 0, bstart = 0, bend = 0; -+ int size; -+ int valid = 0; -+ -+ unionfs_read_lock(inode->i_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ /* don't open unhashed/deleted files */ -+ if (d_deleted(dentry)) { -+ err = -ENOENT; -+ goto out_nofree; -+ } -+ -+ /* XXX: should I change 'false' below to the 'willwrite' flag? */ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out_nofree; -+ } -+ -+ file->private_data = -+ kzalloc(sizeof(struct unionfs_file_info), GFP_KERNEL); -+ if (unlikely(!UNIONFS_F(file))) { -+ err = -ENOMEM; -+ goto out_nofree; -+ } -+ fbstart(file) = -1; -+ fbend(file) = -1; -+ atomic_set(&UNIONFS_F(file)->generation, -+ atomic_read(&UNIONFS_I(inode)->generation)); -+ -+ size = sizeof(struct file *) * sbmax(inode->i_sb); -+ UNIONFS_F(file)->lower_files = kzalloc(size, GFP_KERNEL); -+ if (unlikely(!UNIONFS_F(file)->lower_files)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ size = sizeof(int) * sbmax(inode->i_sb); -+ UNIONFS_F(file)->saved_branch_ids = kzalloc(size, GFP_KERNEL); -+ if (unlikely(!UNIONFS_F(file)->saved_branch_ids)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ bstart = fbstart(file) = dbstart(dentry); -+ bend = fbend(file) = dbend(dentry); -+ -+ /* -+ * open all directories and make the unionfs file struct point to -+ * these lower file structs -+ */ -+ if (S_ISDIR(inode->i_mode)) -+ err = __open_dir(inode, file); /* open a dir */ -+ else -+ err = __open_file(inode, file, parent); /* open a file */ -+ -+ /* freeing the allocated resources, and fput the opened files */ -+ if (err) { -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_file = unionfs_lower_file_idx(file, bindex); -+ if (!lower_file) -+ continue; -+ -+ branchput(dentry->d_sb, bindex); -+ /* fput calls dput for lower_dentry */ -+ fput(lower_file); -+ } -+ } -+ -+out: -+ if (err) { -+ kfree(UNIONFS_F(file)->lower_files); -+ kfree(UNIONFS_F(file)->saved_branch_ids); -+ kfree(UNIONFS_F(file)); -+ } -+out_nofree: -+ if (!err) { -+ unionfs_postcopyup_setmnt(dentry); -+ unionfs_copy_attr_times(inode); -+ unionfs_check_file(file); -+ unionfs_check_inode(inode); -+ } -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(inode->i_sb); -+ return err; -+} -+ -+/* -+ * release all lower object references & free the file info structure -+ * -+ * No need to grab sb info's rwsem. -+ */ -+int unionfs_file_release(struct inode *inode, struct file *file) -+{ -+ struct file *lower_file = NULL; -+ struct unionfs_file_info *fileinfo; -+ struct unionfs_inode_info *inodeinfo; -+ struct super_block *sb = inode->i_sb; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ int bindex, bstart, bend; -+ int err = 0; -+ -+ /* -+ * Since mm/memory.c:might_fault() (under PROVE_LOCKING) was -+ * modified in 2.6.29-rc1 to call might_lock_read on mmap_sem, this -+ * has been causing false positives in file system stacking layers. -+ * In particular, our ->mmap is called after sys_mmap2 already holds -+ * mmap_sem, then we lock our own mutexes; but earlier, it's -+ * possible for lockdep to have locked our mutexes first, and then -+ * we call a lower ->readdir which could call might_fault. The -+ * different ordering of the locks is what lockdep complains about -+ * -- unnecessarily. Therefore, we have no choice but to tell -+ * lockdep to temporarily turn off lockdep here. Note: the comments -+ * inside might_sleep also suggest that it would have been -+ * nicer to only annotate paths that needs that might_lock_read. -+ */ -+ lockdep_off(); -+ unionfs_read_lock(sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ /* -+ * We try to revalidate, but the VFS ignores return return values -+ * from file->release, so we must always try to succeed here, -+ * including to do the kfree and dput below. So if revalidation -+ * failed, all we can do is print some message and keep going. -+ */ -+ err = unionfs_file_revalidate(file, parent, -+ UNIONFS_F(file)->wrote_to_file); -+ if (!err) -+ unionfs_check_file(file); -+ fileinfo = UNIONFS_F(file); -+ BUG_ON(file->f_path.dentry->d_inode != inode); -+ inodeinfo = UNIONFS_I(inode); -+ -+ /* fput all the lower files */ -+ bstart = fbstart(file); -+ bend = fbend(file); -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_file = unionfs_lower_file_idx(file, bindex); -+ -+ if (lower_file) { -+ unionfs_set_lower_file_idx(file, bindex, NULL); -+ fput(lower_file); -+ branchput(sb, bindex); -+ } -+ -+ /* if there are no more refs to the dentry, dput it */ -+ if (d_deleted(dentry)) { -+ dput(unionfs_lower_dentry_idx(dentry, bindex)); -+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL); -+ } -+ } -+ -+ kfree(fileinfo->lower_files); -+ kfree(fileinfo->saved_branch_ids); -+ -+ if (fileinfo->rdstate) { -+ fileinfo->rdstate->access = jiffies; -+ spin_lock(&inodeinfo->rdlock); -+ inodeinfo->rdcount++; -+ list_add_tail(&fileinfo->rdstate->cache, -+ &inodeinfo->readdircache); -+ mark_inode_dirty(inode); -+ spin_unlock(&inodeinfo->rdlock); -+ fileinfo->rdstate = NULL; -+ } -+ kfree(fileinfo); -+ -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(sb); -+ lockdep_on(); -+ return err; -+} -+ -+/* pass the ioctl to the lower fs */ -+static long do_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ struct file *lower_file; -+ int err; -+ -+ lower_file = unionfs_lower_file(file); -+ -+ err = -ENOTTY; -+ if (!lower_file || !lower_file->f_op) -+ goto out; -+ if (lower_file->f_op->unlocked_ioctl) { -+ err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg); -+#ifdef CONFIG_COMPAT -+ } else if (lower_file->f_op->ioctl) { -+ err = lower_file->f_op->compat_ioctl( -+ lower_file->f_path.dentry->d_inode, -+ lower_file, cmd, arg); -+#endif -+ } -+ -+out: -+ return err; -+} -+ -+/* -+ * return to user-space the branch indices containing the file in question -+ * -+ * We use fd_set and therefore we are limited to the number of the branches -+ * to FD_SETSIZE, which is currently 1024 - plenty for most people -+ */ -+static int unionfs_ioctl_queryfile(struct file *file, struct dentry *parent, -+ unsigned int cmd, unsigned long arg) -+{ -+ int err = 0; -+ fd_set branchlist; -+ int bstart = 0, bend = 0, bindex = 0; -+ int orig_bstart, orig_bend; -+ struct dentry *dentry, *lower_dentry; -+ struct vfsmount *mnt; -+ -+ dentry = file->f_path.dentry; -+ orig_bstart = dbstart(dentry); -+ orig_bend = dbend(dentry); -+ err = unionfs_partial_lookup(dentry, parent); -+ if (err) -+ goto out; -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ -+ FD_ZERO(&branchlist); -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry) -+ continue; -+ if (likely(lower_dentry->d_inode)) -+ FD_SET(bindex, &branchlist); -+ /* purge any lower objects after partial_lookup */ -+ if (bindex < orig_bstart || bindex > orig_bend) { -+ dput(lower_dentry); -+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL); -+ iput(unionfs_lower_inode_idx(dentry->d_inode, bindex)); -+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex, -+ NULL); -+ mnt = unionfs_lower_mnt_idx(dentry, bindex); -+ if (!mnt) -+ continue; -+ unionfs_mntput(dentry, bindex); -+ unionfs_set_lower_mnt_idx(dentry, bindex, NULL); -+ } -+ } -+ /* restore original dentry's offsets */ -+ dbstart(dentry) = orig_bstart; -+ dbend(dentry) = orig_bend; -+ ibstart(dentry->d_inode) = orig_bstart; -+ ibend(dentry->d_inode) = orig_bend; -+ -+ err = copy_to_user((void __user *)arg, &branchlist, sizeof(fd_set)); -+ if (unlikely(err)) -+ err = -EFAULT; -+ -+out: -+ return err < 0 ? err : bend; -+} -+ -+long unionfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ long err; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, true); -+ if (unlikely(err)) -+ goto out; -+ -+ /* check if asked for local commands */ -+ switch (cmd) { -+ case UNIONFS_IOCTL_INCGEN: -+ /* Increment the superblock generation count */ -+ pr_info("unionfs: incgen ioctl deprecated; " -+ "use \"-o remount,incgen\"\n"); -+ err = -ENOSYS; -+ break; -+ -+ case UNIONFS_IOCTL_QUERYFILE: -+ /* Return list of branches containing the given file */ -+ err = unionfs_ioctl_queryfile(file, parent, cmd, arg); -+ break; -+ -+ default: -+ /* pass the ioctl down */ -+ err = do_ioctl(file, cmd, arg); -+ break; -+ } -+ -+out: -+ unionfs_check_file(file); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+int unionfs_flush(struct file *file, fl_owner_t id) -+{ -+ int err = 0; -+ struct file *lower_file = NULL; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ int bindex, bstart, bend; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, -+ UNIONFS_F(file)->wrote_to_file); -+ if (unlikely(err)) -+ goto out; -+ unionfs_check_file(file); -+ -+ bstart = fbstart(file); -+ bend = fbend(file); -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_file = unionfs_lower_file_idx(file, bindex); -+ -+ if (lower_file && lower_file->f_op && -+ lower_file->f_op->flush) { -+ err = lower_file->f_op->flush(lower_file, id); -+ if (err) -+ goto out; -+ } -+ -+ } -+ -+out: -+ if (!err) -+ unionfs_check_file(file); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c -new file mode 100644 -index 0000000..37c2654 ---- /dev/null -+++ b/fs/unionfs/copyup.c -@@ -0,0 +1,896 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * For detailed explanation of copyup see: -+ * Documentation/filesystems/unionfs/concepts.txt -+ */ -+ -+#ifdef CONFIG_UNION_FS_XATTR -+/* copyup all extended attrs for a given dentry */ -+static int copyup_xattrs(struct dentry *old_lower_dentry, -+ struct dentry *new_lower_dentry) -+{ -+ int err = 0; -+ ssize_t list_size = -1; -+ char *name_list = NULL; -+ char *attr_value = NULL; -+ char *name_list_buf = NULL; -+ -+ /* query the actual size of the xattr list */ -+ list_size = vfs_listxattr(old_lower_dentry, NULL, 0); -+ if (list_size <= 0) { -+ err = list_size; -+ goto out; -+ } -+ -+ /* allocate space for the actual list */ -+ name_list = unionfs_xattr_alloc(list_size + 1, XATTR_LIST_MAX); -+ if (unlikely(!name_list || IS_ERR(name_list))) { -+ err = PTR_ERR(name_list); -+ goto out; -+ } -+ -+ name_list_buf = name_list; /* save for kfree at end */ -+ -+ /* now get the actual xattr list of the source file */ -+ list_size = vfs_listxattr(old_lower_dentry, name_list, list_size); -+ if (list_size <= 0) { -+ err = list_size; -+ goto out; -+ } -+ -+ /* allocate space to hold each xattr's value */ -+ attr_value = unionfs_xattr_alloc(XATTR_SIZE_MAX, XATTR_SIZE_MAX); -+ if (unlikely(!attr_value || IS_ERR(attr_value))) { -+ err = PTR_ERR(name_list); -+ goto out; -+ } -+ -+ /* in a loop, get and set each xattr from src to dst file */ -+ while (*name_list) { -+ ssize_t size; -+ -+ /* Lock here since vfs_getxattr doesn't lock for us */ -+ mutex_lock(&old_lower_dentry->d_inode->i_mutex); -+ size = vfs_getxattr(old_lower_dentry, name_list, -+ attr_value, XATTR_SIZE_MAX); -+ mutex_unlock(&old_lower_dentry->d_inode->i_mutex); -+ if (size < 0) { -+ err = size; -+ goto out; -+ } -+ if (size > XATTR_SIZE_MAX) { -+ err = -E2BIG; -+ goto out; -+ } -+ /* Don't lock here since vfs_setxattr does it for us. */ -+ err = vfs_setxattr(new_lower_dentry, name_list, attr_value, -+ size, 0); -+ /* -+ * Selinux depends on "security.*" xattrs, so to maintain -+ * the security of copied-up files, if Selinux is active, -+ * then we must copy these xattrs as well. So we need to -+ * temporarily get FOWNER privileges. -+ * XXX: move entire copyup code to SIOQ. -+ */ -+ if (err == -EPERM && !capable(CAP_FOWNER)) { -+ const struct cred *old_creds; -+ struct cred *new_creds; -+ -+ new_creds = prepare_creds(); -+ if (unlikely(!new_creds)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ cap_raise(new_creds->cap_effective, CAP_FOWNER); -+ old_creds = override_creds(new_creds); -+ err = vfs_setxattr(new_lower_dentry, name_list, -+ attr_value, size, 0); -+ revert_creds(old_creds); -+ } -+ if (err < 0) -+ goto out; -+ name_list += strlen(name_list) + 1; -+ } -+out: -+ unionfs_xattr_kfree(name_list_buf); -+ unionfs_xattr_kfree(attr_value); -+ /* Ignore if xattr isn't supported */ -+ if (err == -ENOTSUPP || err == -EOPNOTSUPP) -+ err = 0; -+ return err; -+} -+#endif /* CONFIG_UNION_FS_XATTR */ -+ -+/* -+ * Determine the mode based on the copyup flags, and the existing dentry. -+ * -+ * Handle file systems which may not support certain options. For example -+ * jffs2 doesn't allow one to chmod a symlink. So we ignore such harmless -+ * errors, rather than propagating them up, which results in copyup errors -+ * and errors returned back to users. -+ */ -+static int copyup_permissions(struct super_block *sb, -+ struct dentry *old_lower_dentry, -+ struct dentry *new_lower_dentry) -+{ -+ struct inode *i = old_lower_dentry->d_inode; -+ struct iattr newattrs; -+ int err; -+ -+ newattrs.ia_atime = i->i_atime; -+ newattrs.ia_mtime = i->i_mtime; -+ newattrs.ia_ctime = i->i_ctime; -+ newattrs.ia_gid = i->i_gid; -+ newattrs.ia_uid = i->i_uid; -+ newattrs.ia_valid = ATTR_CTIME | ATTR_ATIME | ATTR_MTIME | -+ ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_FORCE | -+ ATTR_GID | ATTR_UID; -+ mutex_lock(&new_lower_dentry->d_inode->i_mutex); -+ err = notify_change(new_lower_dentry, &newattrs); -+ if (err) -+ goto out; -+ -+ /* now try to change the mode and ignore EOPNOTSUPP on symlinks */ -+ newattrs.ia_mode = i->i_mode; -+ newattrs.ia_valid = ATTR_MODE | ATTR_FORCE; -+ err = notify_change(new_lower_dentry, &newattrs); -+ if (err == -EOPNOTSUPP && -+ S_ISLNK(new_lower_dentry->d_inode->i_mode)) { -+ printk(KERN_WARNING -+ "unionfs: changing \"%s\" symlink mode unsupported\n", -+ new_lower_dentry->d_name.name); -+ err = 0; -+ } -+ -+out: -+ mutex_unlock(&new_lower_dentry->d_inode->i_mutex); -+ return err; -+} -+ -+/* -+ * create the new device/file/directory - use copyup_permission to copyup -+ * times, and mode -+ * -+ * if the object being copied up is a regular file, the file is only created, -+ * the contents have to be copied up separately -+ */ -+static int __copyup_ndentry(struct dentry *old_lower_dentry, -+ struct dentry *new_lower_dentry, -+ struct dentry *new_lower_parent_dentry, -+ char *symbuf) -+{ -+ int err = 0; -+ umode_t old_mode = old_lower_dentry->d_inode->i_mode; -+ struct sioq_args args; -+ -+ if (S_ISDIR(old_mode)) { -+ args.mkdir.parent = new_lower_parent_dentry->d_inode; -+ args.mkdir.dentry = new_lower_dentry; -+ args.mkdir.mode = old_mode; -+ -+ run_sioq(__unionfs_mkdir, &args); -+ err = args.err; -+ } else if (S_ISLNK(old_mode)) { -+ args.symlink.parent = new_lower_parent_dentry->d_inode; -+ args.symlink.dentry = new_lower_dentry; -+ args.symlink.symbuf = symbuf; -+ -+ run_sioq(__unionfs_symlink, &args); -+ err = args.err; -+ } else if (S_ISBLK(old_mode) || S_ISCHR(old_mode) || -+ S_ISFIFO(old_mode) || S_ISSOCK(old_mode)) { -+ args.mknod.parent = new_lower_parent_dentry->d_inode; -+ args.mknod.dentry = new_lower_dentry; -+ args.mknod.mode = old_mode; -+ args.mknod.dev = old_lower_dentry->d_inode->i_rdev; -+ -+ run_sioq(__unionfs_mknod, &args); -+ err = args.err; -+ } else if (S_ISREG(old_mode)) { -+ struct nameidata nd; -+ err = init_lower_nd(&nd, LOOKUP_CREATE); -+ if (unlikely(err < 0)) -+ goto out; -+ args.create.nd = &nd; -+ args.create.parent = new_lower_parent_dentry->d_inode; -+ args.create.dentry = new_lower_dentry; -+ args.create.mode = old_mode; -+ -+ run_sioq(__unionfs_create, &args); -+ err = args.err; -+ release_lower_nd(&nd, err); -+ } else { -+ printk(KERN_CRIT "unionfs: unknown inode type %d\n", -+ old_mode); -+ BUG(); -+ } -+ -+out: -+ return err; -+} -+ -+static int __copyup_reg_data(struct dentry *dentry, -+ struct dentry *new_lower_dentry, int new_bindex, -+ struct dentry *old_lower_dentry, int old_bindex, -+ struct file **copyup_file, loff_t len) -+{ -+ struct super_block *sb = dentry->d_sb; -+ struct file *input_file; -+ struct file *output_file; -+ struct vfsmount *output_mnt; -+ mm_segment_t old_fs; -+ char *buf = NULL; -+ ssize_t read_bytes, write_bytes; -+ loff_t size; -+ int err = 0; -+ -+ /* open old file */ -+ unionfs_mntget(dentry, old_bindex); -+ branchget(sb, old_bindex); -+ /* dentry_open calls dput and mntput if it returns an error */ -+ input_file = dentry_open(old_lower_dentry, -+ unionfs_lower_mnt_idx(dentry, old_bindex), -+ O_RDONLY | O_LARGEFILE, current_cred()); -+ if (IS_ERR(input_file)) { -+ dput(old_lower_dentry); -+ err = PTR_ERR(input_file); -+ goto out; -+ } -+ if (unlikely(!input_file->f_op || !input_file->f_op->read)) { -+ err = -EINVAL; -+ goto out_close_in; -+ } -+ -+ /* open new file */ -+ dget(new_lower_dentry); -+ output_mnt = unionfs_mntget(sb->s_root, new_bindex); -+ branchget(sb, new_bindex); -+ output_file = dentry_open(new_lower_dentry, output_mnt, -+ O_RDWR | O_LARGEFILE, current_cred()); -+ if (IS_ERR(output_file)) { -+ err = PTR_ERR(output_file); -+ goto out_close_in2; -+ } -+ if (unlikely(!output_file->f_op || !output_file->f_op->write)) { -+ err = -EINVAL; -+ goto out_close_out; -+ } -+ -+ /* allocating a buffer */ -+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL); -+ if (unlikely(!buf)) { -+ err = -ENOMEM; -+ goto out_close_out; -+ } -+ -+ input_file->f_pos = 0; -+ output_file->f_pos = 0; -+ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ size = len; -+ err = 0; -+ do { -+ if (len >= PAGE_SIZE) -+ size = PAGE_SIZE; -+ else if ((len < PAGE_SIZE) && (len > 0)) -+ size = len; -+ -+ len -= PAGE_SIZE; -+ -+ read_bytes = -+ input_file->f_op->read(input_file, -+ (char __user *)buf, size, -+ &input_file->f_pos); -+ if (read_bytes <= 0) { -+ err = read_bytes; -+ break; -+ } -+ -+ /* see Documentation/filesystems/unionfs/issues.txt */ -+ lockdep_off(); -+ write_bytes = -+ output_file->f_op->write(output_file, -+ (char __user *)buf, -+ read_bytes, -+ &output_file->f_pos); -+ lockdep_on(); -+ if ((write_bytes < 0) || (write_bytes < read_bytes)) { -+ err = write_bytes; -+ break; -+ } -+ } while ((read_bytes > 0) && (len > 0)); -+ -+ set_fs(old_fs); -+ -+ kfree(buf); -+ -+ if (!err) -+ err = output_file->f_op->fsync(output_file, 0); -+ -+ if (err) -+ goto out_close_out; -+ -+ if (copyup_file) { -+ *copyup_file = output_file; -+ goto out_close_in; -+ } -+ -+out_close_out: -+ fput(output_file); -+ -+out_close_in2: -+ branchput(sb, new_bindex); -+ -+out_close_in: -+ fput(input_file); -+ -+out: -+ branchput(sb, old_bindex); -+ -+ return err; -+} -+ -+/* -+ * dput the lower references for old and new dentry & clear a lower dentry -+ * pointer -+ */ -+static void __clear(struct dentry *dentry, struct dentry *old_lower_dentry, -+ int old_bstart, int old_bend, -+ struct dentry *new_lower_dentry, int new_bindex) -+{ -+ /* get rid of the lower dentry and all its traces */ -+ unionfs_set_lower_dentry_idx(dentry, new_bindex, NULL); -+ dbstart(dentry) = old_bstart; -+ dbend(dentry) = old_bend; -+ -+ dput(new_lower_dentry); -+ dput(old_lower_dentry); -+} -+ -+/* -+ * Copy up a dentry to a file of specified name. -+ * -+ * @dir: used to pull the ->i_sb to access other branches -+ * @dentry: the non-negative dentry whose lower_inode we should copy -+ * @bstart: the branch of the lower_inode to copy from -+ * @new_bindex: the branch to create the new file in -+ * @name: the name of the file to create -+ * @namelen: length of @name -+ * @copyup_file: the "struct file" to return (optional) -+ * @len: how many bytes to copy-up? -+ */ -+int copyup_dentry(struct inode *dir, struct dentry *dentry, int bstart, -+ int new_bindex, const char *name, int namelen, -+ struct file **copyup_file, loff_t len) -+{ -+ struct dentry *new_lower_dentry; -+ struct dentry *old_lower_dentry = NULL; -+ struct super_block *sb; -+ int err = 0; -+ int old_bindex; -+ int old_bstart; -+ int old_bend; -+ struct dentry *new_lower_parent_dentry = NULL; -+ mm_segment_t oldfs; -+ char *symbuf = NULL; -+ -+ verify_locked(dentry); -+ -+ old_bindex = bstart; -+ old_bstart = dbstart(dentry); -+ old_bend = dbend(dentry); -+ -+ BUG_ON(new_bindex < 0); -+ BUG_ON(new_bindex >= old_bindex); -+ -+ sb = dir->i_sb; -+ -+ err = is_robranch_super(sb, new_bindex); -+ if (err) -+ goto out; -+ -+ /* Create the directory structure above this dentry. */ -+ new_lower_dentry = create_parents(dir, dentry, name, new_bindex); -+ if (IS_ERR(new_lower_dentry)) { -+ err = PTR_ERR(new_lower_dentry); -+ goto out; -+ } -+ -+ old_lower_dentry = unionfs_lower_dentry_idx(dentry, old_bindex); -+ /* we conditionally dput this old_lower_dentry at end of function */ -+ dget(old_lower_dentry); -+ -+ /* For symlinks, we must read the link before we lock the directory. */ -+ if (S_ISLNK(old_lower_dentry->d_inode->i_mode)) { -+ -+ symbuf = kmalloc(PATH_MAX, GFP_KERNEL); -+ if (unlikely(!symbuf)) { -+ __clear(dentry, old_lower_dentry, -+ old_bstart, old_bend, -+ new_lower_dentry, new_bindex); -+ err = -ENOMEM; -+ goto out_free; -+ } -+ -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = old_lower_dentry->d_inode->i_op->readlink( -+ old_lower_dentry, -+ (char __user *)symbuf, -+ PATH_MAX); -+ set_fs(oldfs); -+ if (err < 0) { -+ __clear(dentry, old_lower_dentry, -+ old_bstart, old_bend, -+ new_lower_dentry, new_bindex); -+ goto out_free; -+ } -+ symbuf[err] = '\0'; -+ } -+ -+ /* Now we lock the parent, and create the object in the new branch. */ -+ new_lower_parent_dentry = lock_parent(new_lower_dentry); -+ -+ /* create the new inode */ -+ err = __copyup_ndentry(old_lower_dentry, new_lower_dentry, -+ new_lower_parent_dentry, symbuf); -+ -+ if (err) { -+ __clear(dentry, old_lower_dentry, -+ old_bstart, old_bend, -+ new_lower_dentry, new_bindex); -+ goto out_unlock; -+ } -+ -+ /* We actually copyup the file here. */ -+ if (S_ISREG(old_lower_dentry->d_inode->i_mode)) -+ err = __copyup_reg_data(dentry, new_lower_dentry, new_bindex, -+ old_lower_dentry, old_bindex, -+ copyup_file, len); -+ if (err) -+ goto out_unlink; -+ -+ /* Set permissions. */ -+ err = copyup_permissions(sb, old_lower_dentry, new_lower_dentry); -+ if (err) -+ goto out_unlink; -+ -+#ifdef CONFIG_UNION_FS_XATTR -+ /* Selinux uses extended attributes for permissions. */ -+ err = copyup_xattrs(old_lower_dentry, new_lower_dentry); -+ if (err) -+ goto out_unlink; -+#endif /* CONFIG_UNION_FS_XATTR */ -+ -+ /* do not allow files getting deleted to be re-interposed */ -+ if (!d_deleted(dentry)) -+ unionfs_reinterpose(dentry); -+ -+ goto out_unlock; -+ -+out_unlink: -+ /* -+ * copyup failed, because we possibly ran out of space or -+ * quota, or something else happened so let's unlink; we don't -+ * really care about the return value of vfs_unlink -+ */ -+ vfs_unlink(new_lower_parent_dentry->d_inode, new_lower_dentry); -+ -+ if (copyup_file) { -+ /* need to close the file */ -+ -+ fput(*copyup_file); -+ branchput(sb, new_bindex); -+ } -+ -+ /* -+ * TODO: should we reset the error to something like -EIO? -+ * -+ * If we don't reset, the user may get some nonsensical errors, but -+ * on the other hand, if we reset to EIO, we guarantee that the user -+ * will get a "confusing" error message. -+ */ -+ -+out_unlock: -+ unlock_dir(new_lower_parent_dentry); -+ -+out_free: -+ /* -+ * If old_lower_dentry was not a file, then we need to dput it. If -+ * it was a file, then it was already dput indirectly by other -+ * functions we call above which operate on regular files. -+ */ -+ if (old_lower_dentry && old_lower_dentry->d_inode && -+ !S_ISREG(old_lower_dentry->d_inode->i_mode)) -+ dput(old_lower_dentry); -+ kfree(symbuf); -+ -+ if (err) { -+ /* -+ * if directory creation succeeded, but inode copyup failed, -+ * then purge new dentries. -+ */ -+ if (dbstart(dentry) < old_bstart && -+ ibstart(dentry->d_inode) > dbstart(dentry)) -+ __clear(dentry, NULL, old_bstart, old_bend, -+ unionfs_lower_dentry(dentry), dbstart(dentry)); -+ goto out; -+ } -+ if (!S_ISDIR(dentry->d_inode->i_mode)) { -+ unionfs_postcopyup_release(dentry); -+ if (!unionfs_lower_inode(dentry->d_inode)) { -+ /* -+ * If we got here, then we copied up to an -+ * unlinked-open file, whose name is .unionfsXXXXX. -+ */ -+ struct inode *inode = new_lower_dentry->d_inode; -+ atomic_inc(&inode->i_count); -+ unionfs_set_lower_inode_idx(dentry->d_inode, -+ ibstart(dentry->d_inode), -+ inode); -+ } -+ } -+ unionfs_postcopyup_setmnt(dentry); -+ /* sync inode times from copied-up inode to our inode */ -+ unionfs_copy_attr_times(dentry->d_inode); -+ unionfs_check_inode(dir); -+ unionfs_check_dentry(dentry); -+out: -+ return err; -+} -+ -+/* -+ * This function creates a copy of a file represented by 'file' which -+ * currently resides in branch 'bstart' to branch 'new_bindex.' The copy -+ * will be named "name". -+ */ -+int copyup_named_file(struct inode *dir, struct file *file, char *name, -+ int bstart, int new_bindex, loff_t len) -+{ -+ int err = 0; -+ struct file *output_file = NULL; -+ -+ err = copyup_dentry(dir, file->f_path.dentry, bstart, new_bindex, -+ name, strlen(name), &output_file, len); -+ if (!err) { -+ fbstart(file) = new_bindex; -+ unionfs_set_lower_file_idx(file, new_bindex, output_file); -+ } -+ -+ return err; -+} -+ -+/* -+ * This function creates a copy of a file represented by 'file' which -+ * currently resides in branch 'bstart' to branch 'new_bindex'. -+ */ -+int copyup_file(struct inode *dir, struct file *file, int bstart, -+ int new_bindex, loff_t len) -+{ -+ int err = 0; -+ struct file *output_file = NULL; -+ struct dentry *dentry = file->f_path.dentry; -+ -+ err = copyup_dentry(dir, dentry, bstart, new_bindex, -+ dentry->d_name.name, dentry->d_name.len, -+ &output_file, len); -+ if (!err) { -+ fbstart(file) = new_bindex; -+ unionfs_set_lower_file_idx(file, new_bindex, output_file); -+ } -+ -+ return err; -+} -+ -+/* purge a dentry's lower-branch states (dput/mntput, etc.) */ -+static void __cleanup_dentry(struct dentry *dentry, int bindex, -+ int old_bstart, int old_bend) -+{ -+ int loop_start; -+ int loop_end; -+ int new_bstart = -1; -+ int new_bend = -1; -+ int i; -+ -+ loop_start = min(old_bstart, bindex); -+ loop_end = max(old_bend, bindex); -+ -+ /* -+ * This loop sets the bstart and bend for the new dentry by -+ * traversing from left to right. It also dputs all negative -+ * dentries except bindex -+ */ -+ for (i = loop_start; i <= loop_end; i++) { -+ if (!unionfs_lower_dentry_idx(dentry, i)) -+ continue; -+ -+ if (i == bindex) { -+ new_bend = i; -+ if (new_bstart < 0) -+ new_bstart = i; -+ continue; -+ } -+ -+ if (!unionfs_lower_dentry_idx(dentry, i)->d_inode) { -+ dput(unionfs_lower_dentry_idx(dentry, i)); -+ unionfs_set_lower_dentry_idx(dentry, i, NULL); -+ -+ unionfs_mntput(dentry, i); -+ unionfs_set_lower_mnt_idx(dentry, i, NULL); -+ } else { -+ if (new_bstart < 0) -+ new_bstart = i; -+ new_bend = i; -+ } -+ } -+ -+ if (new_bstart < 0) -+ new_bstart = bindex; -+ if (new_bend < 0) -+ new_bend = bindex; -+ dbstart(dentry) = new_bstart; -+ dbend(dentry) = new_bend; -+ -+} -+ -+/* set lower inode ptr and update bstart & bend if necessary */ -+static void __set_inode(struct dentry *upper, struct dentry *lower, -+ int bindex) -+{ -+ unionfs_set_lower_inode_idx(upper->d_inode, bindex, -+ igrab(lower->d_inode)); -+ if (likely(ibstart(upper->d_inode) > bindex)) -+ ibstart(upper->d_inode) = bindex; -+ if (likely(ibend(upper->d_inode) < bindex)) -+ ibend(upper->d_inode) = bindex; -+ -+} -+ -+/* set lower dentry ptr and update bstart & bend if necessary */ -+static void __set_dentry(struct dentry *upper, struct dentry *lower, -+ int bindex) -+{ -+ unionfs_set_lower_dentry_idx(upper, bindex, lower); -+ if (likely(dbstart(upper) > bindex)) -+ dbstart(upper) = bindex; -+ if (likely(dbend(upper) < bindex)) -+ dbend(upper) = bindex; -+} -+ -+/* -+ * This function replicates the directory structure up-to given dentry -+ * in the bindex branch. -+ */ -+struct dentry *create_parents(struct inode *dir, struct dentry *dentry, -+ const char *name, int bindex) -+{ -+ int err; -+ struct dentry *child_dentry; -+ struct dentry *parent_dentry; -+ struct dentry *lower_parent_dentry = NULL; -+ struct dentry *lower_dentry = NULL; -+ const char *childname; -+ unsigned int childnamelen; -+ int nr_dentry; -+ int count = 0; -+ int old_bstart; -+ int old_bend; -+ struct dentry **path = NULL; -+ struct super_block *sb; -+ -+ verify_locked(dentry); -+ -+ err = is_robranch_super(dir->i_sb, bindex); -+ if (err) { -+ lower_dentry = ERR_PTR(err); -+ goto out; -+ } -+ -+ old_bstart = dbstart(dentry); -+ old_bend = dbend(dentry); -+ -+ lower_dentry = ERR_PTR(-ENOMEM); -+ -+ /* There is no sense allocating any less than the minimum. */ -+ nr_dentry = 1; -+ path = kmalloc(nr_dentry * sizeof(struct dentry *), GFP_KERNEL); -+ if (unlikely(!path)) -+ goto out; -+ -+ /* assume the negative dentry of unionfs as the parent dentry */ -+ parent_dentry = dentry; -+ -+ /* -+ * This loop finds the first parent that exists in the given branch. -+ * We start building the directory structure from there. At the end -+ * of the loop, the following should hold: -+ * - child_dentry is the first nonexistent child -+ * - parent_dentry is the first existent parent -+ * - path[0] is the = deepest child -+ * - path[count] is the first child to create -+ */ -+ do { -+ child_dentry = parent_dentry; -+ -+ /* find the parent directory dentry in unionfs */ -+ parent_dentry = dget_parent(child_dentry); -+ -+ /* find out the lower_parent_dentry in the given branch */ -+ lower_parent_dentry = -+ unionfs_lower_dentry_idx(parent_dentry, bindex); -+ -+ /* grow path table */ -+ if (count == nr_dentry) { -+ void *p; -+ -+ nr_dentry *= 2; -+ p = krealloc(path, nr_dentry * sizeof(struct dentry *), -+ GFP_KERNEL); -+ if (unlikely(!p)) { -+ lower_dentry = ERR_PTR(-ENOMEM); -+ goto out; -+ } -+ path = p; -+ } -+ -+ /* store the child dentry */ -+ path[count++] = child_dentry; -+ } while (!lower_parent_dentry); -+ count--; -+ -+ sb = dentry->d_sb; -+ -+ /* -+ * This code goes between the begin/end labels and basically -+ * emulates a while(child_dentry != dentry), only cleaner and -+ * shorter than what would be a much longer while loop. -+ */ -+begin: -+ /* get lower parent dir in the current branch */ -+ lower_parent_dentry = unionfs_lower_dentry_idx(parent_dentry, bindex); -+ dput(parent_dentry); -+ -+ /* init the values to lookup */ -+ childname = child_dentry->d_name.name; -+ childnamelen = child_dentry->d_name.len; -+ -+ if (child_dentry != dentry) { -+ /* lookup child in the underlying file system */ -+ lower_dentry = lookup_lck_len(childname, lower_parent_dentry, -+ childnamelen); -+ if (IS_ERR(lower_dentry)) -+ goto out; -+ } else { -+ /* -+ * Is the name a whiteout of the child name ? lookup the -+ * whiteout child in the underlying file system -+ */ -+ lower_dentry = lookup_lck_len(name, lower_parent_dentry, -+ strlen(name)); -+ if (IS_ERR(lower_dentry)) -+ goto out; -+ -+ /* Replace the current dentry (if any) with the new one */ -+ dput(unionfs_lower_dentry_idx(dentry, bindex)); -+ unionfs_set_lower_dentry_idx(dentry, bindex, -+ lower_dentry); -+ -+ __cleanup_dentry(dentry, bindex, old_bstart, old_bend); -+ goto out; -+ } -+ -+ if (lower_dentry->d_inode) { -+ /* -+ * since this already exists we dput to avoid -+ * multiple references on the same dentry -+ */ -+ dput(lower_dentry); -+ } else { -+ struct sioq_args args; -+ -+ /* it's a negative dentry, create a new dir */ -+ lower_parent_dentry = lock_parent(lower_dentry); -+ -+ args.mkdir.parent = lower_parent_dentry->d_inode; -+ args.mkdir.dentry = lower_dentry; -+ args.mkdir.mode = child_dentry->d_inode->i_mode; -+ -+ run_sioq(__unionfs_mkdir, &args); -+ err = args.err; -+ -+ if (!err) -+ err = copyup_permissions(dir->i_sb, child_dentry, -+ lower_dentry); -+ unlock_dir(lower_parent_dentry); -+ if (err) { -+ dput(lower_dentry); -+ lower_dentry = ERR_PTR(err); -+ goto out; -+ } -+ -+ } -+ -+ __set_inode(child_dentry, lower_dentry, bindex); -+ __set_dentry(child_dentry, lower_dentry, bindex); -+ /* -+ * update times of this dentry, but also the parent, because if -+ * we changed, the parent may have changed too. -+ */ -+ fsstack_copy_attr_times(parent_dentry->d_inode, -+ lower_parent_dentry->d_inode); -+ unionfs_copy_attr_times(child_dentry->d_inode); -+ -+ parent_dentry = child_dentry; -+ child_dentry = path[--count]; -+ goto begin; -+out: -+ /* cleanup any leftover locks from the do/while loop above */ -+ if (IS_ERR(lower_dentry)) -+ while (count) -+ dput(path[count--]); -+ kfree(path); -+ return lower_dentry; -+} -+ -+/* -+ * Post-copyup helper to ensure we have valid mnts: set lower mnt of -+ * dentry+parents to the first parent node that has an mnt. -+ */ -+void unionfs_postcopyup_setmnt(struct dentry *dentry) -+{ -+ struct dentry *parent, *hasone; -+ int bindex = dbstart(dentry); -+ -+ if (unionfs_lower_mnt_idx(dentry, bindex)) -+ return; -+ hasone = dentry->d_parent; -+ /* this loop should stop at root dentry */ -+ while (!unionfs_lower_mnt_idx(hasone, bindex)) -+ hasone = hasone->d_parent; -+ parent = dentry; -+ while (!unionfs_lower_mnt_idx(parent, bindex)) { -+ unionfs_set_lower_mnt_idx(parent, bindex, -+ unionfs_mntget(hasone, bindex)); -+ parent = parent->d_parent; -+ } -+} -+ -+/* -+ * Post-copyup helper to release all non-directory source objects of a -+ * copied-up file. Regular files should have only one lower object. -+ */ -+void unionfs_postcopyup_release(struct dentry *dentry) -+{ -+ int bstart, bend; -+ -+ BUG_ON(S_ISDIR(dentry->d_inode->i_mode)); -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ -+ path_put_lowers(dentry, bstart + 1, bend, false); -+ iput_lowers(dentry->d_inode, bstart + 1, bend, false); -+ -+ dbend(dentry) = bstart; -+ ibend(dentry->d_inode) = ibstart(dentry->d_inode) = bstart; -+} -diff --git a/fs/unionfs/debug.c b/fs/unionfs/debug.c -new file mode 100644 -index 0000000..6092e69 ---- /dev/null -+++ b/fs/unionfs/debug.c -@@ -0,0 +1,548 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * Helper debugging functions for maintainers (and for users to report back -+ * useful information back to maintainers) -+ */ -+ -+/* it's always useful to know what part of the code called us */ -+#define PRINT_CALLER(fname, fxn, line) \ -+ do { \ -+ if (!printed_caller) { \ -+ pr_debug("PC:%s:%s:%d\n", (fname), (fxn), (line)); \ -+ printed_caller = 1; \ -+ } \ -+ } while (0) -+ -+/* -+ * __unionfs_check_{inode,dentry,file} perform exhaustive sanity checking on -+ * the fan-out of various Unionfs objects. We check that no lower objects -+ * exist outside the start/end branch range; that all objects within are -+ * non-NULL (with some allowed exceptions); that for every lower file -+ * there's a lower dentry+inode; that the start/end ranges match for all -+ * corresponding lower objects; that open files/symlinks have only one lower -+ * objects, but directories can have several; and more. -+ */ -+void __unionfs_check_inode(const struct inode *inode, -+ const char *fname, const char *fxn, int line) -+{ -+ int bindex; -+ int istart, iend; -+ struct inode *lower_inode; -+ struct super_block *sb; -+ int printed_caller = 0; -+ void *poison_ptr; -+ -+ /* for inodes now */ -+ BUG_ON(!inode); -+ sb = inode->i_sb; -+ istart = ibstart(inode); -+ iend = ibend(inode); -+ /* don't check inode if no lower branches */ -+ if (istart < 0 && iend < 0) -+ return; -+ if (unlikely(istart > iend)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" Ci0: inode=%p istart/end=%d:%d\n", -+ inode, istart, iend); -+ } -+ if (unlikely((istart == -1 && iend != -1) || -+ (istart != -1 && iend == -1))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" Ci1: inode=%p istart/end=%d:%d\n", -+ inode, istart, iend); -+ } -+ if (!S_ISDIR(inode->i_mode)) { -+ if (unlikely(iend != istart)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" Ci2: inode=%p istart=%d iend=%d\n", -+ inode, istart, iend); -+ } -+ } -+ -+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) { -+ if (unlikely(!UNIONFS_I(inode))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" Ci3: no inode_info %p\n", inode); -+ return; -+ } -+ if (unlikely(!UNIONFS_I(inode)->lower_inodes)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" Ci4: no lower_inodes %p\n", inode); -+ return; -+ } -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (lower_inode) { -+ memset(&poison_ptr, POISON_INUSE, sizeof(void *)); -+ if (unlikely(bindex < istart || bindex > iend)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" Ci5: inode/linode=%p:%p bindex=%d " -+ "istart/end=%d:%d\n", inode, -+ lower_inode, bindex, istart, iend); -+ } else if (unlikely(lower_inode == poison_ptr)) { -+ /* freed inode! */ -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" Ci6: inode/linode=%p:%p bindex=%d " -+ "istart/end=%d:%d\n", inode, -+ lower_inode, bindex, istart, iend); -+ } -+ continue; -+ } -+ /* if we get here, then lower_inode == NULL */ -+ if (bindex < istart || bindex > iend) -+ continue; -+ /* -+ * directories can have NULL lower inodes in b/t start/end, -+ * but NOT if at the start/end range. -+ */ -+ if (unlikely(S_ISDIR(inode->i_mode) && -+ bindex > istart && bindex < iend)) -+ continue; -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" Ci7: inode/linode=%p:%p " -+ "bindex=%d istart/end=%d:%d\n", -+ inode, lower_inode, bindex, istart, iend); -+ } -+} -+ -+void __unionfs_check_dentry(const struct dentry *dentry, -+ const char *fname, const char *fxn, int line) -+{ -+ int bindex; -+ int dstart, dend, istart, iend; -+ struct dentry *lower_dentry; -+ struct inode *inode, *lower_inode; -+ struct super_block *sb; -+ struct vfsmount *lower_mnt; -+ int printed_caller = 0; -+ void *poison_ptr; -+ -+ BUG_ON(!dentry); -+ sb = dentry->d_sb; -+ inode = dentry->d_inode; -+ dstart = dbstart(dentry); -+ dend = dbend(dentry); -+ /* don't check dentry/mnt if no lower branches */ -+ if (dstart < 0 && dend < 0) -+ goto check_inode; -+ BUG_ON(dstart > dend); -+ -+ if (unlikely((dstart == -1 && dend != -1) || -+ (dstart != -1 && dend == -1))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CD0: dentry=%p dstart/end=%d:%d\n", -+ dentry, dstart, dend); -+ } -+ /* -+ * check for NULL dentries inside the start/end range, or -+ * non-NULL dentries outside the start/end range. -+ */ -+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (lower_dentry) { -+ if (unlikely(bindex < dstart || bindex > dend)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CD1: dentry/lower=%p:%p(%p) " -+ "bindex=%d dstart/end=%d:%d\n", -+ dentry, lower_dentry, -+ (lower_dentry ? lower_dentry->d_inode : -+ (void *) -1L), -+ bindex, dstart, dend); -+ } -+ } else { /* lower_dentry == NULL */ -+ if (bindex < dstart || bindex > dend) -+ continue; -+ /* -+ * Directories can have NULL lower inodes in b/t -+ * start/end, but NOT if at the start/end range. -+ * Ignore this rule, however, if this is a NULL -+ * dentry or a deleted dentry. -+ */ -+ if (unlikely(!d_deleted((struct dentry *) dentry) && -+ inode && -+ !(inode && S_ISDIR(inode->i_mode) && -+ bindex > dstart && bindex < dend))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CD2: dentry/lower=%p:%p(%p) " -+ "bindex=%d dstart/end=%d:%d\n", -+ dentry, lower_dentry, -+ (lower_dentry ? -+ lower_dentry->d_inode : -+ (void *) -1L), -+ bindex, dstart, dend); -+ } -+ } -+ } -+ -+ /* check for vfsmounts same as for dentries */ -+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) { -+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex); -+ if (lower_mnt) { -+ if (unlikely(bindex < dstart || bindex > dend)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CM0: dentry/lmnt=%p:%p bindex=%d " -+ "dstart/end=%d:%d\n", dentry, -+ lower_mnt, bindex, dstart, dend); -+ } -+ } else { /* lower_mnt == NULL */ -+ if (bindex < dstart || bindex > dend) -+ continue; -+ /* -+ * Directories can have NULL lower inodes in b/t -+ * start/end, but NOT if at the start/end range. -+ * Ignore this rule, however, if this is a NULL -+ * dentry. -+ */ -+ if (unlikely(inode && -+ !(inode && S_ISDIR(inode->i_mode) && -+ bindex > dstart && bindex < dend))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CM1: dentry/lmnt=%p:%p " -+ "bindex=%d dstart/end=%d:%d\n", -+ dentry, lower_mnt, bindex, -+ dstart, dend); -+ } -+ } -+ } -+ -+check_inode: -+ /* for inodes now */ -+ if (!inode) -+ return; -+ istart = ibstart(inode); -+ iend = ibend(inode); -+ /* don't check inode if no lower branches */ -+ if (istart < 0 && iend < 0) -+ return; -+ BUG_ON(istart > iend); -+ if (unlikely((istart == -1 && iend != -1) || -+ (istart != -1 && iend == -1))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CI0: dentry/inode=%p:%p istart/end=%d:%d\n", -+ dentry, inode, istart, iend); -+ } -+ if (unlikely(istart != dstart)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CI1: dentry/inode=%p:%p istart=%d dstart=%d\n", -+ dentry, inode, istart, dstart); -+ } -+ if (unlikely(iend != dend)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CI2: dentry/inode=%p:%p iend=%d dend=%d\n", -+ dentry, inode, iend, dend); -+ } -+ -+ if (!S_ISDIR(inode->i_mode)) { -+ if (unlikely(dend != dstart)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CI3: dentry/inode=%p:%p dstart=%d dend=%d\n", -+ dentry, inode, dstart, dend); -+ } -+ if (unlikely(iend != istart)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CI4: dentry/inode=%p:%p istart=%d iend=%d\n", -+ dentry, inode, istart, iend); -+ } -+ } -+ -+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (lower_inode) { -+ memset(&poison_ptr, POISON_INUSE, sizeof(void *)); -+ if (unlikely(bindex < istart || bindex > iend)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CI5: dentry/linode=%p:%p bindex=%d " -+ "istart/end=%d:%d\n", dentry, -+ lower_inode, bindex, istart, iend); -+ } else if (unlikely(lower_inode == poison_ptr)) { -+ /* freed inode! */ -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CI6: dentry/linode=%p:%p bindex=%d " -+ "istart/end=%d:%d\n", dentry, -+ lower_inode, bindex, istart, iend); -+ } -+ continue; -+ } -+ /* if we get here, then lower_inode == NULL */ -+ if (bindex < istart || bindex > iend) -+ continue; -+ /* -+ * directories can have NULL lower inodes in b/t start/end, -+ * but NOT if at the start/end range. -+ */ -+ if (unlikely(S_ISDIR(inode->i_mode) && -+ bindex > istart && bindex < iend)) -+ continue; -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CI7: dentry/linode=%p:%p " -+ "bindex=%d istart/end=%d:%d\n", -+ dentry, lower_inode, bindex, istart, iend); -+ } -+ -+ /* -+ * If it's a directory, then intermediate objects b/t start/end can -+ * be NULL. But, check that all three are NULL: lower dentry, mnt, -+ * and inode. -+ */ -+ if (dstart >= 0 && dend >= 0 && S_ISDIR(inode->i_mode)) -+ for (bindex = dstart+1; bindex < dend; bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ lower_dentry = unionfs_lower_dentry_idx(dentry, -+ bindex); -+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex); -+ if (unlikely(!((lower_inode && lower_dentry && -+ lower_mnt) || -+ (!lower_inode && -+ !lower_dentry && !lower_mnt)))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" Cx: lmnt/ldentry/linode=%p:%p:%p " -+ "bindex=%d dstart/end=%d:%d\n", -+ lower_mnt, lower_dentry, lower_inode, -+ bindex, dstart, dend); -+ } -+ } -+ /* check if lower inode is newer than upper one (it shouldn't) */ -+ if (unlikely(is_newer_lower(dentry) && !is_negative_lower(dentry))) { -+ PRINT_CALLER(fname, fxn, line); -+ for (bindex = ibstart(inode); bindex <= ibend(inode); -+ bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (unlikely(!lower_inode)) -+ continue; -+ pr_debug(" CI8: bindex=%d mtime/lmtime=%lu.%lu/%lu.%lu " -+ "ctime/lctime=%lu.%lu/%lu.%lu\n", -+ bindex, -+ inode->i_mtime.tv_sec, -+ inode->i_mtime.tv_nsec, -+ lower_inode->i_mtime.tv_sec, -+ lower_inode->i_mtime.tv_nsec, -+ inode->i_ctime.tv_sec, -+ inode->i_ctime.tv_nsec, -+ lower_inode->i_ctime.tv_sec, -+ lower_inode->i_ctime.tv_nsec); -+ } -+ } -+} -+ -+void __unionfs_check_file(const struct file *file, -+ const char *fname, const char *fxn, int line) -+{ -+ int bindex; -+ int dstart, dend, fstart, fend; -+ struct dentry *dentry; -+ struct file *lower_file; -+ struct inode *inode; -+ struct super_block *sb; -+ int printed_caller = 0; -+ -+ BUG_ON(!file); -+ dentry = file->f_path.dentry; -+ sb = dentry->d_sb; -+ dstart = dbstart(dentry); -+ dend = dbend(dentry); -+ BUG_ON(dstart > dend); -+ fstart = fbstart(file); -+ fend = fbend(file); -+ BUG_ON(fstart > fend); -+ -+ if (unlikely((fstart == -1 && fend != -1) || -+ (fstart != -1 && fend == -1))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CF0: file/dentry=%p:%p fstart/end=%d:%d\n", -+ file, dentry, fstart, fend); -+ } -+ if (unlikely(fstart != dstart)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CF1: file/dentry=%p:%p fstart=%d dstart=%d\n", -+ file, dentry, fstart, dstart); -+ } -+ if (unlikely(fend != dend)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CF2: file/dentry=%p:%p fend=%d dend=%d\n", -+ file, dentry, fend, dend); -+ } -+ inode = dentry->d_inode; -+ if (!S_ISDIR(inode->i_mode)) { -+ if (unlikely(fend != fstart)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CF3: file/inode=%p:%p fstart=%d fend=%d\n", -+ file, inode, fstart, fend); -+ } -+ if (unlikely(dend != dstart)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CF4: file/dentry=%p:%p dstart=%d dend=%d\n", -+ file, dentry, dstart, dend); -+ } -+ } -+ -+ /* -+ * check for NULL dentries inside the start/end range, or -+ * non-NULL dentries outside the start/end range. -+ */ -+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) { -+ lower_file = unionfs_lower_file_idx(file, bindex); -+ if (lower_file) { -+ if (unlikely(bindex < fstart || bindex > fend)) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CF5: file/lower=%p:%p bindex=%d " -+ "fstart/end=%d:%d\n", file, -+ lower_file, bindex, fstart, fend); -+ } -+ } else { /* lower_file == NULL */ -+ if (bindex >= fstart && bindex <= fend) { -+ /* -+ * directories can have NULL lower inodes in -+ * b/t start/end, but NOT if at the -+ * start/end range. -+ */ -+ if (unlikely(!(S_ISDIR(inode->i_mode) && -+ bindex > fstart && -+ bindex < fend))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CF6: file/lower=%p:%p " -+ "bindex=%d fstart/end=%d:%d\n", -+ file, lower_file, bindex, -+ fstart, fend); -+ } -+ } -+ } -+ } -+ -+ __unionfs_check_dentry(dentry, fname, fxn, line); -+} -+ -+void __unionfs_check_nd(const struct nameidata *nd, -+ const char *fname, const char *fxn, int line) -+{ -+ struct file *file; -+ int printed_caller = 0; -+ -+ if (unlikely(!nd)) -+ return; -+ if (nd->flags & LOOKUP_OPEN) { -+ file = nd->intent.open.file; -+ if (unlikely(file->f_path.dentry && -+ strcmp(file->f_path.dentry->d_sb->s_type->name, -+ UNIONFS_NAME))) { -+ PRINT_CALLER(fname, fxn, line); -+ pr_debug(" CND1: lower_file of type %s\n", -+ file->f_path.dentry->d_sb->s_type->name); -+ } -+ } -+} -+ -+static unsigned int __mnt_get_count(struct vfsmount *mnt) -+{ -+#ifdef CONFIG_SMP -+ unsigned int count = 0; -+ int cpu; -+ -+ for_each_possible_cpu(cpu) { -+ count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count; -+ } -+ -+ return count; -+#else -+ return mnt->mnt_count; -+#endif -+} -+ -+/* useful to track vfsmount leaks that could cause EBUSY on unmount */ -+void __show_branch_counts(const struct super_block *sb, -+ const char *file, const char *fxn, int line) -+{ -+ int i; -+ struct vfsmount *mnt; -+ -+ pr_debug("BC:"); -+ for (i = 0; i < sbmax(sb); i++) { -+ if (likely(sb->s_root)) -+ mnt = UNIONFS_D(sb->s_root)->lower_paths[i].mnt; -+ else -+ mnt = NULL; -+ printk(KERN_CONT "%d:", -+ (mnt ? __mnt_get_count(mnt) : -99)); -+ } -+ printk(KERN_CONT "%s:%s:%d\n", file, fxn, line); -+} -+ -+void __show_inode_times(const struct inode *inode, -+ const char *file, const char *fxn, int line) -+{ -+ struct inode *lower_inode; -+ int bindex; -+ -+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (unlikely(!lower_inode)) -+ continue; -+ pr_debug("IT(%lu:%d): %s:%s:%d " -+ "um=%lu/%lu lm=%lu/%lu uc=%lu/%lu lc=%lu/%lu\n", -+ inode->i_ino, bindex, -+ file, fxn, line, -+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec, -+ lower_inode->i_mtime.tv_sec, -+ lower_inode->i_mtime.tv_nsec, -+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, -+ lower_inode->i_ctime.tv_sec, -+ lower_inode->i_ctime.tv_nsec); -+ } -+} -+ -+void __show_dinode_times(const struct dentry *dentry, -+ const char *file, const char *fxn, int line) -+{ -+ struct inode *inode = dentry->d_inode; -+ struct inode *lower_inode; -+ int bindex; -+ -+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (!lower_inode) -+ continue; -+ pr_debug("DT(%s:%lu:%d): %s:%s:%d " -+ "um=%lu/%lu lm=%lu/%lu uc=%lu/%lu lc=%lu/%lu\n", -+ dentry->d_name.name, inode->i_ino, bindex, -+ file, fxn, line, -+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec, -+ lower_inode->i_mtime.tv_sec, -+ lower_inode->i_mtime.tv_nsec, -+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec, -+ lower_inode->i_ctime.tv_sec, -+ lower_inode->i_ctime.tv_nsec); -+ } -+} -+ -+void __show_inode_counts(const struct inode *inode, -+ const char *file, const char *fxn, int line) -+{ -+ struct inode *lower_inode; -+ int bindex; -+ -+ if (unlikely(!inode)) { -+ pr_debug("SiC: Null inode\n"); -+ return; -+ } -+ for (bindex = sbstart(inode->i_sb); bindex <= sbend(inode->i_sb); -+ bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (unlikely(!lower_inode)) -+ continue; -+ pr_debug("SIC(%lu:%d:%d): lc=%d %s:%s:%d\n", -+ inode->i_ino, bindex, -+ atomic_read(&(inode)->i_count), -+ atomic_read(&(lower_inode)->i_count), -+ file, fxn, line); -+ } -+} -diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c -new file mode 100644 -index 0000000..c0205a4 ---- /dev/null -+++ b/fs/unionfs/dentry.c -@@ -0,0 +1,406 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+bool is_negative_lower(const struct dentry *dentry) -+{ -+ int bindex; -+ struct dentry *lower_dentry; -+ -+ BUG_ON(!dentry); -+ /* cache coherency: check if file was deleted on lower branch */ -+ if (dbstart(dentry) < 0) -+ return true; -+ for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ /* unhashed (i.e., unlinked) lower dentries don't count */ -+ if (lower_dentry && lower_dentry->d_inode && -+ !d_deleted(lower_dentry) && -+ !(lower_dentry->d_flags & DCACHE_NFSFS_RENAMED)) -+ return false; -+ } -+ return true; -+} -+ -+static inline void __dput_lowers(struct dentry *dentry, int start, int end) -+{ -+ struct dentry *lower_dentry; -+ int bindex; -+ -+ if (start < 0) -+ return; -+ for (bindex = start; bindex <= end; bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry) -+ continue; -+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL); -+ dput(lower_dentry); -+ } -+} -+ -+/* -+ * Purge and invalidate as many data pages of a unionfs inode. This is -+ * called when the lower inode has changed, and we want to force processes -+ * to re-get the new data. -+ */ -+static inline void purge_inode_data(struct inode *inode) -+{ -+ /* remove all non-private mappings */ -+ unmap_mapping_range(inode->i_mapping, 0, 0, 0); -+ /* invalidate as many pages as possible */ -+ invalidate_mapping_pages(inode->i_mapping, 0, -1); -+ /* -+ * Don't try to truncate_inode_pages here, because this could lead -+ * to a deadlock between some of address_space ops and dentry -+ * revalidation: the address space op is invoked with a lock on our -+ * own page, and truncate_inode_pages will block on locked pages. -+ */ -+} -+ -+/* -+ * Revalidate a single file/symlink/special dentry. Assume that info nodes -+ * of the @dentry and its @parent are locked. Assume parent is valid, -+ * otherwise return false (and let's hope the VFS will try to re-lookup this -+ * dentry). Returns true if valid, false otherwise. -+ */ -+bool __unionfs_d_revalidate(struct dentry *dentry, struct dentry *parent, -+ bool willwrite) -+{ -+ bool valid = true; /* default is valid */ -+ struct dentry *lower_dentry; -+ struct dentry *result; -+ int bindex, bstart, bend; -+ int sbgen, dgen, pdgen; -+ int positive = 0; -+ int interpose_flag; -+ -+ verify_locked(dentry); -+ verify_locked(parent); -+ -+ /* if the dentry is unhashed, do NOT revalidate */ -+ if (d_deleted(dentry)) -+ goto out; -+ -+ dgen = atomic_read(&UNIONFS_D(dentry)->generation); -+ -+ if (is_newer_lower(dentry)) { -+ /* root dentry is always valid */ -+ if (IS_ROOT(dentry)) { -+ unionfs_copy_attr_times(dentry->d_inode); -+ } else { -+ /* -+ * reset generation number to zero, guaranteed to be -+ * "old" -+ */ -+ dgen = 0; -+ atomic_set(&UNIONFS_D(dentry)->generation, dgen); -+ } -+ if (!willwrite) -+ purge_inode_data(dentry->d_inode); -+ } -+ -+ sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation); -+ -+ BUG_ON(dbstart(dentry) == -1); -+ if (dentry->d_inode) -+ positive = 1; -+ -+ /* if our dentry is valid, then validate all lower ones */ -+ if (sbgen == dgen) -+ goto validate_lowers; -+ -+ /* The root entry should always be valid */ -+ BUG_ON(IS_ROOT(dentry)); -+ -+ /* We can't work correctly if our parent isn't valid. */ -+ pdgen = atomic_read(&UNIONFS_D(parent)->generation); -+ -+ /* Free the pointers for our inodes and this dentry. */ -+ path_put_lowers_all(dentry, false); -+ -+ interpose_flag = INTERPOSE_REVAL_NEG; -+ if (positive) { -+ interpose_flag = INTERPOSE_REVAL; -+ iput_lowers_all(dentry->d_inode, true); -+ } -+ -+ if (realloc_dentry_private_data(dentry) != 0) { -+ valid = false; -+ goto out; -+ } -+ -+ result = unionfs_lookup_full(dentry, parent, interpose_flag); -+ if (result) { -+ if (IS_ERR(result)) { -+ valid = false; -+ goto out; -+ } -+ /* -+ * current unionfs_lookup_backend() doesn't return -+ * a valid dentry -+ */ -+ dput(dentry); -+ dentry = result; -+ } -+ -+ if (unlikely(positive && is_negative_lower(dentry))) { -+ /* call make_bad_inode here ? */ -+ d_drop(dentry); -+ valid = false; -+ goto out; -+ } -+ -+ /* -+ * if we got here then we have revalidated our dentry and all lower -+ * ones, so we can return safely. -+ */ -+ if (!valid) /* lower dentry revalidation failed */ -+ goto out; -+ -+ /* -+ * If the parent's gen no. matches the superblock's gen no., then -+ * we can update our denty's gen no. If they didn't match, then it -+ * was OK to revalidate this dentry with a stale parent, but we'll -+ * purposely not update our dentry's gen no. (so it can be redone); -+ * and, we'll mark our parent dentry as invalid so it'll force it -+ * (and our dentry) to be revalidated. -+ */ -+ if (pdgen == sbgen) -+ atomic_set(&UNIONFS_D(dentry)->generation, sbgen); -+ goto out; -+ -+validate_lowers: -+ -+ /* The revalidation must occur across all branches */ -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ BUG_ON(bstart == -1); -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ int err; -+ struct nameidata lower_nd; -+ -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry || !lower_dentry->d_op -+ || !lower_dentry->d_op->d_revalidate) -+ continue; -+ /* -+ * Don't pass nameidata to lower file system, because we -+ * don't want an arbitrary lower file being opened or -+ * returned to us: it may be useless to us because of the -+ * fanout nature of unionfs (cf. file/directory open-file -+ * invariants). We will open lower files as and when needed -+ * later on. -+ */ -+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN); -+ if (unlikely(err < 0)) { -+ valid = false; -+ break; -+ } -+ if (!lower_dentry->d_op->d_revalidate(lower_dentry, &lower_nd)) -+ valid = false; -+ release_lower_nd(&lower_nd, err); -+ } -+ -+ if (!dentry->d_inode || -+ ibstart(dentry->d_inode) < 0 || -+ ibend(dentry->d_inode) < 0) { -+ valid = false; -+ goto out; -+ } -+ -+ if (valid) { -+ /* -+ * If we get here, and we copy the meta-data from the lower -+ * inode to our inode, then it is vital that we have already -+ * purged all unionfs-level file data. We do that in the -+ * caller (__unionfs_d_revalidate) by calling -+ * purge_inode_data. -+ */ -+ unionfs_copy_attr_all(dentry->d_inode, -+ unionfs_lower_inode(dentry->d_inode)); -+ fsstack_copy_inode_size(dentry->d_inode, -+ unionfs_lower_inode(dentry->d_inode)); -+ } -+ -+out: -+ return valid; -+} -+ -+/* -+ * Determine if the lower inode objects have changed from below the unionfs -+ * inode. Return true if changed, false otherwise. -+ * -+ * We check if the mtime or ctime have changed. However, the inode times -+ * can be changed by anyone without much protection, including -+ * asynchronously. This can sometimes cause unionfs to find that the lower -+ * file system doesn't change its inode times quick enough, resulting in a -+ * false positive indication (which is harmless, it just makes unionfs do -+ * extra work in re-validating the objects). To minimize the chances of -+ * these situations, we still consider such small time changes valid, but we -+ * don't print debugging messages unless the time changes are greater than -+ * UNIONFS_MIN_CC_TIME (which defaults to 3 seconds, as with NFS's acregmin) -+ * because significant changes are more likely due to users manually -+ * touching lower files. -+ */ -+bool is_newer_lower(const struct dentry *dentry) -+{ -+ int bindex; -+ struct inode *inode; -+ struct inode *lower_inode; -+ -+ /* ignore if we're called on semi-initialized dentries/inodes */ -+ if (!dentry || !UNIONFS_D(dentry)) -+ return false; -+ inode = dentry->d_inode; -+ if (!inode || !UNIONFS_I(inode)->lower_inodes || -+ ibstart(inode) < 0 || ibend(inode) < 0) -+ return false; -+ -+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (!lower_inode) -+ continue; -+ -+ /* check if mtime/ctime have changed */ -+ if (unlikely(timespec_compare(&inode->i_mtime, -+ &lower_inode->i_mtime) < 0)) { -+ if ((lower_inode->i_mtime.tv_sec - -+ inode->i_mtime.tv_sec) > UNIONFS_MIN_CC_TIME) { -+ pr_info("unionfs: new lower inode mtime " -+ "(bindex=%d, name=%s)\n", bindex, -+ dentry->d_name.name); -+ show_dinode_times(dentry); -+ } -+ return true; -+ } -+ if (unlikely(timespec_compare(&inode->i_ctime, -+ &lower_inode->i_ctime) < 0)) { -+ if ((lower_inode->i_ctime.tv_sec - -+ inode->i_ctime.tv_sec) > UNIONFS_MIN_CC_TIME) { -+ pr_info("unionfs: new lower inode ctime " -+ "(bindex=%d, name=%s)\n", bindex, -+ dentry->d_name.name); -+ show_dinode_times(dentry); -+ } -+ return true; -+ } -+ } -+ -+ /* -+ * Last check: if this is a positive dentry, but somehow all lower -+ * dentries are negative or unhashed, then this dentry needs to be -+ * revalidated, because someone probably deleted the objects from -+ * the lower branches directly. -+ */ -+ if (is_negative_lower(dentry)) -+ return true; -+ -+ return false; /* default: lower is not newer */ -+} -+ -+static int unionfs_d_revalidate(struct dentry *dentry, -+ struct nameidata *nd_unused) -+{ -+ bool valid = true; -+ int err = 1; /* 1 means valid for the VFS */ -+ struct dentry *parent; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (valid) { -+ unionfs_postcopyup_setmnt(dentry); -+ unionfs_check_dentry(dentry); -+ } else { -+ d_drop(dentry); -+ err = valid; -+ } -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ -+ return err; -+} -+ -+static void unionfs_d_release(struct dentry *dentry) -+{ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ if (unlikely(!UNIONFS_D(dentry))) -+ goto out; /* skip if no lower branches */ -+ /* must lock our branch configuration here */ -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ unionfs_check_dentry(dentry); -+ /* this could be a negative dentry, so check first */ -+ if (dbstart(dentry) < 0) { -+ unionfs_unlock_dentry(dentry); -+ goto out; /* due to a (normal) failed lookup */ -+ } -+ -+ /* Release all the lower dentries */ -+ path_put_lowers_all(dentry, true); -+ -+ unionfs_unlock_dentry(dentry); -+ -+out: -+ free_dentry_private_data(dentry); -+ unionfs_read_unlock(dentry->d_sb); -+ return; -+} -+ -+/* -+ * Called when we're removing the last reference to our dentry. So we -+ * should drop all lower references too. -+ */ -+static void unionfs_d_iput(struct dentry *dentry, struct inode *inode) -+{ -+ int rc; -+ -+ BUG_ON(!dentry); -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ if (!UNIONFS_D(dentry) || dbstart(dentry) < 0) -+ goto drop_lower_inodes; -+ path_put_lowers_all(dentry, false); -+ -+drop_lower_inodes: -+ rc = atomic_read(&inode->i_count); -+ if (rc == 1 && inode->i_nlink == 1 && ibstart(inode) >= 0) { -+ /* see Documentation/filesystems/unionfs/issues.txt */ -+ lockdep_off(); -+ iput(unionfs_lower_inode(inode)); -+ lockdep_on(); -+ unionfs_set_lower_inode(inode, NULL); -+ /* XXX: may need to set start/end to -1? */ -+ } -+ -+ iput(inode); -+ -+ unionfs_unlock_dentry(dentry); -+ unionfs_read_unlock(dentry->d_sb); -+} -+ -+struct dentry_operations unionfs_dops = { -+ .d_revalidate = unionfs_d_revalidate, -+ .d_release = unionfs_d_release, -+ .d_iput = unionfs_d_iput, -+}; -diff --git a/fs/unionfs/dirfops.c b/fs/unionfs/dirfops.c -new file mode 100644 -index 0000000..72a9c1a ---- /dev/null -+++ b/fs/unionfs/dirfops.c -@@ -0,0 +1,302 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* Make sure our rdstate is playing by the rules. */ -+static void verify_rdstate_offset(struct unionfs_dir_state *rdstate) -+{ -+ BUG_ON(rdstate->offset >= DIREOF); -+ BUG_ON(rdstate->cookie >= MAXRDCOOKIE); -+} -+ -+struct unionfs_getdents_callback { -+ struct unionfs_dir_state *rdstate; -+ void *dirent; -+ int entries_written; -+ int filldir_called; -+ int filldir_error; -+ filldir_t filldir; -+ struct super_block *sb; -+}; -+ -+/* based on generic filldir in fs/readir.c */ -+static int unionfs_filldir(void *dirent, const char *oname, int namelen, -+ loff_t offset, u64 ino, unsigned int d_type) -+{ -+ struct unionfs_getdents_callback *buf = dirent; -+ struct filldir_node *found = NULL; -+ int err = 0; -+ int is_whiteout; -+ char *name = (char *) oname; -+ -+ buf->filldir_called++; -+ -+ is_whiteout = is_whiteout_name(&name, &namelen); -+ -+ found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout); -+ -+ if (found) { -+ /* -+ * If we had non-whiteout entry in dir cache, then mark it -+ * as a whiteout and but leave it in the dir cache. -+ */ -+ if (is_whiteout && !found->whiteout) -+ found->whiteout = is_whiteout; -+ goto out; -+ } -+ -+ /* if 'name' isn't a whiteout, filldir it. */ -+ if (!is_whiteout) { -+ off_t pos = rdstate2offset(buf->rdstate); -+ u64 unionfs_ino = ino; -+ -+ err = buf->filldir(buf->dirent, name, namelen, pos, -+ unionfs_ino, d_type); -+ buf->rdstate->offset++; -+ verify_rdstate_offset(buf->rdstate); -+ } -+ /* -+ * If we did fill it, stuff it in our hash, otherwise return an -+ * error. -+ */ -+ if (err) { -+ buf->filldir_error = err; -+ goto out; -+ } -+ buf->entries_written++; -+ err = add_filldir_node(buf->rdstate, name, namelen, -+ buf->rdstate->bindex, is_whiteout); -+ if (err) -+ buf->filldir_error = err; -+ -+out: -+ return err; -+} -+ -+static int unionfs_readdir(struct file *file, void *dirent, filldir_t filldir) -+{ -+ int err = 0; -+ struct file *lower_file = NULL; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ struct inode *inode = NULL; -+ struct unionfs_getdents_callback buf; -+ struct unionfs_dir_state *uds; -+ int bend; -+ loff_t offset; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, false); -+ if (unlikely(err)) -+ goto out; -+ -+ inode = dentry->d_inode; -+ -+ uds = UNIONFS_F(file)->rdstate; -+ if (!uds) { -+ if (file->f_pos == DIREOF) { -+ goto out; -+ } else if (file->f_pos > 0) { -+ uds = find_rdstate(inode, file->f_pos); -+ if (unlikely(!uds)) { -+ err = -ESTALE; -+ goto out; -+ } -+ UNIONFS_F(file)->rdstate = uds; -+ } else { -+ init_rdstate(file); -+ uds = UNIONFS_F(file)->rdstate; -+ } -+ } -+ bend = fbend(file); -+ -+ while (uds->bindex <= bend) { -+ lower_file = unionfs_lower_file_idx(file, uds->bindex); -+ if (!lower_file) { -+ uds->bindex++; -+ uds->dirpos = 0; -+ continue; -+ } -+ -+ /* prepare callback buffer */ -+ buf.filldir_called = 0; -+ buf.filldir_error = 0; -+ buf.entries_written = 0; -+ buf.dirent = dirent; -+ buf.filldir = filldir; -+ buf.rdstate = uds; -+ buf.sb = inode->i_sb; -+ -+ /* Read starting from where we last left off. */ -+ offset = vfs_llseek(lower_file, uds->dirpos, SEEK_SET); -+ if (offset < 0) { -+ err = offset; -+ goto out; -+ } -+ err = vfs_readdir(lower_file, unionfs_filldir, &buf); -+ -+ /* Save the position for when we continue. */ -+ offset = vfs_llseek(lower_file, 0, SEEK_CUR); -+ if (offset < 0) { -+ err = offset; -+ goto out; -+ } -+ uds->dirpos = offset; -+ -+ /* Copy the atime. */ -+ fsstack_copy_attr_atime(inode, -+ lower_file->f_path.dentry->d_inode); -+ -+ if (err < 0) -+ goto out; -+ -+ if (buf.filldir_error) -+ break; -+ -+ if (!buf.entries_written) { -+ uds->bindex++; -+ uds->dirpos = 0; -+ } -+ } -+ -+ if (!buf.filldir_error && uds->bindex >= bend) { -+ /* Save the number of hash entries for next time. */ -+ UNIONFS_I(inode)->hashsize = uds->hashentries; -+ free_rdstate(uds); -+ UNIONFS_F(file)->rdstate = NULL; -+ file->f_pos = DIREOF; -+ } else { -+ file->f_pos = rdstate2offset(uds); -+ } -+ -+out: -+ if (!err) -+ unionfs_check_file(file); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+/* -+ * This is not meant to be a generic repositioning function. If you do -+ * things that aren't supported, then we return EINVAL. -+ * -+ * What is allowed: -+ * (1) seeking to the same position that you are currently at -+ * This really has no effect, but returns where you are. -+ * (2) seeking to the beginning of the file -+ * This throws out all state, and lets you begin again. -+ */ -+static loff_t unionfs_dir_llseek(struct file *file, loff_t offset, int origin) -+{ -+ struct unionfs_dir_state *rdstate; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ loff_t err; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, false); -+ if (unlikely(err)) -+ goto out; -+ -+ rdstate = UNIONFS_F(file)->rdstate; -+ -+ /* -+ * we let users seek to their current position, but not anywhere -+ * else. -+ */ -+ if (!offset) { -+ switch (origin) { -+ case SEEK_SET: -+ if (rdstate) { -+ free_rdstate(rdstate); -+ UNIONFS_F(file)->rdstate = NULL; -+ } -+ init_rdstate(file); -+ err = 0; -+ break; -+ case SEEK_CUR: -+ err = file->f_pos; -+ break; -+ case SEEK_END: -+ /* Unsupported, because we would break everything. */ -+ err = -EINVAL; -+ break; -+ } -+ } else { -+ switch (origin) { -+ case SEEK_SET: -+ if (rdstate) { -+ if (offset == rdstate2offset(rdstate)) -+ err = offset; -+ else if (file->f_pos == DIREOF) -+ err = DIREOF; -+ else -+ err = -EINVAL; -+ } else { -+ struct inode *inode; -+ inode = dentry->d_inode; -+ rdstate = find_rdstate(inode, offset); -+ if (rdstate) { -+ UNIONFS_F(file)->rdstate = rdstate; -+ err = rdstate->offset; -+ } else { -+ err = -EINVAL; -+ } -+ } -+ break; -+ case SEEK_CUR: -+ case SEEK_END: -+ /* Unsupported, because we would break everything. */ -+ err = -EINVAL; -+ break; -+ } -+ } -+ -+out: -+ if (!err) -+ unionfs_check_file(file); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+/* -+ * Trimmed directory options, we shouldn't pass everything down since -+ * we don't want to operate on partial directories. -+ */ -+struct file_operations unionfs_dir_fops = { -+ .llseek = unionfs_dir_llseek, -+ .read = generic_read_dir, -+ .readdir = unionfs_readdir, -+ .unlocked_ioctl = unionfs_ioctl, -+ .open = unionfs_open, -+ .release = unionfs_file_release, -+ .flush = unionfs_flush, -+ .fsync = unionfs_fsync, -+ .fasync = unionfs_fasync, -+}; -diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c -new file mode 100644 -index 0000000..62ec9af ---- /dev/null -+++ b/fs/unionfs/dirhelper.c -@@ -0,0 +1,158 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+#define RD_NONE 0 -+#define RD_CHECK_EMPTY 1 -+/* The callback structure for check_empty. */ -+struct unionfs_rdutil_callback { -+ int err; -+ int filldir_called; -+ struct unionfs_dir_state *rdstate; -+ int mode; -+}; -+ -+/* This filldir function makes sure only whiteouts exist within a directory. */ -+static int readdir_util_callback(void *dirent, const char *oname, int namelen, -+ loff_t offset, u64 ino, unsigned int d_type) -+{ -+ int err = 0; -+ struct unionfs_rdutil_callback *buf = dirent; -+ int is_whiteout; -+ struct filldir_node *found; -+ char *name = (char *) oname; -+ -+ buf->filldir_called = 1; -+ -+ if (name[0] == '.' && (namelen == 1 || -+ (name[1] == '.' && namelen == 2))) -+ goto out; -+ -+ is_whiteout = is_whiteout_name(&name, &namelen); -+ -+ found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout); -+ /* If it was found in the table there was a previous whiteout. */ -+ if (found) -+ goto out; -+ -+ /* -+ * if it wasn't found and isn't a whiteout, the directory isn't -+ * empty. -+ */ -+ err = -ENOTEMPTY; -+ if ((buf->mode == RD_CHECK_EMPTY) && !is_whiteout) -+ goto out; -+ -+ err = add_filldir_node(buf->rdstate, name, namelen, -+ buf->rdstate->bindex, is_whiteout); -+ -+out: -+ buf->err = err; -+ return err; -+} -+ -+/* Is a directory logically empty? */ -+int check_empty(struct dentry *dentry, struct dentry *parent, -+ struct unionfs_dir_state **namelist) -+{ -+ int err = 0; -+ struct dentry *lower_dentry = NULL; -+ struct vfsmount *mnt; -+ struct super_block *sb; -+ struct file *lower_file; -+ struct unionfs_rdutil_callback *buf = NULL; -+ int bindex, bstart, bend, bopaque; -+ -+ sb = dentry->d_sb; -+ -+ -+ BUG_ON(!S_ISDIR(dentry->d_inode->i_mode)); -+ -+ err = unionfs_partial_lookup(dentry, parent); -+ if (err) -+ goto out; -+ -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ bopaque = dbopaque(dentry); -+ if (0 <= bopaque && bopaque < bend) -+ bend = bopaque; -+ -+ buf = kmalloc(sizeof(struct unionfs_rdutil_callback), GFP_KERNEL); -+ if (unlikely(!buf)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ buf->err = 0; -+ buf->mode = RD_CHECK_EMPTY; -+ buf->rdstate = alloc_rdstate(dentry->d_inode, bstart); -+ if (unlikely(!buf->rdstate)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ /* Process the lower directories with rdutil_callback as a filldir. */ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry) -+ continue; -+ if (!lower_dentry->d_inode) -+ continue; -+ if (!S_ISDIR(lower_dentry->d_inode->i_mode)) -+ continue; -+ -+ dget(lower_dentry); -+ mnt = unionfs_mntget(dentry, bindex); -+ branchget(sb, bindex); -+ lower_file = dentry_open(lower_dentry, mnt, O_RDONLY, current_cred()); -+ if (IS_ERR(lower_file)) { -+ err = PTR_ERR(lower_file); -+ branchput(sb, bindex); -+ goto out; -+ } -+ -+ do { -+ buf->filldir_called = 0; -+ buf->rdstate->bindex = bindex; -+ err = vfs_readdir(lower_file, -+ readdir_util_callback, buf); -+ if (buf->err) -+ err = buf->err; -+ } while ((err >= 0) && buf->filldir_called); -+ -+ /* fput calls dput for lower_dentry */ -+ fput(lower_file); -+ branchput(sb, bindex); -+ -+ if (err < 0) -+ goto out; -+ } -+ -+out: -+ if (buf) { -+ if (namelist && !err) -+ *namelist = buf->rdstate; -+ else if (buf->rdstate) -+ free_rdstate(buf->rdstate); -+ kfree(buf); -+ } -+ -+ -+ return err; -+} -diff --git a/fs/unionfs/fanout.h b/fs/unionfs/fanout.h -new file mode 100644 -index 0000000..ae1b86a ---- /dev/null -+++ b/fs/unionfs/fanout.h -@@ -0,0 +1,407 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 _FANOUT_H_ -+#define _FANOUT_H_ -+ -+/* -+ * Inode to private data -+ * -+ * Since we use containers and the struct inode is _inside_ the -+ * unionfs_inode_info structure, UNIONFS_I will always (given a non-NULL -+ * inode pointer), return a valid non-NULL pointer. -+ */ -+static inline struct unionfs_inode_info *UNIONFS_I(const struct inode *inode) -+{ -+ return container_of(inode, struct unionfs_inode_info, vfs_inode); -+} -+ -+#define ibstart(ino) (UNIONFS_I(ino)->bstart) -+#define ibend(ino) (UNIONFS_I(ino)->bend) -+ -+/* Dentry to private data */ -+#define UNIONFS_D(dent) ((struct unionfs_dentry_info *)(dent)->d_fsdata) -+#define dbstart(dent) (UNIONFS_D(dent)->bstart) -+#define dbend(dent) (UNIONFS_D(dent)->bend) -+#define dbopaque(dent) (UNIONFS_D(dent)->bopaque) -+ -+/* Superblock to private data */ -+#define UNIONFS_SB(super) ((struct unionfs_sb_info *)(super)->s_fs_info) -+#define sbstart(sb) 0 -+#define sbend(sb) (UNIONFS_SB(sb)->bend) -+#define sbmax(sb) (UNIONFS_SB(sb)->bend + 1) -+#define sbhbid(sb) (UNIONFS_SB(sb)->high_branch_id) -+ -+/* File to private Data */ -+#define UNIONFS_F(file) ((struct unionfs_file_info *)((file)->private_data)) -+#define fbstart(file) (UNIONFS_F(file)->bstart) -+#define fbend(file) (UNIONFS_F(file)->bend) -+ -+/* macros to manipulate branch IDs in stored in our superblock */ -+static inline int branch_id(struct super_block *sb, int index) -+{ -+ BUG_ON(!sb || index < 0); -+ return UNIONFS_SB(sb)->data[index].branch_id; -+} -+ -+static inline void set_branch_id(struct super_block *sb, int index, int val) -+{ -+ BUG_ON(!sb || index < 0); -+ UNIONFS_SB(sb)->data[index].branch_id = val; -+} -+ -+static inline void new_branch_id(struct super_block *sb, int index) -+{ -+ BUG_ON(!sb || index < 0); -+ set_branch_id(sb, index, ++UNIONFS_SB(sb)->high_branch_id); -+} -+ -+/* -+ * Find new index of matching branch with an existing superblock of a known -+ * (possibly old) id. This is needed because branches could have been -+ * added/deleted causing the branches of any open files to shift. -+ * -+ * @sb: the new superblock which may have new/different branch IDs -+ * @id: the old/existing id we're looking for -+ * Returns index of newly found branch (0 or greater), -1 otherwise. -+ */ -+static inline int branch_id_to_idx(struct super_block *sb, int id) -+{ -+ int i; -+ for (i = 0; i < sbmax(sb); i++) { -+ if (branch_id(sb, i) == id) -+ return i; -+ } -+ /* in the non-ODF code, this should really never happen */ -+ printk(KERN_WARNING "unionfs: cannot find branch with id %d\n", id); -+ return -1; -+} -+ -+/* File to lower file. */ -+static inline struct file *unionfs_lower_file(const struct file *f) -+{ -+ BUG_ON(!f); -+ return UNIONFS_F(f)->lower_files[fbstart(f)]; -+} -+ -+static inline struct file *unionfs_lower_file_idx(const struct file *f, -+ int index) -+{ -+ BUG_ON(!f || index < 0); -+ return UNIONFS_F(f)->lower_files[index]; -+} -+ -+static inline void unionfs_set_lower_file_idx(struct file *f, int index, -+ struct file *val) -+{ -+ BUG_ON(!f || index < 0); -+ UNIONFS_F(f)->lower_files[index] = val; -+ /* save branch ID (may be redundant?) */ -+ UNIONFS_F(f)->saved_branch_ids[index] = -+ branch_id((f)->f_path.dentry->d_sb, index); -+} -+ -+static inline void unionfs_set_lower_file(struct file *f, struct file *val) -+{ -+ BUG_ON(!f); -+ unionfs_set_lower_file_idx((f), fbstart(f), (val)); -+} -+ -+/* Inode to lower inode. */ -+static inline struct inode *unionfs_lower_inode(const struct inode *i) -+{ -+ BUG_ON(!i); -+ return UNIONFS_I(i)->lower_inodes[ibstart(i)]; -+} -+ -+static inline struct inode *unionfs_lower_inode_idx(const struct inode *i, -+ int index) -+{ -+ BUG_ON(!i || index < 0); -+ return UNIONFS_I(i)->lower_inodes[index]; -+} -+ -+static inline void unionfs_set_lower_inode_idx(struct inode *i, int index, -+ struct inode *val) -+{ -+ BUG_ON(!i || index < 0); -+ UNIONFS_I(i)->lower_inodes[index] = val; -+} -+ -+static inline void unionfs_set_lower_inode(struct inode *i, struct inode *val) -+{ -+ BUG_ON(!i); -+ UNIONFS_I(i)->lower_inodes[ibstart(i)] = val; -+} -+ -+/* Superblock to lower superblock. */ -+static inline struct super_block *unionfs_lower_super( -+ const struct super_block *sb) -+{ -+ BUG_ON(!sb); -+ return UNIONFS_SB(sb)->data[sbstart(sb)].sb; -+} -+ -+static inline struct super_block *unionfs_lower_super_idx( -+ const struct super_block *sb, -+ int index) -+{ -+ BUG_ON(!sb || index < 0); -+ return UNIONFS_SB(sb)->data[index].sb; -+} -+ -+static inline void unionfs_set_lower_super_idx(struct super_block *sb, -+ int index, -+ struct super_block *val) -+{ -+ BUG_ON(!sb || index < 0); -+ UNIONFS_SB(sb)->data[index].sb = val; -+} -+ -+static inline void unionfs_set_lower_super(struct super_block *sb, -+ struct super_block *val) -+{ -+ BUG_ON(!sb); -+ UNIONFS_SB(sb)->data[sbstart(sb)].sb = val; -+} -+ -+/* Branch count macros. */ -+static inline int branch_count(const struct super_block *sb, int index) -+{ -+ BUG_ON(!sb || index < 0); -+ return atomic_read(&UNIONFS_SB(sb)->data[index].open_files); -+} -+ -+static inline void set_branch_count(struct super_block *sb, int index, int val) -+{ -+ BUG_ON(!sb || index < 0); -+ atomic_set(&UNIONFS_SB(sb)->data[index].open_files, val); -+} -+ -+static inline void branchget(struct super_block *sb, int index) -+{ -+ BUG_ON(!sb || index < 0); -+ atomic_inc(&UNIONFS_SB(sb)->data[index].open_files); -+} -+ -+static inline void branchput(struct super_block *sb, int index) -+{ -+ BUG_ON(!sb || index < 0); -+ atomic_dec(&UNIONFS_SB(sb)->data[index].open_files); -+} -+ -+/* Dentry macros */ -+static inline void unionfs_set_lower_dentry_idx(struct dentry *dent, int index, -+ struct dentry *val) -+{ -+ BUG_ON(!dent || index < 0); -+ UNIONFS_D(dent)->lower_paths[index].dentry = val; -+} -+ -+static inline struct dentry *unionfs_lower_dentry_idx( -+ const struct dentry *dent, -+ int index) -+{ -+ BUG_ON(!dent || index < 0); -+ return UNIONFS_D(dent)->lower_paths[index].dentry; -+} -+ -+static inline struct dentry *unionfs_lower_dentry(const struct dentry *dent) -+{ -+ BUG_ON(!dent); -+ return unionfs_lower_dentry_idx(dent, dbstart(dent)); -+} -+ -+static inline void unionfs_set_lower_mnt_idx(struct dentry *dent, int index, -+ struct vfsmount *mnt) -+{ -+ BUG_ON(!dent || index < 0); -+ UNIONFS_D(dent)->lower_paths[index].mnt = mnt; -+} -+ -+static inline struct vfsmount *unionfs_lower_mnt_idx( -+ const struct dentry *dent, -+ int index) -+{ -+ BUG_ON(!dent || index < 0); -+ return UNIONFS_D(dent)->lower_paths[index].mnt; -+} -+ -+static inline struct vfsmount *unionfs_lower_mnt(const struct dentry *dent) -+{ -+ BUG_ON(!dent); -+ return unionfs_lower_mnt_idx(dent, dbstart(dent)); -+} -+ -+/* Macros for locking a dentry. */ -+enum unionfs_dentry_lock_class { -+ UNIONFS_DMUTEX_NORMAL, -+ UNIONFS_DMUTEX_ROOT, -+ UNIONFS_DMUTEX_PARENT, -+ UNIONFS_DMUTEX_CHILD, -+ UNIONFS_DMUTEX_WHITEOUT, -+ UNIONFS_DMUTEX_REVAL_PARENT, /* for file/dentry revalidate */ -+ UNIONFS_DMUTEX_REVAL_CHILD, /* for file/dentry revalidate */ -+}; -+ -+static inline void unionfs_lock_dentry(struct dentry *d, -+ unsigned int subclass) -+{ -+ BUG_ON(!d); -+ mutex_lock_nested(&UNIONFS_D(d)->lock, subclass); -+} -+ -+static inline void unionfs_unlock_dentry(struct dentry *d) -+{ -+ BUG_ON(!d); -+ mutex_unlock(&UNIONFS_D(d)->lock); -+} -+ -+static inline struct dentry *unionfs_lock_parent(struct dentry *d, -+ unsigned int subclass) -+{ -+ struct dentry *p; -+ -+ BUG_ON(!d); -+ p = dget_parent(d); -+ if (p != d) -+ mutex_lock_nested(&UNIONFS_D(p)->lock, subclass); -+ return p; -+} -+ -+static inline void unionfs_unlock_parent(struct dentry *d, struct dentry *p) -+{ -+ BUG_ON(!d); -+ BUG_ON(!p); -+ if (p != d) { -+ BUG_ON(!mutex_is_locked(&UNIONFS_D(p)->lock)); -+ mutex_unlock(&UNIONFS_D(p)->lock); -+ } -+ dput(p); -+} -+ -+static inline void verify_locked(struct dentry *d) -+{ -+ BUG_ON(!d); -+ BUG_ON(!mutex_is_locked(&UNIONFS_D(d)->lock)); -+} -+ -+/* macros to put lower objects */ -+ -+/* -+ * iput lower inodes of an unionfs dentry, from bstart to bend. If -+ * @free_lower is true, then also kfree the memory used to hold the lower -+ * object pointers. -+ */ -+static inline void iput_lowers(struct inode *inode, -+ int bstart, int bend, bool free_lower) -+{ -+ struct inode *lower_inode; -+ int bindex; -+ -+ BUG_ON(!inode); -+ BUG_ON(!UNIONFS_I(inode)); -+ BUG_ON(bstart < 0); -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (lower_inode) { -+ unionfs_set_lower_inode_idx(inode, bindex, NULL); -+ /* see Documentation/filesystems/unionfs/issues.txt */ -+ lockdep_off(); -+ iput(lower_inode); -+ lockdep_on(); -+ } -+ } -+ -+ if (free_lower) { -+ kfree(UNIONFS_I(inode)->lower_inodes); -+ UNIONFS_I(inode)->lower_inodes = NULL; -+ } -+} -+ -+/* iput all lower inodes, and reset start/end branch indices to -1 */ -+static inline void iput_lowers_all(struct inode *inode, bool free_lower) -+{ -+ int bstart, bend; -+ -+ BUG_ON(!inode); -+ BUG_ON(!UNIONFS_I(inode)); -+ bstart = ibstart(inode); -+ bend = ibend(inode); -+ BUG_ON(bstart < 0); -+ -+ iput_lowers(inode, bstart, bend, free_lower); -+ ibstart(inode) = ibend(inode) = -1; -+} -+ -+/* -+ * dput/mntput all lower dentries and vfsmounts of an unionfs dentry, from -+ * bstart to bend. If @free_lower is true, then also kfree the memory used -+ * to hold the lower object pointers. -+ * -+ * XXX: implement using path_put VFS macros -+ */ -+static inline void path_put_lowers(struct dentry *dentry, -+ int bstart, int bend, bool free_lower) -+{ -+ struct dentry *lower_dentry; -+ struct vfsmount *lower_mnt; -+ int bindex; -+ -+ BUG_ON(!dentry); -+ BUG_ON(!UNIONFS_D(dentry)); -+ BUG_ON(bstart < 0); -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (lower_dentry) { -+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL); -+ dput(lower_dentry); -+ } -+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex); -+ if (lower_mnt) { -+ unionfs_set_lower_mnt_idx(dentry, bindex, NULL); -+ mntput(lower_mnt); -+ } -+ } -+ -+ if (free_lower) { -+ kfree(UNIONFS_D(dentry)->lower_paths); -+ UNIONFS_D(dentry)->lower_paths = NULL; -+ } -+} -+ -+/* -+ * dput/mntput all lower dentries and vfsmounts, and reset start/end branch -+ * indices to -1. -+ */ -+static inline void path_put_lowers_all(struct dentry *dentry, bool free_lower) -+{ -+ int bstart, bend; -+ -+ BUG_ON(!dentry); -+ BUG_ON(!UNIONFS_D(dentry)); -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ BUG_ON(bstart < 0); -+ -+ path_put_lowers(dentry, bstart, bend, free_lower); -+ dbstart(dentry) = dbend(dentry) = -1; -+} -+ -+#endif /* not _FANOUT_H */ -diff --git a/fs/unionfs/file.c b/fs/unionfs/file.c -new file mode 100644 -index 0000000..416c52f ---- /dev/null -+++ b/fs/unionfs/file.c -@@ -0,0 +1,382 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+static ssize_t unionfs_read(struct file *file, char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ int err; -+ struct file *lower_file; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, false); -+ if (unlikely(err)) -+ goto out; -+ -+ lower_file = unionfs_lower_file(file); -+ err = vfs_read(lower_file, buf, count, ppos); -+ /* update our inode atime upon a successful lower read */ -+ if (err >= 0) { -+ fsstack_copy_attr_atime(dentry->d_inode, -+ lower_file->f_path.dentry->d_inode); -+ unionfs_check_file(file); -+ } -+ -+out: -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+static ssize_t unionfs_write(struct file *file, const char __user *buf, -+ size_t count, loff_t *ppos) -+{ -+ int err = 0; -+ struct file *lower_file; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, true); -+ if (unlikely(err)) -+ goto out; -+ -+ lower_file = unionfs_lower_file(file); -+ err = vfs_write(lower_file, buf, count, ppos); -+ /* update our inode times+sizes upon a successful lower write */ -+ if (err >= 0) { -+ fsstack_copy_inode_size(dentry->d_inode, -+ lower_file->f_path.dentry->d_inode); -+ fsstack_copy_attr_times(dentry->d_inode, -+ lower_file->f_path.dentry->d_inode); -+ UNIONFS_F(file)->wrote_to_file = true; /* for delayed copyup */ -+ unionfs_check_file(file); -+ } -+ -+out: -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+static int unionfs_file_readdir(struct file *file, void *dirent, -+ filldir_t filldir) -+{ -+ return -ENOTDIR; -+} -+ -+static int unionfs_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ int err = 0; -+ bool willwrite; -+ struct file *lower_file; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ const struct vm_operations_struct *saved_vm_ops = NULL; -+ -+ /* -+ * Since mm/memory.c:might_fault() (under PROVE_LOCKING) was -+ * modified in 2.6.29-rc1 to call might_lock_read on mmap_sem, this -+ * has been causing false positives in file system stacking layers. -+ * In particular, our ->mmap is called after sys_mmap2 already holds -+ * mmap_sem, then we lock our own mutexes; but earlier, it's -+ * possible for lockdep to have locked our mutexes first, and then -+ * we call a lower ->readdir which could call might_fault. The -+ * different ordering of the locks is what lockdep complains about -+ * -- unnecessarily. Therefore, we have no choice but to tell -+ * lockdep to temporarily turn off lockdep here. Note: the comments -+ * inside might_sleep also suggest that it would have been -+ * nicer to only annotate paths that needs that might_lock_read. -+ */ -+ lockdep_off(); -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ /* This might be deferred to mmap's writepage */ -+ willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags); -+ err = unionfs_file_revalidate(file, parent, willwrite); -+ if (unlikely(err)) -+ goto out; -+ unionfs_check_file(file); -+ -+ /* -+ * File systems which do not implement ->writepage may use -+ * generic_file_readonly_mmap as their ->mmap op. If you call -+ * generic_file_readonly_mmap with VM_WRITE, you'd get an -EINVAL. -+ * But we cannot call the lower ->mmap op, so we can't tell that -+ * writeable mappings won't work. Therefore, our only choice is to -+ * check if the lower file system supports the ->writepage, and if -+ * not, return EINVAL (the same error that -+ * generic_file_readonly_mmap returns in that case). -+ */ -+ lower_file = unionfs_lower_file(file); -+ if (willwrite && !lower_file->f_mapping->a_ops->writepage) { -+ err = -EINVAL; -+ printk(KERN_ERR "unionfs: branch %d file system does not " -+ "support writeable mmap\n", fbstart(file)); -+ goto out; -+ } -+ -+ /* -+ * find and save lower vm_ops. -+ * -+ * XXX: the VFS should have a cleaner way of finding the lower vm_ops -+ */ -+ if (!UNIONFS_F(file)->lower_vm_ops) { -+ err = lower_file->f_op->mmap(lower_file, vma); -+ if (err) { -+ printk(KERN_ERR "unionfs: lower mmap failed %d\n", err); -+ goto out; -+ } -+ saved_vm_ops = vma->vm_ops; -+ err = do_munmap(current->mm, vma->vm_start, -+ vma->vm_end - vma->vm_start); -+ if (err) { -+ printk(KERN_ERR "unionfs: do_munmap failed %d\n", err); -+ goto out; -+ } -+ } -+ -+ file->f_mapping->a_ops = &unionfs_dummy_aops; -+ err = generic_file_mmap(file, vma); -+ file->f_mapping->a_ops = &unionfs_aops; -+ if (err) { -+ printk(KERN_ERR "unionfs: generic_file_mmap failed %d\n", err); -+ goto out; -+ } -+ vma->vm_ops = &unionfs_vm_ops; -+ if (!UNIONFS_F(file)->lower_vm_ops) -+ UNIONFS_F(file)->lower_vm_ops = saved_vm_ops; -+ -+out: -+ if (!err) { -+ /* copyup could cause parent dir times to change */ -+ unionfs_copy_attr_times(parent->d_inode); -+ unionfs_check_file(file); -+ } -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ lockdep_on(); -+ return err; -+} -+ -+int unionfs_fsync(struct file *file, int datasync) -+{ -+ int bindex, bstart, bend; -+ struct file *lower_file; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *lower_dentry; -+ struct dentry *parent; -+ struct inode *lower_inode, *inode; -+ int err = -EINVAL; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, true); -+ if (unlikely(err)) -+ goto out; -+ unionfs_check_file(file); -+ -+ bstart = fbstart(file); -+ bend = fbend(file); -+ if (bstart < 0 || bend < 0) -+ goto out; -+ -+ inode = dentry->d_inode; -+ if (unlikely(!inode)) { -+ printk(KERN_ERR -+ "unionfs: null lower inode in unionfs_fsync\n"); -+ goto out; -+ } -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (!lower_inode || !lower_inode->i_fop->fsync) -+ continue; -+ lower_file = unionfs_lower_file_idx(file, bindex); -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ mutex_lock(&lower_inode->i_mutex); -+ err = lower_inode->i_fop->fsync(lower_file, datasync); -+ if (!err && bindex == bstart) -+ fsstack_copy_attr_times(inode, lower_inode); -+ mutex_unlock(&lower_inode->i_mutex); -+ if (err) -+ goto out; -+ } -+ -+out: -+ if (!err) -+ unionfs_check_file(file); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+int unionfs_fasync(int fd, struct file *file, int flag) -+{ -+ int bindex, bstart, bend; -+ struct file *lower_file; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ struct inode *lower_inode, *inode; -+ int err = 0; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, true); -+ if (unlikely(err)) -+ goto out; -+ unionfs_check_file(file); -+ -+ bstart = fbstart(file); -+ bend = fbend(file); -+ if (bstart < 0 || bend < 0) -+ goto out; -+ -+ inode = dentry->d_inode; -+ if (unlikely(!inode)) { -+ printk(KERN_ERR -+ "unionfs: null lower inode in unionfs_fasync\n"); -+ goto out; -+ } -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (!lower_inode || !lower_inode->i_fop->fasync) -+ continue; -+ lower_file = unionfs_lower_file_idx(file, bindex); -+ mutex_lock(&lower_inode->i_mutex); -+ err = lower_inode->i_fop->fasync(fd, lower_file, flag); -+ if (!err && bindex == bstart) -+ fsstack_copy_attr_times(inode, lower_inode); -+ mutex_unlock(&lower_inode->i_mutex); -+ if (err) -+ goto out; -+ } -+ -+out: -+ if (!err) -+ unionfs_check_file(file); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+static ssize_t unionfs_splice_read(struct file *file, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags) -+{ -+ ssize_t err; -+ struct file *lower_file; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, false); -+ if (unlikely(err)) -+ goto out; -+ -+ lower_file = unionfs_lower_file(file); -+ err = vfs_splice_to(lower_file, ppos, pipe, len, flags); -+ /* update our inode atime upon a successful lower splice-read */ -+ if (err >= 0) { -+ fsstack_copy_attr_atime(dentry->d_inode, -+ lower_file->f_path.dentry->d_inode); -+ unionfs_check_file(file); -+ } -+ -+out: -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+static ssize_t unionfs_splice_write(struct pipe_inode_info *pipe, -+ struct file *file, loff_t *ppos, -+ size_t len, unsigned int flags) -+{ -+ ssize_t err = 0; -+ struct file *lower_file; -+ struct dentry *dentry = file->f_path.dentry; -+ struct dentry *parent; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ err = unionfs_file_revalidate(file, parent, true); -+ if (unlikely(err)) -+ goto out; -+ -+ lower_file = unionfs_lower_file(file); -+ err = vfs_splice_from(pipe, lower_file, ppos, len, flags); -+ /* update our inode times+sizes upon a successful lower write */ -+ if (err >= 0) { -+ fsstack_copy_inode_size(dentry->d_inode, -+ lower_file->f_path.dentry->d_inode); -+ fsstack_copy_attr_times(dentry->d_inode, -+ lower_file->f_path.dentry->d_inode); -+ unionfs_check_file(file); -+ } -+ -+out: -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+struct file_operations unionfs_main_fops = { -+ .llseek = generic_file_llseek, -+ .read = unionfs_read, -+ .write = unionfs_write, -+ .readdir = unionfs_file_readdir, -+ .unlocked_ioctl = unionfs_ioctl, -+#ifdef CONFIG_COMPAT -+ .compat_ioctl = unionfs_ioctl, -+#endif -+ .mmap = unionfs_mmap, -+ .open = unionfs_open, -+ .flush = unionfs_flush, -+ .release = unionfs_file_release, -+ .fsync = unionfs_fsync, -+ .fasync = unionfs_fasync, -+ .splice_read = unionfs_splice_read, -+ .splice_write = unionfs_splice_write, -+}; -diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c -new file mode 100644 -index 0000000..b207c13 ---- /dev/null -+++ b/fs/unionfs/inode.c -@@ -0,0 +1,1099 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * Find a writeable branch to create new object in. Checks all writeble -+ * branches of the parent inode, from istart to iend order; if none are -+ * suitable, also tries branch 0 (which may require a copyup). -+ * -+ * Return a lower_dentry we can use to create object in, or ERR_PTR. -+ */ -+static struct dentry *find_writeable_branch(struct inode *parent, -+ struct dentry *dentry) -+{ -+ int err = -EINVAL; -+ int bindex, istart, iend; -+ struct dentry *lower_dentry = NULL; -+ -+ istart = ibstart(parent); -+ iend = ibend(parent); -+ if (istart < 0) -+ goto out; -+ -+begin: -+ for (bindex = istart; bindex <= iend; bindex++) { -+ /* skip non-writeable branches */ -+ err = is_robranch_super(dentry->d_sb, bindex); -+ if (err) { -+ err = -EROFS; -+ continue; -+ } -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry) -+ continue; -+ /* -+ * check for whiteouts in writeable branch, and remove them -+ * if necessary. -+ */ -+ err = check_unlink_whiteout(dentry, lower_dentry, bindex); -+ if (err > 0) /* ignore if whiteout found and removed */ -+ err = 0; -+ if (err) -+ continue; -+ /* if get here, we can write to the branch */ -+ break; -+ } -+ /* -+ * If istart wasn't already branch 0, and we got any error, then try -+ * branch 0 (which may require copyup) -+ */ -+ if (err && istart > 0) { -+ istart = iend = 0; -+ goto begin; -+ } -+ -+ /* -+ * If we tried even branch 0, and still got an error, abort. But if -+ * the error was an EROFS, then we should try to copyup. -+ */ -+ if (err && err != -EROFS) -+ goto out; -+ -+ /* -+ * If we get here, then check if copyup needed. If lower_dentry is -+ * NULL, create the entire dentry directory structure in branch 0. -+ */ -+ if (!lower_dentry) { -+ bindex = 0; -+ lower_dentry = create_parents(parent, dentry, -+ dentry->d_name.name, bindex); -+ if (IS_ERR(lower_dentry)) { -+ err = PTR_ERR(lower_dentry); -+ goto out; -+ } -+ } -+ err = 0; /* all's well */ -+out: -+ if (err) -+ return ERR_PTR(err); -+ return lower_dentry; -+} -+ -+static int unionfs_create(struct inode *dir, struct dentry *dentry, -+ int mode, struct nameidata *nd_unused) -+{ -+ int err = 0; -+ struct dentry *lower_dentry = NULL; -+ struct dentry *lower_parent_dentry = NULL; -+ struct dentry *parent; -+ int valid = 0; -+ struct nameidata lower_nd; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; /* same as what real_lookup does */ -+ goto out; -+ } -+ -+ lower_dentry = find_writeable_branch(dir, dentry); -+ if (IS_ERR(lower_dentry)) { -+ err = PTR_ERR(lower_dentry); -+ goto out; -+ } -+ -+ lower_parent_dentry = lock_parent(lower_dentry); -+ if (IS_ERR(lower_parent_dentry)) { -+ err = PTR_ERR(lower_parent_dentry); -+ goto out_unlock; -+ } -+ -+ err = init_lower_nd(&lower_nd, LOOKUP_CREATE); -+ if (unlikely(err < 0)) -+ goto out_unlock; -+ err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, -+ &lower_nd); -+ release_lower_nd(&lower_nd, err); -+ -+ if (!err) { -+ err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0)); -+ if (!err) { -+ unionfs_copy_attr_times(dir); -+ fsstack_copy_inode_size(dir, -+ lower_parent_dentry->d_inode); -+ /* update no. of links on parent directory */ -+ dir->i_nlink = unionfs_get_nlinks(dir); -+ } -+ } -+ -+out_unlock: -+ unlock_dir(lower_parent_dentry); -+out: -+ if (!err) { -+ unionfs_postcopyup_setmnt(dentry); -+ unionfs_check_inode(dir); -+ unionfs_check_dentry(dentry); -+ } -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+/* -+ * unionfs_lookup is the only special function which takes a dentry, yet we -+ * do NOT want to call __unionfs_d_revalidate_chain because by definition, -+ * we don't have a valid dentry here yet. -+ */ -+static struct dentry *unionfs_lookup(struct inode *dir, -+ struct dentry *dentry, -+ struct nameidata *nd_unused) -+{ -+ struct dentry *ret, *parent; -+ int err = 0; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ -+ /* -+ * As long as we lock/dget the parent, then can skip validating the -+ * parent now; we may have to rebuild this dentry on the next -+ * ->d_revalidate, however. -+ */ -+ -+ /* allocate dentry private data. We free it in ->d_release */ -+ err = new_dentry_private_data(dentry, UNIONFS_DMUTEX_CHILD); -+ if (unlikely(err)) { -+ ret = ERR_PTR(err); -+ goto out; -+ } -+ -+ ret = unionfs_lookup_full(dentry, parent, INTERPOSE_LOOKUP); -+ -+ if (!IS_ERR(ret)) { -+ if (ret) -+ dentry = ret; -+ /* lookup_full can return multiple positive dentries */ -+ if (dentry->d_inode && !S_ISDIR(dentry->d_inode->i_mode)) { -+ BUG_ON(dbstart(dentry) < 0); -+ unionfs_postcopyup_release(dentry); -+ } -+ unionfs_copy_attr_times(dentry->d_inode); -+ } -+ -+ unionfs_check_inode(dir); -+ if (!IS_ERR(ret)) -+ unionfs_check_dentry(dentry); -+ unionfs_check_dentry(parent); -+ unionfs_unlock_dentry(dentry); /* locked in new_dentry_private data */ -+ -+out: -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ -+ return ret; -+} -+ -+static int unionfs_link(struct dentry *old_dentry, struct inode *dir, -+ struct dentry *new_dentry) -+{ -+ int err = 0; -+ struct dentry *lower_old_dentry = NULL; -+ struct dentry *lower_new_dentry = NULL; -+ struct dentry *lower_dir_dentry = NULL; -+ struct dentry *old_parent, *new_parent; -+ char *name = NULL; -+ bool valid; -+ -+ unionfs_read_lock(old_dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ old_parent = dget_parent(old_dentry); -+ new_parent = dget_parent(new_dentry); -+ unionfs_double_lock_parents(old_parent, new_parent); -+ unionfs_double_lock_dentry(old_dentry, new_dentry); -+ -+ valid = __unionfs_d_revalidate(old_dentry, old_parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ if (new_dentry->d_inode) { -+ valid = __unionfs_d_revalidate(new_dentry, new_parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ } -+ -+ lower_new_dentry = unionfs_lower_dentry(new_dentry); -+ -+ /* check for a whiteout in new dentry branch, and delete it */ -+ err = check_unlink_whiteout(new_dentry, lower_new_dentry, -+ dbstart(new_dentry)); -+ if (err > 0) { /* whiteout found and removed successfully */ -+ lower_dir_dentry = dget_parent(lower_new_dentry); -+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); -+ dput(lower_dir_dentry); -+ dir->i_nlink = unionfs_get_nlinks(dir); -+ err = 0; -+ } -+ if (err) -+ goto out; -+ -+ /* check if parent hierachy is needed, then link in same branch */ -+ if (dbstart(old_dentry) != dbstart(new_dentry)) { -+ lower_new_dentry = create_parents(dir, new_dentry, -+ new_dentry->d_name.name, -+ dbstart(old_dentry)); -+ err = PTR_ERR(lower_new_dentry); -+ if (IS_COPYUP_ERR(err)) -+ goto docopyup; -+ if (!lower_new_dentry || IS_ERR(lower_new_dentry)) -+ goto out; -+ } -+ lower_new_dentry = unionfs_lower_dentry(new_dentry); -+ lower_old_dentry = unionfs_lower_dentry(old_dentry); -+ -+ BUG_ON(dbstart(old_dentry) != dbstart(new_dentry)); -+ lower_dir_dentry = lock_parent(lower_new_dentry); -+ err = is_robranch(old_dentry); -+ if (!err) { -+ /* see Documentation/filesystems/unionfs/issues.txt */ -+ lockdep_off(); -+ err = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, -+ lower_new_dentry); -+ lockdep_on(); -+ } -+ unlock_dir(lower_dir_dentry); -+ -+docopyup: -+ if (IS_COPYUP_ERR(err)) { -+ int old_bstart = dbstart(old_dentry); -+ int bindex; -+ -+ for (bindex = old_bstart - 1; bindex >= 0; bindex--) { -+ err = copyup_dentry(old_parent->d_inode, -+ old_dentry, old_bstart, -+ bindex, old_dentry->d_name.name, -+ old_dentry->d_name.len, NULL, -+ i_size_read(old_dentry->d_inode)); -+ if (err) -+ continue; -+ lower_new_dentry = -+ create_parents(dir, new_dentry, -+ new_dentry->d_name.name, -+ bindex); -+ lower_old_dentry = unionfs_lower_dentry(old_dentry); -+ lower_dir_dentry = lock_parent(lower_new_dentry); -+ /* see Documentation/filesystems/unionfs/issues.txt */ -+ lockdep_off(); -+ /* do vfs_link */ -+ err = vfs_link(lower_old_dentry, -+ lower_dir_dentry->d_inode, -+ lower_new_dentry); -+ lockdep_on(); -+ unlock_dir(lower_dir_dentry); -+ goto check_link; -+ } -+ goto out; -+ } -+ -+check_link: -+ if (err || !lower_new_dentry->d_inode) -+ goto out; -+ -+ /* Its a hard link, so use the same inode */ -+ new_dentry->d_inode = igrab(old_dentry->d_inode); -+ d_add(new_dentry, new_dentry->d_inode); -+ unionfs_copy_attr_all(dir, lower_new_dentry->d_parent->d_inode); -+ fsstack_copy_inode_size(dir, lower_new_dentry->d_parent->d_inode); -+ -+ /* propagate number of hard-links */ -+ old_dentry->d_inode->i_nlink = unionfs_get_nlinks(old_dentry->d_inode); -+ /* new dentry's ctime may have changed due to hard-link counts */ -+ unionfs_copy_attr_times(new_dentry->d_inode); -+ -+out: -+ if (!new_dentry->d_inode) -+ d_drop(new_dentry); -+ -+ kfree(name); -+ if (!err) -+ unionfs_postcopyup_setmnt(new_dentry); -+ -+ unionfs_check_inode(dir); -+ unionfs_check_dentry(new_dentry); -+ unionfs_check_dentry(old_dentry); -+ -+ unionfs_double_unlock_dentry(old_dentry, new_dentry); -+ unionfs_double_unlock_parents(old_parent, new_parent); -+ dput(new_parent); -+ dput(old_parent); -+ unionfs_read_unlock(old_dentry->d_sb); -+ -+ return err; -+} -+ -+static int unionfs_symlink(struct inode *dir, struct dentry *dentry, -+ const char *symname) -+{ -+ int err = 0; -+ struct dentry *lower_dentry = NULL; -+ struct dentry *wh_dentry = NULL; -+ struct dentry *lower_parent_dentry = NULL; -+ struct dentry *parent; -+ char *name = NULL; -+ int valid = 0; -+ umode_t mode; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ -+ /* -+ * It's only a bug if this dentry was not negative and couldn't be -+ * revalidated (shouldn't happen). -+ */ -+ BUG_ON(!valid && dentry->d_inode); -+ -+ lower_dentry = find_writeable_branch(dir, dentry); -+ if (IS_ERR(lower_dentry)) { -+ err = PTR_ERR(lower_dentry); -+ goto out; -+ } -+ -+ lower_parent_dentry = lock_parent(lower_dentry); -+ if (IS_ERR(lower_parent_dentry)) { -+ err = PTR_ERR(lower_parent_dentry); -+ goto out_unlock; -+ } -+ -+ mode = S_IALLUGO; -+ err = vfs_symlink(lower_parent_dentry->d_inode, lower_dentry, symname); -+ if (!err) { -+ err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0)); -+ if (!err) { -+ unionfs_copy_attr_times(dir); -+ fsstack_copy_inode_size(dir, -+ lower_parent_dentry->d_inode); -+ /* update no. of links on parent directory */ -+ dir->i_nlink = unionfs_get_nlinks(dir); -+ } -+ } -+ -+out_unlock: -+ unlock_dir(lower_parent_dentry); -+out: -+ dput(wh_dentry); -+ kfree(name); -+ -+ if (!err) { -+ unionfs_postcopyup_setmnt(dentry); -+ unionfs_check_inode(dir); -+ unionfs_check_dentry(dentry); -+ } -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+static int unionfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) -+{ -+ int err = 0; -+ struct dentry *lower_dentry = NULL; -+ struct dentry *lower_parent_dentry = NULL; -+ struct dentry *parent; -+ int bindex = 0, bstart; -+ char *name = NULL; -+ int valid; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; /* same as what real_lookup does */ -+ goto out; -+ } -+ -+ bstart = dbstart(dentry); -+ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ -+ /* check for a whiteout in new dentry branch, and delete it */ -+ err = check_unlink_whiteout(dentry, lower_dentry, bstart); -+ if (err > 0) /* whiteout found and removed successfully */ -+ err = 0; -+ if (err) { -+ /* exit if the error returned was NOT -EROFS */ -+ if (!IS_COPYUP_ERR(err)) -+ goto out; -+ bstart--; -+ } -+ -+ /* check if copyup's needed, and mkdir */ -+ for (bindex = bstart; bindex >= 0; bindex--) { -+ int i; -+ int bend = dbend(dentry); -+ -+ if (is_robranch_super(dentry->d_sb, bindex)) -+ continue; -+ -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry) { -+ lower_dentry = create_parents(dir, dentry, -+ dentry->d_name.name, -+ bindex); -+ if (!lower_dentry || IS_ERR(lower_dentry)) { -+ printk(KERN_ERR "unionfs: lower dentry " -+ " NULL for bindex = %d\n", bindex); -+ continue; -+ } -+ } -+ -+ lower_parent_dentry = lock_parent(lower_dentry); -+ -+ if (IS_ERR(lower_parent_dentry)) { -+ err = PTR_ERR(lower_parent_dentry); -+ goto out; -+ } -+ -+ err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry, -+ mode); -+ -+ unlock_dir(lower_parent_dentry); -+ -+ /* did the mkdir succeed? */ -+ if (err) -+ break; -+ -+ for (i = bindex + 1; i <= bend; i++) { -+ /* XXX: use path_put_lowers? */ -+ if (unionfs_lower_dentry_idx(dentry, i)) { -+ dput(unionfs_lower_dentry_idx(dentry, i)); -+ unionfs_set_lower_dentry_idx(dentry, i, NULL); -+ } -+ } -+ dbend(dentry) = bindex; -+ -+ /* -+ * Only INTERPOSE_LOOKUP can return a value other than 0 on -+ * err. -+ */ -+ err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0)); -+ if (!err) { -+ unionfs_copy_attr_times(dir); -+ fsstack_copy_inode_size(dir, -+ lower_parent_dentry->d_inode); -+ -+ /* update number of links on parent directory */ -+ dir->i_nlink = unionfs_get_nlinks(dir); -+ } -+ -+ err = make_dir_opaque(dentry, dbstart(dentry)); -+ if (err) { -+ printk(KERN_ERR "unionfs: mkdir: error creating " -+ ".wh.__dir_opaque: %d\n", err); -+ goto out; -+ } -+ -+ /* we are done! */ -+ break; -+ } -+ -+out: -+ if (!dentry->d_inode) -+ d_drop(dentry); -+ -+ kfree(name); -+ -+ if (!err) { -+ unionfs_copy_attr_times(dentry->d_inode); -+ unionfs_postcopyup_setmnt(dentry); -+ } -+ unionfs_check_inode(dir); -+ unionfs_check_dentry(dentry); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ -+ return err; -+} -+ -+static int unionfs_mknod(struct inode *dir, struct dentry *dentry, int mode, -+ dev_t dev) -+{ -+ int err = 0; -+ struct dentry *lower_dentry = NULL; -+ struct dentry *wh_dentry = NULL; -+ struct dentry *lower_parent_dentry = NULL; -+ struct dentry *parent; -+ char *name = NULL; -+ int valid = 0; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ -+ /* -+ * It's only a bug if this dentry was not negative and couldn't be -+ * revalidated (shouldn't happen). -+ */ -+ BUG_ON(!valid && dentry->d_inode); -+ -+ lower_dentry = find_writeable_branch(dir, dentry); -+ if (IS_ERR(lower_dentry)) { -+ err = PTR_ERR(lower_dentry); -+ goto out; -+ } -+ -+ lower_parent_dentry = lock_parent(lower_dentry); -+ if (IS_ERR(lower_parent_dentry)) { -+ err = PTR_ERR(lower_parent_dentry); -+ goto out_unlock; -+ } -+ -+ err = vfs_mknod(lower_parent_dentry->d_inode, lower_dentry, mode, dev); -+ if (!err) { -+ err = PTR_ERR(unionfs_interpose(dentry, dir->i_sb, 0)); -+ if (!err) { -+ unionfs_copy_attr_times(dir); -+ fsstack_copy_inode_size(dir, -+ lower_parent_dentry->d_inode); -+ /* update no. of links on parent directory */ -+ dir->i_nlink = unionfs_get_nlinks(dir); -+ } -+ } -+ -+out_unlock: -+ unlock_dir(lower_parent_dentry); -+out: -+ dput(wh_dentry); -+ kfree(name); -+ -+ if (!err) { -+ unionfs_postcopyup_setmnt(dentry); -+ unionfs_check_inode(dir); -+ unionfs_check_dentry(dentry); -+ } -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+/* requires sb, dentry, and parent to already be locked */ -+static int __unionfs_readlink(struct dentry *dentry, char __user *buf, -+ int bufsiz) -+{ -+ int err; -+ struct dentry *lower_dentry; -+ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ -+ if (!lower_dentry->d_inode->i_op || -+ !lower_dentry->d_inode->i_op->readlink) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ err = lower_dentry->d_inode->i_op->readlink(lower_dentry, -+ buf, bufsiz); -+ if (err >= 0) -+ fsstack_copy_attr_atime(dentry->d_inode, -+ lower_dentry->d_inode); -+ -+out: -+ return err; -+} -+ -+static int unionfs_readlink(struct dentry *dentry, char __user *buf, -+ int bufsiz) -+{ -+ int err; -+ struct dentry *parent; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ if (unlikely(!__unionfs_d_revalidate(dentry, parent, false))) { -+ err = -ESTALE; -+ goto out; -+ } -+ -+ err = __unionfs_readlink(dentry, buf, bufsiz); -+ -+out: -+ unionfs_check_dentry(dentry); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ -+ return err; -+} -+ -+static void *unionfs_follow_link(struct dentry *dentry, struct nameidata *nd) -+{ -+ char *buf; -+ int len = PAGE_SIZE, err; -+ mm_segment_t old_fs; -+ struct dentry *parent; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ /* This is freed by the put_link method assuming a successful call. */ -+ buf = kmalloc(len, GFP_KERNEL); -+ if (unlikely(!buf)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ /* read the symlink, and then we will follow it */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = __unionfs_readlink(dentry, buf, len); -+ set_fs(old_fs); -+ if (err < 0) { -+ kfree(buf); -+ buf = NULL; -+ goto out; -+ } -+ buf[err] = 0; -+ nd_set_link(nd, buf); -+ err = 0; -+ -+out: -+ if (err >= 0) { -+ unionfs_check_nd(nd); -+ unionfs_check_dentry(dentry); -+ } -+ -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ -+ return ERR_PTR(err); -+} -+ -+/* this @nd *IS* still used */ -+static void unionfs_put_link(struct dentry *dentry, struct nameidata *nd, -+ void *cookie) -+{ -+ struct dentry *parent; -+ char *buf; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ if (unlikely(!__unionfs_d_revalidate(dentry, parent, false))) -+ printk(KERN_ERR -+ "unionfs: put_link failed to revalidate dentry\n"); -+ -+ unionfs_check_dentry(dentry); -+#if 0 -+ /* XXX: can't run this check b/c this fxn can receive a poisoned 'nd' PTR */ -+ unionfs_check_nd(nd); -+#endif -+ buf = nd_get_link(nd); -+ if (!IS_ERR(buf)) -+ kfree(buf); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+} -+ -+/* -+ * This is a variant of fs/namei.c:permission() or inode_permission() which -+ * skips over EROFS tests (because we perform copyup on EROFS). -+ */ -+static int __inode_permission(struct inode *inode, int mask, unsigned int flags) -+{ -+ int retval; -+ -+ /* nobody gets write access to an immutable file */ -+ if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) -+ return -EACCES; -+ -+ /* Ordinary permission routines do not understand MAY_APPEND. */ -+ if (inode->i_op && inode->i_op->permission) { -+ retval = inode->i_op->permission(inode, mask, flags); -+ if (!retval) { -+ /* -+ * Exec permission on a regular file is denied if none -+ * of the execute bits are set. -+ * -+ * This check should be done by the ->permission() -+ * method. -+ */ -+ if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode) && -+ !(inode->i_mode & S_IXUGO)) -+ return -EACCES; -+ } -+ } else { -+ retval = generic_permission(inode, mask, flags, NULL); -+ } -+ if (retval) -+ return retval; -+ -+ return security_inode_permission(inode, -+ mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND)); -+} -+ -+/* -+ * Don't grab the superblock read-lock in unionfs_permission, which prevents -+ * a deadlock with the branch-management "add branch" code (which grabbed -+ * the write lock). It is safe to not grab the read lock here, because even -+ * with branch management taking place, there is no chance that -+ * unionfs_permission, or anything it calls, will use stale branch -+ * information. -+ */ -+static int unionfs_permission(struct inode *inode, int mask, unsigned int flags) -+{ -+ struct inode *lower_inode = NULL; -+ int err = 0; -+ int bindex, bstart, bend; -+ int is_file; -+ const int write_mask = (mask & MAY_WRITE) && !(mask & MAY_READ); -+ struct inode *inode_grabbed; -+ struct dentry *dentry; -+ -+ if (flags & IPERM_FLAG_RCU) { -+ err = -ECHILD; -+ goto out_nograb; -+ } -+ -+ dentry = d_find_alias(inode); -+ if (dentry) -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ inode_grabbed = igrab(inode); -+ is_file = !S_ISDIR(inode->i_mode); -+ -+ if (!UNIONFS_I(inode)->lower_inodes) { -+ if (is_file) /* dirs can be unlinked but chdir'ed to */ -+ err = -ESTALE; /* force revalidate */ -+ goto out; -+ } -+ bstart = ibstart(inode); -+ bend = ibend(inode); -+ if (unlikely(bstart < 0 || bend < 0)) { -+ /* -+ * With branch-management, we can get a stale inode here. -+ * If so, we return ESTALE back to link_path_walk, which -+ * would discard the dcache entry and re-lookup the -+ * dentry+inode. This should be equivalent to issuing -+ * __unionfs_d_revalidate_chain on nd.dentry here. -+ */ -+ if (is_file) /* dirs can be unlinked but chdir'ed to */ -+ err = -ESTALE; /* force revalidate */ -+ goto out; -+ } -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (!lower_inode) -+ continue; -+ -+ /* -+ * check the condition for D-F-D underlying files/directories, -+ * we don't have to check for files, if we are checking for -+ * directories. -+ */ -+ if (!is_file && !S_ISDIR(lower_inode->i_mode)) -+ continue; -+ -+ /* -+ * We check basic permissions, but we ignore any conditions -+ * such as readonly file systems or branches marked as -+ * readonly, because those conditions should lead to a -+ * copyup taking place later on. However, if user never had -+ * access to the file, then no copyup could ever take place. -+ */ -+ err = __inode_permission(lower_inode, mask, flags); -+ if (err && err != -EACCES && err != EPERM && bindex > 0) { -+ umode_t mode = lower_inode->i_mode; -+ if ((is_robranch_super(inode->i_sb, bindex) || -+ __is_rdonly(lower_inode)) && -+ (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) -+ err = 0; -+ if (IS_COPYUP_ERR(err)) -+ err = 0; -+ } -+ -+ /* -+ * NFS HACK: NFSv2/3 return EACCES on readonly-exported, -+ * locally readonly-mounted file systems, instead of EROFS -+ * like other file systems do. So we have no choice here -+ * but to intercept this and ignore it for NFS branches -+ * marked readonly. Specifically, we avoid using NFS's own -+ * "broken" ->permission method, and rely on -+ * generic_permission() to do basic checking for us. -+ */ -+ if (err && err == -EACCES && -+ is_robranch_super(inode->i_sb, bindex) && -+ lower_inode->i_sb->s_magic == NFS_SUPER_MAGIC) -+ err = generic_permission(lower_inode, mask, flags, NULL); -+ -+ /* -+ * The permissions are an intersection of the overall directory -+ * permissions, so we fail if one fails. -+ */ -+ if (err) -+ goto out; -+ -+ /* only the leftmost file matters. */ -+ if (is_file || write_mask) { -+ if (is_file && write_mask) { -+ err = get_write_access(lower_inode); -+ if (!err) -+ put_write_access(lower_inode); -+ } -+ break; -+ } -+ } -+ /* sync times which may have changed (asynchronously) below */ -+ unionfs_copy_attr_times(inode); -+ -+out: -+ unionfs_check_inode(inode); -+ if (dentry) { -+ unionfs_unlock_dentry(dentry); -+ dput(dentry); -+ } -+ iput(inode_grabbed); -+out_nograb: -+ return err; -+} -+ -+static int unionfs_setattr(struct dentry *dentry, struct iattr *ia) -+{ -+ int err = 0; -+ struct dentry *lower_dentry; -+ struct dentry *parent; -+ struct inode *inode; -+ struct inode *lower_inode; -+ int bstart, bend, bindex; -+ loff_t size; -+ struct iattr lower_ia; -+ -+ /* check if user has permission to change inode */ -+ err = inode_change_ok(dentry->d_inode, ia); -+ if (err) -+ goto out_err; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ if (unlikely(!__unionfs_d_revalidate(dentry, parent, false))) { -+ err = -ESTALE; -+ goto out; -+ } -+ -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ inode = dentry->d_inode; -+ -+ /* -+ * mode change is for clearing setuid/setgid. Allow lower filesystem -+ * to reinterpret it in its own way. -+ */ -+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) -+ ia->ia_valid &= ~ATTR_MODE; -+ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ if (!lower_dentry) { /* should never happen after above revalidate */ -+ err = -EINVAL; -+ goto out; -+ } -+ -+ /* -+ * Get the lower inode directly from lower dentry, in case ibstart -+ * is -1 (which happens when the file is open but unlinked. -+ */ -+ lower_inode = lower_dentry->d_inode; -+ -+ /* check if user has permission to change lower inode */ -+ err = inode_change_ok(lower_inode, ia); -+ if (err) -+ goto out; -+ -+ /* copyup if the file is on a read only branch */ -+ if (is_robranch_super(dentry->d_sb, bstart) -+ || __is_rdonly(lower_inode)) { -+ /* check if we have a branch to copy up to */ -+ if (bstart <= 0) { -+ err = -EACCES; -+ goto out; -+ } -+ -+ if (ia->ia_valid & ATTR_SIZE) -+ size = ia->ia_size; -+ else -+ size = i_size_read(inode); -+ /* copyup to next available branch */ -+ for (bindex = bstart - 1; bindex >= 0; bindex--) { -+ err = copyup_dentry(parent->d_inode, -+ dentry, bstart, bindex, -+ dentry->d_name.name, -+ dentry->d_name.len, -+ NULL, size); -+ if (!err) -+ break; -+ } -+ if (err) -+ goto out; -+ /* get updated lower_dentry/inode after copyup */ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ lower_inode = unionfs_lower_inode(inode); -+ /* -+ * check for whiteouts in writeable branch, and remove them -+ * if necessary. -+ */ -+ if (lower_dentry) { -+ err = check_unlink_whiteout(dentry, lower_dentry, -+ bindex); -+ if (err > 0) /* ignore if whiteout found and removed */ -+ err = 0; -+ } -+ } -+ -+ /* -+ * If shrinking, first truncate upper level to cancel writing dirty -+ * pages beyond the new eof; and also if its' maxbytes is more -+ * limiting (fail with -EFBIG before making any change to the lower -+ * level). There is no need to vmtruncate the upper level -+ * afterwards in the other cases: we fsstack_copy_inode_size from -+ * the lower level. -+ */ -+ if (ia->ia_valid & ATTR_SIZE) { -+ size = i_size_read(inode); -+ if (ia->ia_size < size || (ia->ia_size > size && -+ inode->i_sb->s_maxbytes < lower_inode->i_sb->s_maxbytes)) { -+ err = vmtruncate(inode, ia->ia_size); -+ if (err) -+ goto out; -+ } -+ } -+ -+ /* notify the (possibly copied-up) lower inode */ -+ /* -+ * Note: we use lower_dentry->d_inode, because lower_inode may be -+ * unlinked (no inode->i_sb and i_ino==0. This happens if someone -+ * tries to open(), unlink(), then ftruncate() a file. -+ */ -+ /* prepare our own lower struct iattr (with our own lower file) */ -+ memcpy(&lower_ia, ia, sizeof(lower_ia)); -+ if (ia->ia_valid & ATTR_FILE) { -+ lower_ia.ia_file = unionfs_lower_file(ia->ia_file); -+ BUG_ON(!lower_ia.ia_file); // XXX? -+ } -+ -+ mutex_lock(&lower_dentry->d_inode->i_mutex); -+ err = notify_change(lower_dentry, &lower_ia); -+ mutex_unlock(&lower_dentry->d_inode->i_mutex); -+ if (err) -+ goto out; -+ -+ /* get attributes from the first lower inode */ -+ if (ibstart(inode) >= 0) -+ unionfs_copy_attr_all(inode, lower_inode); -+ /* -+ * unionfs_copy_attr_all will copy the lower times to our inode if -+ * the lower ones are newer (useful for cache coherency). However, -+ * ->setattr is the only place in which we may have to copy the -+ * lower inode times absolutely, to support utimes(2). -+ */ -+ if (ia->ia_valid & ATTR_MTIME_SET) -+ inode->i_mtime = lower_inode->i_mtime; -+ if (ia->ia_valid & ATTR_CTIME) -+ inode->i_ctime = lower_inode->i_ctime; -+ if (ia->ia_valid & ATTR_ATIME_SET) -+ inode->i_atime = lower_inode->i_atime; -+ fsstack_copy_inode_size(inode, lower_inode); -+ -+out: -+ if (!err) -+ unionfs_check_dentry(dentry); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+out_err: -+ return err; -+} -+ -+struct inode_operations unionfs_symlink_iops = { -+ .readlink = unionfs_readlink, -+ .permission = unionfs_permission, -+ .follow_link = unionfs_follow_link, -+ .setattr = unionfs_setattr, -+ .put_link = unionfs_put_link, -+}; -+ -+struct inode_operations unionfs_dir_iops = { -+ .create = unionfs_create, -+ .lookup = unionfs_lookup, -+ .link = unionfs_link, -+ .unlink = unionfs_unlink, -+ .symlink = unionfs_symlink, -+ .mkdir = unionfs_mkdir, -+ .rmdir = unionfs_rmdir, -+ .mknod = unionfs_mknod, -+ .rename = unionfs_rename, -+ .permission = unionfs_permission, -+ .setattr = unionfs_setattr, -+#ifdef CONFIG_UNION_FS_XATTR -+ .setxattr = unionfs_setxattr, -+ .getxattr = unionfs_getxattr, -+ .removexattr = unionfs_removexattr, -+ .listxattr = unionfs_listxattr, -+#endif /* CONFIG_UNION_FS_XATTR */ -+}; -+ -+struct inode_operations unionfs_main_iops = { -+ .permission = unionfs_permission, -+ .setattr = unionfs_setattr, -+#ifdef CONFIG_UNION_FS_XATTR -+ .setxattr = unionfs_setxattr, -+ .getxattr = unionfs_getxattr, -+ .removexattr = unionfs_removexattr, -+ .listxattr = unionfs_listxattr, -+#endif /* CONFIG_UNION_FS_XATTR */ -+}; -diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c -new file mode 100644 -index 0000000..3cbde56 ---- /dev/null -+++ b/fs/unionfs/lookup.c -@@ -0,0 +1,569 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * Lookup one path component @name relative to a path pair. -+ * Behaves nearly the same as lookup_one_len (i.e., return negative dentry -+ * on ENOENT), but uses the @mnt passed, so it can cross bind mounts and -+ * other lower mounts properly. If @new_mnt is non-null, will fill in the -+ * new mnt there. Caller is responsible to dput/mntput/path_put returned -+ * @dentry and @new_mnt. -+ */ -+struct dentry *__lookup_one(struct dentry *base, struct vfsmount *mnt, -+ const char *name, struct vfsmount **new_mnt) -+{ -+ struct dentry *dentry = NULL; -+ struct nameidata lower_nd; -+ int err; -+ -+ /* we use flags=0 to get basic lookup */ -+ err = vfs_path_lookup(base, mnt, name, 0, &lower_nd); -+ -+ switch (err) { -+ case 0: /* no error */ -+ dentry = lower_nd.path.dentry; -+ if (new_mnt) -+ *new_mnt = lower_nd.path.mnt; /* rc already inc'ed */ -+ break; -+ case -ENOENT: -+ /* -+ * We don't consider ENOENT an error, and we want to return -+ * a negative dentry (ala lookup_one_len). As we know -+ * there was no inode for this name before (-ENOENT), then -+ * it's safe to call lookup_one_len (which doesn't take a -+ * vfsmount). -+ */ -+ dentry = lookup_lck_len(name, base, strlen(name)); -+ if (new_mnt) -+ *new_mnt = mntget(lower_nd.path.mnt); -+ break; -+ default: /* all other real errors */ -+ dentry = ERR_PTR(err); -+ break; -+ } -+ -+ return dentry; -+} -+ -+/* -+ * This is a utility function that fills in a unionfs dentry. -+ * Caller must lock this dentry with unionfs_lock_dentry. -+ * -+ * Returns: 0 (ok), or -ERRNO if an error occurred. -+ * XXX: get rid of _partial_lookup and make callers call _lookup_full directly -+ */ -+int unionfs_partial_lookup(struct dentry *dentry, struct dentry *parent) -+{ -+ struct dentry *tmp; -+ int err = -ENOSYS; -+ -+ tmp = unionfs_lookup_full(dentry, parent, INTERPOSE_PARTIAL); -+ -+ if (!tmp) { -+ err = 0; -+ goto out; -+ } -+ if (IS_ERR(tmp)) { -+ err = PTR_ERR(tmp); -+ goto out; -+ } -+ /* XXX: need to change the interface */ -+ BUG_ON(tmp != dentry); -+out: -+ return err; -+} -+ -+/* The dentry cache is just so we have properly sized dentries. */ -+static struct kmem_cache *unionfs_dentry_cachep; -+int unionfs_init_dentry_cache(void) -+{ -+ unionfs_dentry_cachep = -+ kmem_cache_create("unionfs_dentry", -+ sizeof(struct unionfs_dentry_info), -+ 0, SLAB_RECLAIM_ACCOUNT, NULL); -+ -+ return (unionfs_dentry_cachep ? 0 : -ENOMEM); -+} -+ -+void unionfs_destroy_dentry_cache(void) -+{ -+ if (unionfs_dentry_cachep) -+ kmem_cache_destroy(unionfs_dentry_cachep); -+} -+ -+void free_dentry_private_data(struct dentry *dentry) -+{ -+ if (!dentry || !dentry->d_fsdata) -+ return; -+ kfree(UNIONFS_D(dentry)->lower_paths); -+ UNIONFS_D(dentry)->lower_paths = NULL; -+ kmem_cache_free(unionfs_dentry_cachep, dentry->d_fsdata); -+ dentry->d_fsdata = NULL; -+} -+ -+static inline int __realloc_dentry_private_data(struct dentry *dentry) -+{ -+ struct unionfs_dentry_info *info = UNIONFS_D(dentry); -+ void *p; -+ int size; -+ -+ BUG_ON(!info); -+ -+ size = sizeof(struct path) * sbmax(dentry->d_sb); -+ p = krealloc(info->lower_paths, size, GFP_ATOMIC); -+ if (unlikely(!p)) -+ return -ENOMEM; -+ -+ info->lower_paths = p; -+ -+ info->bstart = -1; -+ info->bend = -1; -+ info->bopaque = -1; -+ info->bcount = sbmax(dentry->d_sb); -+ atomic_set(&info->generation, -+ atomic_read(&UNIONFS_SB(dentry->d_sb)->generation)); -+ -+ memset(info->lower_paths, 0, size); -+ -+ return 0; -+} -+ -+/* UNIONFS_D(dentry)->lock must be locked */ -+int realloc_dentry_private_data(struct dentry *dentry) -+{ -+ if (!__realloc_dentry_private_data(dentry)) -+ return 0; -+ -+ kfree(UNIONFS_D(dentry)->lower_paths); -+ free_dentry_private_data(dentry); -+ return -ENOMEM; -+} -+ -+/* allocate new dentry private data */ -+int new_dentry_private_data(struct dentry *dentry, int subclass) -+{ -+ struct unionfs_dentry_info *info = UNIONFS_D(dentry); -+ -+ BUG_ON(info); -+ -+ info = kmem_cache_alloc(unionfs_dentry_cachep, GFP_ATOMIC); -+ if (unlikely(!info)) -+ return -ENOMEM; -+ -+ mutex_init(&info->lock); -+ mutex_lock_nested(&info->lock, subclass); -+ -+ info->lower_paths = NULL; -+ -+ dentry->d_fsdata = info; -+ -+ if (!__realloc_dentry_private_data(dentry)) -+ return 0; -+ -+ mutex_unlock(&info->lock); -+ free_dentry_private_data(dentry); -+ return -ENOMEM; -+} -+ -+/* -+ * scan through the lower dentry objects, and set bstart to reflect the -+ * starting branch -+ */ -+void update_bstart(struct dentry *dentry) -+{ -+ int bindex; -+ int bstart = dbstart(dentry); -+ int bend = dbend(dentry); -+ struct dentry *lower_dentry; -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry) -+ continue; -+ if (lower_dentry->d_inode) { -+ dbstart(dentry) = bindex; -+ break; -+ } -+ dput(lower_dentry); -+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL); -+ } -+} -+ -+ -+/* -+ * Initialize a nameidata structure (the intent part) we can pass to a lower -+ * file system. Returns 0 on success or -error (only -ENOMEM possible). -+ * Inside that nd structure, this function may also return an allocated -+ * struct file (for open intents). The caller, when done with this nd, must -+ * kfree the intent file (using release_lower_nd). -+ * -+ * XXX: this code, and the callers of this code, should be redone using -+ * vfs_path_lookup() when (1) the nameidata structure is refactored into a -+ * separate intent-structure, and (2) open_namei() is broken into a VFS-only -+ * function and a method that other file systems can call. -+ */ -+int init_lower_nd(struct nameidata *nd, unsigned int flags) -+{ -+ int err = 0; -+#ifdef ALLOC_LOWER_ND_FILE -+ /* -+ * XXX: one day we may need to have the lower return an open file -+ * for us. It is not needed in 2.6.23-rc1 for nfs2/nfs3, but may -+ * very well be needed for nfs4. -+ */ -+ struct file *file; -+#endif /* ALLOC_LOWER_ND_FILE */ -+ -+ memset(nd, 0, sizeof(struct nameidata)); -+ if (!flags) -+ return err; -+ -+ switch (flags) { -+ case LOOKUP_CREATE: -+ nd->intent.open.flags |= O_CREAT; -+ /* fall through: shared code for create/open cases */ -+ case LOOKUP_OPEN: -+ nd->flags = flags; -+ nd->intent.open.flags |= (FMODE_READ | FMODE_WRITE); -+#ifdef ALLOC_LOWER_ND_FILE -+ file = kzalloc(sizeof(struct file), GFP_KERNEL); -+ if (unlikely(!file)) { -+ err = -ENOMEM; -+ break; /* exit switch statement and thus return */ -+ } -+ nd->intent.open.file = file; -+#endif /* ALLOC_LOWER_ND_FILE */ -+ break; -+ default: -+ /* -+ * We should never get here, for now. -+ * We can add new cases here later on. -+ */ -+ pr_debug("unionfs: unknown nameidata flag 0x%x\n", flags); -+ BUG(); -+ break; -+ } -+ -+ return err; -+} -+ -+void release_lower_nd(struct nameidata *nd, int err) -+{ -+ if (!nd->intent.open.file) -+ return; -+ else if (!err) -+ release_open_intent(nd); -+#ifdef ALLOC_LOWER_ND_FILE -+ kfree(nd->intent.open.file); -+#endif /* ALLOC_LOWER_ND_FILE */ -+} -+ -+/* -+ * Main (and complex) driver function for Unionfs's lookup -+ * -+ * Returns: NULL (ok), ERR_PTR if an error occurred, or a non-null non-error -+ * PTR if d_splice returned a different dentry. -+ * -+ * If lookupmode is INTERPOSE_PARTIAL/REVAL/REVAL_NEG, the passed dentry's -+ * inode info must be locked. If lookupmode is INTERPOSE_LOOKUP (i.e., a -+ * newly looked-up dentry), then unionfs_lookup_backend will return a locked -+ * dentry's info, which the caller must unlock. -+ */ -+struct dentry *unionfs_lookup_full(struct dentry *dentry, -+ struct dentry *parent, int lookupmode) -+{ -+ int err = 0; -+ struct dentry *lower_dentry = NULL; -+ struct vfsmount *lower_mnt; -+ struct vfsmount *lower_dir_mnt; -+ struct dentry *wh_lower_dentry = NULL; -+ struct dentry *lower_dir_dentry = NULL; -+ struct dentry *d_interposed = NULL; -+ int bindex, bstart, bend, bopaque; -+ int opaque, num_positive = 0; -+ const char *name; -+ int namelen; -+ int pos_start, pos_end; -+ -+ /* -+ * We should already have a lock on this dentry in the case of a -+ * partial lookup, or a revalidation. Otherwise it is returned from -+ * new_dentry_private_data already locked. -+ */ -+ verify_locked(dentry); -+ verify_locked(parent); -+ -+ /* must initialize dentry operations */ -+ dentry->d_op = &unionfs_dops; -+ -+ /* We never partial lookup the root directory. */ -+ if (IS_ROOT(dentry)) -+ goto out; -+ -+ name = dentry->d_name.name; -+ namelen = dentry->d_name.len; -+ -+ /* No dentries should get created for possible whiteout names. */ -+ if (!is_validname(name)) { -+ err = -EPERM; -+ goto out_free; -+ } -+ -+ /* Now start the actual lookup procedure. */ -+ bstart = dbstart(parent); -+ bend = dbend(parent); -+ bopaque = dbopaque(parent); -+ BUG_ON(bstart < 0); -+ -+ /* adjust bend to bopaque if needed */ -+ if ((bopaque >= 0) && (bopaque < bend)) -+ bend = bopaque; -+ -+ /* lookup all possible dentries */ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex); -+ -+ /* skip if we already have a positive lower dentry */ -+ if (lower_dentry) { -+ if (dbstart(dentry) < 0) -+ dbstart(dentry) = bindex; -+ if (bindex > dbend(dentry)) -+ dbend(dentry) = bindex; -+ if (lower_dentry->d_inode) -+ num_positive++; -+ continue; -+ } -+ -+ lower_dir_dentry = -+ unionfs_lower_dentry_idx(parent, bindex); -+ /* if the lower dentry's parent does not exist, skip this */ -+ if (!lower_dir_dentry || !lower_dir_dentry->d_inode) -+ continue; -+ -+ /* also skip it if the parent isn't a directory. */ -+ if (!S_ISDIR(lower_dir_dentry->d_inode->i_mode)) -+ continue; /* XXX: should be BUG_ON */ -+ -+ /* check for whiteouts: stop lookup if found */ -+ wh_lower_dentry = lookup_whiteout(name, lower_dir_dentry); -+ if (IS_ERR(wh_lower_dentry)) { -+ err = PTR_ERR(wh_lower_dentry); -+ goto out_free; -+ } -+ if (wh_lower_dentry->d_inode) { -+ dbend(dentry) = dbopaque(dentry) = bindex; -+ if (dbstart(dentry) < 0) -+ dbstart(dentry) = bindex; -+ dput(wh_lower_dentry); -+ break; -+ } -+ dput(wh_lower_dentry); -+ -+ /* Now do regular lookup; lookup @name */ -+ lower_dir_mnt = unionfs_lower_mnt_idx(parent, bindex); -+ lower_mnt = NULL; /* XXX: needed? */ -+ -+ lower_dentry = __lookup_one(lower_dir_dentry, lower_dir_mnt, -+ name, &lower_mnt); -+ -+ if (IS_ERR(lower_dentry)) { -+ err = PTR_ERR(lower_dentry); -+ goto out_free; -+ } -+ unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry); -+ if (!lower_mnt) -+ lower_mnt = unionfs_mntget(dentry->d_sb->s_root, -+ bindex); -+ unionfs_set_lower_mnt_idx(dentry, bindex, lower_mnt); -+ -+ /* adjust dbstart/end */ -+ if (dbstart(dentry) < 0) -+ dbstart(dentry) = bindex; -+ if (bindex > dbend(dentry)) -+ dbend(dentry) = bindex; -+ /* -+ * We always store the lower dentries above, and update -+ * dbstart/dbend, even if the whole unionfs dentry is -+ * negative (i.e., no lower inodes). -+ */ -+ if (!lower_dentry->d_inode) -+ continue; -+ num_positive++; -+ -+ /* -+ * check if we just found an opaque directory, if so, stop -+ * lookups here. -+ */ -+ if (!S_ISDIR(lower_dentry->d_inode->i_mode)) -+ continue; -+ opaque = is_opaque_dir(dentry, bindex); -+ if (opaque < 0) { -+ err = opaque; -+ goto out_free; -+ } else if (opaque) { -+ dbend(dentry) = dbopaque(dentry) = bindex; -+ break; -+ } -+ dbend(dentry) = bindex; -+ -+ /* update parent directory's atime with the bindex */ -+ fsstack_copy_attr_atime(parent->d_inode, -+ lower_dir_dentry->d_inode); -+ } -+ -+ /* sanity checks, then decide if to process a negative dentry */ -+ BUG_ON(dbstart(dentry) < 0 && dbend(dentry) >= 0); -+ BUG_ON(dbstart(dentry) >= 0 && dbend(dentry) < 0); -+ -+ if (num_positive > 0) -+ goto out_positive; -+ -+ /*** handle NEGATIVE dentries ***/ -+ -+ /* -+ * If negative, keep only first lower negative dentry, to save on -+ * memory. -+ */ -+ if (dbstart(dentry) < dbend(dentry)) { -+ path_put_lowers(dentry, dbstart(dentry) + 1, -+ dbend(dentry), false); -+ dbend(dentry) = dbstart(dentry); -+ } -+ if (lookupmode == INTERPOSE_PARTIAL) -+ goto out; -+ if (lookupmode == INTERPOSE_LOOKUP) { -+ /* -+ * If all we found was a whiteout in the first available -+ * branch, then create a negative dentry for a possibly new -+ * file to be created. -+ */ -+ if (dbopaque(dentry) < 0) -+ goto out; -+ /* XXX: need to get mnt here */ -+ bindex = dbstart(dentry); -+ if (unionfs_lower_dentry_idx(dentry, bindex)) -+ goto out; -+ lower_dir_dentry = -+ unionfs_lower_dentry_idx(parent, bindex); -+ if (!lower_dir_dentry || !lower_dir_dentry->d_inode) -+ goto out; -+ if (!S_ISDIR(lower_dir_dentry->d_inode->i_mode)) -+ goto out; /* XXX: should be BUG_ON */ -+ /* XXX: do we need to cross bind mounts here? */ -+ lower_dentry = lookup_lck_len(name, lower_dir_dentry, namelen); -+ if (IS_ERR(lower_dentry)) { -+ err = PTR_ERR(lower_dentry); -+ goto out; -+ } -+ /* XXX: need to mntget/mntput as needed too! */ -+ unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry); -+ /* XXX: wrong mnt for crossing bind mounts! */ -+ lower_mnt = unionfs_mntget(dentry->d_sb->s_root, bindex); -+ unionfs_set_lower_mnt_idx(dentry, bindex, lower_mnt); -+ -+ goto out; -+ } -+ -+ /* if we're revalidating a positive dentry, don't make it negative */ -+ if (lookupmode != INTERPOSE_REVAL) -+ d_add(dentry, NULL); -+ -+ goto out; -+ -+out_positive: -+ /*** handle POSITIVE dentries ***/ -+ -+ /* -+ * This unionfs dentry is positive (at least one lower inode -+ * exists), so scan entire dentry from beginning to end, and remove -+ * any negative lower dentries, if any. Then, update dbstart/dbend -+ * to reflect the start/end of positive dentries. -+ */ -+ pos_start = pos_end = -1; -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, -+ bindex); -+ if (lower_dentry && lower_dentry->d_inode) { -+ if (pos_start < 0) -+ pos_start = bindex; -+ if (bindex > pos_end) -+ pos_end = bindex; -+ continue; -+ } -+ path_put_lowers(dentry, bindex, bindex, false); -+ } -+ if (pos_start >= 0) -+ dbstart(dentry) = pos_start; -+ if (pos_end >= 0) -+ dbend(dentry) = pos_end; -+ -+ /* Partial lookups need to re-interpose, or throw away older negs. */ -+ if (lookupmode == INTERPOSE_PARTIAL) { -+ if (dentry->d_inode) { -+ unionfs_reinterpose(dentry); -+ goto out; -+ } -+ -+ /* -+ * This dentry was positive, so it is as if we had a -+ * negative revalidation. -+ */ -+ lookupmode = INTERPOSE_REVAL_NEG; -+ update_bstart(dentry); -+ } -+ -+ /* -+ * Interpose can return a dentry if d_splice returned a different -+ * dentry. -+ */ -+ d_interposed = unionfs_interpose(dentry, dentry->d_sb, lookupmode); -+ if (IS_ERR(d_interposed)) -+ err = PTR_ERR(d_interposed); -+ else if (d_interposed) -+ dentry = d_interposed; -+ -+ if (!err) -+ goto out; -+ d_drop(dentry); -+ -+out_free: -+ /* should dput/mntput all the underlying dentries on error condition */ -+ if (dbstart(dentry) >= 0) -+ path_put_lowers_all(dentry, false); -+ /* free lower_paths unconditionally */ -+ kfree(UNIONFS_D(dentry)->lower_paths); -+ UNIONFS_D(dentry)->lower_paths = NULL; -+ -+out: -+ if (dentry && UNIONFS_D(dentry)) { -+ BUG_ON(dbstart(dentry) < 0 && dbend(dentry) >= 0); -+ BUG_ON(dbstart(dentry) >= 0 && dbend(dentry) < 0); -+ } -+ if (d_interposed && UNIONFS_D(d_interposed)) { -+ BUG_ON(dbstart(d_interposed) < 0 && dbend(d_interposed) >= 0); -+ BUG_ON(dbstart(d_interposed) >= 0 && dbend(d_interposed) < 0); -+ } -+ -+ if (!err && d_interposed) -+ return d_interposed; -+ return ERR_PTR(err); -+} -diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c -new file mode 100644 -index 0000000..fa52f61 ---- /dev/null -+++ b/fs/unionfs/main.c -@@ -0,0 +1,763 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+#include -+#include -+ -+static void unionfs_fill_inode(struct dentry *dentry, -+ struct inode *inode) -+{ -+ struct inode *lower_inode; -+ struct dentry *lower_dentry; -+ int bindex, bstart, bend; -+ -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry) { -+ unionfs_set_lower_inode_idx(inode, bindex, NULL); -+ continue; -+ } -+ -+ /* Initialize the lower inode to the new lower inode. */ -+ if (!lower_dentry->d_inode) -+ continue; -+ -+ unionfs_set_lower_inode_idx(inode, bindex, -+ igrab(lower_dentry->d_inode)); -+ } -+ -+ ibstart(inode) = dbstart(dentry); -+ ibend(inode) = dbend(dentry); -+ -+ /* Use attributes from the first branch. */ -+ lower_inode = unionfs_lower_inode(inode); -+ -+ /* Use different set of inode ops for symlinks & directories */ -+ if (S_ISLNK(lower_inode->i_mode)) -+ inode->i_op = &unionfs_symlink_iops; -+ else if (S_ISDIR(lower_inode->i_mode)) -+ inode->i_op = &unionfs_dir_iops; -+ -+ /* Use different set of file ops for directories */ -+ if (S_ISDIR(lower_inode->i_mode)) -+ inode->i_fop = &unionfs_dir_fops; -+ -+ /* properly initialize special inodes */ -+ if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) || -+ S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode)) -+ init_special_inode(inode, lower_inode->i_mode, -+ lower_inode->i_rdev); -+ -+ /* all well, copy inode attributes */ -+ unionfs_copy_attr_all(inode, lower_inode); -+ fsstack_copy_inode_size(inode, lower_inode); -+} -+ -+/* -+ * Connect a unionfs inode dentry/inode with several lower ones. This is -+ * the classic stackable file system "vnode interposition" action. -+ * -+ * @sb: unionfs's super_block -+ */ -+struct dentry *unionfs_interpose(struct dentry *dentry, struct super_block *sb, -+ int flag) -+{ -+ int err = 0; -+ struct inode *inode; -+ int need_fill_inode = 1; -+ struct dentry *spliced = NULL; -+ -+ verify_locked(dentry); -+ -+ /* -+ * We allocate our new inode below by calling unionfs_iget, -+ * which will initialize some of the new inode's fields -+ */ -+ -+ /* -+ * On revalidate we've already got our own inode and just need -+ * to fix it up. -+ */ -+ if (flag == INTERPOSE_REVAL) { -+ inode = dentry->d_inode; -+ UNIONFS_I(inode)->bstart = -1; -+ UNIONFS_I(inode)->bend = -1; -+ atomic_set(&UNIONFS_I(inode)->generation, -+ atomic_read(&UNIONFS_SB(sb)->generation)); -+ -+ UNIONFS_I(inode)->lower_inodes = -+ kcalloc(sbmax(sb), sizeof(struct inode *), GFP_KERNEL); -+ if (unlikely(!UNIONFS_I(inode)->lower_inodes)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ } else { -+ /* get unique inode number for unionfs */ -+ inode = unionfs_iget(sb, iunique(sb, UNIONFS_ROOT_INO)); -+ if (IS_ERR(inode)) { -+ err = PTR_ERR(inode); -+ goto out; -+ } -+ if (atomic_read(&inode->i_count) > 1) -+ goto skip; -+ } -+ -+ need_fill_inode = 0; -+ unionfs_fill_inode(dentry, inode); -+ -+skip: -+ /* only (our) lookup wants to do a d_add */ -+ switch (flag) { -+ case INTERPOSE_DEFAULT: -+ /* for operations which create new inodes */ -+ d_add(dentry, inode); -+ break; -+ case INTERPOSE_REVAL_NEG: -+ d_instantiate(dentry, inode); -+ break; -+ case INTERPOSE_LOOKUP: -+ spliced = d_splice_alias(inode, dentry); -+ if (spliced && spliced != dentry) { -+ /* -+ * d_splice can return a dentry if it was -+ * disconnected and had to be moved. We must ensure -+ * that the private data of the new dentry is -+ * correct and that the inode info was filled -+ * properly. Finally we must return this new -+ * dentry. -+ */ -+ spliced->d_op = &unionfs_dops; -+ spliced->d_fsdata = dentry->d_fsdata; -+ dentry->d_fsdata = NULL; -+ dentry = spliced; -+ if (need_fill_inode) { -+ need_fill_inode = 0; -+ unionfs_fill_inode(dentry, inode); -+ } -+ goto out_spliced; -+ } else if (!spliced) { -+ if (need_fill_inode) { -+ need_fill_inode = 0; -+ unionfs_fill_inode(dentry, inode); -+ goto out_spliced; -+ } -+ } -+ break; -+ case INTERPOSE_REVAL: -+ /* Do nothing. */ -+ break; -+ default: -+ printk(KERN_CRIT "unionfs: invalid interpose flag passed!\n"); -+ BUG(); -+ } -+ goto out; -+ -+out_spliced: -+ if (!err) -+ return spliced; -+out: -+ return ERR_PTR(err); -+} -+ -+/* like interpose above, but for an already existing dentry */ -+void unionfs_reinterpose(struct dentry *dentry) -+{ -+ struct dentry *lower_dentry; -+ struct inode *inode; -+ int bindex, bstart, bend; -+ -+ verify_locked(dentry); -+ -+ /* This is pre-allocated inode */ -+ inode = dentry->d_inode; -+ -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry) -+ continue; -+ -+ if (!lower_dentry->d_inode) -+ continue; -+ if (unionfs_lower_inode_idx(inode, bindex)) -+ continue; -+ unionfs_set_lower_inode_idx(inode, bindex, -+ igrab(lower_dentry->d_inode)); -+ } -+ ibstart(inode) = dbstart(dentry); -+ ibend(inode) = dbend(dentry); -+} -+ -+/* -+ * make sure the branch we just looked up (nd) makes sense: -+ * -+ * 1) we're not trying to stack unionfs on top of unionfs -+ * 2) it exists -+ * 3) is a directory -+ */ -+int check_branch(const struct path *path) -+{ -+ /* XXX: remove in ODF code -- stacking unions allowed there */ -+ if (!strcmp(path->dentry->d_sb->s_type->name, UNIONFS_NAME)) -+ return -EINVAL; -+ if (!path->dentry->d_inode) -+ return -ENOENT; -+ if (!S_ISDIR(path->dentry->d_inode->i_mode)) -+ return -ENOTDIR; -+ return 0; -+} -+ -+/* checks if two lower_dentries have overlapping branches */ -+static int is_branch_overlap(struct dentry *dent1, struct dentry *dent2) -+{ -+ struct dentry *dent = NULL; -+ -+ dent = dent1; -+ while ((dent != dent2) && (dent->d_parent != dent)) -+ dent = dent->d_parent; -+ -+ if (dent == dent2) -+ return 1; -+ -+ dent = dent2; -+ while ((dent != dent1) && (dent->d_parent != dent)) -+ dent = dent->d_parent; -+ -+ return (dent == dent1); -+} -+ -+/* -+ * Parse "ro" or "rw" options, but default to "rw" if no mode options was -+ * specified. Fill the mode bits in @perms. If encounter an unknown -+ * string, return -EINVAL. Otherwise return 0. -+ */ -+int parse_branch_mode(const char *name, int *perms) -+{ -+ if (!name || !strcmp(name, "rw")) { -+ *perms = MAY_READ | MAY_WRITE; -+ return 0; -+ } -+ if (!strcmp(name, "ro")) { -+ *perms = MAY_READ; -+ return 0; -+ } -+ return -EINVAL; -+} -+ -+/* -+ * parse the dirs= mount argument -+ * -+ * We don't need to lock the superblock private data's rwsem, as we get -+ * called only by unionfs_read_super - it is still a long time before anyone -+ * can even get a reference to us. -+ */ -+static int parse_dirs_option(struct super_block *sb, struct unionfs_dentry_info -+ *lower_root_info, char *options) -+{ -+ struct path path; -+ char *name; -+ int err = 0; -+ int branches = 1; -+ int bindex = 0; -+ int i = 0; -+ int j = 0; -+ struct dentry *dent1; -+ struct dentry *dent2; -+ -+ if (options[0] == '\0') { -+ printk(KERN_ERR "unionfs: no branches specified\n"); -+ err = -EINVAL; -+ goto out_return; -+ } -+ -+ /* -+ * Each colon means we have a separator, this is really just a rough -+ * guess, since strsep will handle empty fields for us. -+ */ -+ for (i = 0; options[i]; i++) -+ if (options[i] == ':') -+ branches++; -+ -+ /* allocate space for underlying pointers to lower dentry */ -+ UNIONFS_SB(sb)->data = -+ kcalloc(branches, sizeof(struct unionfs_data), GFP_KERNEL); -+ if (unlikely(!UNIONFS_SB(sb)->data)) { -+ err = -ENOMEM; -+ goto out_return; -+ } -+ -+ lower_root_info->lower_paths = -+ kcalloc(branches, sizeof(struct path), GFP_KERNEL); -+ if (unlikely(!lower_root_info->lower_paths)) { -+ err = -ENOMEM; -+ /* free the underlying pointer array */ -+ kfree(UNIONFS_SB(sb)->data); -+ UNIONFS_SB(sb)->data = NULL; -+ goto out_return; -+ } -+ -+ /* now parsing a string such as "b1:b2=rw:b3=ro:b4" */ -+ branches = 0; -+ while ((name = strsep(&options, ":")) != NULL) { -+ int perms; -+ char *mode = strchr(name, '='); -+ -+ if (!name) -+ continue; -+ if (!*name) { /* bad use of ':' (extra colons) */ -+ err = -EINVAL; -+ goto out; -+ } -+ -+ branches++; -+ -+ /* strip off '=' if any */ -+ if (mode) -+ *mode++ = '\0'; -+ -+ err = parse_branch_mode(mode, &perms); -+ if (err) { -+ printk(KERN_ERR "unionfs: invalid mode \"%s\" for " -+ "branch %d\n", mode, bindex); -+ goto out; -+ } -+ /* ensure that leftmost branch is writeable */ -+ if (!bindex && !(perms & MAY_WRITE)) { -+ printk(KERN_ERR "unionfs: leftmost branch cannot be " -+ "read-only (use \"-o ro\" to create a " -+ "read-only union)\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ err = kern_path(name, LOOKUP_FOLLOW, &path); -+ if (err) { -+ printk(KERN_ERR "unionfs: error accessing " -+ "lower directory '%s' (error %d)\n", -+ name, err); -+ goto out; -+ } -+ -+ err = check_branch(&path); -+ if (err) { -+ printk(KERN_ERR "unionfs: lower directory " -+ "'%s' is not a valid branch\n", name); -+ path_put(&path); -+ goto out; -+ } -+ -+ lower_root_info->lower_paths[bindex].dentry = path.dentry; -+ lower_root_info->lower_paths[bindex].mnt = path.mnt; -+ -+ set_branchperms(sb, bindex, perms); -+ set_branch_count(sb, bindex, 0); -+ new_branch_id(sb, bindex); -+ -+ if (lower_root_info->bstart < 0) -+ lower_root_info->bstart = bindex; -+ lower_root_info->bend = bindex; -+ bindex++; -+ } -+ -+ if (branches == 0) { -+ printk(KERN_ERR "unionfs: no branches specified\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ BUG_ON(branches != (lower_root_info->bend + 1)); -+ -+ /* -+ * Ensure that no overlaps exist in the branches. -+ * -+ * This test is required because the Linux kernel has no support -+ * currently for ensuring coherency between stackable layers and -+ * branches. If we were to allow overlapping branches, it would be -+ * possible, for example, to delete a file via one branch, which -+ * would not be reflected in another branch. Such incoherency could -+ * lead to inconsistencies and even kernel oopses. Rather than -+ * implement hacks to work around some of these cache-coherency -+ * problems, we prevent branch overlapping, for now. A complete -+ * solution will involve proper kernel/VFS support for cache -+ * coherency, at which time we could safely remove this -+ * branch-overlapping test. -+ */ -+ for (i = 0; i < branches; i++) { -+ dent1 = lower_root_info->lower_paths[i].dentry; -+ for (j = i + 1; j < branches; j++) { -+ dent2 = lower_root_info->lower_paths[j].dentry; -+ if (is_branch_overlap(dent1, dent2)) { -+ printk(KERN_ERR "unionfs: branches %d and " -+ "%d overlap\n", i, j); -+ err = -EINVAL; -+ goto out; -+ } -+ } -+ } -+ -+out: -+ if (err) { -+ for (i = 0; i < branches; i++) -+ path_put(&lower_root_info->lower_paths[i]); -+ -+ kfree(lower_root_info->lower_paths); -+ kfree(UNIONFS_SB(sb)->data); -+ -+ /* -+ * MUST clear the pointers to prevent potential double free if -+ * the caller dies later on -+ */ -+ lower_root_info->lower_paths = NULL; -+ UNIONFS_SB(sb)->data = NULL; -+ } -+out_return: -+ return err; -+} -+ -+/* -+ * Parse mount options. See the manual page for usage instructions. -+ * -+ * Returns the dentry object of the lower-level (lower) directory; -+ * We want to mount our stackable file system on top of that lower directory. -+ */ -+static struct unionfs_dentry_info *unionfs_parse_options( -+ struct super_block *sb, -+ char *options) -+{ -+ struct unionfs_dentry_info *lower_root_info; -+ char *optname; -+ int err = 0; -+ int bindex; -+ int dirsfound = 0; -+ -+ /* allocate private data area */ -+ err = -ENOMEM; -+ lower_root_info = -+ kzalloc(sizeof(struct unionfs_dentry_info), GFP_KERNEL); -+ if (unlikely(!lower_root_info)) -+ goto out_error; -+ lower_root_info->bstart = -1; -+ lower_root_info->bend = -1; -+ lower_root_info->bopaque = -1; -+ -+ while ((optname = strsep(&options, ",")) != NULL) { -+ char *optarg; -+ -+ if (!optname || !*optname) -+ continue; -+ -+ optarg = strchr(optname, '='); -+ if (optarg) -+ *optarg++ = '\0'; -+ -+ /* -+ * All of our options take an argument now. Insert ones that -+ * don't, above this check. -+ */ -+ if (!optarg) { -+ printk(KERN_ERR "unionfs: %s requires an argument\n", -+ optname); -+ err = -EINVAL; -+ goto out_error; -+ } -+ -+ if (!strcmp("dirs", optname)) { -+ if (++dirsfound > 1) { -+ printk(KERN_ERR -+ "unionfs: multiple dirs specified\n"); -+ err = -EINVAL; -+ goto out_error; -+ } -+ err = parse_dirs_option(sb, lower_root_info, optarg); -+ if (err) -+ goto out_error; -+ continue; -+ } -+ -+ err = -EINVAL; -+ printk(KERN_ERR -+ "unionfs: unrecognized option '%s'\n", optname); -+ goto out_error; -+ } -+ if (dirsfound != 1) { -+ printk(KERN_ERR "unionfs: dirs option required\n"); -+ err = -EINVAL; -+ goto out_error; -+ } -+ goto out; -+ -+out_error: -+ if (lower_root_info && lower_root_info->lower_paths) { -+ for (bindex = lower_root_info->bstart; -+ bindex >= 0 && bindex <= lower_root_info->bend; -+ bindex++) -+ path_put(&lower_root_info->lower_paths[bindex]); -+ } -+ -+ kfree(lower_root_info->lower_paths); -+ kfree(lower_root_info); -+ -+ kfree(UNIONFS_SB(sb)->data); -+ UNIONFS_SB(sb)->data = NULL; -+ -+ lower_root_info = ERR_PTR(err); -+out: -+ return lower_root_info; -+} -+ -+/* -+ * our custom d_alloc_root work-alike -+ * -+ * we can't use d_alloc_root if we want to use our own interpose function -+ * unchanged, so we simply call our own "fake" d_alloc_root -+ */ -+static struct dentry *unionfs_d_alloc_root(struct super_block *sb) -+{ -+ struct dentry *ret = NULL; -+ -+ if (sb) { -+ static const struct qstr name = { -+ .name = "/", -+ .len = 1 -+ }; -+ -+ ret = d_alloc(NULL, &name); -+ if (likely(ret)) { -+ ret->d_op = &unionfs_dops; -+ ret->d_sb = sb; -+ ret->d_parent = ret; -+ } -+ } -+ return ret; -+} -+ -+/* -+ * There is no need to lock the unionfs_super_info's rwsem as there is no -+ * way anyone can have a reference to the superblock at this point in time. -+ */ -+static int unionfs_read_super(struct super_block *sb, void *raw_data, -+ int silent) -+{ -+ int err = 0; -+ struct unionfs_dentry_info *lower_root_info = NULL; -+ int bindex, bstart, bend; -+ -+ if (!raw_data) { -+ printk(KERN_ERR -+ "unionfs: read_super: missing data argument\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ /* Allocate superblock private data */ -+ sb->s_fs_info = kzalloc(sizeof(struct unionfs_sb_info), GFP_KERNEL); -+ if (unlikely(!UNIONFS_SB(sb))) { -+ printk(KERN_CRIT "unionfs: read_super: out of memory\n"); -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ UNIONFS_SB(sb)->bend = -1; -+ atomic_set(&UNIONFS_SB(sb)->generation, 1); -+ init_rwsem(&UNIONFS_SB(sb)->rwsem); -+ UNIONFS_SB(sb)->high_branch_id = -1; /* -1 == invalid branch ID */ -+ -+ lower_root_info = unionfs_parse_options(sb, raw_data); -+ if (IS_ERR(lower_root_info)) { -+ printk(KERN_ERR -+ "unionfs: read_super: error while parsing options " -+ "(err = %ld)\n", PTR_ERR(lower_root_info)); -+ err = PTR_ERR(lower_root_info); -+ lower_root_info = NULL; -+ goto out_free; -+ } -+ if (lower_root_info->bstart == -1) { -+ err = -ENOENT; -+ goto out_free; -+ } -+ -+ /* set the lower superblock field of upper superblock */ -+ bstart = lower_root_info->bstart; -+ BUG_ON(bstart != 0); -+ sbend(sb) = bend = lower_root_info->bend; -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ struct dentry *d = lower_root_info->lower_paths[bindex].dentry; -+ atomic_inc(&d->d_sb->s_active); -+ unionfs_set_lower_super_idx(sb, bindex, d->d_sb); -+ } -+ -+ /* max Bytes is the maximum bytes from highest priority branch */ -+ sb->s_maxbytes = unionfs_lower_super_idx(sb, 0)->s_maxbytes; -+ -+ /* -+ * Our c/m/atime granularity is 1 ns because we may stack on file -+ * systems whose granularity is as good. This is important for our -+ * time-based cache coherency. -+ */ -+ sb->s_time_gran = 1; -+ -+ sb->s_op = &unionfs_sops; -+ -+ /* See comment next to the definition of unionfs_d_alloc_root */ -+ sb->s_root = unionfs_d_alloc_root(sb); -+ if (unlikely(!sb->s_root)) { -+ err = -ENOMEM; -+ goto out_dput; -+ } -+ -+ /* link the upper and lower dentries */ -+ sb->s_root->d_fsdata = NULL; -+ err = new_dentry_private_data(sb->s_root, UNIONFS_DMUTEX_ROOT); -+ if (unlikely(err)) -+ goto out_freedpd; -+ -+ /* Set the lower dentries for s_root */ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ struct dentry *d; -+ struct vfsmount *m; -+ -+ d = lower_root_info->lower_paths[bindex].dentry; -+ m = lower_root_info->lower_paths[bindex].mnt; -+ -+ unionfs_set_lower_dentry_idx(sb->s_root, bindex, d); -+ unionfs_set_lower_mnt_idx(sb->s_root, bindex, m); -+ } -+ dbstart(sb->s_root) = bstart; -+ dbend(sb->s_root) = bend; -+ -+ /* Set the generation number to one, since this is for the mount. */ -+ atomic_set(&UNIONFS_D(sb->s_root)->generation, 1); -+ -+ /* -+ * Call interpose to create the upper level inode. Only -+ * INTERPOSE_LOOKUP can return a value other than 0 on err. -+ */ -+ err = PTR_ERR(unionfs_interpose(sb->s_root, sb, 0)); -+ unionfs_unlock_dentry(sb->s_root); -+ if (!err) -+ goto out; -+ /* else fall through */ -+ -+out_freedpd: -+ if (UNIONFS_D(sb->s_root)) { -+ kfree(UNIONFS_D(sb->s_root)->lower_paths); -+ free_dentry_private_data(sb->s_root); -+ } -+ dput(sb->s_root); -+ -+out_dput: -+ if (lower_root_info && !IS_ERR(lower_root_info)) { -+ for (bindex = lower_root_info->bstart; -+ bindex <= lower_root_info->bend; bindex++) { -+ struct dentry *d; -+ d = lower_root_info->lower_paths[bindex].dentry; -+ /* drop refs we took earlier */ -+ atomic_dec(&d->d_sb->s_active); -+ path_put(&lower_root_info->lower_paths[bindex]); -+ } -+ kfree(lower_root_info->lower_paths); -+ kfree(lower_root_info); -+ lower_root_info = NULL; -+ } -+ -+out_free: -+ kfree(UNIONFS_SB(sb)->data); -+ kfree(UNIONFS_SB(sb)); -+ sb->s_fs_info = NULL; -+ -+out: -+ if (lower_root_info && !IS_ERR(lower_root_info)) { -+ kfree(lower_root_info->lower_paths); -+ kfree(lower_root_info); -+ } -+ return err; -+} -+ -+static struct dentry *unionfs_mount(struct file_system_type *fs_type, -+ int flags, const char *dev_name, -+ void *raw_data) -+{ -+ struct dentry *dentry; -+ -+ dentry = mount_nodev(fs_type, flags, raw_data, unionfs_read_super); -+ if (!PTR_ERR(dentry)) -+ UNIONFS_SB(dentry->d_sb)->dev_name = -+ kstrdup(dev_name, GFP_KERNEL); -+ return dentry; -+} -+ -+static struct file_system_type unionfs_fs_type = { -+ .owner = THIS_MODULE, -+ .name = UNIONFS_NAME, -+ .mount = unionfs_mount, -+ .kill_sb = generic_shutdown_super, -+ .fs_flags = FS_REVAL_DOT, -+}; -+ -+static int __init init_unionfs_fs(void) -+{ -+ int err; -+ -+ pr_info("Registering unionfs " UNIONFS_VERSION "\n"); -+ -+ err = unionfs_init_filldir_cache(); -+ if (unlikely(err)) -+ goto out; -+ err = unionfs_init_inode_cache(); -+ if (unlikely(err)) -+ goto out; -+ err = unionfs_init_dentry_cache(); -+ if (unlikely(err)) -+ goto out; -+ err = init_sioq(); -+ if (unlikely(err)) -+ goto out; -+ err = register_filesystem(&unionfs_fs_type); -+out: -+ if (unlikely(err)) { -+ stop_sioq(); -+ unionfs_destroy_filldir_cache(); -+ unionfs_destroy_inode_cache(); -+ unionfs_destroy_dentry_cache(); -+ } -+ return err; -+} -+ -+static void __exit exit_unionfs_fs(void) -+{ -+ stop_sioq(); -+ unionfs_destroy_filldir_cache(); -+ unionfs_destroy_inode_cache(); -+ unionfs_destroy_dentry_cache(); -+ unregister_filesystem(&unionfs_fs_type); -+ pr_info("Completed unionfs module unload\n"); -+} -+ -+MODULE_AUTHOR("Erez Zadok, Filesystems and Storage Lab, Stony Brook University" -+ " (http://www.fsl.cs.sunysb.edu)"); -+MODULE_DESCRIPTION("Unionfs " UNIONFS_VERSION -+ " (http://unionfs.filesystems.org)"); -+MODULE_LICENSE("GPL"); -+ -+module_init(init_unionfs_fs); -+module_exit(exit_unionfs_fs); -diff --git a/fs/unionfs/mmap.c b/fs/unionfs/mmap.c -new file mode 100644 -index 0000000..bcc5652 ---- /dev/null -+++ b/fs/unionfs/mmap.c -@@ -0,0 +1,89 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2006 Shaya Potter -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+ -+/* -+ * XXX: we need a dummy readpage handler because generic_file_mmap (which we -+ * use in unionfs_mmap) checks for the existence of -+ * mapping->a_ops->readpage, else it returns -ENOEXEC. The VFS will need to -+ * be fixed to allow a file system to define vm_ops->fault without any -+ * address_space_ops whatsoever. -+ * -+ * Otherwise, we don't want to use our readpage method at all. -+ */ -+static int unionfs_readpage(struct file *file, struct page *page) -+{ -+ BUG(); -+ return -EINVAL; -+} -+ -+static int unionfs_fault(struct vm_area_struct *vma, struct vm_fault *vmf) -+{ -+ int err; -+ struct file *file, *lower_file; -+ const struct vm_operations_struct *lower_vm_ops; -+ struct vm_area_struct lower_vma; -+ -+ BUG_ON(!vma); -+ memcpy(&lower_vma, vma, sizeof(struct vm_area_struct)); -+ file = lower_vma.vm_file; -+ lower_vm_ops = UNIONFS_F(file)->lower_vm_ops; -+ BUG_ON(!lower_vm_ops); -+ -+ lower_file = unionfs_lower_file(file); -+ BUG_ON(!lower_file); -+ /* -+ * XXX: vm_ops->fault may be called in parallel. Because we have to -+ * resort to temporarily changing the vma->vm_file to point to the -+ * lower file, a concurrent invocation of unionfs_fault could see a -+ * different value. In this workaround, we keep a different copy of -+ * the vma structure in our stack, so we never expose a different -+ * value of the vma->vm_file called to us, even temporarily. A -+ * better fix would be to change the calling semantics of ->fault to -+ * take an explicit file pointer. -+ */ -+ lower_vma.vm_file = lower_file; -+ err = lower_vm_ops->fault(&lower_vma, vmf); -+ return err; -+} -+ -+/* -+ * XXX: the default address_space_ops for unionfs is empty. We cannot set -+ * our inode->i_mapping->a_ops to NULL because too many code paths expect -+ * the a_ops vector to be non-NULL. -+ */ -+struct address_space_operations unionfs_aops = { -+ /* empty on purpose */ -+}; -+ -+/* -+ * XXX: we need a second, dummy address_space_ops vector, to be used -+ * temporarily during unionfs_mmap, because the latter calls -+ * generic_file_mmap, which checks if ->readpage exists, else returns -+ * -ENOEXEC. -+ */ -+struct address_space_operations unionfs_dummy_aops = { -+ .readpage = unionfs_readpage, -+}; -+ -+struct vm_operations_struct unionfs_vm_ops = { -+ .fault = unionfs_fault, -+}; -diff --git a/fs/unionfs/rdstate.c b/fs/unionfs/rdstate.c -new file mode 100644 -index 0000000..59b7333 ---- /dev/null -+++ b/fs/unionfs/rdstate.c -@@ -0,0 +1,285 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* This file contains the routines for maintaining readdir state. */ -+ -+/* -+ * There are two structures here, rdstate which is a hash table -+ * of the second structure which is a filldir_node. -+ */ -+ -+/* -+ * This is a struct kmem_cache for filldir nodes, because we allocate a lot -+ * of them and they shouldn't waste memory. If the node has a small name -+ * (as defined by the dentry structure), then we use an inline name to -+ * preserve kmalloc space. -+ */ -+static struct kmem_cache *unionfs_filldir_cachep; -+ -+int unionfs_init_filldir_cache(void) -+{ -+ unionfs_filldir_cachep = -+ kmem_cache_create("unionfs_filldir", -+ sizeof(struct filldir_node), 0, -+ SLAB_RECLAIM_ACCOUNT, NULL); -+ -+ return (unionfs_filldir_cachep ? 0 : -ENOMEM); -+} -+ -+void unionfs_destroy_filldir_cache(void) -+{ -+ if (unionfs_filldir_cachep) -+ kmem_cache_destroy(unionfs_filldir_cachep); -+} -+ -+/* -+ * This is a tuning parameter that tells us roughly how big to make the -+ * hash table in directory entries per page. This isn't perfect, but -+ * at least we get a hash table size that shouldn't be too overloaded. -+ * The following averages are based on my home directory. -+ * 14.44693 Overall -+ * 12.29 Single Page Directories -+ * 117.93 Multi-page directories -+ */ -+#define DENTPAGE 4096 -+#define DENTPERONEPAGE 12 -+#define DENTPERPAGE 118 -+#define MINHASHSIZE 1 -+static int guesstimate_hash_size(struct inode *inode) -+{ -+ struct inode *lower_inode; -+ int bindex; -+ int hashsize = MINHASHSIZE; -+ -+ if (UNIONFS_I(inode)->hashsize > 0) -+ return UNIONFS_I(inode)->hashsize; -+ -+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (!lower_inode) -+ continue; -+ -+ if (i_size_read(lower_inode) == DENTPAGE) -+ hashsize += DENTPERONEPAGE; -+ else -+ hashsize += (i_size_read(lower_inode) / DENTPAGE) * -+ DENTPERPAGE; -+ } -+ -+ return hashsize; -+} -+ -+int init_rdstate(struct file *file) -+{ -+ BUG_ON(sizeof(loff_t) != -+ (sizeof(unsigned int) + sizeof(unsigned int))); -+ BUG_ON(UNIONFS_F(file)->rdstate != NULL); -+ -+ UNIONFS_F(file)->rdstate = alloc_rdstate(file->f_path.dentry->d_inode, -+ fbstart(file)); -+ -+ return (UNIONFS_F(file)->rdstate ? 0 : -ENOMEM); -+} -+ -+struct unionfs_dir_state *find_rdstate(struct inode *inode, loff_t fpos) -+{ -+ struct unionfs_dir_state *rdstate = NULL; -+ struct list_head *pos; -+ -+ spin_lock(&UNIONFS_I(inode)->rdlock); -+ list_for_each(pos, &UNIONFS_I(inode)->readdircache) { -+ struct unionfs_dir_state *r = -+ list_entry(pos, struct unionfs_dir_state, cache); -+ if (fpos == rdstate2offset(r)) { -+ UNIONFS_I(inode)->rdcount--; -+ list_del(&r->cache); -+ rdstate = r; -+ break; -+ } -+ } -+ spin_unlock(&UNIONFS_I(inode)->rdlock); -+ return rdstate; -+} -+ -+struct unionfs_dir_state *alloc_rdstate(struct inode *inode, int bindex) -+{ -+ int i = 0; -+ int hashsize; -+ unsigned long mallocsize = sizeof(struct unionfs_dir_state); -+ struct unionfs_dir_state *rdstate; -+ -+ hashsize = guesstimate_hash_size(inode); -+ mallocsize += hashsize * sizeof(struct list_head); -+ mallocsize = __roundup_pow_of_two(mallocsize); -+ -+ /* This should give us about 500 entries anyway. */ -+ if (mallocsize > PAGE_SIZE) -+ mallocsize = PAGE_SIZE; -+ -+ hashsize = (mallocsize - sizeof(struct unionfs_dir_state)) / -+ sizeof(struct list_head); -+ -+ rdstate = kmalloc(mallocsize, GFP_KERNEL); -+ if (unlikely(!rdstate)) -+ return NULL; -+ -+ spin_lock(&UNIONFS_I(inode)->rdlock); -+ if (UNIONFS_I(inode)->cookie >= (MAXRDCOOKIE - 1)) -+ UNIONFS_I(inode)->cookie = 1; -+ else -+ UNIONFS_I(inode)->cookie++; -+ -+ rdstate->cookie = UNIONFS_I(inode)->cookie; -+ spin_unlock(&UNIONFS_I(inode)->rdlock); -+ rdstate->offset = 1; -+ rdstate->access = jiffies; -+ rdstate->bindex = bindex; -+ rdstate->dirpos = 0; -+ rdstate->hashentries = 0; -+ rdstate->size = hashsize; -+ for (i = 0; i < rdstate->size; i++) -+ INIT_LIST_HEAD(&rdstate->list[i]); -+ -+ return rdstate; -+} -+ -+static void free_filldir_node(struct filldir_node *node) -+{ -+ if (node->namelen >= DNAME_INLINE_LEN) -+ kfree(node->name); -+ kmem_cache_free(unionfs_filldir_cachep, node); -+} -+ -+void free_rdstate(struct unionfs_dir_state *state) -+{ -+ struct filldir_node *tmp; -+ int i; -+ -+ for (i = 0; i < state->size; i++) { -+ struct list_head *head = &(state->list[i]); -+ struct list_head *pos, *n; -+ -+ /* traverse the list and deallocate space */ -+ list_for_each_safe(pos, n, head) { -+ tmp = list_entry(pos, struct filldir_node, file_list); -+ list_del(&tmp->file_list); -+ free_filldir_node(tmp); -+ } -+ } -+ -+ kfree(state); -+} -+ -+struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate, -+ const char *name, int namelen, -+ int is_whiteout) -+{ -+ int index; -+ unsigned int hash; -+ struct list_head *head; -+ struct list_head *pos; -+ struct filldir_node *cursor = NULL; -+ int found = 0; -+ -+ BUG_ON(namelen <= 0); -+ -+ hash = full_name_hash(name, namelen); -+ index = hash % rdstate->size; -+ -+ head = &(rdstate->list[index]); -+ list_for_each(pos, head) { -+ cursor = list_entry(pos, struct filldir_node, file_list); -+ -+ if (cursor->namelen == namelen && cursor->hash == hash && -+ !strncmp(cursor->name, name, namelen)) { -+ /* -+ * a duplicate exists, and hence no need to create -+ * entry to the list -+ */ -+ found = 1; -+ -+ /* -+ * if a duplicate is found in this branch, and is -+ * not due to the caller looking for an entry to -+ * whiteout, then the file system may be corrupted. -+ */ -+ if (unlikely(!is_whiteout && -+ cursor->bindex == rdstate->bindex)) -+ printk(KERN_ERR "unionfs: filldir: possible " -+ "I/O error: a file is duplicated " -+ "in the same branch %d: %s\n", -+ rdstate->bindex, cursor->name); -+ break; -+ } -+ } -+ -+ if (!found) -+ cursor = NULL; -+ -+ return cursor; -+} -+ -+int add_filldir_node(struct unionfs_dir_state *rdstate, const char *name, -+ int namelen, int bindex, int whiteout) -+{ -+ struct filldir_node *new; -+ unsigned int hash; -+ int index; -+ int err = 0; -+ struct list_head *head; -+ -+ BUG_ON(namelen <= 0); -+ -+ hash = full_name_hash(name, namelen); -+ index = hash % rdstate->size; -+ head = &(rdstate->list[index]); -+ -+ new = kmem_cache_alloc(unionfs_filldir_cachep, GFP_KERNEL); -+ if (unlikely(!new)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ INIT_LIST_HEAD(&new->file_list); -+ new->namelen = namelen; -+ new->hash = hash; -+ new->bindex = bindex; -+ new->whiteout = whiteout; -+ -+ if (namelen < DNAME_INLINE_LEN) { -+ new->name = new->iname; -+ } else { -+ new->name = kmalloc(namelen + 1, GFP_KERNEL); -+ if (unlikely(!new->name)) { -+ kmem_cache_free(unionfs_filldir_cachep, new); -+ new = NULL; -+ goto out; -+ } -+ } -+ -+ memcpy(new->name, name, namelen); -+ new->name[namelen] = '\0'; -+ -+ rdstate->hashentries++; -+ -+ list_add(&(new->file_list), head); -+out: -+ return err; -+} -diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c -new file mode 100644 -index 0000000..c8ab910 ---- /dev/null -+++ b/fs/unionfs/rename.c -@@ -0,0 +1,522 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * This is a helper function for rename, used when rename ends up with hosed -+ * over dentries and we need to revert. -+ */ -+static int unionfs_refresh_lower_dentry(struct dentry *dentry, -+ struct dentry *parent, int bindex) -+{ -+ struct dentry *lower_dentry; -+ struct dentry *lower_parent; -+ int err = 0; -+ struct nameidata lower_nd; -+ -+ verify_locked(dentry); -+ -+ lower_parent = unionfs_lower_dentry_idx(parent, bindex); -+ -+ BUG_ON(!S_ISDIR(lower_parent->d_inode->i_mode)); -+ -+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN); -+ if (unlikely(err < 0)) -+ goto out; -+ lower_dentry = lookup_one_len_nd(dentry->d_name.name, lower_parent, -+ dentry->d_name.len, &lower_nd); -+ release_lower_nd(&lower_nd, err); -+ if (IS_ERR(lower_dentry)) { -+ err = PTR_ERR(lower_dentry); -+ goto out; -+ } -+ -+ dput(unionfs_lower_dentry_idx(dentry, bindex)); -+ iput(unionfs_lower_inode_idx(dentry->d_inode, bindex)); -+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex, NULL); -+ -+ if (!lower_dentry->d_inode) { -+ dput(lower_dentry); -+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL); -+ } else { -+ unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry); -+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex, -+ igrab(lower_dentry->d_inode)); -+ } -+ -+out: -+ return err; -+} -+ -+static int __unionfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct dentry *old_parent, -+ struct inode *new_dir, struct dentry *new_dentry, -+ struct dentry *new_parent, -+ int bindex) -+{ -+ int err = 0; -+ struct dentry *lower_old_dentry; -+ struct dentry *lower_new_dentry; -+ struct dentry *lower_old_dir_dentry; -+ struct dentry *lower_new_dir_dentry; -+ struct dentry *trap; -+ -+ lower_new_dentry = unionfs_lower_dentry_idx(new_dentry, bindex); -+ lower_old_dentry = unionfs_lower_dentry_idx(old_dentry, bindex); -+ -+ if (!lower_new_dentry) { -+ lower_new_dentry = -+ create_parents(new_parent->d_inode, -+ new_dentry, new_dentry->d_name.name, -+ bindex); -+ if (IS_ERR(lower_new_dentry)) { -+ err = PTR_ERR(lower_new_dentry); -+ if (IS_COPYUP_ERR(err)) -+ goto out; -+ printk(KERN_ERR "unionfs: error creating directory " -+ "tree for rename, bindex=%d err=%d\n", -+ bindex, err); -+ goto out; -+ } -+ } -+ -+ /* check for and remove whiteout, if any */ -+ err = check_unlink_whiteout(new_dentry, lower_new_dentry, bindex); -+ if (err > 0) /* ignore if whiteout found and successfully removed */ -+ err = 0; -+ if (err) -+ goto out; -+ -+ /* check of old_dentry branch is writable */ -+ err = is_robranch_super(old_dentry->d_sb, bindex); -+ if (err) -+ goto out; -+ -+ dget(lower_old_dentry); -+ dget(lower_new_dentry); -+ lower_old_dir_dentry = dget_parent(lower_old_dentry); -+ lower_new_dir_dentry = dget_parent(lower_new_dentry); -+ -+ trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); -+ /* source should not be ancenstor of target */ -+ if (trap == lower_old_dentry) { -+ err = -EINVAL; -+ goto out_err_unlock; -+ } -+ /* target should not be ancenstor of source */ -+ if (trap == lower_new_dentry) { -+ err = -ENOTEMPTY; -+ goto out_err_unlock; -+ } -+ err = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, -+ lower_new_dir_dentry->d_inode, lower_new_dentry); -+out_err_unlock: -+ if (!err) { -+ /* update parent dir times */ -+ fsstack_copy_attr_times(old_dir, lower_old_dir_dentry->d_inode); -+ fsstack_copy_attr_times(new_dir, lower_new_dir_dentry->d_inode); -+ } -+ unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); -+ -+ dput(lower_old_dir_dentry); -+ dput(lower_new_dir_dentry); -+ dput(lower_old_dentry); -+ dput(lower_new_dentry); -+ -+out: -+ if (!err) { -+ /* Fixup the new_dentry. */ -+ if (bindex < dbstart(new_dentry)) -+ dbstart(new_dentry) = bindex; -+ else if (bindex > dbend(new_dentry)) -+ dbend(new_dentry) = bindex; -+ } -+ -+ return err; -+} -+ -+/* -+ * Main rename code. This is sufficiently complex, that it's documented in -+ * Documentation/filesystems/unionfs/rename.txt. This routine calls -+ * __unionfs_rename() above to perform some of the work. -+ */ -+static int do_unionfs_rename(struct inode *old_dir, -+ struct dentry *old_dentry, -+ struct dentry *old_parent, -+ struct inode *new_dir, -+ struct dentry *new_dentry, -+ struct dentry *new_parent) -+{ -+ int err = 0; -+ int bindex; -+ int old_bstart, old_bend; -+ int new_bstart, new_bend; -+ int do_copyup = -1; -+ int local_err = 0; -+ int eio = 0; -+ int revert = 0; -+ -+ old_bstart = dbstart(old_dentry); -+ old_bend = dbend(old_dentry); -+ -+ new_bstart = dbstart(new_dentry); -+ new_bend = dbend(new_dentry); -+ -+ /* Rename source to destination. */ -+ err = __unionfs_rename(old_dir, old_dentry, old_parent, -+ new_dir, new_dentry, new_parent, -+ old_bstart); -+ if (err) { -+ if (!IS_COPYUP_ERR(err)) -+ goto out; -+ do_copyup = old_bstart - 1; -+ } else { -+ revert = 1; -+ } -+ -+ /* -+ * Unlink all instances of destination that exist to the left of -+ * bstart of source. On error, revert back, goto out. -+ */ -+ for (bindex = old_bstart - 1; bindex >= new_bstart; bindex--) { -+ struct dentry *unlink_dentry; -+ struct dentry *unlink_dir_dentry; -+ -+ BUG_ON(bindex < 0); -+ unlink_dentry = unionfs_lower_dentry_idx(new_dentry, bindex); -+ if (!unlink_dentry) -+ continue; -+ -+ unlink_dir_dentry = lock_parent(unlink_dentry); -+ err = is_robranch_super(old_dir->i_sb, bindex); -+ if (!err) -+ err = vfs_unlink(unlink_dir_dentry->d_inode, -+ unlink_dentry); -+ -+ fsstack_copy_attr_times(new_parent->d_inode, -+ unlink_dir_dentry->d_inode); -+ /* propagate number of hard-links */ -+ new_parent->d_inode->i_nlink = -+ unionfs_get_nlinks(new_parent->d_inode); -+ -+ unlock_dir(unlink_dir_dentry); -+ if (!err) { -+ if (bindex != new_bstart) { -+ dput(unlink_dentry); -+ unionfs_set_lower_dentry_idx(new_dentry, -+ bindex, NULL); -+ } -+ } else if (IS_COPYUP_ERR(err)) { -+ do_copyup = bindex - 1; -+ } else if (revert) { -+ goto revert; -+ } -+ } -+ -+ if (do_copyup != -1) { -+ for (bindex = do_copyup; bindex >= 0; bindex--) { -+ /* -+ * copyup the file into some left directory, so that -+ * you can rename it -+ */ -+ err = copyup_dentry(old_parent->d_inode, -+ old_dentry, old_bstart, bindex, -+ old_dentry->d_name.name, -+ old_dentry->d_name.len, NULL, -+ i_size_read(old_dentry->d_inode)); -+ /* if copyup failed, try next branch to the left */ -+ if (err) -+ continue; -+ /* -+ * create whiteout before calling __unionfs_rename -+ * because the latter will change the old_dentry's -+ * lower name and parent dir, resulting in the -+ * whiteout getting created in the wrong dir. -+ */ -+ err = create_whiteout(old_dentry, bindex); -+ if (err) { -+ printk(KERN_ERR "unionfs: can't create a " -+ "whiteout for %s in rename (err=%d)\n", -+ old_dentry->d_name.name, err); -+ continue; -+ } -+ err = __unionfs_rename(old_dir, old_dentry, old_parent, -+ new_dir, new_dentry, new_parent, -+ bindex); -+ break; -+ } -+ } -+ -+ /* make it opaque */ -+ if (S_ISDIR(old_dentry->d_inode->i_mode)) { -+ err = make_dir_opaque(old_dentry, dbstart(old_dentry)); -+ if (err) -+ goto revert; -+ } -+ -+ /* -+ * Create whiteout for source, only if: -+ * (1) There is more than one underlying instance of source. -+ * (We did a copy_up is taken care of above). -+ */ -+ if ((old_bstart != old_bend) && (do_copyup == -1)) { -+ err = create_whiteout(old_dentry, old_bstart); -+ if (err) { -+ /* can't fix anything now, so we exit with -EIO */ -+ printk(KERN_ERR "unionfs: can't create a whiteout for " -+ "%s in rename!\n", old_dentry->d_name.name); -+ err = -EIO; -+ } -+ } -+ -+out: -+ return err; -+ -+revert: -+ /* Do revert here. */ -+ local_err = unionfs_refresh_lower_dentry(new_dentry, new_parent, -+ old_bstart); -+ if (local_err) { -+ printk(KERN_ERR "unionfs: revert failed in rename: " -+ "the new refresh failed\n"); -+ eio = -EIO; -+ } -+ -+ local_err = unionfs_refresh_lower_dentry(old_dentry, old_parent, -+ old_bstart); -+ if (local_err) { -+ printk(KERN_ERR "unionfs: revert failed in rename: " -+ "the old refresh failed\n"); -+ eio = -EIO; -+ goto revert_out; -+ } -+ -+ if (!unionfs_lower_dentry_idx(new_dentry, bindex) || -+ !unionfs_lower_dentry_idx(new_dentry, bindex)->d_inode) { -+ printk(KERN_ERR "unionfs: revert failed in rename: " -+ "the object disappeared from under us!\n"); -+ eio = -EIO; -+ goto revert_out; -+ } -+ -+ if (unionfs_lower_dentry_idx(old_dentry, bindex) && -+ unionfs_lower_dentry_idx(old_dentry, bindex)->d_inode) { -+ printk(KERN_ERR "unionfs: revert failed in rename: " -+ "the object was created underneath us!\n"); -+ eio = -EIO; -+ goto revert_out; -+ } -+ -+ local_err = __unionfs_rename(new_dir, new_dentry, new_parent, -+ old_dir, old_dentry, old_parent, -+ old_bstart); -+ -+ /* If we can't fix it, then we cop-out with -EIO. */ -+ if (local_err) { -+ printk(KERN_ERR "unionfs: revert failed in rename!\n"); -+ eio = -EIO; -+ } -+ -+ local_err = unionfs_refresh_lower_dentry(new_dentry, new_parent, -+ bindex); -+ if (local_err) -+ eio = -EIO; -+ local_err = unionfs_refresh_lower_dentry(old_dentry, old_parent, -+ bindex); -+ if (local_err) -+ eio = -EIO; -+ -+revert_out: -+ if (eio) -+ err = eio; -+ return err; -+} -+ -+/* -+ * We can't copyup a directory, because it may involve huge numbers of -+ * children, etc. Doing that in the kernel would be bad, so instead we -+ * return EXDEV to the user-space utility that caused this, and let the -+ * user-space recurse and ask us to copy up each file separately. -+ */ -+static int may_rename_dir(struct dentry *dentry, struct dentry *parent) -+{ -+ int err, bstart; -+ -+ err = check_empty(dentry, parent, NULL); -+ if (err == -ENOTEMPTY) { -+ if (is_robranch(dentry)) -+ return -EXDEV; -+ } else if (err) { -+ return err; -+ } -+ -+ bstart = dbstart(dentry); -+ if (dbend(dentry) == bstart || dbopaque(dentry) == bstart) -+ return 0; -+ -+ dbstart(dentry) = bstart + 1; -+ err = check_empty(dentry, parent, NULL); -+ dbstart(dentry) = bstart; -+ if (err == -ENOTEMPTY) -+ err = -EXDEV; -+ return err; -+} -+ -+/* -+ * The locking rules in unionfs_rename are complex. We could use a simpler -+ * superblock-level name-space lock for renames and copy-ups. -+ */ -+int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry) -+{ -+ int err = 0; -+ struct dentry *wh_dentry; -+ struct dentry *old_parent, *new_parent; -+ int valid = true; -+ -+ unionfs_read_lock(old_dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ old_parent = dget_parent(old_dentry); -+ new_parent = dget_parent(new_dentry); -+ /* un/lock parent dentries only if they differ from old/new_dentry */ -+ if (old_parent != old_dentry && -+ old_parent != new_dentry) -+ unionfs_lock_dentry(old_parent, UNIONFS_DMUTEX_REVAL_PARENT); -+ if (new_parent != old_dentry && -+ new_parent != new_dentry && -+ new_parent != old_parent) -+ unionfs_lock_dentry(new_parent, UNIONFS_DMUTEX_REVAL_CHILD); -+ unionfs_double_lock_dentry(old_dentry, new_dentry); -+ -+ valid = __unionfs_d_revalidate(old_dentry, old_parent, false); -+ if (!valid) { -+ err = -ESTALE; -+ goto out; -+ } -+ if (!d_deleted(new_dentry) && new_dentry->d_inode) { -+ valid = __unionfs_d_revalidate(new_dentry, new_parent, false); -+ if (!valid) { -+ err = -ESTALE; -+ goto out; -+ } -+ } -+ -+ if (!S_ISDIR(old_dentry->d_inode->i_mode)) -+ err = unionfs_partial_lookup(old_dentry, old_parent); -+ else -+ err = may_rename_dir(old_dentry, old_parent); -+ -+ if (err) -+ goto out; -+ -+ err = unionfs_partial_lookup(new_dentry, new_parent); -+ if (err) -+ goto out; -+ -+ /* -+ * if new_dentry is already lower because of whiteout, -+ * simply override it even if the whited-out dir is not empty. -+ */ -+ wh_dentry = find_first_whiteout(new_dentry); -+ if (!IS_ERR(wh_dentry)) { -+ dput(wh_dentry); -+ } else if (new_dentry->d_inode) { -+ if (S_ISDIR(old_dentry->d_inode->i_mode) != -+ S_ISDIR(new_dentry->d_inode->i_mode)) { -+ err = S_ISDIR(old_dentry->d_inode->i_mode) ? -+ -ENOTDIR : -EISDIR; -+ goto out; -+ } -+ -+ if (S_ISDIR(new_dentry->d_inode->i_mode)) { -+ struct unionfs_dir_state *namelist = NULL; -+ /* check if this unionfs directory is empty or not */ -+ err = check_empty(new_dentry, new_parent, &namelist); -+ if (err) -+ goto out; -+ -+ if (!is_robranch(new_dentry)) -+ err = delete_whiteouts(new_dentry, -+ dbstart(new_dentry), -+ namelist); -+ -+ free_rdstate(namelist); -+ -+ if (err) -+ goto out; -+ } -+ } -+ -+ err = do_unionfs_rename(old_dir, old_dentry, old_parent, -+ new_dir, new_dentry, new_parent); -+ if (err) -+ goto out; -+ -+ /* -+ * force re-lookup since the dir on ro branch is not renamed, and -+ * lower dentries still indicate the un-renamed ones. -+ */ -+ if (S_ISDIR(old_dentry->d_inode->i_mode)) -+ atomic_dec(&UNIONFS_D(old_dentry)->generation); -+ else -+ unionfs_postcopyup_release(old_dentry); -+ if (new_dentry->d_inode && !S_ISDIR(new_dentry->d_inode->i_mode)) { -+ unionfs_postcopyup_release(new_dentry); -+ unionfs_postcopyup_setmnt(new_dentry); -+ if (!unionfs_lower_inode(new_dentry->d_inode)) { -+ /* -+ * If we get here, it means that no copyup was -+ * needed, and that a file by the old name already -+ * existing on the destination branch; that file got -+ * renamed earlier in this function, so all we need -+ * to do here is set the lower inode. -+ */ -+ struct inode *inode; -+ inode = unionfs_lower_inode(old_dentry->d_inode); -+ igrab(inode); -+ unionfs_set_lower_inode_idx(new_dentry->d_inode, -+ dbstart(new_dentry), -+ inode); -+ } -+ } -+ /* if all of this renaming succeeded, update our times */ -+ unionfs_copy_attr_times(old_dentry->d_inode); -+ unionfs_copy_attr_times(new_dentry->d_inode); -+ unionfs_check_inode(old_dir); -+ unionfs_check_inode(new_dir); -+ unionfs_check_dentry(old_dentry); -+ unionfs_check_dentry(new_dentry); -+ -+out: -+ if (err) /* clear the new_dentry stuff created */ -+ d_drop(new_dentry); -+ -+ unionfs_double_unlock_dentry(old_dentry, new_dentry); -+ if (new_parent != old_dentry && -+ new_parent != new_dentry && -+ new_parent != old_parent) -+ unionfs_unlock_dentry(new_parent); -+ if (old_parent != old_dentry && -+ old_parent != new_dentry) -+ unionfs_unlock_dentry(old_parent); -+ dput(new_parent); -+ dput(old_parent); -+ unionfs_read_unlock(old_dentry->d_sb); -+ -+ return err; -+} -diff --git a/fs/unionfs/sioq.c b/fs/unionfs/sioq.c -new file mode 100644 -index 0000000..b923742 ---- /dev/null -+++ b/fs/unionfs/sioq.c -@@ -0,0 +1,101 @@ -+/* -+ * Copyright (c) 2006-2011 Erez Zadok -+ * Copyright (c) 2006 Charles P. Wright -+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2006 Junjiro Okajima -+ * Copyright (c) 2006 David P. Quigley -+ * Copyright (c) 2006-2011 Stony Brook University -+ * Copyright (c) 2006-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * Super-user IO work Queue - sometimes we need to perform actions which -+ * would fail due to the unix permissions on the parent directory (e.g., -+ * rmdir a directory which appears empty, but in reality contains -+ * whiteouts). -+ */ -+ -+static struct workqueue_struct *superio_workqueue; -+ -+int __init init_sioq(void) -+{ -+ int err; -+ -+ superio_workqueue = create_workqueue("unionfs_siod"); -+ if (!IS_ERR(superio_workqueue)) -+ return 0; -+ -+ err = PTR_ERR(superio_workqueue); -+ printk(KERN_ERR "unionfs: create_workqueue failed %d\n", err); -+ superio_workqueue = NULL; -+ return err; -+} -+ -+void stop_sioq(void) -+{ -+ if (superio_workqueue) -+ destroy_workqueue(superio_workqueue); -+} -+ -+void run_sioq(work_func_t func, struct sioq_args *args) -+{ -+ INIT_WORK(&args->work, func); -+ -+ init_completion(&args->comp); -+ while (!queue_work(superio_workqueue, &args->work)) { -+ /* TODO: do accounting if needed */ -+ schedule(); -+ } -+ wait_for_completion(&args->comp); -+} -+ -+void __unionfs_create(struct work_struct *work) -+{ -+ struct sioq_args *args = container_of(work, struct sioq_args, work); -+ struct create_args *c = &args->create; -+ -+ args->err = vfs_create(c->parent, c->dentry, c->mode, c->nd); -+ complete(&args->comp); -+} -+ -+void __unionfs_mkdir(struct work_struct *work) -+{ -+ struct sioq_args *args = container_of(work, struct sioq_args, work); -+ struct mkdir_args *m = &args->mkdir; -+ -+ args->err = vfs_mkdir(m->parent, m->dentry, m->mode); -+ complete(&args->comp); -+} -+ -+void __unionfs_mknod(struct work_struct *work) -+{ -+ struct sioq_args *args = container_of(work, struct sioq_args, work); -+ struct mknod_args *m = &args->mknod; -+ -+ args->err = vfs_mknod(m->parent, m->dentry, m->mode, m->dev); -+ complete(&args->comp); -+} -+ -+void __unionfs_symlink(struct work_struct *work) -+{ -+ struct sioq_args *args = container_of(work, struct sioq_args, work); -+ struct symlink_args *s = &args->symlink; -+ -+ args->err = vfs_symlink(s->parent, s->dentry, s->symbuf); -+ complete(&args->comp); -+} -+ -+void __unionfs_unlink(struct work_struct *work) -+{ -+ struct sioq_args *args = container_of(work, struct sioq_args, work); -+ struct unlink_args *u = &args->unlink; -+ -+ args->err = vfs_unlink(u->parent, u->dentry); -+ complete(&args->comp); -+} -diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h -new file mode 100644 -index 0000000..c2dfb94 ---- /dev/null -+++ b/fs/unionfs/sioq.h -@@ -0,0 +1,91 @@ -+/* -+ * Copyright (c) 2006-2011 Erez Zadok -+ * Copyright (c) 2006 Charles P. Wright -+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2006 Junjiro Okajima -+ * Copyright (c) 2006 David P. Quigley -+ * Copyright (c) 2006-2011 Stony Brook University -+ * Copyright (c) 2006-2011 The Research Foundation of SUNY -+ * -+ * 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 _SIOQ_H -+#define _SIOQ_H -+ -+struct deletewh_args { -+ struct unionfs_dir_state *namelist; -+ struct dentry *dentry; -+ int bindex; -+}; -+ -+struct is_opaque_args { -+ struct dentry *dentry; -+}; -+ -+struct create_args { -+ struct inode *parent; -+ struct dentry *dentry; -+ umode_t mode; -+ struct nameidata *nd; -+}; -+ -+struct mkdir_args { -+ struct inode *parent; -+ struct dentry *dentry; -+ umode_t mode; -+}; -+ -+struct mknod_args { -+ struct inode *parent; -+ struct dentry *dentry; -+ umode_t mode; -+ dev_t dev; -+}; -+ -+struct symlink_args { -+ struct inode *parent; -+ struct dentry *dentry; -+ char *symbuf; -+}; -+ -+struct unlink_args { -+ struct inode *parent; -+ struct dentry *dentry; -+}; -+ -+ -+struct sioq_args { -+ struct completion comp; -+ struct work_struct work; -+ int err; -+ void *ret; -+ -+ union { -+ struct deletewh_args deletewh; -+ struct is_opaque_args is_opaque; -+ struct create_args create; -+ struct mkdir_args mkdir; -+ struct mknod_args mknod; -+ struct symlink_args symlink; -+ struct unlink_args unlink; -+ }; -+}; -+ -+/* Extern definitions for SIOQ functions */ -+extern int __init init_sioq(void); -+extern void stop_sioq(void); -+extern void run_sioq(work_func_t func, struct sioq_args *args); -+ -+/* Extern definitions for our privilege escalation helpers */ -+extern void __unionfs_create(struct work_struct *work); -+extern void __unionfs_mkdir(struct work_struct *work); -+extern void __unionfs_mknod(struct work_struct *work); -+extern void __unionfs_symlink(struct work_struct *work); -+extern void __unionfs_unlink(struct work_struct *work); -+extern void __delete_whiteouts(struct work_struct *work); -+extern void __is_opaque_dir(struct work_struct *work); -+ -+#endif /* not _SIOQ_H */ -diff --git a/fs/unionfs/subr.c b/fs/unionfs/subr.c -new file mode 100644 -index 0000000..bdca2f7 ---- /dev/null -+++ b/fs/unionfs/subr.c -@@ -0,0 +1,95 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * returns the right n_link value based on the inode type -+ */ -+int unionfs_get_nlinks(const struct inode *inode) -+{ -+ /* don't bother to do all the work since we're unlinked */ -+ if (inode->i_nlink == 0) -+ return 0; -+ -+ if (!S_ISDIR(inode->i_mode)) -+ return unionfs_lower_inode(inode)->i_nlink; -+ -+ /* -+ * For directories, we return 1. The only place that could cares -+ * about links is readdir, and there's d_type there so even that -+ * doesn't matter. -+ */ -+ return 1; -+} -+ -+/* copy a/m/ctime from the lower branch with the newest times */ -+void unionfs_copy_attr_times(struct inode *upper) -+{ -+ int bindex; -+ struct inode *lower; -+ -+ if (!upper) -+ return; -+ if (ibstart(upper) < 0) { -+#ifdef CONFIG_UNION_FS_DEBUG -+ WARN_ON(ibstart(upper) < 0); -+#endif /* CONFIG_UNION_FS_DEBUG */ -+ return; -+ } -+ for (bindex = ibstart(upper); bindex <= ibend(upper); bindex++) { -+ lower = unionfs_lower_inode_idx(upper, bindex); -+ if (!lower) -+ continue; /* not all lower dir objects may exist */ -+ if (unlikely(timespec_compare(&upper->i_mtime, -+ &lower->i_mtime) < 0)) -+ upper->i_mtime = lower->i_mtime; -+ if (unlikely(timespec_compare(&upper->i_ctime, -+ &lower->i_ctime) < 0)) -+ upper->i_ctime = lower->i_ctime; -+ if (unlikely(timespec_compare(&upper->i_atime, -+ &lower->i_atime) < 0)) -+ upper->i_atime = lower->i_atime; -+ } -+} -+ -+/* -+ * A unionfs/fanout version of fsstack_copy_attr_all. Uses a -+ * unionfs_get_nlinks to properly calcluate the number of links to a file. -+ * Also, copies the max() of all a/m/ctimes for all lower inodes (which is -+ * important if the lower inode is a directory type) -+ */ -+void unionfs_copy_attr_all(struct inode *dest, -+ const struct inode *src) -+{ -+ dest->i_mode = src->i_mode; -+ dest->i_uid = src->i_uid; -+ dest->i_gid = src->i_gid; -+ dest->i_rdev = src->i_rdev; -+ -+ unionfs_copy_attr_times(dest); -+ -+ dest->i_blkbits = src->i_blkbits; -+ dest->i_flags = src->i_flags; -+ -+ /* -+ * Update the nlinks AFTER updating the above fields, because the -+ * get_links callback may depend on them. -+ */ -+ dest->i_nlink = unionfs_get_nlinks(dest); -+} -diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c -new file mode 100644 -index 0000000..c3ac814 ---- /dev/null -+++ b/fs/unionfs/super.c -@@ -0,0 +1,1030 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * The inode cache is used with alloc_inode for both our inode info and the -+ * vfs inode. -+ */ -+static struct kmem_cache *unionfs_inode_cachep; -+ -+struct inode *unionfs_iget(struct super_block *sb, unsigned long ino) -+{ -+ int size; -+ struct unionfs_inode_info *info; -+ struct inode *inode; -+ -+ inode = iget_locked(sb, ino); -+ if (!inode) -+ return ERR_PTR(-ENOMEM); -+ if (!(inode->i_state & I_NEW)) -+ return inode; -+ -+ info = UNIONFS_I(inode); -+ memset(info, 0, offsetof(struct unionfs_inode_info, vfs_inode)); -+ info->bstart = -1; -+ info->bend = -1; -+ atomic_set(&info->generation, -+ atomic_read(&UNIONFS_SB(inode->i_sb)->generation)); -+ spin_lock_init(&info->rdlock); -+ info->rdcount = 1; -+ info->hashsize = -1; -+ INIT_LIST_HEAD(&info->readdircache); -+ -+ size = sbmax(inode->i_sb) * sizeof(struct inode *); -+ info->lower_inodes = kzalloc(size, GFP_KERNEL); -+ if (unlikely(!info->lower_inodes)) { -+ printk(KERN_CRIT "unionfs: no kernel memory when allocating " -+ "lower-pointer array!\n"); -+ iget_failed(inode); -+ return ERR_PTR(-ENOMEM); -+ } -+ -+ inode->i_version++; -+ inode->i_op = &unionfs_main_iops; -+ inode->i_fop = &unionfs_main_fops; -+ -+ inode->i_mapping->a_ops = &unionfs_aops; -+ -+ /* -+ * reset times so unionfs_copy_attr_all can keep out time invariants -+ * right (upper inode time being the max of all lower ones). -+ */ -+ inode->i_atime.tv_sec = inode->i_atime.tv_nsec = 0; -+ inode->i_mtime.tv_sec = inode->i_mtime.tv_nsec = 0; -+ inode->i_ctime.tv_sec = inode->i_ctime.tv_nsec = 0; -+ unlock_new_inode(inode); -+ return inode; -+} -+ -+/* -+ * final actions when unmounting a file system -+ * -+ * No need to lock rwsem. -+ */ -+static void unionfs_put_super(struct super_block *sb) -+{ -+ int bindex, bstart, bend; -+ struct unionfs_sb_info *spd; -+ int leaks = 0; -+ -+ spd = UNIONFS_SB(sb); -+ if (!spd) -+ return; -+ -+ bstart = sbstart(sb); -+ bend = sbend(sb); -+ -+ /* Make sure we have no leaks of branchget/branchput. */ -+ for (bindex = bstart; bindex <= bend; bindex++) -+ if (unlikely(branch_count(sb, bindex) != 0)) { -+ printk(KERN_CRIT -+ "unionfs: branch %d has %d references left!\n", -+ bindex, branch_count(sb, bindex)); -+ leaks = 1; -+ } -+ WARN_ON(leaks != 0); -+ -+ /* decrement lower super references */ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ struct super_block *s; -+ s = unionfs_lower_super_idx(sb, bindex); -+ unionfs_set_lower_super_idx(sb, bindex, NULL); -+ atomic_dec(&s->s_active); -+ } -+ -+ kfree(spd->dev_name); -+ kfree(spd->data); -+ kfree(spd); -+ sb->s_fs_info = NULL; -+} -+ -+/* -+ * Since people use this to answer the "How big of a file can I write?" -+ * question, we report the size of the highest priority branch as the size of -+ * the union. -+ */ -+static int unionfs_statfs(struct dentry *dentry, struct kstatfs *buf) -+{ -+ int err = 0; -+ struct super_block *sb; -+ struct dentry *lower_dentry; -+ struct dentry *parent; -+ struct path lower_path; -+ bool valid; -+ -+ sb = dentry->d_sb; -+ -+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ unionfs_check_dentry(dentry); -+ -+ lower_dentry = unionfs_lower_dentry(sb->s_root); -+ lower_path.dentry = lower_dentry; -+ lower_path.mnt = unionfs_mntget(sb->s_root, 0); -+ err = vfs_statfs(&lower_path, buf); -+ mntput(lower_path.mnt); -+ -+ /* set return buf to our f/s to avoid confusing user-level utils */ -+ buf->f_type = UNIONFS_SUPER_MAGIC; -+ /* -+ * Our maximum file name can is shorter by a few bytes because every -+ * file name could potentially be whited-out. -+ * -+ * XXX: this restriction goes away with ODF. -+ */ -+ unionfs_set_max_namelen(&buf->f_namelen); -+ -+ /* -+ * reset two fields to avoid confusing user-land. -+ * XXX: is this still necessary? -+ */ -+ memset(&buf->f_fsid, 0, sizeof(__kernel_fsid_t)); -+ memset(&buf->f_spare, 0, sizeof(buf->f_spare)); -+ -+out: -+ unionfs_check_dentry(dentry); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(sb); -+ return err; -+} -+ -+/* handle mode changing during remount */ -+static noinline_for_stack int do_remount_mode_option( -+ char *optarg, -+ int cur_branches, -+ struct unionfs_data *new_data, -+ struct path *new_lower_paths) -+{ -+ int err = -EINVAL; -+ int perms, idx; -+ char *modename = strchr(optarg, '='); -+ struct path path; -+ -+ /* by now, optarg contains the branch name */ -+ if (!*optarg) { -+ printk(KERN_ERR -+ "unionfs: no branch specified for mode change\n"); -+ goto out; -+ } -+ if (!modename) { -+ printk(KERN_ERR "unionfs: branch \"%s\" requires a mode\n", -+ optarg); -+ goto out; -+ } -+ *modename++ = '\0'; -+ err = parse_branch_mode(modename, &perms); -+ if (err) { -+ printk(KERN_ERR "unionfs: invalid mode \"%s\" for \"%s\"\n", -+ modename, optarg); -+ goto out; -+ } -+ -+ /* -+ * Find matching branch index. For now, this assumes that nothing -+ * has been mounted on top of this Unionfs stack. Once we have /odf -+ * and cache-coherency resolved, we'll address the branch-path -+ * uniqueness. -+ */ -+ err = kern_path(optarg, LOOKUP_FOLLOW, &path); -+ if (err) { -+ printk(KERN_ERR "unionfs: error accessing " -+ "lower directory \"%s\" (error %d)\n", -+ optarg, err); -+ goto out; -+ } -+ for (idx = 0; idx < cur_branches; idx++) -+ if (path.mnt == new_lower_paths[idx].mnt && -+ path.dentry == new_lower_paths[idx].dentry) -+ break; -+ path_put(&path); /* no longer needed */ -+ if (idx == cur_branches) { -+ err = -ENOENT; /* err may have been reset above */ -+ printk(KERN_ERR "unionfs: branch \"%s\" " -+ "not found\n", optarg); -+ goto out; -+ } -+ /* check/change mode for existing branch */ -+ /* we don't warn if perms==branchperms */ -+ new_data[idx].branchperms = perms; -+ err = 0; -+out: -+ return err; -+} -+ -+/* handle branch deletion during remount */ -+static noinline_for_stack int do_remount_del_option( -+ char *optarg, int cur_branches, -+ struct unionfs_data *new_data, -+ struct path *new_lower_paths) -+{ -+ int err = -EINVAL; -+ int idx; -+ struct path path; -+ -+ /* optarg contains the branch name to delete */ -+ -+ /* -+ * Find matching branch index. For now, this assumes that nothing -+ * has been mounted on top of this Unionfs stack. Once we have /odf -+ * and cache-coherency resolved, we'll address the branch-path -+ * uniqueness. -+ */ -+ err = kern_path(optarg, LOOKUP_FOLLOW, &path); -+ if (err) { -+ printk(KERN_ERR "unionfs: error accessing " -+ "lower directory \"%s\" (error %d)\n", -+ optarg, err); -+ goto out; -+ } -+ for (idx = 0; idx < cur_branches; idx++) -+ if (path.mnt == new_lower_paths[idx].mnt && -+ path.dentry == new_lower_paths[idx].dentry) -+ break; -+ path_put(&path); /* no longer needed */ -+ if (idx == cur_branches) { -+ printk(KERN_ERR "unionfs: branch \"%s\" " -+ "not found\n", optarg); -+ err = -ENOENT; -+ goto out; -+ } -+ /* check if there are any open files on the branch to be deleted */ -+ if (atomic_read(&new_data[idx].open_files) > 0) { -+ err = -EBUSY; -+ goto out; -+ } -+ -+ /* -+ * Now we have to delete the branch. First, release any handles it -+ * has. Then, move the remaining array indexes past "idx" in -+ * new_data and new_lower_paths one to the left. Finally, adjust -+ * cur_branches. -+ */ -+ path_put(&new_lower_paths[idx]); -+ -+ if (idx < cur_branches - 1) { -+ /* if idx==cur_branches-1, we delete last branch: easy */ -+ memmove(&new_data[idx], &new_data[idx+1], -+ (cur_branches - 1 - idx) * -+ sizeof(struct unionfs_data)); -+ memmove(&new_lower_paths[idx], &new_lower_paths[idx+1], -+ (cur_branches - 1 - idx) * sizeof(struct path)); -+ } -+ -+ err = 0; -+out: -+ return err; -+} -+ -+/* handle branch insertion during remount */ -+static noinline_for_stack int do_remount_add_option( -+ char *optarg, int cur_branches, -+ struct unionfs_data *new_data, -+ struct path *new_lower_paths, -+ int *high_branch_id) -+{ -+ int err = -EINVAL; -+ int perms; -+ int idx = 0; /* default: insert at beginning */ -+ char *new_branch , *modename = NULL; -+ struct path path; -+ -+ /* -+ * optarg can be of several forms: -+ * -+ * /bar:/foo insert /foo before /bar -+ * /bar:/foo=ro insert /foo in ro mode before /bar -+ * /foo insert /foo in the beginning (prepend) -+ * :/foo insert /foo at the end (append) -+ */ -+ if (*optarg == ':') { /* append? */ -+ new_branch = optarg + 1; /* skip ':' */ -+ idx = cur_branches; -+ goto found_insertion_point; -+ } -+ new_branch = strchr(optarg, ':'); -+ if (!new_branch) { /* prepend? */ -+ new_branch = optarg; -+ goto found_insertion_point; -+ } -+ *new_branch++ = '\0'; /* holds path+mode of new branch */ -+ -+ /* -+ * Find matching branch index. For now, this assumes that nothing -+ * has been mounted on top of this Unionfs stack. Once we have /odf -+ * and cache-coherency resolved, we'll address the branch-path -+ * uniqueness. -+ */ -+ err = kern_path(optarg, LOOKUP_FOLLOW, &path); -+ if (err) { -+ printk(KERN_ERR "unionfs: error accessing " -+ "lower directory \"%s\" (error %d)\n", -+ optarg, err); -+ goto out; -+ } -+ for (idx = 0; idx < cur_branches; idx++) -+ if (path.mnt == new_lower_paths[idx].mnt && -+ path.dentry == new_lower_paths[idx].dentry) -+ break; -+ path_put(&path); /* no longer needed */ -+ if (idx == cur_branches) { -+ printk(KERN_ERR "unionfs: branch \"%s\" " -+ "not found\n", optarg); -+ err = -ENOENT; -+ goto out; -+ } -+ -+ /* -+ * At this point idx will hold the index where the new branch should -+ * be inserted before. -+ */ -+found_insertion_point: -+ /* find the mode for the new branch */ -+ if (new_branch) -+ modename = strchr(new_branch, '='); -+ if (modename) -+ *modename++ = '\0'; -+ if (!new_branch || !*new_branch) { -+ printk(KERN_ERR "unionfs: null new branch\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ err = parse_branch_mode(modename, &perms); -+ if (err) { -+ printk(KERN_ERR "unionfs: invalid mode \"%s\" for " -+ "branch \"%s\"\n", modename, new_branch); -+ goto out; -+ } -+ err = kern_path(new_branch, LOOKUP_FOLLOW, &path); -+ if (err) { -+ printk(KERN_ERR "unionfs: error accessing " -+ "lower directory \"%s\" (error %d)\n", -+ new_branch, err); -+ goto out; -+ } -+ /* -+ * It's probably safe to check_mode the new branch to insert. Note: -+ * we don't allow inserting branches which are unionfs's by -+ * themselves (check_branch returns EINVAL in that case). This is -+ * because this code base doesn't support stacking unionfs: the ODF -+ * code base supports that correctly. -+ */ -+ err = check_branch(&path); -+ if (err) { -+ printk(KERN_ERR "unionfs: lower directory " -+ "\"%s\" is not a valid branch\n", optarg); -+ path_put(&path); -+ goto out; -+ } -+ -+ /* -+ * Now we have to insert the new branch. But first, move the bits -+ * to make space for the new branch, if needed. Finally, adjust -+ * cur_branches. -+ * We don't release nd here; it's kept until umount/remount. -+ */ -+ if (idx < cur_branches) { -+ /* if idx==cur_branches, we append: easy */ -+ memmove(&new_data[idx+1], &new_data[idx], -+ (cur_branches - idx) * sizeof(struct unionfs_data)); -+ memmove(&new_lower_paths[idx+1], &new_lower_paths[idx], -+ (cur_branches - idx) * sizeof(struct path)); -+ } -+ new_lower_paths[idx].dentry = path.dentry; -+ new_lower_paths[idx].mnt = path.mnt; -+ -+ new_data[idx].sb = path.dentry->d_sb; -+ atomic_set(&new_data[idx].open_files, 0); -+ new_data[idx].branchperms = perms; -+ new_data[idx].branch_id = ++*high_branch_id; /* assign new branch ID */ -+ -+ err = 0; -+out: -+ return err; -+} -+ -+ -+/* -+ * Support branch management options on remount. -+ * -+ * See Documentation/filesystems/unionfs/ for details. -+ * -+ * @flags: numeric mount options -+ * @options: mount options string -+ * -+ * This function can rearrange a mounted union dynamically, adding and -+ * removing branches, including changing branch modes. Clearly this has to -+ * be done safely and atomically. Luckily, the VFS already calls this -+ * function with lock_super(sb) and lock_kernel() held, preventing -+ * concurrent mixing of new mounts, remounts, and unmounts. Moreover, -+ * do_remount_sb(), our caller function, already called shrink_dcache_sb(sb) -+ * to purge dentries/inodes from our superblock, and also called -+ * fsync_super(sb) to purge any dirty pages. So we're good. -+ * -+ * XXX: however, our remount code may also need to invalidate mapped pages -+ * so as to force them to be re-gotten from the (newly reconfigured) lower -+ * branches. This has to wait for proper mmap and cache coherency support -+ * in the VFS. -+ * -+ */ -+static int unionfs_remount_fs(struct super_block *sb, int *flags, -+ char *options) -+{ -+ int err = 0; -+ int i; -+ char *optionstmp, *tmp_to_free; /* kstrdup'ed of "options" */ -+ char *optname; -+ int cur_branches = 0; /* no. of current branches */ -+ int new_branches = 0; /* no. of branches actually left in the end */ -+ int add_branches; /* est. no. of branches to add */ -+ int del_branches; /* est. no. of branches to del */ -+ int max_branches; /* max possible no. of branches */ -+ struct unionfs_data *new_data = NULL, *tmp_data = NULL; -+ struct path *new_lower_paths = NULL, *tmp_lower_paths = NULL; -+ struct inode **new_lower_inodes = NULL; -+ int new_high_branch_id; /* new high branch ID */ -+ int size; /* memory allocation size, temp var */ -+ int old_ibstart, old_ibend; -+ -+ unionfs_write_lock(sb); -+ -+ /* -+ * The VFS will take care of "ro" and "rw" flags, and we can safely -+ * ignore MS_SILENT, but anything else left over is an error. So we -+ * need to check if any other flags may have been passed (none are -+ * allowed/supported as of now). -+ */ -+ if ((*flags & ~(MS_RDONLY | MS_SILENT)) != 0) { -+ printk(KERN_ERR -+ "unionfs: remount flags 0x%x unsupported\n", *flags); -+ err = -EINVAL; -+ goto out_error; -+ } -+ -+ /* -+ * If 'options' is NULL, it's probably because the user just changed -+ * the union to a "ro" or "rw" and the VFS took care of it. So -+ * nothing to do and we're done. -+ */ -+ if (!options || options[0] == '\0') -+ goto out_error; -+ -+ /* -+ * Find out how many branches we will have in the end, counting -+ * "add" and "del" commands. Copy the "options" string because -+ * strsep modifies the string and we need it later. -+ */ -+ tmp_to_free = kstrdup(options, GFP_KERNEL); -+ optionstmp = tmp_to_free; -+ if (unlikely(!optionstmp)) { -+ err = -ENOMEM; -+ goto out_free; -+ } -+ cur_branches = sbmax(sb); /* current no. branches */ -+ new_branches = sbmax(sb); -+ del_branches = 0; -+ add_branches = 0; -+ new_high_branch_id = sbhbid(sb); /* save current high_branch_id */ -+ while ((optname = strsep(&optionstmp, ",")) != NULL) { -+ char *optarg; -+ -+ if (!optname || !*optname) -+ continue; -+ -+ optarg = strchr(optname, '='); -+ if (optarg) -+ *optarg++ = '\0'; -+ -+ if (!strcmp("add", optname)) -+ add_branches++; -+ else if (!strcmp("del", optname)) -+ del_branches++; -+ } -+ kfree(tmp_to_free); -+ /* after all changes, will we have at least one branch left? */ -+ if ((new_branches + add_branches - del_branches) < 1) { -+ printk(KERN_ERR -+ "unionfs: no branches left after remount\n"); -+ err = -EINVAL; -+ goto out_free; -+ } -+ -+ /* -+ * Since we haven't actually parsed all the add/del options, nor -+ * have we checked them for errors, we don't know for sure how many -+ * branches we will have after all changes have taken place. In -+ * fact, the total number of branches left could be less than what -+ * we have now. So we need to allocate space for a temporary -+ * placeholder that is at least as large as the maximum number of -+ * branches we *could* have, which is the current number plus all -+ * the additions. Once we're done with these temp placeholders, we -+ * may have to re-allocate the final size, copy over from the temp, -+ * and then free the temps (done near the end of this function). -+ */ -+ max_branches = cur_branches + add_branches; -+ /* allocate space for new pointers to lower dentry */ -+ tmp_data = kcalloc(max_branches, -+ sizeof(struct unionfs_data), GFP_KERNEL); -+ if (unlikely(!tmp_data)) { -+ err = -ENOMEM; -+ goto out_free; -+ } -+ /* allocate space for new pointers to lower paths */ -+ tmp_lower_paths = kcalloc(max_branches, -+ sizeof(struct path), GFP_KERNEL); -+ if (unlikely(!tmp_lower_paths)) { -+ err = -ENOMEM; -+ goto out_free; -+ } -+ /* copy current info into new placeholders, incrementing refcnts */ -+ memcpy(tmp_data, UNIONFS_SB(sb)->data, -+ cur_branches * sizeof(struct unionfs_data)); -+ memcpy(tmp_lower_paths, UNIONFS_D(sb->s_root)->lower_paths, -+ cur_branches * sizeof(struct path)); -+ for (i = 0; i < cur_branches; i++) -+ path_get(&tmp_lower_paths[i]); /* drop refs at end of fxn */ -+ -+ /******************************************************************* -+ * For each branch command, do kern_path on the requested branch, -+ * and apply the change to a temp branch list. To handle errors, we -+ * already dup'ed the old arrays (above), and increased the refcnts -+ * on various f/s objects. So now we can do all the kern_path'ss -+ * and branch-management commands on the new arrays. If it fail mid -+ * way, we free the tmp arrays and *put all objects. If we succeed, -+ * then we free old arrays and *put its objects, and then replace -+ * the arrays with the new tmp list (we may have to re-allocate the -+ * memory because the temp lists could have been larger than what we -+ * actually needed). -+ *******************************************************************/ -+ -+ while ((optname = strsep(&options, ",")) != NULL) { -+ char *optarg; -+ -+ if (!optname || !*optname) -+ continue; -+ /* -+ * At this stage optname holds a comma-delimited option, but -+ * without the commas. Next, we need to break the string on -+ * the '=' symbol to separate CMD=ARG, where ARG itself can -+ * be KEY=VAL. For example, in mode=/foo=rw, CMD is "mode", -+ * KEY is "/foo", and VAL is "rw". -+ */ -+ optarg = strchr(optname, '='); -+ if (optarg) -+ *optarg++ = '\0'; -+ /* incgen remount option (instead of old ioctl) */ -+ if (!strcmp("incgen", optname)) { -+ err = 0; -+ goto out_no_change; -+ } -+ -+ /* -+ * All of our options take an argument now. (Insert ones -+ * that don't above this check.) So at this stage optname -+ * contains the CMD part and optarg contains the ARG part. -+ */ -+ if (!optarg || !*optarg) { -+ printk(KERN_ERR "unionfs: all remount options require " -+ "an argument (%s)\n", optname); -+ err = -EINVAL; -+ goto out_release; -+ } -+ -+ if (!strcmp("add", optname)) { -+ err = do_remount_add_option(optarg, new_branches, -+ tmp_data, -+ tmp_lower_paths, -+ &new_high_branch_id); -+ if (err) -+ goto out_release; -+ new_branches++; -+ if (new_branches > UNIONFS_MAX_BRANCHES) { -+ printk(KERN_ERR "unionfs: command exceeds " -+ "%d branches\n", UNIONFS_MAX_BRANCHES); -+ err = -E2BIG; -+ goto out_release; -+ } -+ continue; -+ } -+ if (!strcmp("del", optname)) { -+ err = do_remount_del_option(optarg, new_branches, -+ tmp_data, -+ tmp_lower_paths); -+ if (err) -+ goto out_release; -+ new_branches--; -+ continue; -+ } -+ if (!strcmp("mode", optname)) { -+ err = do_remount_mode_option(optarg, new_branches, -+ tmp_data, -+ tmp_lower_paths); -+ if (err) -+ goto out_release; -+ continue; -+ } -+ -+ /* -+ * When you use "mount -o remount,ro", mount(8) will -+ * reportedly pass the original dirs= string from -+ * /proc/mounts. So for now, we have to ignore dirs= and -+ * not consider it an error, unless we want to allow users -+ * to pass dirs= in remount. Note that to allow the VFS to -+ * actually process the ro/rw remount options, we have to -+ * return 0 from this function. -+ */ -+ if (!strcmp("dirs", optname)) { -+ printk(KERN_WARNING -+ "unionfs: remount ignoring option \"%s\"\n", -+ optname); -+ continue; -+ } -+ -+ err = -EINVAL; -+ printk(KERN_ERR -+ "unionfs: unrecognized option \"%s\"\n", optname); -+ goto out_release; -+ } -+ -+out_no_change: -+ -+ /****************************************************************** -+ * WE'RE ALMOST DONE: check if leftmost branch might be read-only, -+ * see if we need to allocate a small-sized new vector, copy the -+ * vectors to their correct place, release the refcnt of the older -+ * ones, and return. Also handle invalidating any pages that will -+ * have to be re-read. -+ *******************************************************************/ -+ -+ if (!(tmp_data[0].branchperms & MAY_WRITE)) { -+ printk(KERN_ERR "unionfs: leftmost branch cannot be read-only " -+ "(use \"remount,ro\" to create a read-only union)\n"); -+ err = -EINVAL; -+ goto out_release; -+ } -+ -+ /* (re)allocate space for new pointers to lower dentry */ -+ size = new_branches * sizeof(struct unionfs_data); -+ new_data = krealloc(tmp_data, size, GFP_KERNEL); -+ if (unlikely(!new_data)) { -+ err = -ENOMEM; -+ goto out_release; -+ } -+ -+ /* allocate space for new pointers to lower paths */ -+ size = new_branches * sizeof(struct path); -+ new_lower_paths = krealloc(tmp_lower_paths, size, GFP_KERNEL); -+ if (unlikely(!new_lower_paths)) { -+ err = -ENOMEM; -+ goto out_release; -+ } -+ -+ /* allocate space for new pointers to lower inodes */ -+ new_lower_inodes = kcalloc(new_branches, -+ sizeof(struct inode *), GFP_KERNEL); -+ if (unlikely(!new_lower_inodes)) { -+ err = -ENOMEM; -+ goto out_release; -+ } -+ -+ /* -+ * OK, just before we actually put the new set of branches in place, -+ * we need to ensure that our own f/s has no dirty objects left. -+ * Luckily, do_remount_sb() already calls shrink_dcache_sb(sb) and -+ * fsync_super(sb), taking care of dentries, inodes, and dirty -+ * pages. So all that's left is for us to invalidate any leftover -+ * (non-dirty) pages to ensure that they will be re-read from the -+ * new lower branches (and to support mmap). -+ */ -+ -+ /* -+ * Once we finish the remounting successfully, our superblock -+ * generation number will have increased. This will be detected by -+ * our dentry-revalidation code upon subsequent f/s operations -+ * through unionfs. The revalidation code will rebuild the union of -+ * lower inodes for a given unionfs inode and invalidate any pages -+ * of such "stale" inodes (by calling our purge_inode_data -+ * function). This revalidation will happen lazily and -+ * incrementally, as users perform operations on cached inodes. We -+ * would like to encourage this revalidation to happen sooner if -+ * possible, so we like to try to invalidate as many other pages in -+ * our superblock as we can. We used to call drop_pagecache_sb() or -+ * a variant thereof, but either method was racy (drop_caches alone -+ * is known to be racy). So now we let the revalidation happen on a -+ * per file basis in ->d_revalidate. -+ */ -+ -+ /* grab new lower super references; release old ones */ -+ for (i = 0; i < new_branches; i++) -+ atomic_inc(&new_data[i].sb->s_active); -+ for (i = 0; i < sbmax(sb); i++) -+ atomic_dec(&UNIONFS_SB(sb)->data[i].sb->s_active); -+ -+ /* copy new vectors into their correct place */ -+ tmp_data = UNIONFS_SB(sb)->data; -+ UNIONFS_SB(sb)->data = new_data; -+ new_data = NULL; /* so don't free good pointers below */ -+ tmp_lower_paths = UNIONFS_D(sb->s_root)->lower_paths; -+ UNIONFS_D(sb->s_root)->lower_paths = new_lower_paths; -+ new_lower_paths = NULL; /* so don't free good pointers below */ -+ -+ /* update our unionfs_sb_info and root dentry index of last branch */ -+ i = sbmax(sb); /* save no. of branches to release at end */ -+ sbend(sb) = new_branches - 1; -+ dbend(sb->s_root) = new_branches - 1; -+ old_ibstart = ibstart(sb->s_root->d_inode); -+ old_ibend = ibend(sb->s_root->d_inode); -+ ibend(sb->s_root->d_inode) = new_branches - 1; -+ UNIONFS_D(sb->s_root)->bcount = new_branches; -+ new_branches = i; /* no. of branches to release below */ -+ -+ /* -+ * Update lower inodes: 3 steps -+ * 1. grab ref on all new lower inodes -+ */ -+ for (i = dbstart(sb->s_root); i <= dbend(sb->s_root); i++) { -+ struct dentry *lower_dentry = -+ unionfs_lower_dentry_idx(sb->s_root, i); -+ igrab(lower_dentry->d_inode); -+ new_lower_inodes[i] = lower_dentry->d_inode; -+ } -+ /* 2. release reference on all older lower inodes */ -+ iput_lowers(sb->s_root->d_inode, old_ibstart, old_ibend, true); -+ /* 3. update root dentry's inode to new lower_inodes array */ -+ UNIONFS_I(sb->s_root->d_inode)->lower_inodes = new_lower_inodes; -+ new_lower_inodes = NULL; -+ -+ /* maxbytes may have changed */ -+ sb->s_maxbytes = unionfs_lower_super_idx(sb, 0)->s_maxbytes; -+ /* update high branch ID */ -+ sbhbid(sb) = new_high_branch_id; -+ -+ /* update our sb->generation for revalidating objects */ -+ i = atomic_inc_return(&UNIONFS_SB(sb)->generation); -+ atomic_set(&UNIONFS_D(sb->s_root)->generation, i); -+ atomic_set(&UNIONFS_I(sb->s_root->d_inode)->generation, i); -+ if (!(*flags & MS_SILENT)) -+ pr_info("unionfs: %s: new generation number %d\n", -+ UNIONFS_SB(sb)->dev_name, i); -+ /* finally, update the root dentry's times */ -+ unionfs_copy_attr_times(sb->s_root->d_inode); -+ err = 0; /* reset to success */ -+ -+ /* -+ * The code above falls through to the next label, and releases the -+ * refcnts of the older ones (stored in tmp_*): if we fell through -+ * here, it means success. However, if we jump directly to this -+ * label from any error above, then an error occurred after we -+ * grabbed various refcnts, and so we have to release the -+ * temporarily constructed structures. -+ */ -+out_release: -+ /* no need to cleanup/release anything in tmp_data */ -+ if (tmp_lower_paths) -+ for (i = 0; i < new_branches; i++) -+ path_put(&tmp_lower_paths[i]); -+out_free: -+ kfree(tmp_lower_paths); -+ kfree(tmp_data); -+ kfree(new_lower_paths); -+ kfree(new_data); -+ kfree(new_lower_inodes); -+out_error: -+ unionfs_check_dentry(sb->s_root); -+ unionfs_write_unlock(sb); -+ return err; -+} -+ -+/* -+ * Called by iput() when the inode reference count reached zero -+ * and the inode is not hashed anywhere. Used to clear anything -+ * that needs to be, before the inode is completely destroyed and put -+ * on the inode free list. -+ * -+ * No need to lock sb info's rwsem. -+ */ -+static void unionfs_evict_inode(struct inode *inode) -+{ -+ int bindex, bstart, bend; -+ struct inode *lower_inode; -+ struct list_head *pos, *n; -+ struct unionfs_dir_state *rdstate; -+ -+ truncate_inode_pages(&inode->i_data, 0); -+ end_writeback(inode); -+ -+ list_for_each_safe(pos, n, &UNIONFS_I(inode)->readdircache) { -+ rdstate = list_entry(pos, struct unionfs_dir_state, cache); -+ list_del(&rdstate->cache); -+ free_rdstate(rdstate); -+ } -+ -+ /* -+ * Decrement a reference to a lower_inode, which was incremented -+ * by our read_inode when it was created initially. -+ */ -+ bstart = ibstart(inode); -+ bend = ibend(inode); -+ if (bstart >= 0) { -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_inode = unionfs_lower_inode_idx(inode, bindex); -+ if (!lower_inode) -+ continue; -+ unionfs_set_lower_inode_idx(inode, bindex, NULL); -+ /* see Documentation/filesystems/unionfs/issues.txt */ -+ lockdep_off(); -+ iput(lower_inode); -+ lockdep_on(); -+ } -+ } -+ -+ kfree(UNIONFS_I(inode)->lower_inodes); -+ UNIONFS_I(inode)->lower_inodes = NULL; -+} -+ -+static struct inode *unionfs_alloc_inode(struct super_block *sb) -+{ -+ struct unionfs_inode_info *i; -+ -+ i = kmem_cache_alloc(unionfs_inode_cachep, GFP_KERNEL); -+ if (unlikely(!i)) -+ return NULL; -+ -+ /* memset everything up to the inode to 0 */ -+ memset(i, 0, offsetof(struct unionfs_inode_info, vfs_inode)); -+ -+ i->vfs_inode.i_version = 1; -+ return &i->vfs_inode; -+} -+ -+static void unionfs_destroy_inode(struct inode *inode) -+{ -+ kmem_cache_free(unionfs_inode_cachep, UNIONFS_I(inode)); -+} -+ -+/* unionfs inode cache constructor */ -+static void init_once(void *obj) -+{ -+ struct unionfs_inode_info *i = obj; -+ -+ inode_init_once(&i->vfs_inode); -+} -+ -+int unionfs_init_inode_cache(void) -+{ -+ int err = 0; -+ -+ unionfs_inode_cachep = -+ kmem_cache_create("unionfs_inode_cache", -+ sizeof(struct unionfs_inode_info), 0, -+ SLAB_RECLAIM_ACCOUNT, init_once); -+ if (unlikely(!unionfs_inode_cachep)) -+ err = -ENOMEM; -+ return err; -+} -+ -+/* unionfs inode cache destructor */ -+void unionfs_destroy_inode_cache(void) -+{ -+ if (unionfs_inode_cachep) -+ kmem_cache_destroy(unionfs_inode_cachep); -+} -+ -+/* -+ * Called when we have a dirty inode, right here we only throw out -+ * parts of our readdir list that are too old. -+ * -+ * No need to grab sb info's rwsem. -+ */ -+static int unionfs_write_inode(struct inode *inode, -+ struct writeback_control *wbc) -+{ -+ struct list_head *pos, *n; -+ struct unionfs_dir_state *rdstate; -+ -+ spin_lock(&UNIONFS_I(inode)->rdlock); -+ list_for_each_safe(pos, n, &UNIONFS_I(inode)->readdircache) { -+ rdstate = list_entry(pos, struct unionfs_dir_state, cache); -+ /* We keep this list in LRU order. */ -+ if ((rdstate->access + RDCACHE_JIFFIES) > jiffies) -+ break; -+ UNIONFS_I(inode)->rdcount--; -+ list_del(&rdstate->cache); -+ free_rdstate(rdstate); -+ } -+ spin_unlock(&UNIONFS_I(inode)->rdlock); -+ -+ return 0; -+} -+ -+/* -+ * Used only in nfs, to kill any pending RPC tasks, so that subsequent -+ * code can actually succeed and won't leave tasks that need handling. -+ */ -+static void unionfs_umount_begin(struct super_block *sb) -+{ -+ struct super_block *lower_sb; -+ int bindex, bstart, bend; -+ -+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD); -+ -+ bstart = sbstart(sb); -+ bend = sbend(sb); -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_sb = unionfs_lower_super_idx(sb, bindex); -+ -+ if (lower_sb && lower_sb->s_op && -+ lower_sb->s_op->umount_begin) -+ lower_sb->s_op->umount_begin(lower_sb); -+ } -+ -+ unionfs_read_unlock(sb); -+} -+ -+static int unionfs_show_options(struct seq_file *m, struct vfsmount *mnt) -+{ -+ struct super_block *sb = mnt->mnt_sb; -+ int ret = 0; -+ char *tmp_page; -+ char *path; -+ int bindex, bstart, bend; -+ int perms; -+ -+ /* to prevent a silly lockdep warning with namespace_sem */ -+ lockdep_off(); -+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD); -+ unionfs_lock_dentry(sb->s_root, UNIONFS_DMUTEX_CHILD); -+ -+ tmp_page = (char *) __get_free_page(GFP_KERNEL); -+ if (unlikely(!tmp_page)) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ bstart = sbstart(sb); -+ bend = sbend(sb); -+ -+ seq_printf(m, ",dirs="); -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ struct path p; -+ p.dentry = unionfs_lower_dentry_idx(sb->s_root, bindex); -+ p.mnt = unionfs_lower_mnt_idx(sb->s_root, bindex); -+ path = d_path(&p, tmp_page, PAGE_SIZE); -+ if (IS_ERR(path)) { -+ ret = PTR_ERR(path); -+ goto out; -+ } -+ -+ perms = branchperms(sb, bindex); -+ -+ seq_printf(m, "%s=%s", path, -+ perms & MAY_WRITE ? "rw" : "ro"); -+ if (bindex != bend) -+ seq_printf(m, ":"); -+ } -+ -+out: -+ free_page((unsigned long) tmp_page); -+ -+ unionfs_unlock_dentry(sb->s_root); -+ unionfs_read_unlock(sb); -+ lockdep_on(); -+ -+ return ret; -+} -+ -+struct super_operations unionfs_sops = { -+ .put_super = unionfs_put_super, -+ .statfs = unionfs_statfs, -+ .remount_fs = unionfs_remount_fs, -+ .evict_inode = unionfs_evict_inode, -+ .umount_begin = unionfs_umount_begin, -+ .show_options = unionfs_show_options, -+ .write_inode = unionfs_write_inode, -+ .alloc_inode = unionfs_alloc_inode, -+ .destroy_inode = unionfs_destroy_inode, -+}; -diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h -new file mode 100644 -index 0000000..1821705 ---- /dev/null -+++ b/fs/unionfs/union.h -@@ -0,0 +1,679 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 _UNION_H_ -+#define _UNION_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+/* the file system name */ -+#define UNIONFS_NAME "unionfs" -+ -+/* unionfs root inode number */ -+#define UNIONFS_ROOT_INO 1 -+ -+/* number of times we try to get a unique temporary file name */ -+#define GET_TMPNAM_MAX_RETRY 5 -+ -+/* maximum number of branches we support, to avoid memory blowup */ -+#define UNIONFS_MAX_BRANCHES 128 -+ -+/* minimum time (seconds) required for time-based cache-coherency */ -+#define UNIONFS_MIN_CC_TIME 3 -+ -+/* Operations vectors defined in specific files. */ -+extern struct file_operations unionfs_main_fops; -+extern struct file_operations unionfs_dir_fops; -+extern struct inode_operations unionfs_main_iops; -+extern struct inode_operations unionfs_dir_iops; -+extern struct inode_operations unionfs_symlink_iops; -+extern struct super_operations unionfs_sops; -+extern struct dentry_operations unionfs_dops; -+extern struct address_space_operations unionfs_aops, unionfs_dummy_aops; -+extern struct vm_operations_struct unionfs_vm_ops; -+ -+/* How long should an entry be allowed to persist */ -+#define RDCACHE_JIFFIES (5*HZ) -+ -+/* compatibility with Real-Time patches */ -+#ifdef CONFIG_PREEMPT_RT -+# define unionfs_rw_semaphore compat_rw_semaphore -+#else /* not CONFIG_PREEMPT_RT */ -+# define unionfs_rw_semaphore rw_semaphore -+#endif /* not CONFIG_PREEMPT_RT */ -+ -+/* file private data. */ -+struct unionfs_file_info { -+ int bstart; -+ int bend; -+ atomic_t generation; -+ -+ struct unionfs_dir_state *rdstate; -+ struct file **lower_files; -+ int *saved_branch_ids; /* IDs of branches when file was opened */ -+ const struct vm_operations_struct *lower_vm_ops; -+ bool wrote_to_file; /* for delayed copyup */ -+}; -+ -+/* unionfs inode data in memory */ -+struct unionfs_inode_info { -+ int bstart; -+ int bend; -+ atomic_t generation; -+ /* Stuff for readdir over NFS. */ -+ spinlock_t rdlock; -+ struct list_head readdircache; -+ int rdcount; -+ int hashsize; -+ int cookie; -+ -+ /* The lower inodes */ -+ struct inode **lower_inodes; -+ -+ struct inode vfs_inode; -+}; -+ -+/* unionfs dentry data in memory */ -+struct unionfs_dentry_info { -+ /* -+ * The semaphore is used to lock the dentry as soon as we get into a -+ * unionfs function from the VFS. Our lock ordering is that children -+ * go before their parents. -+ */ -+ struct mutex lock; -+ int bstart; -+ int bend; -+ int bopaque; -+ int bcount; -+ atomic_t generation; -+ struct path *lower_paths; -+}; -+ -+/* These are the pointers to our various objects. */ -+struct unionfs_data { -+ struct super_block *sb; /* lower super_block */ -+ atomic_t open_files; /* number of open files on branch */ -+ int branchperms; -+ int branch_id; /* unique branch ID at re/mount time */ -+}; -+ -+/* unionfs super-block data in memory */ -+struct unionfs_sb_info { -+ int bend; -+ -+ atomic_t generation; -+ -+ /* -+ * This rwsem is used to make sure that a branch management -+ * operation... -+ * 1) will not begin before all currently in-flight operations -+ * complete. -+ * 2) any new operations do not execute until the currently -+ * running branch management operation completes. -+ * -+ * The write_lock_owner records the PID of the task which grabbed -+ * the rw_sem for writing. If the same task also tries to grab the -+ * read lock, we allow it. This prevents a self-deadlock when -+ * branch-management is used on a pivot_root'ed union, because we -+ * have to ->lookup paths which belong to the same union. -+ */ -+ struct unionfs_rw_semaphore rwsem; -+ pid_t write_lock_owner; /* PID of rw_sem owner (write lock) */ -+ int high_branch_id; /* last unique branch ID given */ -+ char *dev_name; /* to identify different unions in pr_debug */ -+ struct unionfs_data *data; -+}; -+ -+/* -+ * structure for making the linked list of entries by readdir on left branch -+ * to compare with entries on right branch -+ */ -+struct filldir_node { -+ struct list_head file_list; /* list for directory entries */ -+ char *name; /* name entry */ -+ int hash; /* name hash */ -+ int namelen; /* name len since name is not 0 terminated */ -+ -+ /* -+ * we can check for duplicate whiteouts and files in the same branch -+ * in order to return -EIO. -+ */ -+ int bindex; -+ -+ /* is this a whiteout entry? */ -+ int whiteout; -+ -+ /* Inline name, so we don't need to separately kmalloc small ones */ -+ char iname[DNAME_INLINE_LEN]; -+}; -+ -+/* Directory hash table. */ -+struct unionfs_dir_state { -+ unsigned int cookie; /* the cookie, based off of rdversion */ -+ unsigned int offset; /* The entry we have returned. */ -+ int bindex; -+ loff_t dirpos; /* offset within the lower level directory */ -+ int size; /* How big is the hash table? */ -+ int hashentries; /* How many entries have been inserted? */ -+ unsigned long access; -+ -+ /* This cache list is used when the inode keeps us around. */ -+ struct list_head cache; -+ struct list_head list[0]; -+}; -+ -+/* externs needed for fanout.h or sioq.h */ -+extern int unionfs_get_nlinks(const struct inode *inode); -+extern void unionfs_copy_attr_times(struct inode *upper); -+extern void unionfs_copy_attr_all(struct inode *dest, const struct inode *src); -+ -+/* include miscellaneous macros */ -+#include "fanout.h" -+#include "sioq.h" -+ -+/* externs for cache creation/deletion routines */ -+extern void unionfs_destroy_filldir_cache(void); -+extern int unionfs_init_filldir_cache(void); -+extern int unionfs_init_inode_cache(void); -+extern void unionfs_destroy_inode_cache(void); -+extern int unionfs_init_dentry_cache(void); -+extern void unionfs_destroy_dentry_cache(void); -+ -+/* Initialize and free readdir-specific state. */ -+extern int init_rdstate(struct file *file); -+extern struct unionfs_dir_state *alloc_rdstate(struct inode *inode, -+ int bindex); -+extern struct unionfs_dir_state *find_rdstate(struct inode *inode, -+ loff_t fpos); -+extern void free_rdstate(struct unionfs_dir_state *state); -+extern int add_filldir_node(struct unionfs_dir_state *rdstate, -+ const char *name, int namelen, int bindex, -+ int whiteout); -+extern struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate, -+ const char *name, int namelen, -+ int is_whiteout); -+ -+extern struct dentry **alloc_new_dentries(int objs); -+extern struct unionfs_data *alloc_new_data(int objs); -+ -+/* We can only use 32-bits of offset for rdstate --- blech! */ -+#define DIREOF (0xfffff) -+#define RDOFFBITS 20 /* This is the number of bits in DIREOF. */ -+#define MAXRDCOOKIE (0xfff) -+/* Turn an rdstate into an offset. */ -+static inline off_t rdstate2offset(struct unionfs_dir_state *buf) -+{ -+ off_t tmp; -+ -+ tmp = ((buf->cookie & MAXRDCOOKIE) << RDOFFBITS) -+ | (buf->offset & DIREOF); -+ return tmp; -+} -+ -+/* Macros for locking a super_block. */ -+enum unionfs_super_lock_class { -+ UNIONFS_SMUTEX_NORMAL, -+ UNIONFS_SMUTEX_PARENT, /* when locking on behalf of file */ -+ UNIONFS_SMUTEX_CHILD, /* when locking on behalf of dentry */ -+}; -+static inline void unionfs_read_lock(struct super_block *sb, int subclass) -+{ -+ if (UNIONFS_SB(sb)->write_lock_owner && -+ UNIONFS_SB(sb)->write_lock_owner == current->pid) -+ return; -+ down_read_nested(&UNIONFS_SB(sb)->rwsem, subclass); -+} -+static inline void unionfs_read_unlock(struct super_block *sb) -+{ -+ if (UNIONFS_SB(sb)->write_lock_owner && -+ UNIONFS_SB(sb)->write_lock_owner == current->pid) -+ return; -+ up_read(&UNIONFS_SB(sb)->rwsem); -+} -+static inline void unionfs_write_lock(struct super_block *sb) -+{ -+ down_write(&UNIONFS_SB(sb)->rwsem); -+ UNIONFS_SB(sb)->write_lock_owner = current->pid; -+} -+static inline void unionfs_write_unlock(struct super_block *sb) -+{ -+ up_write(&UNIONFS_SB(sb)->rwsem); -+ UNIONFS_SB(sb)->write_lock_owner = 0; -+} -+ -+static inline void unionfs_double_lock_dentry(struct dentry *d1, -+ struct dentry *d2) -+{ -+ BUG_ON(d1 == d2); -+ if (d1 < d2) { -+ unionfs_lock_dentry(d1, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(d2, UNIONFS_DMUTEX_CHILD); -+ } else { -+ unionfs_lock_dentry(d2, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(d1, UNIONFS_DMUTEX_CHILD); -+ } -+} -+ -+static inline void unionfs_double_unlock_dentry(struct dentry *d1, -+ struct dentry *d2) -+{ -+ BUG_ON(d1 == d2); -+ if (d1 < d2) { /* unlock in reverse order than double_lock_dentry */ -+ unionfs_unlock_dentry(d1); -+ unionfs_unlock_dentry(d2); -+ } else { -+ unionfs_unlock_dentry(d2); -+ unionfs_unlock_dentry(d1); -+ } -+} -+ -+static inline void unionfs_double_lock_parents(struct dentry *p1, -+ struct dentry *p2) -+{ -+ if (p1 == p2) { -+ unionfs_lock_dentry(p1, UNIONFS_DMUTEX_REVAL_PARENT); -+ return; -+ } -+ if (p1 < p2) { -+ unionfs_lock_dentry(p1, UNIONFS_DMUTEX_REVAL_PARENT); -+ unionfs_lock_dentry(p2, UNIONFS_DMUTEX_REVAL_CHILD); -+ } else { -+ unionfs_lock_dentry(p2, UNIONFS_DMUTEX_REVAL_PARENT); -+ unionfs_lock_dentry(p1, UNIONFS_DMUTEX_REVAL_CHILD); -+ } -+} -+ -+static inline void unionfs_double_unlock_parents(struct dentry *p1, -+ struct dentry *p2) -+{ -+ if (p1 == p2) { -+ unionfs_unlock_dentry(p1); -+ return; -+ } -+ if (p1 < p2) { /* unlock in reverse order of double_lock_parents */ -+ unionfs_unlock_dentry(p1); -+ unionfs_unlock_dentry(p2); -+ } else { -+ unionfs_unlock_dentry(p2); -+ unionfs_unlock_dentry(p1); -+ } -+} -+ -+extern int new_dentry_private_data(struct dentry *dentry, int subclass); -+extern int realloc_dentry_private_data(struct dentry *dentry); -+extern void free_dentry_private_data(struct dentry *dentry); -+extern void update_bstart(struct dentry *dentry); -+extern int init_lower_nd(struct nameidata *nd, unsigned int flags); -+extern void release_lower_nd(struct nameidata *nd, int err); -+ -+/* -+ * EXTERNALS: -+ */ -+ -+/* replicates the directory structure up to given dentry in given branch */ -+extern struct dentry *create_parents(struct inode *dir, struct dentry *dentry, -+ const char *name, int bindex); -+ -+/* partial lookup */ -+extern int unionfs_partial_lookup(struct dentry *dentry, -+ struct dentry *parent); -+extern struct dentry *unionfs_lookup_full(struct dentry *dentry, -+ struct dentry *parent, -+ int lookupmode); -+ -+/* copies a file from dbstart to newbindex branch */ -+extern int copyup_file(struct inode *dir, struct file *file, int bstart, -+ int newbindex, loff_t size); -+extern int copyup_named_file(struct inode *dir, struct file *file, -+ char *name, int bstart, int new_bindex, -+ loff_t len); -+/* copies a dentry from dbstart to newbindex branch */ -+extern int copyup_dentry(struct inode *dir, struct dentry *dentry, -+ int bstart, int new_bindex, const char *name, -+ int namelen, struct file **copyup_file, loff_t len); -+/* helper functions for post-copyup actions */ -+extern void unionfs_postcopyup_setmnt(struct dentry *dentry); -+extern void unionfs_postcopyup_release(struct dentry *dentry); -+ -+/* Is this directory empty: 0 if it is empty, -ENOTEMPTY if not. */ -+extern int check_empty(struct dentry *dentry, struct dentry *parent, -+ struct unionfs_dir_state **namelist); -+/* whiteout and opaque directory helpers */ -+extern char *alloc_whname(const char *name, int len); -+extern bool is_whiteout_name(char **namep, int *namelenp); -+extern bool is_validname(const char *name); -+extern struct dentry *lookup_whiteout(const char *name, -+ struct dentry *lower_parent); -+extern struct dentry *find_first_whiteout(struct dentry *dentry); -+extern int unlink_whiteout(struct dentry *wh_dentry); -+extern int check_unlink_whiteout(struct dentry *dentry, -+ struct dentry *lower_dentry, int bindex); -+extern int create_whiteout(struct dentry *dentry, int start); -+extern int delete_whiteouts(struct dentry *dentry, int bindex, -+ struct unionfs_dir_state *namelist); -+extern int is_opaque_dir(struct dentry *dentry, int bindex); -+extern int make_dir_opaque(struct dentry *dir, int bindex); -+extern void unionfs_set_max_namelen(long *namelen); -+ -+extern void unionfs_reinterpose(struct dentry *this_dentry); -+extern struct super_block *unionfs_duplicate_super(struct super_block *sb); -+ -+/* Locking functions. */ -+extern int unionfs_setlk(struct file *file, int cmd, struct file_lock *fl); -+extern int unionfs_getlk(struct file *file, struct file_lock *fl); -+ -+/* Common file operations. */ -+extern int unionfs_file_revalidate(struct file *file, struct dentry *parent, -+ bool willwrite); -+extern int unionfs_open(struct inode *inode, struct file *file); -+extern int unionfs_file_release(struct inode *inode, struct file *file); -+extern int unionfs_flush(struct file *file, fl_owner_t id); -+extern long unionfs_ioctl(struct file *file, unsigned int cmd, -+ unsigned long arg); -+extern int unionfs_fsync(struct file *file, int datasync); -+extern int unionfs_fasync(int fd, struct file *file, int flag); -+ -+/* Inode operations */ -+extern struct inode *unionfs_iget(struct super_block *sb, unsigned long ino); -+extern int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry); -+extern int unionfs_unlink(struct inode *dir, struct dentry *dentry); -+extern int unionfs_rmdir(struct inode *dir, struct dentry *dentry); -+ -+extern bool __unionfs_d_revalidate(struct dentry *dentry, -+ struct dentry *parent, bool willwrite); -+extern bool is_negative_lower(const struct dentry *dentry); -+extern bool is_newer_lower(const struct dentry *dentry); -+extern void purge_sb_data(struct super_block *sb); -+ -+/* The values for unionfs_interpose's flag. */ -+#define INTERPOSE_DEFAULT 0 -+#define INTERPOSE_LOOKUP 1 -+#define INTERPOSE_REVAL 2 -+#define INTERPOSE_REVAL_NEG 3 -+#define INTERPOSE_PARTIAL 4 -+ -+extern struct dentry *unionfs_interpose(struct dentry *this_dentry, -+ struct super_block *sb, int flag); -+ -+#ifdef CONFIG_UNION_FS_XATTR -+/* Extended attribute functions. */ -+extern void *unionfs_xattr_alloc(size_t size, size_t limit); -+static inline void unionfs_xattr_kfree(const void *p) -+{ -+ kfree(p); -+} -+extern ssize_t unionfs_getxattr(struct dentry *dentry, const char *name, -+ void *value, size_t size); -+extern int unionfs_removexattr(struct dentry *dentry, const char *name); -+extern ssize_t unionfs_listxattr(struct dentry *dentry, char *list, -+ size_t size); -+extern int unionfs_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags); -+#endif /* CONFIG_UNION_FS_XATTR */ -+ -+/* The root directory is unhashed, but isn't deleted. */ -+static inline int d_deleted(struct dentry *d) -+{ -+ return d_unhashed(d) && (d != d->d_sb->s_root); -+} -+ -+/* unionfs_permission, check if we should bypass error to facilitate copyup */ -+#define IS_COPYUP_ERR(err) ((err) == -EROFS) -+ -+/* unionfs_open, check if we need to copyup the file */ -+#define OPEN_WRITE_FLAGS (O_WRONLY | O_RDWR | O_APPEND) -+#define IS_WRITE_FLAG(flag) ((flag) & OPEN_WRITE_FLAGS) -+ -+static inline int branchperms(const struct super_block *sb, int index) -+{ -+ BUG_ON(index < 0); -+ return UNIONFS_SB(sb)->data[index].branchperms; -+} -+ -+static inline int set_branchperms(struct super_block *sb, int index, int perms) -+{ -+ BUG_ON(index < 0); -+ UNIONFS_SB(sb)->data[index].branchperms = perms; -+ return perms; -+} -+ -+/* check if readonly lower inode, but possibly unlinked (no inode->i_sb) */ -+static inline int __is_rdonly(const struct inode *inode) -+{ -+ /* if unlinked, can't be readonly (?) */ -+ if (!inode->i_sb) -+ return 0; -+ return IS_RDONLY(inode); -+ -+} -+/* Is this file on a read-only branch? */ -+static inline int is_robranch_super(const struct super_block *sb, int index) -+{ -+ int ret; -+ -+ ret = (!(branchperms(sb, index) & MAY_WRITE)) ? -EROFS : 0; -+ return ret; -+} -+ -+/* Is this file on a read-only branch? */ -+static inline int is_robranch_idx(const struct dentry *dentry, int index) -+{ -+ struct super_block *lower_sb; -+ -+ BUG_ON(index < 0); -+ -+ if (!(branchperms(dentry->d_sb, index) & MAY_WRITE)) -+ return -EROFS; -+ -+ lower_sb = unionfs_lower_super_idx(dentry->d_sb, index); -+ BUG_ON(lower_sb == NULL); -+ /* -+ * test sb flags directly, not IS_RDONLY(lower_inode) because the -+ * lower_dentry could be a negative. -+ */ -+ if (lower_sb->s_flags & MS_RDONLY) -+ return -EROFS; -+ -+ return 0; -+} -+ -+static inline int is_robranch(const struct dentry *dentry) -+{ -+ int index; -+ -+ index = UNIONFS_D(dentry)->bstart; -+ BUG_ON(index < 0); -+ -+ return is_robranch_idx(dentry, index); -+} -+ -+/* -+ * EXTERNALS: -+ */ -+extern int check_branch(const struct path *path); -+extern int parse_branch_mode(const char *name, int *perms); -+ -+/* locking helpers */ -+static inline struct dentry *lock_parent(struct dentry *dentry) -+{ -+ struct dentry *dir = dget_parent(dentry); -+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); -+ return dir; -+} -+static inline struct dentry *lock_parent_wh(struct dentry *dentry) -+{ -+ struct dentry *dir = dget_parent(dentry); -+ -+ mutex_lock_nested(&dir->d_inode->i_mutex, UNIONFS_DMUTEX_WHITEOUT); -+ return dir; -+} -+ -+static inline void unlock_dir(struct dentry *dir) -+{ -+ mutex_unlock(&dir->d_inode->i_mutex); -+ dput(dir); -+} -+ -+/* lock base inode mutex before calling lookup_one_len */ -+static inline struct dentry *lookup_lck_len(const char *name, -+ struct dentry *base, int len) -+{ -+ struct dentry *d; -+ struct nameidata lower_nd; -+ int err; -+ -+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN); -+ if (unlikely(err < 0)) { -+ d = ERR_PTR(err); -+ goto out; -+ } -+ mutex_lock(&base->d_inode->i_mutex); -+ d = lookup_one_len_nd(name, base, len, &lower_nd); -+ release_lower_nd(&lower_nd, err); -+ mutex_unlock(&base->d_inode->i_mutex); -+out: -+ return d; -+} -+ -+static inline struct vfsmount *unionfs_mntget(struct dentry *dentry, -+ int bindex) -+{ -+ struct vfsmount *mnt; -+ -+ BUG_ON(!dentry || bindex < 0); -+ -+ mnt = mntget(unionfs_lower_mnt_idx(dentry, bindex)); -+#ifdef CONFIG_UNION_FS_DEBUG -+ if (!mnt) -+ pr_debug("unionfs: mntget: mnt=%p bindex=%d\n", -+ mnt, bindex); -+#endif /* CONFIG_UNION_FS_DEBUG */ -+ -+ return mnt; -+} -+ -+static inline void unionfs_mntput(struct dentry *dentry, int bindex) -+{ -+ struct vfsmount *mnt; -+ -+ if (!dentry && bindex < 0) -+ return; -+ BUG_ON(!dentry || bindex < 0); -+ -+ mnt = unionfs_lower_mnt_idx(dentry, bindex); -+#ifdef CONFIG_UNION_FS_DEBUG -+ /* -+ * Directories can have NULL lower objects in between start/end, but -+ * NOT if at the start/end range. We cannot verify that this dentry -+ * is a type=DIR, because it may already be a negative dentry. But -+ * if dbstart is greater than dbend, we know that this couldn't have -+ * been a regular file: it had to have been a directory. -+ */ -+ if (!mnt && !(bindex > dbstart(dentry) && bindex < dbend(dentry))) -+ pr_debug("unionfs: mntput: mnt=%p bindex=%d\n", mnt, bindex); -+#endif /* CONFIG_UNION_FS_DEBUG */ -+ mntput(mnt); -+} -+ -+#ifdef CONFIG_UNION_FS_DEBUG -+ -+/* useful for tracking code reachability */ -+#define UDBG pr_debug("DBG:%s:%s:%d\n", __FILE__, __func__, __LINE__) -+ -+#define unionfs_check_inode(i) __unionfs_check_inode((i), \ -+ __FILE__, __func__, __LINE__) -+#define unionfs_check_dentry(d) __unionfs_check_dentry((d), \ -+ __FILE__, __func__, __LINE__) -+#define unionfs_check_file(f) __unionfs_check_file((f), \ -+ __FILE__, __func__, __LINE__) -+#define unionfs_check_nd(n) __unionfs_check_nd((n), \ -+ __FILE__, __func__, __LINE__) -+#define show_branch_counts(sb) __show_branch_counts((sb), \ -+ __FILE__, __func__, __LINE__) -+#define show_inode_times(i) __show_inode_times((i), \ -+ __FILE__, __func__, __LINE__) -+#define show_dinode_times(d) __show_dinode_times((d), \ -+ __FILE__, __func__, __LINE__) -+#define show_inode_counts(i) __show_inode_counts((i), \ -+ __FILE__, __func__, __LINE__) -+ -+extern void __unionfs_check_inode(const struct inode *inode, const char *fname, -+ const char *fxn, int line); -+extern void __unionfs_check_dentry(const struct dentry *dentry, -+ const char *fname, const char *fxn, -+ int line); -+extern void __unionfs_check_file(const struct file *file, -+ const char *fname, const char *fxn, int line); -+extern void __unionfs_check_nd(const struct nameidata *nd, -+ const char *fname, const char *fxn, int line); -+extern void __show_branch_counts(const struct super_block *sb, -+ const char *file, const char *fxn, int line); -+extern void __show_inode_times(const struct inode *inode, -+ const char *file, const char *fxn, int line); -+extern void __show_dinode_times(const struct dentry *dentry, -+ const char *file, const char *fxn, int line); -+extern void __show_inode_counts(const struct inode *inode, -+ const char *file, const char *fxn, int line); -+ -+#else /* not CONFIG_UNION_FS_DEBUG */ -+ -+/* we leave useful hooks for these check functions throughout the code */ -+#define unionfs_check_inode(i) do { } while (0) -+#define unionfs_check_dentry(d) do { } while (0) -+#define unionfs_check_file(f) do { } while (0) -+#define unionfs_check_nd(n) do { } while (0) -+#define show_branch_counts(sb) do { } while (0) -+#define show_inode_times(i) do { } while (0) -+#define show_dinode_times(d) do { } while (0) -+#define show_inode_counts(i) do { } while (0) -+ -+#endif /* not CONFIG_UNION_FS_DEBUG */ -+ -+#endif /* not _UNION_H_ */ -diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c -new file mode 100644 -index 0000000..bf447bb ---- /dev/null -+++ b/fs/unionfs/unlink.c -@@ -0,0 +1,278 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * Helper function for Unionfs's unlink operation. -+ * -+ * The main goal of this function is to optimize the unlinking of non-dir -+ * objects in unionfs by deleting all possible lower inode objects from the -+ * underlying branches having same dentry name as the non-dir dentry on -+ * which this unlink operation is called. This way we delete as many lower -+ * inodes as possible, and save space. Whiteouts need to be created in -+ * branch0 only if unlinking fails on any of the lower branch other than -+ * branch0, or if a lower branch is marked read-only. -+ * -+ * Also, while unlinking a file, if we encounter any dir type entry in any -+ * intermediate branch, then we remove the directory by calling vfs_rmdir. -+ * The following special cases are also handled: -+ -+ * (1) If an error occurs in branch0 during vfs_unlink, then we return -+ * appropriate error. -+ * -+ * (2) If we get an error during unlink in any of other lower branch other -+ * than branch0, then we create a whiteout in branch0. -+ * -+ * (3) If a whiteout already exists in any intermediate branch, we delete -+ * all possible inodes only up to that branch (this is an "opaqueness" -+ * as as per Documentation/filesystems/unionfs/concepts.txt). -+ * -+ */ -+static int unionfs_unlink_whiteout(struct inode *dir, struct dentry *dentry, -+ struct dentry *parent) -+{ -+ struct dentry *lower_dentry; -+ struct dentry *lower_dir_dentry; -+ int bindex; -+ int err = 0; -+ -+ err = unionfs_partial_lookup(dentry, parent); -+ if (err) -+ goto out; -+ -+ /* trying to unlink all possible valid instances */ -+ for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ if (!lower_dentry || !lower_dentry->d_inode) -+ continue; -+ -+ lower_dir_dentry = lock_parent(lower_dentry); -+ -+ /* avoid destroying the lower inode if the object is in use */ -+ dget(lower_dentry); -+ err = is_robranch_super(dentry->d_sb, bindex); -+ if (!err) { -+ /* see Documentation/filesystems/unionfs/issues.txt */ -+ lockdep_off(); -+ if (!S_ISDIR(lower_dentry->d_inode->i_mode)) -+ err = vfs_unlink(lower_dir_dentry->d_inode, -+ lower_dentry); -+ else -+ err = vfs_rmdir(lower_dir_dentry->d_inode, -+ lower_dentry); -+ lockdep_on(); -+ } -+ -+ /* if lower object deletion succeeds, update inode's times */ -+ if (!err) -+ unionfs_copy_attr_times(dentry->d_inode); -+ dput(lower_dentry); -+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); -+ unlock_dir(lower_dir_dentry); -+ -+ if (err) -+ break; -+ } -+ -+ /* -+ * Create the whiteout in branch 0 (highest priority) only if (a) -+ * there was an error in any intermediate branch other than branch 0 -+ * due to failure of vfs_unlink/vfs_rmdir or (b) a branch marked or -+ * mounted read-only. -+ */ -+ if (err) { -+ if ((bindex == 0) || -+ ((bindex == dbstart(dentry)) && -+ (!IS_COPYUP_ERR(err)))) -+ goto out; -+ else { -+ if (!IS_COPYUP_ERR(err)) -+ pr_debug("unionfs: lower object deletion " -+ "failed in branch:%d\n", bindex); -+ err = create_whiteout(dentry, sbstart(dentry->d_sb)); -+ } -+ } -+ -+out: -+ if (!err) -+ inode_dec_link_count(dentry->d_inode); -+ -+ /* We don't want to leave negative leftover dentries for revalidate. */ -+ if (!err && (dbopaque(dentry) != -1)) -+ update_bstart(dentry); -+ -+ return err; -+} -+ -+int unionfs_unlink(struct inode *dir, struct dentry *dentry) -+{ -+ int err = 0; -+ struct inode *inode = dentry->d_inode; -+ struct dentry *parent; -+ int valid; -+ -+ BUG_ON(S_ISDIR(inode->i_mode)); -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ unionfs_check_dentry(dentry); -+ -+ err = unionfs_unlink_whiteout(dir, dentry, parent); -+ /* call d_drop so the system "forgets" about us */ -+ if (!err) { -+ unionfs_postcopyup_release(dentry); -+ unionfs_postcopyup_setmnt(parent); -+ if (inode->i_nlink == 0) /* drop lower inodes */ -+ iput_lowers_all(inode, false); -+ d_drop(dentry); -+ /* -+ * if unlink/whiteout succeeded, parent dir mtime has -+ * changed -+ */ -+ unionfs_copy_attr_times(dir); -+ } -+ -+out: -+ if (!err) { -+ unionfs_check_dentry(dentry); -+ unionfs_check_inode(dir); -+ } -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+static int unionfs_rmdir_first(struct inode *dir, struct dentry *dentry, -+ struct unionfs_dir_state *namelist) -+{ -+ int err; -+ struct dentry *lower_dentry; -+ struct dentry *lower_dir_dentry = NULL; -+ -+ /* Here we need to remove whiteout entries. */ -+ err = delete_whiteouts(dentry, dbstart(dentry), namelist); -+ if (err) -+ goto out; -+ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ -+ lower_dir_dentry = lock_parent(lower_dentry); -+ -+ /* avoid destroying the lower inode if the file is in use */ -+ dget(lower_dentry); -+ err = is_robranch(dentry); -+ if (!err) -+ err = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); -+ dput(lower_dentry); -+ -+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); -+ /* propagate number of hard-links */ -+ dentry->d_inode->i_nlink = unionfs_get_nlinks(dentry->d_inode); -+ -+out: -+ if (lower_dir_dentry) -+ unlock_dir(lower_dir_dentry); -+ return err; -+} -+ -+int unionfs_rmdir(struct inode *dir, struct dentry *dentry) -+{ -+ int err = 0; -+ struct unionfs_dir_state *namelist = NULL; -+ struct dentry *parent; -+ int dstart, dend; -+ bool valid; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ unionfs_check_dentry(dentry); -+ -+ /* check if this unionfs directory is empty or not */ -+ err = check_empty(dentry, parent, &namelist); -+ if (err) -+ goto out; -+ -+ err = unionfs_rmdir_first(dir, dentry, namelist); -+ dstart = dbstart(dentry); -+ dend = dbend(dentry); -+ /* -+ * We create a whiteout for the directory if there was an error to -+ * rmdir the first directory entry in the union. Otherwise, we -+ * create a whiteout only if there is no chance that a lower -+ * priority branch might also have the same named directory. IOW, -+ * if there is not another same-named directory at a lower priority -+ * branch, then we don't need to create a whiteout for it. -+ */ -+ if (!err) { -+ if (dstart < dend) -+ err = create_whiteout(dentry, dstart); -+ } else { -+ int new_err; -+ -+ if (dstart == 0) -+ goto out; -+ -+ /* exit if the error returned was NOT -EROFS */ -+ if (!IS_COPYUP_ERR(err)) -+ goto out; -+ -+ new_err = create_whiteout(dentry, dstart - 1); -+ if (new_err != -EEXIST) -+ err = new_err; -+ } -+ -+out: -+ /* -+ * Drop references to lower dentry/inode so storage space for them -+ * can be reclaimed. Then, call d_drop so the system "forgets" -+ * about us. -+ */ -+ if (!err) { -+ iput_lowers_all(dentry->d_inode, false); -+ dput(unionfs_lower_dentry_idx(dentry, dstart)); -+ unionfs_set_lower_dentry_idx(dentry, dstart, NULL); -+ d_drop(dentry); -+ /* update our lower vfsmnts, in case a copyup took place */ -+ unionfs_postcopyup_setmnt(dentry); -+ unionfs_check_dentry(dentry); -+ unionfs_check_inode(dir); -+ } -+ -+ if (namelist) -+ free_rdstate(namelist); -+ -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -diff --git a/fs/unionfs/whiteout.c b/fs/unionfs/whiteout.c -new file mode 100644 -index 0000000..582cef2 ---- /dev/null -+++ b/fs/unionfs/whiteout.c -@@ -0,0 +1,601 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* -+ * whiteout and opaque directory helpers -+ */ -+ -+/* What do we use for whiteouts. */ -+#define UNIONFS_WHPFX ".wh." -+#define UNIONFS_WHLEN 4 -+/* -+ * If a directory contains this file, then it is opaque. We start with the -+ * .wh. flag so that it is blocked by lookup. -+ */ -+#define UNIONFS_DIR_OPAQUE_NAME "__dir_opaque" -+#define UNIONFS_DIR_OPAQUE UNIONFS_WHPFX UNIONFS_DIR_OPAQUE_NAME -+ -+/* construct whiteout filename */ -+char *alloc_whname(const char *name, int len) -+{ -+ char *buf; -+ -+ buf = kmalloc(len + UNIONFS_WHLEN + 1, GFP_KERNEL); -+ if (unlikely(!buf)) -+ return ERR_PTR(-ENOMEM); -+ -+ strcpy(buf, UNIONFS_WHPFX); -+ strlcat(buf, name, len + UNIONFS_WHLEN + 1); -+ -+ return buf; -+} -+ -+/* -+ * XXX: this can be inline or CPP macro, but is here to keep all whiteout -+ * code in one place. -+ */ -+void unionfs_set_max_namelen(long *namelen) -+{ -+ *namelen -= UNIONFS_WHLEN; -+} -+ -+/* check if @namep is a whiteout, update @namep and @namelenp accordingly */ -+bool is_whiteout_name(char **namep, int *namelenp) -+{ -+ if (*namelenp > UNIONFS_WHLEN && -+ !strncmp(*namep, UNIONFS_WHPFX, UNIONFS_WHLEN)) { -+ *namep += UNIONFS_WHLEN; -+ *namelenp -= UNIONFS_WHLEN; -+ return true; -+ } -+ return false; -+} -+ -+/* is the filename valid == !(whiteout for a file or opaque dir marker) */ -+bool is_validname(const char *name) -+{ -+ if (!strncmp(name, UNIONFS_WHPFX, UNIONFS_WHLEN)) -+ return false; -+ if (!strncmp(name, UNIONFS_DIR_OPAQUE_NAME, -+ sizeof(UNIONFS_DIR_OPAQUE_NAME) - 1)) -+ return false; -+ return true; -+} -+ -+/* -+ * Look for a whiteout @name in @lower_parent directory. If error, return -+ * ERR_PTR. Caller must dput() the returned dentry if not an error. -+ * -+ * XXX: some callers can reuse the whname allocated buffer to avoid repeated -+ * free then re-malloc calls. Need to provide a different API for those -+ * callers. -+ */ -+struct dentry *lookup_whiteout(const char *name, struct dentry *lower_parent) -+{ -+ char *whname = NULL; -+ int err = 0, namelen; -+ struct dentry *wh_dentry = NULL; -+ -+ namelen = strlen(name); -+ whname = alloc_whname(name, namelen); -+ if (unlikely(IS_ERR(whname))) { -+ err = PTR_ERR(whname); -+ goto out; -+ } -+ -+ /* check if whiteout exists in this branch: lookup .wh.foo */ -+ wh_dentry = lookup_lck_len(whname, lower_parent, strlen(whname)); -+ if (IS_ERR(wh_dentry)) { -+ err = PTR_ERR(wh_dentry); -+ goto out; -+ } -+ -+ /* check if negative dentry (ENOENT) */ -+ if (!wh_dentry->d_inode) -+ goto out; -+ -+ /* whiteout found: check if valid type */ -+ if (!S_ISREG(wh_dentry->d_inode->i_mode)) { -+ printk(KERN_ERR "unionfs: invalid whiteout %s entry type %d\n", -+ whname, wh_dentry->d_inode->i_mode); -+ dput(wh_dentry); -+ err = -EIO; -+ goto out; -+ } -+ -+out: -+ kfree(whname); -+ if (err) -+ wh_dentry = ERR_PTR(err); -+ return wh_dentry; -+} -+ -+/* find and return first whiteout in parent directory, else ENOENT */ -+struct dentry *find_first_whiteout(struct dentry *dentry) -+{ -+ int bindex, bstart, bend; -+ struct dentry *parent, *lower_parent, *wh_dentry; -+ -+ parent = dget_parent(dentry); -+ -+ bstart = dbstart(parent); -+ bend = dbend(parent); -+ wh_dentry = ERR_PTR(-ENOENT); -+ -+ for (bindex = bstart; bindex <= bend; bindex++) { -+ lower_parent = unionfs_lower_dentry_idx(parent, bindex); -+ if (!lower_parent) -+ continue; -+ wh_dentry = lookup_whiteout(dentry->d_name.name, lower_parent); -+ if (IS_ERR(wh_dentry)) -+ continue; -+ if (wh_dentry->d_inode) -+ break; -+ dput(wh_dentry); -+ wh_dentry = ERR_PTR(-ENOENT); -+ } -+ -+ dput(parent); -+ -+ return wh_dentry; -+} -+ -+/* -+ * Unlink a whiteout dentry. Returns 0 or -errno. Caller must hold and -+ * release dentry reference. -+ */ -+int unlink_whiteout(struct dentry *wh_dentry) -+{ -+ int err; -+ struct dentry *lower_dir_dentry; -+ -+ /* dget and lock parent dentry */ -+ lower_dir_dentry = lock_parent_wh(wh_dentry); -+ -+ /* see Documentation/filesystems/unionfs/issues.txt */ -+ lockdep_off(); -+ err = vfs_unlink(lower_dir_dentry->d_inode, wh_dentry); -+ lockdep_on(); -+ unlock_dir(lower_dir_dentry); -+ -+ /* -+ * Whiteouts are special files and should be deleted no matter what -+ * (as if they never existed), in order to allow this create -+ * operation to succeed. This is especially important in sticky -+ * directories: a whiteout may have been created by one user, but -+ * the newly created file may be created by another user. -+ * Therefore, in order to maintain Unix semantics, if the vfs_unlink -+ * above failed, then we have to try to directly unlink the -+ * whiteout. Note: in the ODF version of unionfs, whiteout are -+ * handled much more cleanly. -+ */ -+ if (err == -EPERM) { -+ struct inode *inode = lower_dir_dentry->d_inode; -+ err = inode->i_op->unlink(inode, wh_dentry); -+ } -+ if (err) -+ printk(KERN_ERR "unionfs: could not unlink whiteout %s, " -+ "err = %d\n", wh_dentry->d_name.name, err); -+ -+ return err; -+ -+} -+ -+/* -+ * Helper function when creating new objects (create, symlink, mknod, etc.). -+ * Checks to see if there's a whiteout in @lower_dentry's parent directory, -+ * whose name is taken from @dentry. Then tries to remove that whiteout, if -+ * found. If is a branch marked readonly, return -EROFS. -+ * If it finds both a regular file and a whiteout, delete whiteout (this -+ * should never happen). -+ * -+ * Return 0 if no whiteout was found. Return 1 if one was found and -+ * successfully removed. Therefore a value >= 0 tells the caller that -+ * @lower_dentry belongs to a good branch to create the new object in). -+ * Return -ERRNO if an error occurred during whiteout lookup or in trying to -+ * unlink the whiteout. -+ */ -+int check_unlink_whiteout(struct dentry *dentry, struct dentry *lower_dentry, -+ int bindex) -+{ -+ int err; -+ struct dentry *wh_dentry = NULL; -+ struct dentry *lower_dir_dentry = NULL; -+ -+ /* look for whiteout dentry first */ -+ lower_dir_dentry = dget_parent(lower_dentry); -+ wh_dentry = lookup_whiteout(dentry->d_name.name, lower_dir_dentry); -+ dput(lower_dir_dentry); -+ if (IS_ERR(wh_dentry)) { -+ err = PTR_ERR(wh_dentry); -+ goto out; -+ } -+ -+ if (!wh_dentry->d_inode) { /* no whiteout exists*/ -+ err = 0; -+ goto out_dput; -+ } -+ -+ /* check if regular file and whiteout were both found */ -+ if (unlikely(lower_dentry->d_inode)) -+ printk(KERN_WARNING "unionfs: removing whiteout; regular " -+ "file exists in directory %s (branch %d)\n", -+ lower_dir_dentry->d_name.name, bindex); -+ -+ /* check if branch is writeable */ -+ err = is_robranch_super(dentry->d_sb, bindex); -+ if (err) -+ goto out_dput; -+ -+ /* .wh.foo has been found, so let's unlink it */ -+ err = unlink_whiteout(wh_dentry); -+ if (!err) -+ err = 1; /* a whiteout was found and successfully removed */ -+out_dput: -+ dput(wh_dentry); -+out: -+ return err; -+} -+ -+/* -+ * Pass an unionfs dentry and an index. It will try to create a whiteout -+ * for the filename in dentry, and will try in branch 'index'. On error, -+ * it will proceed to a branch to the left. -+ */ -+int create_whiteout(struct dentry *dentry, int start) -+{ -+ int bstart, bend, bindex; -+ struct dentry *lower_dir_dentry; -+ struct dentry *lower_dentry; -+ struct dentry *lower_wh_dentry; -+ struct nameidata nd; -+ char *name = NULL; -+ int err = -EINVAL; -+ -+ verify_locked(dentry); -+ -+ bstart = dbstart(dentry); -+ bend = dbend(dentry); -+ -+ /* create dentry's whiteout equivalent */ -+ name = alloc_whname(dentry->d_name.name, dentry->d_name.len); -+ if (unlikely(IS_ERR(name))) { -+ err = PTR_ERR(name); -+ goto out; -+ } -+ -+ for (bindex = start; bindex >= 0; bindex--) { -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ -+ if (!lower_dentry) { -+ /* -+ * if lower dentry is not present, create the -+ * entire lower dentry directory structure and go -+ * ahead. Since we want to just create whiteout, we -+ * only want the parent dentry, and hence get rid of -+ * this dentry. -+ */ -+ lower_dentry = create_parents(dentry->d_inode, -+ dentry, -+ dentry->d_name.name, -+ bindex); -+ if (!lower_dentry || IS_ERR(lower_dentry)) { -+ int ret = PTR_ERR(lower_dentry); -+ if (!IS_COPYUP_ERR(ret)) -+ printk(KERN_ERR -+ "unionfs: create_parents for " -+ "whiteout failed: bindex=%d " -+ "err=%d\n", bindex, ret); -+ continue; -+ } -+ } -+ -+ lower_wh_dentry = -+ lookup_lck_len(name, lower_dentry->d_parent, -+ dentry->d_name.len + UNIONFS_WHLEN); -+ if (IS_ERR(lower_wh_dentry)) -+ continue; -+ -+ /* -+ * The whiteout already exists. This used to be impossible, -+ * but now is possible because of opaqueness. -+ */ -+ if (lower_wh_dentry->d_inode) { -+ dput(lower_wh_dentry); -+ err = 0; -+ goto out; -+ } -+ -+ err = init_lower_nd(&nd, LOOKUP_CREATE); -+ if (unlikely(err < 0)) -+ goto out; -+ lower_dir_dentry = lock_parent_wh(lower_wh_dentry); -+ err = is_robranch_super(dentry->d_sb, bindex); -+ if (!err) -+ err = vfs_create(lower_dir_dentry->d_inode, -+ lower_wh_dentry, -+ current_umask() & S_IRUGO, -+ &nd); -+ unlock_dir(lower_dir_dentry); -+ dput(lower_wh_dentry); -+ release_lower_nd(&nd, err); -+ -+ if (!err || !IS_COPYUP_ERR(err)) -+ break; -+ } -+ -+ /* set dbopaque so that lookup will not proceed after this branch */ -+ if (!err) -+ dbopaque(dentry) = bindex; -+ -+out: -+ kfree(name); -+ return err; -+} -+ -+/* -+ * Delete all of the whiteouts in a given directory for rmdir. -+ * -+ * lower directory inode should be locked -+ */ -+static int do_delete_whiteouts(struct dentry *dentry, int bindex, -+ struct unionfs_dir_state *namelist) -+{ -+ int err = 0; -+ struct dentry *lower_dir_dentry = NULL; -+ struct dentry *lower_dentry; -+ char *name = NULL, *p; -+ struct inode *lower_dir; -+ int i; -+ struct list_head *pos; -+ struct filldir_node *cursor; -+ -+ /* Find out lower parent dentry */ -+ lower_dir_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ BUG_ON(!S_ISDIR(lower_dir_dentry->d_inode->i_mode)); -+ lower_dir = lower_dir_dentry->d_inode; -+ BUG_ON(!S_ISDIR(lower_dir->i_mode)); -+ -+ err = -ENOMEM; -+ name = __getname(); -+ if (unlikely(!name)) -+ goto out; -+ strcpy(name, UNIONFS_WHPFX); -+ p = name + UNIONFS_WHLEN; -+ -+ err = 0; -+ for (i = 0; !err && i < namelist->size; i++) { -+ list_for_each(pos, &namelist->list[i]) { -+ cursor = -+ list_entry(pos, struct filldir_node, -+ file_list); -+ /* Only operate on whiteouts in this branch. */ -+ if (cursor->bindex != bindex) -+ continue; -+ if (!cursor->whiteout) -+ continue; -+ -+ strlcpy(p, cursor->name, PATH_MAX - UNIONFS_WHLEN); -+ lower_dentry = -+ lookup_lck_len(name, lower_dir_dentry, -+ cursor->namelen + -+ UNIONFS_WHLEN); -+ if (IS_ERR(lower_dentry)) { -+ err = PTR_ERR(lower_dentry); -+ break; -+ } -+ if (lower_dentry->d_inode) -+ err = vfs_unlink(lower_dir, lower_dentry); -+ dput(lower_dentry); -+ if (err) -+ break; -+ } -+ } -+ -+ __putname(name); -+ -+ /* After all of the removals, we should copy the attributes once. */ -+ fsstack_copy_attr_times(dentry->d_inode, lower_dir_dentry->d_inode); -+ -+out: -+ return err; -+} -+ -+ -+void __delete_whiteouts(struct work_struct *work) -+{ -+ struct sioq_args *args = container_of(work, struct sioq_args, work); -+ struct deletewh_args *d = &args->deletewh; -+ -+ args->err = do_delete_whiteouts(d->dentry, d->bindex, d->namelist); -+ complete(&args->comp); -+} -+ -+/* delete whiteouts in a dir (for rmdir operation) using sioq if necessary */ -+int delete_whiteouts(struct dentry *dentry, int bindex, -+ struct unionfs_dir_state *namelist) -+{ -+ int err; -+ struct super_block *sb; -+ struct dentry *lower_dir_dentry; -+ struct inode *lower_dir; -+ struct sioq_args args; -+ -+ sb = dentry->d_sb; -+ -+ BUG_ON(!S_ISDIR(dentry->d_inode->i_mode)); -+ BUG_ON(bindex < dbstart(dentry)); -+ BUG_ON(bindex > dbend(dentry)); -+ err = is_robranch_super(sb, bindex); -+ if (err) -+ goto out; -+ -+ lower_dir_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ BUG_ON(!S_ISDIR(lower_dir_dentry->d_inode->i_mode)); -+ lower_dir = lower_dir_dentry->d_inode; -+ BUG_ON(!S_ISDIR(lower_dir->i_mode)); -+ -+ if (!inode_permission(lower_dir, MAY_WRITE | MAY_EXEC)) { -+ err = do_delete_whiteouts(dentry, bindex, namelist); -+ } else { -+ args.deletewh.namelist = namelist; -+ args.deletewh.dentry = dentry; -+ args.deletewh.bindex = bindex; -+ run_sioq(__delete_whiteouts, &args); -+ err = args.err; -+ } -+ -+out: -+ return err; -+} -+ -+/**************************************************************************** -+ * Opaque directory helpers * -+ ****************************************************************************/ -+ -+/* -+ * is_opaque_dir: returns 0 if it is NOT an opaque dir, 1 if it is, and -+ * -errno if an error occurred trying to figure this out. -+ */ -+int is_opaque_dir(struct dentry *dentry, int bindex) -+{ -+ int err = 0; -+ struct dentry *lower_dentry; -+ struct dentry *wh_lower_dentry; -+ struct inode *lower_inode; -+ struct sioq_args args; -+ struct nameidata lower_nd; -+ -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ lower_inode = lower_dentry->d_inode; -+ -+ BUG_ON(!S_ISDIR(lower_inode->i_mode)); -+ -+ mutex_lock(&lower_inode->i_mutex); -+ -+ if (!inode_permission(lower_inode, MAY_EXEC)) { -+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN); -+ if (unlikely(err < 0)) { -+ mutex_unlock(&lower_inode->i_mutex); -+ goto out; -+ } -+ wh_lower_dentry = -+ lookup_one_len_nd(UNIONFS_DIR_OPAQUE, lower_dentry, -+ sizeof(UNIONFS_DIR_OPAQUE) - 1, -+ &lower_nd); -+ release_lower_nd(&lower_nd, err); -+ } else { -+ args.is_opaque.dentry = lower_dentry; -+ run_sioq(__is_opaque_dir, &args); -+ wh_lower_dentry = args.ret; -+ } -+ -+ mutex_unlock(&lower_inode->i_mutex); -+ -+ if (IS_ERR(wh_lower_dentry)) { -+ err = PTR_ERR(wh_lower_dentry); -+ goto out; -+ } -+ -+ /* This is an opaque dir iff wh_lower_dentry is positive */ -+ err = !!wh_lower_dentry->d_inode; -+ -+ dput(wh_lower_dentry); -+out: -+ return err; -+} -+ -+void __is_opaque_dir(struct work_struct *work) -+{ -+ struct sioq_args *args = container_of(work, struct sioq_args, work); -+ struct nameidata lower_nd; -+ int err; -+ -+ err = init_lower_nd(&lower_nd, LOOKUP_OPEN); -+ if (unlikely(err < 0)) -+ return; -+ args->ret = lookup_one_len_nd(UNIONFS_DIR_OPAQUE, -+ args->is_opaque.dentry, -+ sizeof(UNIONFS_DIR_OPAQUE) - 1, -+ &lower_nd); -+ release_lower_nd(&lower_nd, err); -+ complete(&args->comp); -+} -+ -+int make_dir_opaque(struct dentry *dentry, int bindex) -+{ -+ int err = 0; -+ struct dentry *lower_dentry, *diropq; -+ struct inode *lower_dir; -+ struct nameidata nd; -+ const struct cred *old_creds; -+ struct cred *new_creds; -+ -+ /* -+ * Opaque directory whiteout markers are special files (like regular -+ * whiteouts), and should appear to the users as if they don't -+ * exist. They should be created/deleted regardless of directory -+ * search/create permissions, but only for the duration of this -+ * creation of the .wh.__dir_opaque: file. Note, this does not -+ * circumvent normal ->permission). -+ */ -+ new_creds = prepare_creds(); -+ if (unlikely(!new_creds)) { -+ err = -ENOMEM; -+ goto out_err; -+ } -+ cap_raise(new_creds->cap_effective, CAP_DAC_READ_SEARCH); -+ cap_raise(new_creds->cap_effective, CAP_DAC_OVERRIDE); -+ old_creds = override_creds(new_creds); -+ -+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex); -+ lower_dir = lower_dentry->d_inode; -+ BUG_ON(!S_ISDIR(dentry->d_inode->i_mode) || -+ !S_ISDIR(lower_dir->i_mode)); -+ -+ mutex_lock(&lower_dir->i_mutex); -+ err = init_lower_nd(&nd, LOOKUP_OPEN); -+ if (unlikely(err < 0)) -+ goto out; -+ diropq = lookup_one_len_nd(UNIONFS_DIR_OPAQUE, lower_dentry, -+ sizeof(UNIONFS_DIR_OPAQUE) - 1, &nd); -+ release_lower_nd(&nd, err); -+ if (IS_ERR(diropq)) { -+ err = PTR_ERR(diropq); -+ goto out; -+ } -+ -+ err = init_lower_nd(&nd, LOOKUP_CREATE); -+ if (unlikely(err < 0)) -+ goto out; -+ if (!diropq->d_inode) -+ err = vfs_create(lower_dir, diropq, S_IRUGO, &nd); -+ if (!err) -+ dbopaque(dentry) = bindex; -+ release_lower_nd(&nd, err); -+ -+ dput(diropq); -+ -+out: -+ mutex_unlock(&lower_dir->i_mutex); -+ revert_creds(old_creds); -+out_err: -+ return err; -+} -diff --git a/fs/unionfs/xattr.c b/fs/unionfs/xattr.c -new file mode 100644 -index 0000000..a93d803 ---- /dev/null -+++ b/fs/unionfs/xattr.c -@@ -0,0 +1,173 @@ -+/* -+ * Copyright (c) 2003-2011 Erez Zadok -+ * Copyright (c) 2003-2006 Charles P. Wright -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2005-2006 Junjiro Okajima -+ * Copyright (c) 2005 Arun M. Krishnakumar -+ * Copyright (c) 2004-2006 David P. Quigley -+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair -+ * Copyright (c) 2003 Puja Gupta -+ * Copyright (c) 2003 Harikesavan Krishnan -+ * Copyright (c) 2003-2011 Stony Brook University -+ * Copyright (c) 2003-2011 The Research Foundation of SUNY -+ * -+ * 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 "union.h" -+ -+/* This is lifted from fs/xattr.c */ -+void *unionfs_xattr_alloc(size_t size, size_t limit) -+{ -+ void *ptr; -+ -+ if (size > limit) -+ return ERR_PTR(-E2BIG); -+ -+ if (!size) /* size request, no buffer is needed */ -+ return NULL; -+ -+ ptr = kmalloc(size, GFP_KERNEL); -+ if (unlikely(!ptr)) -+ return ERR_PTR(-ENOMEM); -+ return ptr; -+} -+ -+/* -+ * BKL held by caller. -+ * dentry->d_inode->i_mutex locked -+ */ -+ssize_t unionfs_getxattr(struct dentry *dentry, const char *name, void *value, -+ size_t size) -+{ -+ struct dentry *lower_dentry = NULL; -+ struct dentry *parent; -+ int err = -EOPNOTSUPP; -+ bool valid; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ -+ err = vfs_getxattr(lower_dentry, (char *) name, value, size); -+ -+out: -+ unionfs_check_dentry(dentry); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+/* -+ * BKL held by caller. -+ * dentry->d_inode->i_mutex locked -+ */ -+int unionfs_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ struct dentry *lower_dentry = NULL; -+ struct dentry *parent; -+ int err = -EOPNOTSUPP; -+ bool valid; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ -+ err = vfs_setxattr(lower_dentry, (char *) name, (void *) value, -+ size, flags); -+ -+out: -+ unionfs_check_dentry(dentry); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+/* -+ * BKL held by caller. -+ * dentry->d_inode->i_mutex locked -+ */ -+int unionfs_removexattr(struct dentry *dentry, const char *name) -+{ -+ struct dentry *lower_dentry = NULL; -+ struct dentry *parent; -+ int err = -EOPNOTSUPP; -+ bool valid; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ -+ err = vfs_removexattr(lower_dentry, (char *) name); -+ -+out: -+ unionfs_check_dentry(dentry); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -+ -+/* -+ * BKL held by caller. -+ * dentry->d_inode->i_mutex locked -+ */ -+ssize_t unionfs_listxattr(struct dentry *dentry, char *list, size_t size) -+{ -+ struct dentry *lower_dentry = NULL; -+ struct dentry *parent; -+ int err = -EOPNOTSUPP; -+ char *encoded_list = NULL; -+ bool valid; -+ -+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); -+ parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); -+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); -+ -+ valid = __unionfs_d_revalidate(dentry, parent, false); -+ if (unlikely(!valid)) { -+ err = -ESTALE; -+ goto out; -+ } -+ -+ lower_dentry = unionfs_lower_dentry(dentry); -+ -+ encoded_list = list; -+ err = vfs_listxattr(lower_dentry, encoded_list, size); -+ -+out: -+ unionfs_check_dentry(dentry); -+ unionfs_unlock_dentry(dentry); -+ unionfs_unlock_parent(dentry, parent); -+ unionfs_read_unlock(dentry->d_sb); -+ return err; -+} -diff --git a/include/linux/fs_stack.h b/include/linux/fs_stack.h -index da317c7..64f1ced 100644 ---- a/include/linux/fs_stack.h -+++ b/include/linux/fs_stack.h -@@ -1,7 +1,19 @@ -+/* -+ * Copyright (c) 2006-2009 Erez Zadok -+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2006-2009 Stony Brook University -+ * Copyright (c) 2006-2009 The Research Foundation of SUNY -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ - #ifndef _LINUX_FS_STACK_H - #define _LINUX_FS_STACK_H - --/* This file defines generic functions used primarily by stackable -+/* -+ * This file defines generic functions used primarily by stackable - * filesystems; none of these functions require i_mutex to be held. - */ - -diff --git a/include/linux/magic.h b/include/linux/magic.h -index 1e5df2a..01ee54d 100644 ---- a/include/linux/magic.h -+++ b/include/linux/magic.h -@@ -50,6 +50,8 @@ - #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" - #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs" - -+#define UNIONFS_SUPER_MAGIC 0xf15f083d -+ - #define SMB_SUPER_MAGIC 0x517B - #define USBDEVICE_SUPER_MAGIC 0x9fa2 - #define CGROUP_SUPER_MAGIC 0x27e0eb -diff --git a/include/linux/namei.h b/include/linux/namei.h -index eba45ea..8e19e9c 100644 ---- a/include/linux/namei.h -+++ b/include/linux/namei.h -@@ -81,8 +81,11 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, - - extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, - int (*open)(struct inode *, struct file *)); -+extern void release_open_intent(struct nameidata *); - - extern struct dentry *lookup_one_len(const char *, struct dentry *, int); -+extern struct dentry *lookup_one_len_nd(const char *, struct dentry *, int, -+ struct nameidata *nd); - - extern int follow_down_one(struct path *); - extern int follow_down(struct path *); -diff --git a/include/linux/splice.h b/include/linux/splice.h -index 997c3b4..54f5501 100644 ---- a/include/linux/splice.h -+++ b/include/linux/splice.h -@@ -81,6 +81,11 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *, - struct splice_pipe_desc *); - extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, - splice_direct_actor *); -+extern long vfs_splice_from(struct pipe_inode_info *pipe, struct file *out, -+ loff_t *ppos, size_t len, unsigned int flags); -+extern long vfs_splice_to(struct file *in, loff_t *ppos, -+ struct pipe_inode_info *pipe, size_t len, -+ unsigned int flags); - - /* - * for dynamic pipe sizing -diff --git a/include/linux/union_fs.h b/include/linux/union_fs.h -new file mode 100644 -index 0000000..c84d97e ---- /dev/null -+++ b/include/linux/union_fs.h -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (c) 2003-2009 Erez Zadok -+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek -+ * Copyright (c) 2003-2009 Stony Brook University -+ * Copyright (c) 2003-2009 The Research Foundation of SUNY -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef _LINUX_UNION_FS_H -+#define _LINUX_UNION_FS_H -+ -+/* -+ * DEFINITIONS FOR USER AND KERNEL CODE: -+ */ -+# define UNIONFS_IOCTL_INCGEN _IOR(0x15, 11, int) -+# define UNIONFS_IOCTL_QUERYFILE _IOR(0x15, 15, int) -+ -+#endif /* _LINUX_UNIONFS_H */ -+ -diff --git a/security/security.c b/security/security.c -index 4ba6d4c..093d8b4 100644 ---- a/security/security.c -+++ b/security/security.c -@@ -520,6 +520,7 @@ int security_inode_permission(struct inode *inode, int mask) - return 0; - return security_ops->inode_permission(inode, mask, 0); - } -+EXPORT_SYMBOL(security_inode_permission); - - int security_inode_exec_permission(struct inode *inode, unsigned int flags) - { --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0030-omap-Change-omap_device-activate-latency-messages-fr.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0030-omap-Change-omap_device-activate-latency-messages-fr.patch deleted file mode 100644 index 7dc80905..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0030-omap-Change-omap_device-activate-latency-messages-fr.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 728b784863056a2b2e35134f71082271ebab0892 Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Mon, 23 May 2011 12:16:50 -0700 -Subject: [PATCH 30/32] omap: Change omap_device activate latency messages from pr_warning to pr_debug - -Messages can be safely ignored, so reduce console noise - -Signed-off-by: Steve Sakoman ---- - arch/arm/plat-omap/omap_device.c | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c -index 9bbda9a..ca8a479 100644 ---- a/arch/arm/plat-omap/omap_device.c -+++ b/arch/arm/plat-omap/omap_device.c -@@ -145,12 +145,12 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat) - odpl->activate_lat_worst = act_lat; - if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) { - odpl->activate_lat = act_lat; -- pr_warning("omap_device: %s.%d: new worst case " -+ pr_debug("omap_device: %s.%d: new worst case " - "activate latency %d: %llu\n", - od->pdev.name, od->pdev.id, - od->pm_lat_level, act_lat); - } else -- pr_warning("omap_device: %s.%d: activate " -+ pr_debug("omap_device: %s.%d: activate " - "latency %d higher than exptected. " - "(%llu > %d)\n", - od->pdev.name, od->pdev.id, --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0031-omap-overo-Add-opp-init.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0031-omap-overo-Add-opp-init.patch deleted file mode 100644 index 07df7634..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0031-omap-overo-Add-opp-init.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 530abfee962141f263344b4de3ca48b57e5e514c Mon Sep 17 00:00:00 2001 -From: Steve Sakoman -Date: Tue, 24 May 2011 20:36:07 -0700 -Subject: [PATCH 31/32] omap: overo: Add opp init - -omap: overo: Add opp init - -Work in progress - -Signed-off-by: Steve Sakoman ---- - arch/arm/mach-omap2/board-overo.c | 49 +++++++++++++++++++++++++++++++++++++ - 1 files changed, 49 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c -index 05dd3eb..8c2d21f 100644 ---- a/arch/arm/mach-omap2/board-overo.c -+++ b/arch/arm/mach-omap2/board-overo.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -43,6 +44,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -54,6 +56,7 @@ - #include - - #include "mux.h" -+#include "pm.h" - #include "sdram-micron-mt46h32m32lf-6.h" - #include "hsmmc.h" - -@@ -755,6 +758,51 @@ static struct omap_musb_board_data musb_board_data = { - .power = 100, - }; - -+static void __init overo_opp_init(void) -+{ -+ int r = 0; -+ -+ /* Initialize the omap3 opp table */ -+ if (omap3_opp_init()) { -+ pr_err("%s: opp default init failed\n", __func__); -+ return; -+ } -+ -+ /* Custom OPP enabled for 36/3730 */ -+ if (cpu_is_omap3630()) { -+ struct omap_hwmod *mh = omap_hwmod_lookup("mpu"); -+ struct omap_hwmod *dh = omap_hwmod_lookup("iva"); -+ struct device *dev; -+ -+ if (!mh || !dh) { -+ pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", -+ __func__, mh, dh); -+ return; -+ } -+ /* Enable MPU 1GHz and lower opps */ -+ dev = &mh->od->pdev.dev; -+ r = opp_enable(dev, 1000000000); -+ -+ /* Enable IVA 800MHz and lower opps */ -+ dev = &dh->od->pdev.dev; -+ r |= opp_enable(dev, 800000000); -+ -+ if (r) { -+ pr_err("%s: failed to enable higher opp %d\n", -+ __func__, r); -+ /* -+ * Cleanup - disable the higher freqs - we dont care -+ * about the results -+ */ -+ dev = &mh->od->pdev.dev; -+ opp_disable(dev, 1000000000); -+ dev = &dh->od->pdev.dev; -+ opp_disable(dev, 800000000); -+ } -+ } -+ return; -+} -+ - static void __init overo_init(void) - { - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); -@@ -770,6 +818,7 @@ static void __init overo_init(void) - overo_display_init(); - overo_init_led(); - overo_init_keys(); -+ overo_opp_init(); - - /* Ensure SDRC pins are mux'd for self-refresh */ - omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0032-omap3-Add-basic-support-for-720MHz-part.patch b/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0032-omap3-Add-basic-support-for-720MHz-part.patch deleted file mode 100644 index 9a9320d7..00000000 --- a/recipes-kernel/linux/linux-omap-2.6.39/sakoman/0032-omap3-Add-basic-support-for-720MHz-part.patch +++ /dev/null @@ -1,202 +0,0 @@ -From cd9682b39f41675c4e551c607425226b38fab17d Mon Sep 17 00:00:00 2001 -From: Sanjeev Premi -Date: Tue, 18 Jan 2011 13:19:55 +0530 -Subject: [PATCH 32/32] omap3: Add basic support for 720MHz part - -This patch adds support for new speed enhanced parts with ARM -and IVA running at 720MHz and 520MHz respectively. These parts -can be probed at run-time by reading PRODID.SKUID[3:0] at -0x4830A20C [1]. - -This patch specifically does following: - * Detect devices capable of 720MHz. - * Add new OPP - * Ensure that OPP is conditionally enabled. - * Check for presence of IVA before attempting to enable - the corresponding OPP. - - [1] http://focus.ti.com/lit/ug/spruff1d/spruff1d.pdf - -Signed-off-by: Sanjeev Premi ---- - arch/arm/mach-omap2/control.h | 7 ++++ - arch/arm/mach-omap2/id.c | 10 +++++ - arch/arm/mach-omap2/opp3xxx_data.c | 63 ++++++++++++++++++++++++++++++++- - arch/arm/plat-omap/include/plat/cpu.h | 2 + - 4 files changed, 81 insertions(+), 1 deletions(-) - -diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h -index c2804c1..6edd7cc 100644 ---- a/arch/arm/mach-omap2/control.h -+++ b/arch/arm/mach-omap2/control.h -@@ -371,6 +371,13 @@ - #define FEAT_NEON 0 - #define FEAT_NEON_NONE 1 - -+/* -+ * Product ID register -+ */ -+#define OMAP3_PRODID 0x020C -+ -+#define OMAP3_SKUID_MASK 0x0f -+#define OMAP3_SKUID_720MHZ 0x08 - - #ifndef __ASSEMBLY__ - #ifdef CONFIG_ARCH_OMAP2PLUS -diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c -index 2537090..b6ed78a 100644 ---- a/arch/arm/mach-omap2/id.c -+++ b/arch/arm/mach-omap2/id.c -@@ -210,6 +210,15 @@ static void __init omap3_check_features(void) - * TODO: Get additional info (where applicable) - * e.g. Size of L2 cache. - */ -+ -+ /* -+ * Does it support 720MHz? -+ */ -+ status = (OMAP3_SKUID_MASK & read_tap_reg(OMAP3_PRODID)); -+ -+ if (status & OMAP3_SKUID_720MHZ) { -+ omap3_features |= OMAP3_HAS_720MHZ; -+ } - } - - static void __init ti816x_check_features(void) -@@ -490,6 +499,7 @@ static void __init omap3_cpuinfo(void) - OMAP3_SHOW_FEATURE(neon); - OMAP3_SHOW_FEATURE(isp); - OMAP3_SHOW_FEATURE(192mhz_clk); -+ OMAP3_SHOW_FEATURE(720mhz); - - printk(")\n"); - } -diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c -index d95f3f9..44fbc84 100644 ---- a/arch/arm/mach-omap2/opp3xxx_data.c -+++ b/arch/arm/mach-omap2/opp3xxx_data.c -@@ -18,8 +18,10 @@ - * GNU General Public License for more details. - */ - #include -+#include - - #include -+#include - - #include "control.h" - #include "omap_opp_data.h" -@@ -98,6 +100,8 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = { - OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV), - /* MPU OPP5 */ - OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV), -+ /* MPU OPP6 */ -+ OPP_INITIALIZER("mpu", false, 720000000, 1350000), - - /* - * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is -@@ -123,6 +127,8 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = { - OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV), - /* DSP OPP5 */ - OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV), -+ /* DSP OPP6 */ -+ OPP_INITIALIZER("iva", false, 520000000, 1350000), - }; - - static struct omap_opp_def __initdata omap36xx_opp_def_list[] = { -@@ -150,6 +156,57 @@ static struct omap_opp_def __initdata omap36xx_opp_def_list[] = { - OPP_INITIALIZER("iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV), - }; - -+ -+/** -+ * omap3_opp_enable_720Mhz() - Enable the OPP corresponding to 720MHz -+ * -+ * This function would be executed only if the silicon is capable of -+ * running at the 720MHz. -+ */ -+static int __init omap3_opp_enable_720Mhz(void) -+{ -+ int r = -ENODEV; -+ struct omap_hwmod *oh_mpu = omap_hwmod_lookup("mpu"); -+ struct omap_hwmod *oh_iva; -+ struct platform_device *pdev; -+ -+ if (!oh_mpu || !oh_mpu->od) { -+ goto err; -+ } else { -+ pdev = &oh_mpu->od->pdev; -+ -+ r = opp_enable(&pdev->dev, 720000000); -+ if (r < 0) { -+ dev_err(&pdev->dev, -+ "opp_enable() failed for mpu@720MHz"); -+ goto err; -+ } -+ } -+ -+ if (omap3_has_iva()) { -+ oh_iva = omap_hwmod_lookup("iva"); -+ -+ if (!oh_iva || !oh_iva->od) { -+ r = -ENODEV; -+ goto err; -+ } else { -+ pdev = &oh_iva->od->pdev; -+ -+ r = opp_enable(&pdev->dev, 520000000); -+ if (r < 0) { -+ dev_err(&pdev->dev, -+ "opp_enable() failed for iva@520MHz"); -+ goto err; -+ } -+ } -+ } -+ -+ dev_info(&pdev->dev, "Enabled OPP corresponding to 720MHz\n"); -+ -+err: -+ return r; -+} -+ - /** - * omap3_opp_init() - initialize omap3 opp table - */ -@@ -163,10 +220,14 @@ int __init omap3_opp_init(void) - if (cpu_is_omap3630()) - r = omap_init_opp_table(omap36xx_opp_def_list, - ARRAY_SIZE(omap36xx_opp_def_list)); -- else -+ else { - r = omap_init_opp_table(omap34xx_opp_def_list, - ARRAY_SIZE(omap34xx_opp_def_list)); - -+ if (omap3_has_720mhz()) -+ r = omap3_opp_enable_720Mhz(); -+ } -+ - return r; - } - device_initcall(omap3_opp_init); -diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h -index 8198bb6..5204c1e 100644 ---- a/arch/arm/plat-omap/include/plat/cpu.h -+++ b/arch/arm/plat-omap/include/plat/cpu.h -@@ -478,6 +478,7 @@ extern u32 omap3_features; - #define OMAP3_HAS_192MHZ_CLK BIT(5) - #define OMAP3_HAS_IO_WAKEUP BIT(6) - #define OMAP3_HAS_SDRC BIT(7) -+#define OMAP3_HAS_720MHZ BIT(8) - - #define OMAP3_HAS_FEATURE(feat,flag) \ - static inline unsigned int omap3_has_ ##feat(void) \ -@@ -493,5 +494,6 @@ OMAP3_HAS_FEATURE(isp, ISP) - OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) - OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) - OMAP3_HAS_FEATURE(sdrc, SDRC) -+OMAP3_HAS_FEATURE(720mhz, 720MHZ) - - #endif --- -1.6.6.1 - diff --git a/recipes-kernel/linux/linux-omap_2.6.39.bb b/recipes-kernel/linux/linux-omap_2.6.39.bb deleted file mode 100644 index 430fa09b..00000000 --- a/recipes-kernel/linux/linux-omap_2.6.39.bb +++ /dev/null @@ -1,123 +0,0 @@ -require linux.inc - -DESCRIPTION = "Linux kernel for OMAP processors" - -COMPATIBLE_MACHINE = "(beagleboard)" - -# The main PR is now using MACHINE_KERNEL_PR, for omap3 see conf/machine/include/omap3.inc -SRCREV_pn-${PN} = "v2.6.39" -MACHINE_KERNEL_PR_append = "o" - -FILESEXTRAPATHS_prepend := "{THISDIR}/${PN}-${PV}:" - -SRC_URI += "git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git;protocol=git \ - file://defconfig" - -SRC_URI_append = " \ - file://sakoman/0001-OMAP-DSS2-DSI-fix-use_sys_clk-highfreq.patch \ - file://sakoman/0002-OMAP-DSS2-DSI-fix-dsi_dump_clocks.patch \ - file://sakoman/0003-OMAP2PLUS-DSS2-Fix-Return-correct-lcd-clock-source-f.patch \ - file://sakoman/0004-OMAP-DSS-DSI-Fix-DSI-PLL-power-bug.patch \ - file://sakoman/0005-OMAP-DSS2-fix-panel-Kconfig-dependencies.patch \ - file://sakoman/0006-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch \ - file://sakoman/0007-video-add-timings-for-hd720.patch \ - file://sakoman/0008-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch \ - file://sakoman/0009-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch \ - file://sakoman/0010-Revert-omap2_mcspi-Flush-posted-writes.patch \ - file://sakoman/0011-Revert-omap_hsmmc-improve-interrupt-synchronisation.patch \ - file://sakoman/0012-Don-t-turn-SDIO-cards-off-to-save-power.-Doing-so-wi.patch \ - file://sakoman/0014-soc-codecs-Enable-audio-capture-by-default-for-twl40.patch \ - file://sakoman/0015-soc-codecs-twl4030-Turn-on-mic-bias-by-default.patch \ - file://sakoman/0016-RTC-add-support-for-backup-battery-recharge.patch \ - file://sakoman/0017-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch \ - file://sakoman/0018-Add-power-off-support-for-the-TWL4030-companion.patch \ - file://sakoman/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch \ - file://sakoman/0020-Enabling-Hwmon-driver-for-twl4030-madc.patch \ - file://sakoman/0021-mfd-twl-core-enable-madc-clock.patch \ - file://sakoman/0022-rtc-twl-Switch-to-using-threaded-irq.patch \ - file://sakoman/0023-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch \ - file://sakoman/0024-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch \ - file://sakoman/0025-omap-Fix-mtd-subpage-read-alignment.patch \ - file://sakoman/0026-mtd-nand-omap2-Force-all-buffer-reads-to-u32-alignme.patch \ - file://sakoman/0027-omap-nand-fix-subpage-ecc-issue-with-prefetch.patch \ - file://sakoman/0028-OMAP-Overo-Add-support-for-spidev.patch \ - file://sakoman/0029-unionfs-Add-support-for-unionfs-2.5.9.patch \ - file://sakoman/0030-omap-Change-omap_device-activate-latency-messages-fr.patch \ - file://sakoman/0031-omap-overo-Add-opp-init.patch \ - file://sakoman/0032-omap3-Add-basic-support-for-720MHz-part.patch \ - \ - file://beagle/0001-OMAP3-beagle-add-support-for-beagleboard-xM-revision.patch \ - file://beagle/0002-OMAP3-beagle-add-support-for-expansionboards.patch \ - file://beagle/0003-OMAP3-beagle-add-MADC-support.patch \ - file://beagle/0004-OMAP3-beagle-add-regulators-for-camera-interface.patch \ - file://beagle/0005-OMAP3-beagle-HACK-add-in-1GHz-OPP.patch \ - file://beagle/0006-OMAP3-BEAGLE-fix-RTC.patch \ - file://beagle/0007-omap-mmc-Adjust-dto-to-eliminate-timeout-errors.patch \ - \ - file://camera/0001-Add-driver-for-Aptina-Micron-mt9p031-sensor.patch \ - file://camera/0002-v4l-Add-mt9v032-sensor-driver.patch \ - file://camera/0003-Add-support-for-mt9p031-LI-5M03-module-in-Beagleboar.patch \ - \ - file://pm/linux-omap-2.6.39-ti-pm/0001-OMAP3-voltage-remove-spurious-pr_notice-for-debugfs.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0002-OMAP4-PM-remove-redundant-ifdef-CONFIG_PM.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0003-OMAP3-smartreflex-fix-sr_late_init-error-path-in-pro.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0004-OMAP3-smartreflex-request-the-memory-region.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0005-OMAP3-smartreflex-fix-ioremap-leak-on-probe-error.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0006-OMAP3-smartreflex-delete-instance-from-sr_list-on-pr.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0007-OMAP3-smartreflex-delete-debugfs-entries-on-probe-er.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0008-OMAP3-cpuidle-remove-useless-SDP-specific-timings.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0009-OMAP3-SR-make-notify-independent-of-class.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0010-OMAP3-SR-disable-interrupt-by-default.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0011-OMAP3-SR-enable-disable-SR-only-on-need.patch \ - file://pm/linux-omap-2.6.39-ti-pm/0012-OMAP3-SR-fix-cosmetic-indentation.patch \ - \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0001-OMAP-CPUfreq-ensure-driver-initializes-after-cpufreq.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0002-OMAP-CPUfreq-ensure-policy-is-fully-initialized.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0003-OMAP3-PM-CPUFreq-driver-for-OMAP3.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0004-OMAP-PM-CPUFREQ-Fix-conditional-compilation.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0005-cpufreq-fixup-after-new-OPP-layer-merged.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0006-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0007-OMAP2PLUS-cpufreq-Add-SMP-support-to-cater-OMAP4430.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq/0008-OMAP2PLUS-cpufreq-Fix-typo-when-attempting-to-set-mp.patch \ - \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0001-cpufreq-helpers-for-walking-the-frequency-table.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-hotplug/0002-cpufreq-introduce-hotplug-governor.patch \ - \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0001-OMAP2-cpufreq-free-up-table-on-exit.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0002-OMAP2-cpufreq-handle-invalid-cpufreq-table.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0003-OMAP2-cpufreq-minor-comment-cleanup.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0004-OMAP2-cpufreq-use-clk_init_cpufreq_table-if-OPPs-not.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0005-OMAP2-cpufreq-use-cpufreq_frequency_table_target.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpufreq-fixes/0006-OMAP2-cpufreq-fix-freq_table-leak.patch \ - \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0001-OMAP2-clockdomain-Add-an-api-to-read-idle-mode.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0002-OMAP2-clockdomain-Add-SoC-support-for-clkdm_is_idle.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0003-OMAP2-PM-Initialise-sleep_switch-to-a-non-valid-valu.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0004-OMAP2-PM-idle-clkdms-only-if-already-in-idle.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0005-OMAP2-hwmod-Follow-the-recomended-PRCM-sequence.patch \ - file://pm/linux-omap-2.6.39-ti-pm-wip-cpuidle/0006-OMAP-Serial-Check-wk_st-only-if-present.patch \ - \ - file://mfd/0001-mfd-Fix-omap-usbhs-crash-when-rmmoding-ehci-or-ohci.patch \ - file://mfd/0002-mfd-Fix-omap_usbhs_alloc_children-error-handling.patch \ - file://mfd/0003-mfd-Add-omap-usbhs-runtime-PM-support.patch \ - file://mfd/0004-arm-omap-usb-ehci-and-ohci-hwmod-structures-for-omap.patch \ - file://mfd/0005-arm-omap-usb-register-hwmods-of-usbhs.patch \ - file://mfd/0006-arm-omap-usb-device-name-change-for-the-clk-names-of.patch \ - file://mfd/0007-mfd-global-Suspend-and-resume-support-of-ehci-and-oh.patch \ - file://mfd/0008-MFD-TWL4030-Correct-the-warning-print-during-script-.patch \ - file://mfd/0009-MFD-TWL4030-Modifying-the-macro-name-Main_Ref-to-all.patch \ - file://mfd/0010-MFD-TWL4030-power-scripts-for-OMAP3-boards.patch \ - file://mfd/0011-MFD-TWL4030-TWL-version-checking.patch \ - file://mfd/0012-MFD-TWL4030-workaround-changes-for-Erratum-27.patch \ - file://mfd/0013-MFD-TWL4030-optimizing-resource-configuration.patch \ - \ - file://musb/0001-usb-musb-Enable-DMA-mode1-RX-for-USB-Mass-Storage.patch \ - \ - file://net/0001-NFS-Revert-NFSROOT-default-mount-options.patch \ - " - -SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ -" - -S = "${WORKDIR}/git" - -- cgit v1.2.3-54-g00ecf