From patchwork Fri Jan 12 21:24:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derek Basehore X-Patchwork-Id: 10161705 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 421FA602A7 for ; Fri, 12 Jan 2018 21:25:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 326C128A90 for ; Fri, 12 Jan 2018 21:25:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2331E28AAC; Fri, 12 Jan 2018 21:25:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AD2C328A90 for ; Fri, 12 Jan 2018 21:25:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965376AbeALVYy (ORCPT ); Fri, 12 Jan 2018 16:24:54 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:43438 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965292AbeALVYu (ORCPT ); Fri, 12 Jan 2018 16:24:50 -0500 Received: by mail-pg0-f67.google.com with SMTP id f14so5351488pga.10 for ; Fri, 12 Jan 2018 13:24:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kMz20I1yB5bqRCK/g1msnS7g6d0KrCy1FhDC54NRBRQ=; b=gppdTQu4C4Rn9qs3s76kwW3KnyvmgPasOSbrwpHa7kNAjT5hWDl3Vxmwi7s691E/lC kL7qMSdGzDNxsxSCPTzMHdc+mgGXrmr8xyVXtbtcKE2g6O0q9XwXKHbSgRQxXewcOup3 JBK9qV7l7J6yclVYIQRWljOCBeqWdTbWrFvuM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kMz20I1yB5bqRCK/g1msnS7g6d0KrCy1FhDC54NRBRQ=; b=F4T/Y6+6G4ZjmXyxVR6V+vPq65+wvX9VJZLdSnT/PLu+TV6tLCLYh04S4vLOGnnH5S cB++HgwN7H0z97WDmXZKQdnEILo7L/kdb6dkqOgBWYQ9esxp34NjdOTw//M2qf2CWlnS 6IROD5lUxMKS3uQnOoMqYdON4SibDBZfqkC1sNlssZgpqkOZl5ja6g9imxqhyRUxS/dU fH8RH57NUPEgL9bSwuWMCjDbCXAYOP4pSwi2tBCAkInG1S4uE6HfsNh9hKYr1RfD4Mvl rbTycbzwKlYl1m9ZBFJWVMkxssxrZC71V2mTj4d+6V/4jOILJ1alX5HQQRmH5dxvHWNl h/dg== X-Gm-Message-State: AKGB3mKHTmMx0+j6oVO6uXEZEbWInOk+xut+JGxTef4OeNVAGGJ1Jmmd BWFMBuoaIMT9VZGn/tRkiI29Yg== X-Google-Smtp-Source: ACJfBoss5aKIoEh4YiGc+kiMZjlKtBSkjkOVHqVKjARA4Qt+dLq8J8ECApg066eFQwSrZ/Pu/PJWSA== X-Received: by 10.84.212.150 with SMTP id e22mr27368480pli.447.1515792289177; Fri, 12 Jan 2018 13:24:49 -0800 (PST) Received: from exogeni.mtv.corp.google.com ([2620:0:1000:1600:211e:5908:95bc:4888]) by smtp.gmail.com with ESMTPSA id t71sm18616186pfg.115.2018.01.12.13.24.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 12 Jan 2018 13:24:48 -0800 (PST) From: Derek Basehore To: linux-kernel@vger.kernel.org Cc: linux-pm@vger.kernel.org, rafael.j.wysocki@intel.com, tglx@linutronix.de, briannorris@chromium.org, marc.zyngier@arm.com, Derek Basehore Subject: [PATCH 8/8] irqchip/gic-v3: add power down/up sequence Date: Fri, 12 Jan 2018 13:24:22 -0800 Message-Id: <20180112212422.148625-9-dbasehore@chromium.org> X-Mailer: git-send-email 2.16.0.rc1.238.g530d649a79-goog In-Reply-To: <20180112212422.148625-1-dbasehore@chromium.org> References: <20180112212422.148625-1-dbasehore@chromium.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This adds the implementation specific power down/up sequence for the GIC-500 and the GIC-600 (which are implementations of the GIC-v3 specification). This allows the LPI pending information to be properly flushed on suspend if the GIC is disabled. Change-Id: Iad2135b5f5a57f7dc0c15d05e4b9a06e1b4c24d1 Signed-off-by: Derek Basehore --- drivers/irqchip/irq-gic-v3.c | 58 ++++++++++++++++++++++++++++++++++++++ include/linux/irqchip/arm-gic-v3.h | 9 ++++++ 2 files changed, 67 insertions(+) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 95d37fb6f458..5286757dd413 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -816,6 +816,35 @@ static void gic_redist_save(int cpu) ctx->nsacr = readl_relaxed(base + GICR_NSACR); } +static void gic_power_down(void) +{ + void __iomem *base = gic_data.dist_base; + u32 product_id = readl_relaxed(base + GICD_IIDR) >> + GICD_IIDR_PRODUCTID_SHIFT; + + /* + * This power down sequence is implementation defined. It's the same for + * the GIC-500 and GIC-600. + */ + if ((product_id & GIC500_IIDR_PRODUCTID) || + (product_id & GIC600_IIDR_PRODUCTID)) { + u32 val; + + /* + * There's only one instance of the GICR_WAKER register which + * each redistributor maps to. So this just needs to be set for + * the current CPU. + */ + base = gic_data_rdist_rd_base(); + val = readl_relaxed(base + GICR_WAKER); + writel_relaxed(val | GICR_WAKER_Sleep, base + GICR_WAKER); + while (!(readl_relaxed(base + GICR_WAKER) & + GICR_WAKER_Quiescent)) + ; + + } +} + static void gic_dist_save(void) { struct gic_dist_ctx *ctx = gic_data.gicd_ctx; @@ -871,6 +900,7 @@ static int gic_suspend(void) for_each_possible_cpu(cpu) gic_redist_save(cpu); + gic_power_down(); its_save_disable(); gic_dist_save(); @@ -901,6 +931,33 @@ static void gic_rdist_restore(int cpu) gic_do_wait_for_rwp(base); } +static void gic_power_up(void) +{ + void __iomem *base = gic_data.dist_base; + u32 product_id = readl_relaxed(base + GICD_IIDR) >> + GICD_IIDR_PRODUCTID_SHIFT; + + /* + * Same as the power down sequence, this part of the power up sequence + * is implementation defined. + */ + if ((product_id & GIC500_IIDR_PRODUCTID) || + (product_id & GIC600_IIDR_PRODUCTID)) { + u32 val; + + /* + * Need to turn the GIC back on in-case suspend is cancelled. + * The GIC hardware reset state or the platform layer should + * handle this otherwise. + */ + base = gic_data_rdist_rd_base(); + val = readl_relaxed(base + GICR_WAKER); + writel_relaxed(val & ~GICR_WAKER_Sleep, base + GICR_WAKER); + while (readl_relaxed(base + GICR_WAKER) & GICR_WAKER_Quiescent) + ; + } +} + static void gic_dist_restore(void) { struct gic_dist_ctx *ctx = gic_data.gicd_ctx; @@ -937,6 +994,7 @@ static void gic_resume(void) gic_dist_restore(); its_restore_enable(); + gic_power_up(); for_each_possible_cpu(cpu) gic_rdist_restore(cpu); diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index f086987e3cb4..22ced72be1c5 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -59,6 +59,10 @@ #define GICD_NSACR_SHIFT 4 #define GICD_IROUTER_SHIFT 0 +#define GICD_IIDR_PRODUCTID_SHIFT 24 +#define GIC500_IIDR_PRODUCTID 0x00 +#define GIC600_IIDR_PRODUCTID 0x02 + /* * Those registers are actually from GICv2, but the spec demands that they * are implemented as RES0 if ARE is 1 (which we do in KVM's emulated GICv3). @@ -122,8 +126,13 @@ #define GICR_TYPER_CPU_NUMBER(r) (((r) >> 8) & 0xffff) +/* + * Sleep and Quiescent are implementation specific for the GIC-500 and GIC-600. + */ +#define GICR_WAKER_Sleep (1U << 0) #define GICR_WAKER_ProcessorSleep (1U << 1) #define GICR_WAKER_ChildrenAsleep (1U << 2) +#define GICR_WAKER_Quiescent (1U << 31) #define GIC_BASER_CACHE_nCnB 0ULL #define GIC_BASER_CACHE_SameAsInner 0ULL