From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757271AbbFPJh7 (ORCPT ); Tue, 16 Jun 2015 05:37:59 -0400 Received: from terminus.zytor.com ([198.137.202.10]:56159 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756291AbbFPJhi (ORCPT ); Tue, 16 Jun 2015 05:37:38 -0400 Date: Tue, 16 Jun 2015 02:36:53 -0700 From: tip-bot for Javier Martinez Canillas Message-ID: Cc: tglx@linutronix.de, linux-kernel@vger.kernel.org, tomasz.figa@gmail.com, hpa@zytor.com, javier.martinez@collabora.co.uk, k.kozlowski@samsung.com, dianders@chromium.org, kgene@kernel.org, sudeep.holla@arm.com, mingo@kernel.org, parkch98@gmail.com, peter.chubb@nicta.com.au, jason@lakedaemon.net, shuahkhan@gmail.com Reply-To: mingo@kernel.org, kgene@kernel.org, sudeep.holla@arm.com, dianders@chromium.org, jason@lakedaemon.net, shuahkhan@gmail.com, parkch98@gmail.com, peter.chubb@nicta.com.au, tomasz.figa@gmail.com, tglx@linutronix.de, linux-kernel@vger.kernel.org, javier.martinez@collabora.co.uk, k.kozlowski@samsung.com, hpa@zytor.com In-Reply-To: <1434087795-13990-1-git-send-email-javier.martinez@collabora.co.uk> References: <1434087795-13990-1-git-send-email-javier.martinez@collabora.co.uk> To: linux-tip-commits@vger.kernel.org Subject: [tip:irq/core] irqchip: exynos-combiner: Save IRQ enable set on suspend Git-Commit-ID: 6fd4899a54a522ccd6a24fea2318d3b515b95945 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 6fd4899a54a522ccd6a24fea2318d3b515b95945 Gitweb: http://git.kernel.org/tip/6fd4899a54a522ccd6a24fea2318d3b515b95945 Author: Javier Martinez Canillas AuthorDate: Fri, 12 Jun 2015 07:43:15 +0200 Committer: Thomas Gleixner CommitDate: Tue, 16 Jun 2015 11:34:41 +0200 irqchip: exynos-combiner: Save IRQ enable set on suspend The Exynos interrupt combiner IP loses its state when the SoC enters into a low power state during a Suspend-to-RAM. This means that if a IRQ is used as a source, the interrupts for the devices are disabled when the system is resumed from a sleep state so are not triggered. Save the interrupt enable set register for each combiner group and restore it after resume to make sure that the interrupts are enabled. Signed-off-by: Javier Martinez Canillas Reviewed-by: Krzysztof Kozlowski Cc: Jason Cooper Cc: Kukjin Kim Cc: Tomasz Figa Cc: Doug Anderson Cc: linux-arm-kernel@lists.infradead.org Cc: Peter Chubb Cc: Shuah Khan Cc: Chanho Park Cc: Sudeep Holla Link: http://lkml.kernel.org/r/1434087795-13990-1-git-send-email-javier.martinez@collabora.co.uk Signed-off-by: Thomas Gleixner --- drivers/irqchip/exynos-combiner.c | 64 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index a57a3a1..5c82e3b 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -34,9 +35,14 @@ struct combiner_chip_data { unsigned int irq_mask; void __iomem *base; unsigned int parent_irq; +#ifdef CONFIG_PM + u32 pm_save; +#endif }; +static struct combiner_chip_data *combiner_data; static struct irq_domain *combiner_irq_domain; +static unsigned int max_nr = 20; static inline void __iomem *combiner_base(struct irq_data *data) { @@ -170,12 +176,10 @@ static const struct irq_domain_ops combiner_irq_domain_ops = { }; static void __init combiner_init(void __iomem *combiner_base, - struct device_node *np, - unsigned int max_nr) + struct device_node *np) { int i, irq; unsigned int nr_irq; - struct combiner_chip_data *combiner_data; nr_irq = max_nr * IRQ_IN_COMBINER; @@ -201,11 +205,59 @@ static void __init combiner_init(void __iomem *combiner_base, } } +#ifdef CONFIG_PM + +/** + * combiner_suspend - save interrupt combiner state before suspend + * + * Save the interrupt enable set register for all combiner groups since + * the state is lost when the system enters into a sleep state. + * + */ +static int combiner_suspend(void) +{ + int i; + + for (i = 0; i < max_nr; i++) + combiner_data[i].pm_save = + __raw_readl(combiner_data[i].base + COMBINER_ENABLE_SET); + + return 0; +} + +/** + * combiner_resume - restore interrupt combiner state after resume + * + * Restore the interrupt enable set register for all combiner groups since + * the state is lost when the system enters into a sleep state on suspend. + * + */ +static void combiner_resume(void) +{ + int i; + + for (i = 0; i < max_nr; i++) { + __raw_writel(combiner_data[i].irq_mask, + combiner_data[i].base + COMBINER_ENABLE_CLEAR); + __raw_writel(combiner_data[i].pm_save, + combiner_data[i].base + COMBINER_ENABLE_SET); + } +} + +#else +#define combiner_suspend NULL +#define combiner_resume NULL +#endif + +static struct syscore_ops combiner_syscore_ops = { + .suspend = combiner_suspend, + .resume = combiner_resume, +}; + static int __init combiner_of_init(struct device_node *np, struct device_node *parent) { void __iomem *combiner_base; - unsigned int max_nr = 20; combiner_base = of_iomap(np, 0); if (!combiner_base) { @@ -219,7 +271,9 @@ static int __init combiner_of_init(struct device_node *np, __func__, max_nr); } - combiner_init(combiner_base, np, max_nr); + combiner_init(combiner_base, np); + + register_syscore_ops(&combiner_syscore_ops); return 0; }