diff options
author | Bai Ping <b51503@freescale.com> | 2015-01-30 18:56:40 +0800 |
---|---|---|
committer | Bai Ping <b51503@freescale.com> | 2015-02-03 02:05:55 +0800 |
commit | a0bd5ae4e401a3363f7d63bccb5b22dafb64b9d6 (patch) | |
tree | 9924cbd9b97eda58b5aa46266125b80bd90b9fde /arch | |
parent | 2e6207e3506c5b270d21c3763e0eaa77b6ac55cb (diff) |
MLK-10188 arm: imx: Add dummy LDO2p5 regulator for VBUS wakeup
LDO2p5 cannot be disabled in low power idle mode when the USB driver
enables VBUS wakeup. To identify when LDO2p5 can be disabled add a dummy
regulator that the USB driver will enable when VBUS wakeup is required.
This patch is copied from commit 7d849e4d9ebca3c as code the structure has
changed too many. directly cherry-pick has too many conflicts to resolve
Signed-off-by: Bai Ping <b51503@freescale.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/boot/dts/imx6sl.dtsi | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/cpuidle-imx6sl.c | 87 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx6sl_lpm_wfi.S | 11 |
3 files changed, 101 insertions, 2 deletions
diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 1c3fa3581f6e..323754f7cbfe 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -95,6 +95,10 @@ }; }; + reg_vbus_wakeup: usb_vbus_wakeup { + compatible = "fsl,imx6-dummy-ldo2p5"; + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -791,6 +795,7 @@ compatible = "fsl,imx6sl-usbmisc", "fsl,imx6q-usbmisc"; reg = <0x02184800 0x200>; clocks = <&clks IMX6SL_CLK_USBOH3>; + vbus-wakeup-supply = <®_vbus_wakeup>; }; fec: ethernet@02188000 { diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c index c05f0b0e3ea0..ee1550060948 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sl.c +++ b/arch/arm/mach-imx/cpuidle-imx6sl.c @@ -8,6 +8,10 @@ #include <linux/cpuidle.h> #include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/machine.h> #include <asm/cpuidle.h> #include <asm/fncpy.h> #include <asm/proc-fns.h> @@ -45,15 +49,25 @@ static const u32 imx6sl_mmdc_io_offset[] __initconst = { 0x330, 0x334, 0x320, /*SDCKE0, SDCK1, RESET */ }; +static struct regulator *vbus_ldo; +static struct regulator_dev *ldo2p5_dummy_regulator_rdev; +static struct regulator_init_data ldo2p5_dummy_initdata = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; +static int ldo2p5_dummy_enable; + static void (*imx6sl_wfi_in_iram_fn)(void __iomem *iram_vbase, - int audio_mode); + int audio_mode, bool vbus_ldo); static int imx6sl_enter_wait(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { imx6q_set_lpm(WAIT_UNCLOCKED); if (audio_bus_freq_mode || ultra_low_bus_freq_mode) { - imx6sl_wfi_in_iram_fn(wfi_iram_base, audio_bus_freq_mode); + imx6sl_wfi_in_iram_fn(wfi_iram_base, audio_bus_freq_mode, + regulator_is_enabled(vbus_ldo)); } else { /* * Software workaround for ERR005311, see function @@ -96,6 +110,10 @@ int __init imx6sl_cpuidle_init(void) const u32 *mmdc_offset_array; u32 wfi_code_size; + vbus_ldo = regulator_get(NULL, "ldo2p5-dummy"); + if (IS_ERR(vbus_ldo)) + vbus_ldo = NULL; + wfi_iram_base = (void *)(iram_tlb_base_addr + MX6_CPUIDLE_IRAM_ADDR_OFFSET); /* Make sure wif_iram_base is 8 byte aligned. */ @@ -124,3 +142,68 @@ int __init imx6sl_cpuidle_init(void) return cpuidle_register(&imx6sl_cpuidle_driver, NULL); } + +static int imx_ldo2p5_dummy_enable(struct regulator_dev *rdev) +{ + ldo2p5_dummy_enable = 1; + return 0; +} + +static int imx_ldo2p5_dummy_disable(struct regulator_dev *rdev) +{ + ldo2p5_dummy_enable = 0; + return 0; +} + +static int imx_ldo2p5_dummy_is_enable(struct regulator_dev *rdev) +{ + return ldo2p5_dummy_enable; +} + +static struct regulator_ops ldo2p5_dummy_ops = { + .enable = imx_ldo2p5_dummy_enable, + .disable = imx_ldo2p5_dummy_disable, + .is_enabled = imx_ldo2p5_dummy_is_enable, +}; + +static struct regulator_desc ldo2p5_dummy_desc = { + .name = "ldo2p5-dummy", + .id = -1, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .ops = &ldo2p5_dummy_ops, +}; + +static int ldo2p5_dummy_probe(struct platform_device *pdev) +{ + struct regulator_config config = { }; + int ret; + + config.dev = &pdev->dev; + config.init_data = &ldo2p5_dummy_initdata; + config.of_node = pdev->dev.of_node; + + ldo2p5_dummy_regulator_rdev = regulator_register(&ldo2p5_dummy_desc, &config); + if (IS_ERR(ldo2p5_dummy_regulator_rdev)) { + ret = PTR_ERR(ldo2p5_dummy_regulator_rdev); + dev_err(&pdev->dev, "Failed to register dummy ldo2p5 regulator: %d\n", ret); + return ret; + } + return 0; +} + +static const struct of_device_id imx_ldo2p5_dummy_ids[] = { + { .compatible = "fsl,imx6-dummy-ldo2p5"}, + }; +MODULE_DEVICE_TABLE(ofm, imx_ldo2p5_dummy_ids); + +static struct platform_driver ldo2p5_dummy_driver = { + .probe = ldo2p5_dummy_probe, + .driver = { + .name = "ldo2p5-dummy", + .owner = THIS_MODULE, + .of_match_table = imx_ldo2p5_dummy_ids, + }, +}; + +module_platform_driver(ldo2p5_dummy_driver); diff --git a/arch/arm/mach-imx/imx6sl_lpm_wfi.S b/arch/arm/mach-imx/imx6sl_lpm_wfi.S index c10dbd565cbb..439556f7a243 100644 --- a/arch/arm/mach-imx/imx6sl_lpm_wfi.S +++ b/arch/arm/mach-imx/imx6sl_lpm_wfi.S @@ -292,6 +292,13 @@ check_done: orr r6, r6, #0xc000 str r6, [r10, #0x150] + /* + * if the usb VBUS wakeup is enabled, skip + * disable main 2p5. + */ + cmp r2, #0x1 + beq anatop_enter_done + /* Enable the week 2p5 */ ldr r6, [r10, #0x130] orr r6, r6, #0x40000 @@ -350,6 +357,8 @@ anatop_enter_done: cmp r4, #0x0 beq skip_anatop_restore + cmp r2, #0x1 + beq ldo2p5_not_disabled /* * Regular bandgap will not be disabled * in LDO-enabled mode as it is required @@ -407,6 +416,7 @@ skip_bandgap_restore: bic r6, r6, #0x40000 str r6, [r10, #0x130] +ldo2p5_not_disabled: /* * Set the OSC bias current to max * value for normal operation. @@ -618,6 +628,7 @@ poll_dvfs_set: * imx6sl_low_power_wfi code * r0: wfi code base address * r1: audio_bus_freq mode stat + * r2: vbus_ldo status * r4: used for store the PLLs state * r11: used for saving the ARM_PODF origin value * r12: used for saving AHB_PODF origin value |