From 7a872b6fb7fdc4213e9bb4e1c83a65e6b8af7ebd Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 4 Jul 2018 20:19:06 -0700 Subject: soc: ti: wkup_m3_ipc: Add rtc_only with ddr in self refresh mode support Adds rtc_only support. This needs resume function to shutdown and reboot the m3. Signed-off-by: Keerthy Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/wkup_m3_ipc.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c index 369aef5e7228..b732c39e2754 100644 --- a/drivers/soc/ti/wkup_m3_ipc.c +++ b/drivers/soc/ti/wkup_m3_ipc.c @@ -329,12 +329,24 @@ static int wkup_m3_finish_low_power(struct wkup_m3_ipc *m3_ipc) return 0; } +/** + * wkup_m3_set_rtc_only - Set the rtc_only flag + * @wkup_m3_wakeup: struct wkup_m3_wakeup_src * gets assigned the + * wakeup src value + */ +static void wkup_m3_set_rtc_only(struct wkup_m3_ipc *m3_ipc) +{ + if (m3_ipc_state) + m3_ipc_state->is_rtc_only = true; +} + static struct wkup_m3_ipc_ops ipc_ops = { .set_mem_type = wkup_m3_set_mem_type, .set_resume_address = wkup_m3_set_resume_address, .prepare_low_power = wkup_m3_prepare_low_power, .finish_low_power = wkup_m3_finish_low_power, .request_pm_status = wkup_m3_request_pm_status, + .set_rtc_only = wkup_m3_set_rtc_only, }; /** @@ -484,6 +496,32 @@ static int wkup_m3_ipc_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int wkup_m3_ipc_suspend(struct device *dev) +{ + /* + * Nothing needs to be done on suspend even with rtc_only flag set + */ + return 0; +} + +static int wkup_m3_ipc_resume(struct device *dev) +{ + if (m3_ipc_state->is_rtc_only) { + rproc_shutdown(m3_ipc_state->rproc); + rproc_boot(m3_ipc_state->rproc); + } + + m3_ipc_state->is_rtc_only = false; + + return 0; +} + +static const struct dev_pm_ops wkup_m3_ipc_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(wkup_m3_ipc_suspend, wkup_m3_ipc_resume) +}; +#endif + static const struct of_device_id wkup_m3_ipc_of_match[] = { { .compatible = "ti,am3352-wkup-m3-ipc", }, { .compatible = "ti,am4372-wkup-m3-ipc", }, @@ -497,6 +535,9 @@ static struct platform_driver wkup_m3_ipc_driver = { .driver = { .name = "wkup_m3_ipc", .of_match_table = wkup_m3_ipc_of_match, +#ifdef CONFIG_PM + .pm = &wkup_m3_ipc_pm_ops, +#endif }, }; -- cgit v1.2.3 From ec93b62fec9c7138d2b75334d192ecc12376f885 Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Wed, 4 Jul 2018 20:19:06 -0700 Subject: soc: ti: wkup_m3_ipc: Add wkup_m3_request_wake_src Add wkup_m3_request_wake_src to allow users to get the name of the wakeup source after a DeepSleep or Standby transition. Signed-off-by: Dave Gerlach Signed-off-by: Keerthy Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/wkup_m3_ipc.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/wkup_m3_ipc.h | 6 ++++++ 2 files changed, 45 insertions(+) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c index b732c39e2754..6840688236b9 100644 --- a/drivers/soc/ti/wkup_m3_ipc.c +++ b/drivers/soc/ti/wkup_m3_ipc.c @@ -46,6 +46,7 @@ #define M3_BASELINE_VERSION 0x191 #define M3_STATUS_RESP_MASK (0xffff << 16) #define M3_FW_VERSION_MASK 0xffff +#define M3_WAKE_SRC_MASK 0xff #define M3_STATE_UNKNOWN 0 #define M3_STATE_RESET 1 @@ -55,6 +56,23 @@ static struct wkup_m3_ipc *m3_ipc_state; +static const struct wkup_m3_wakeup_src wakeups[] = { + {.irq_nr = 35, .src = "USB0_PHY"}, + {.irq_nr = 36, .src = "USB1_PHY"}, + {.irq_nr = 40, .src = "I2C0"}, + {.irq_nr = 41, .src = "RTC Timer"}, + {.irq_nr = 42, .src = "RTC Alarm"}, + {.irq_nr = 43, .src = "Timer0"}, + {.irq_nr = 44, .src = "Timer1"}, + {.irq_nr = 45, .src = "UART"}, + {.irq_nr = 46, .src = "GPIO0"}, + {.irq_nr = 48, .src = "MPU_WAKE"}, + {.irq_nr = 49, .src = "WDT0"}, + {.irq_nr = 50, .src = "WDT1"}, + {.irq_nr = 51, .src = "ADC_TSC"}, + {.irq_nr = 0, .src = "Unknown"}, +}; + static void am33xx_txev_eoi(struct wkup_m3_ipc *m3_ipc) { writel(AM33XX_M3_TXEV_ACK, @@ -329,6 +347,26 @@ static int wkup_m3_finish_low_power(struct wkup_m3_ipc *m3_ipc) return 0; } +/** + * wkup_m3_request_wake_src - Get the wakeup source info passed from wkup_m3 + * @m3_ipc: Pointer to wkup_m3_ipc context + */ +static const char *wkup_m3_request_wake_src(struct wkup_m3_ipc *m3_ipc) +{ + unsigned int wakeup_src_idx; + int j, val; + + val = wkup_m3_ctrl_ipc_read(m3_ipc, 6); + + wakeup_src_idx = val & M3_WAKE_SRC_MASK; + + for (j = 0; j < ARRAY_SIZE(wakeups) - 1; j++) { + if (wakeups[j].irq_nr == wakeup_src_idx) + return wakeups[j].src; + } + return wakeups[j].src; +} + /** * wkup_m3_set_rtc_only - Set the rtc_only flag * @wkup_m3_wakeup: struct wkup_m3_wakeup_src * gets assigned the @@ -346,6 +384,7 @@ static struct wkup_m3_ipc_ops ipc_ops = { .prepare_low_power = wkup_m3_prepare_low_power, .finish_low_power = wkup_m3_finish_low_power, .request_pm_status = wkup_m3_request_pm_status, + .request_wake_src = wkup_m3_request_wake_src, .set_rtc_only = wkup_m3_set_rtc_only, }; diff --git a/include/linux/wkup_m3_ipc.h b/include/linux/wkup_m3_ipc.h index d639df15e8ba..e497e621dbb7 100644 --- a/include/linux/wkup_m3_ipc.h +++ b/include/linux/wkup_m3_ipc.h @@ -43,12 +43,18 @@ struct wkup_m3_ipc { int is_rtc_only; }; +struct wkup_m3_wakeup_src { + int irq_nr; + char src[10]; +}; + struct wkup_m3_ipc_ops { void (*set_mem_type)(struct wkup_m3_ipc *m3_ipc, int mem_type); void (*set_resume_address)(struct wkup_m3_ipc *m3_ipc, void *addr); int (*prepare_low_power)(struct wkup_m3_ipc *m3_ipc, int state); int (*finish_low_power)(struct wkup_m3_ipc *m3_ipc); int (*request_pm_status)(struct wkup_m3_ipc *m3_ipc); + const char *(*request_wake_src)(struct wkup_m3_ipc *m3_ipc); void (*set_rtc_only)(struct wkup_m3_ipc *m3_ipc); }; -- cgit v1.2.3 From 990c10091db318c7eb7e8935c86b6f7c01585015 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 6 Jul 2018 09:47:51 -0700 Subject: soc: ti: wkup_m3_ipc: mark PM functions as __maybe_unused Everyone gets these #ifdefs wrong, leading to another warning here: drivers/soc/ti/wkup_m3_ipc.c:547:12: error: 'wkup_m3_ipc_resume' defined but not used [-Werror=unused-function] static int wkup_m3_ipc_resume(struct device *dev) drivers/soc/ti/wkup_m3_ipc.c:539:12: error: 'wkup_m3_ipc_suspend' defined but not used [-Werror=unused-function] static int wkup_m3_ipc_suspend(struct device *dev) The easiest way to get it right is to remove all the #ifdefs and let the compiler drop the unused functions silently after we mark them as __maybe_unused. Fixes: 7a872b6fb7fd ("soc: ti: wkup_m3_ipc: Add rtc_only with ddr in self refresh mode support") Signed-off-by: Arnd Bergmann Signed-off-by: Santosh Shilimkar --- drivers/soc/ti/wkup_m3_ipc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers/soc') diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c index 6840688236b9..f5cb8c0af09f 100644 --- a/drivers/soc/ti/wkup_m3_ipc.c +++ b/drivers/soc/ti/wkup_m3_ipc.c @@ -535,8 +535,7 @@ static int wkup_m3_ipc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int wkup_m3_ipc_suspend(struct device *dev) +static int __maybe_unused wkup_m3_ipc_suspend(struct device *dev) { /* * Nothing needs to be done on suspend even with rtc_only flag set @@ -544,7 +543,7 @@ static int wkup_m3_ipc_suspend(struct device *dev) return 0; } -static int wkup_m3_ipc_resume(struct device *dev) +static int __maybe_unused wkup_m3_ipc_resume(struct device *dev) { if (m3_ipc_state->is_rtc_only) { rproc_shutdown(m3_ipc_state->rproc); @@ -559,7 +558,6 @@ static int wkup_m3_ipc_resume(struct device *dev) static const struct dev_pm_ops wkup_m3_ipc_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(wkup_m3_ipc_suspend, wkup_m3_ipc_resume) }; -#endif static const struct of_device_id wkup_m3_ipc_of_match[] = { { .compatible = "ti,am3352-wkup-m3-ipc", }, @@ -574,9 +572,7 @@ static struct platform_driver wkup_m3_ipc_driver = { .driver = { .name = "wkup_m3_ipc", .of_match_table = wkup_m3_ipc_of_match, -#ifdef CONFIG_PM .pm = &wkup_m3_ipc_pm_ops, -#endif }, }; -- cgit v1.2.3