From patchwork Wed Jul 29 10:08:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanjun Guo X-Patchwork-Id: 51632 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by patches.linaro.org (Postfix) with ESMTPS id 5B9DE22DB5 for ; Wed, 29 Jul 2015 10:11:00 +0000 (UTC) Received: by laah7 with SMTP id h7sf2063191laa.2 for ; Wed, 29 Jul 2015 03:10:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=rxMA+LSUofjv6IXNNmbnjZnpNm0DmXeHDlP/32oArd0=; b=gyrRDDSDoRGWmBOHdR8rguXTd8WqhoryPtG/OXcAxKZk8J8LhyZ2gbko0F6gFN5I8L Fes4RBw/avXOG1HwJ3Hrs5GzGcU1Ii33t5lFMYd0vSxHUvDT4OCuZZ0LZfzCT5c+3krh 3ulDojJRhMQcwLSNEUBSwJLApkyOYfUsTDu/DqMRjRMEz6tn1hdW9j+QT+h6uZmFGyiw BqR5KEnqmm/JcyQ9CJSWQrvX4jAAKzVeKunWzVjxv8mag28WSSmVqo5K2WpRSCHE3z+D 2XTABzqeQRj1TSVC7ZKcO7FnA4Vb24/pCGZQTOyAwxkN6ORbmR0rNx6eV6ydjuGWvf0s Sq3Q== X-Gm-Message-State: ALoCoQkz4NG5oy01CnF0RMksgoPf2jxw9kPPZ+XJRzUhC3cKnyCUWj1J6xk039HZmxWRJYlDz4oI X-Received: by 10.152.22.163 with SMTP id e3mr15646955laf.6.1438164659322; Wed, 29 Jul 2015 03:10:59 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.43.2 with SMTP id s2ls21146lal.86.gmail; Wed, 29 Jul 2015 03:10:58 -0700 (PDT) X-Received: by 10.112.138.199 with SMTP id qs7mr37842264lbb.21.1438164658941; Wed, 29 Jul 2015 03:10:58 -0700 (PDT) Received: from mail-lb0-f179.google.com (mail-lb0-f179.google.com. [209.85.217.179]) by mx.google.com with ESMTPS id p7si21118560lag.32.2015.07.29.03.10.58 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2015 03:10:58 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.179 as permitted sender) client-ip=209.85.217.179; Received: by lbbyj8 with SMTP id yj8so3644440lbb.0 for ; Wed, 29 Jul 2015 03:10:58 -0700 (PDT) X-Received: by 10.112.209.106 with SMTP id ml10mr37264230lbc.112.1438164658502; Wed, 29 Jul 2015 03:10:58 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.7.198 with SMTP id l6csp2652984lba; Wed, 29 Jul 2015 03:10:56 -0700 (PDT) X-Received: by 10.66.65.205 with SMTP id z13mr91914235pas.65.1438164655502; Wed, 29 Jul 2015 03:10:55 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id ob4si60687820pdb.122.2015.07.29.03.10.53; Wed, 29 Jul 2015 03:10:55 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752532AbbG2KKs (ORCPT + 27 others); Wed, 29 Jul 2015 06:10:48 -0400 Received: from mail-pd0-f172.google.com ([209.85.192.172]:34051 "EHLO mail-pd0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752496AbbG2KKo (ORCPT ); Wed, 29 Jul 2015 06:10:44 -0400 Received: by pdbbh15 with SMTP id bh15so3530620pdb.1 for ; Wed, 29 Jul 2015 03:10:44 -0700 (PDT) X-Received: by 10.70.0.71 with SMTP id 7mr91807425pdc.157.1438164644400; Wed, 29 Jul 2015 03:10:44 -0700 (PDT) Received: from localhost ([180.150.157.4]) by smtp.googlemail.com with ESMTPSA id oi17sm39815178pdb.74.2015.07.29.03.10.42 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 29 Jul 2015 03:10:43 -0700 (PDT) From: Hanjun Guo To: Marc Zyngier , Jason Cooper , Will Deacon , Catalin Marinas , "Rafael J. Wysocki" Cc: Thomas Gleixner , Jiang Liu , Bjorn Helgaas , Lorenzo Pieralisi , Suravee Suthikulpanit , Timur Tabi , Tomasz Nowicki , Grant Likely , Mark Brown , Wei Huang , linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org, linaro-acpi@lists.linaro.org, Hanjun Guo Subject: [PATCH v4 08/10] ACPI: GIC: Add ACPI helper functions to query irq-domain tokens for for GIC MSI and ITS Date: Wed, 29 Jul 2015 18:08:57 +0800 Message-Id: <1438164539-29256-9-git-send-email-hanjun.guo@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org> References: <1438164539-29256-1-git-send-email-hanjun.guo@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: hanjun.guo@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.179 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Suravee Suthikulpanit This patch introduces acpi_gic_get_msi_token(), which returns irq-domain token that can be used to look up MSI doamin of a device. In both GIC MSI and ITS cases, the base_address specified in the GIC MSI or GIC ITS structure is used as a token for MSI domain. In addition, this patch also provides low-level helper functions to parse and query GIC MSI structure and GIC ITS from MADT. Once parsed, it keeps a copy of the structure for use in subsequent queries to avoid having to map and parse MADT multiple times. Signed-off-by: Suravee Suthikulpanit Signed-off-by: Hanjun Guo --- drivers/acpi/Makefile | 1 + drivers/acpi/acpi_gic.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++ include/acpi/acpi_gic.h | 23 +++++ include/linux/acpi.h | 1 + 4 files changed, 259 insertions(+) create mode 100644 drivers/acpi/acpi_gic.c create mode 100644 include/acpi/acpi_gic.h diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 8321430..def54b9 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -54,6 +54,7 @@ acpi-$(CONFIG_ACPI_NUMA) += numa.o acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o acpi-y += acpi_lpat.o acpi-$(CONFIG_ACPI_GENERIC_GSI) += gsi.o +acpi-$(CONFIG_ARM_GIC_ACPI) += acpi_gic.o # These are (potentially) separate modules diff --git a/drivers/acpi/acpi_gic.c b/drivers/acpi/acpi_gic.c new file mode 100644 index 0000000..11ee4eb --- /dev/null +++ b/drivers/acpi/acpi_gic.c @@ -0,0 +1,234 @@ +/* + * File: acpi_gic.c + * + * ACPI helper functions for ARM GIC + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + * Authors: Suravee Suthikulpanit + */ + +#include +#include + +/* + * GIC MSI Frame data structures + */ +struct gic_msi_frame_handle { + struct list_head list; + struct acpi_madt_generic_msi_frame frame; +}; + +static LIST_HEAD(msi_frame_list); + +static int acpi_num_msi; + +/* + * GIC ITS data structures + */ +struct gic_its_handle { + struct list_head list; + struct acpi_madt_generic_translator trans; +}; + +static LIST_HEAD(its_list); + +static int acpi_num_its; + +/* + * GIC MSI Frame parsing stuff + */ +inline int acpi_gic_get_num_msi_frame(void) +{ + return acpi_num_msi; +} + +static int __init +acpi_parse_madt_msi(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct gic_msi_frame_handle *h; + struct acpi_madt_generic_msi_frame *frame; + + frame = (struct acpi_madt_generic_msi_frame *)header; + if (BAD_MADT_ENTRY(frame, end)) + return -EINVAL; + + h = kzalloc(sizeof(struct gic_msi_frame_handle *), GFP_KERNEL); + if (!h) + return -ENOMEM; + + /** Note: + * We make a copy of this structure since this code is called + * prior to acpi_early_init(), which sets the acpi_gbl_permanent_mmap. + * Therefore, we could not keep just the pointer sincce the memory + * could be unmapped. + */ + memcpy(&h->frame, frame, sizeof(struct acpi_madt_generic_msi_frame)); + + list_add(&h->list, &msi_frame_list); + + return 0; +} + +int __init acpi_gic_msi_init(struct acpi_table_header *table) +{ + int ret = 0; + + if (acpi_num_msi > 0) + return ret; + + ret = acpi_parse_entries(ACPI_SIG_MADT, + sizeof(struct acpi_table_madt), + acpi_parse_madt_msi, table, + ACPI_MADT_TYPE_GENERIC_MSI_FRAME, 0); + if (ret == 0) { + pr_debug("No valid ACPI GIC MSI FRAME exist\n"); + return ret; + } + + acpi_num_msi = ret; + return 0; +} + +int acpi_gic_get_msi_frame(int index, struct acpi_madt_generic_msi_frame **p) +{ + int i = 0; + struct gic_msi_frame_handle *m; + + if (index >= acpi_num_msi) + return -EINVAL; + + list_for_each_entry(m, &msi_frame_list, list) { + if (i == index) + break; + i++; + } + + if (i == acpi_num_msi) + return -EINVAL; + + *p = &(m->frame); + return 0; +} + +/* + * GIC ITS parsing stuff + */ +inline int acpi_gic_get_num_its(void) +{ + return acpi_num_its; +} + +static int __init +acpi_parse_madt_its(struct acpi_subtable_header *header, + const unsigned long end) +{ + struct gic_its_handle *h; + struct acpi_madt_generic_translator *trans; + + trans = (struct acpi_madt_generic_translator *)header; + if (BAD_MADT_ENTRY(trans, end)) + return -EINVAL; + + h = kzalloc(sizeof(struct gic_its_handle *), GFP_KERNEL); + if (!h) + return -ENOMEM; + + memcpy(&h->trans, trans, sizeof(struct acpi_madt_generic_translator)); + + list_add(&h->list, &its_list); + + return 0; +} + +int __init acpi_gic_madt_gic_its_init(struct acpi_table_header *table) +{ + int ret = 0; + + if (acpi_num_its > 0) + return ret; + + ret = acpi_parse_entries(ACPI_SIG_MADT, + sizeof(struct acpi_table_madt), + acpi_parse_madt_its, table, + ACPI_MADT_TYPE_GENERIC_TRANSLATOR, 0); + if (ret == 0) { + pr_debug("No valid ACPI GIC ITS exist\n"); + return ret; + } + + acpi_num_its = ret; + return 0; +} + +int acpi_gic_get_its(int index, struct acpi_madt_generic_translator **p) +{ + int i = 0; + struct gic_its_handle *m; + + if (index >= acpi_num_its) + return -EINVAL; + + list_for_each_entry(m, &its_list, list) { + if (i == index) + break; + i++; + } + + if (i == acpi_num_its) + return -EINVAL; + + *p = &(m->trans); + return 0; +} + +static void *acpi_gic_msi_token(struct device *dev) +{ + int err; + struct acpi_madt_generic_msi_frame *msi; + + /** + * Since ACPI 5.1 currently does not define + * a way to associate MSI frame ID to a device, + * we can only support single MSI frame (index 0) + * at the moment. + */ + err = acpi_gic_get_msi_frame(0, &msi); + if (err) + return NULL; + + return (void *) msi->base_address; +} + +static void *acpi_gic_its_token(struct device *dev) +{ + int err; + struct acpi_madt_generic_translator *trans; + int its_id = 0; + + /** + * TODO: We need a way to retrieve GIC ITS ID from + * struct device pointer (in this case, the device + * would be the PCI host controller. + * + * This would be done by the IORT-related code. + * + * its_id = get_its_id(dev); + */ + + err = acpi_gic_get_its(its_id, &trans); + if (err) + return NULL; + + return (void *) trans->base_address; +} + +void *acpi_gic_get_msi_token(struct device *dev) +{ + void *token = acpi_gic_msi_token(dev); + + if (!token) + token = acpi_gic_its_token(dev); + + return token; +} diff --git a/include/acpi/acpi_gic.h b/include/acpi/acpi_gic.h new file mode 100644 index 0000000..34fa475 --- /dev/null +++ b/include/acpi/acpi_gic.h @@ -0,0 +1,23 @@ +/* + * include/acpi/acpi_gic.h + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + * Authors: Suravee Suthikulpanit + */ + +#ifndef __ACPI_GIC_H__ +#define __ACPI_GIC_H__ + +#ifdef CONFIG_ACPI +int acpi_gic_get_num_msi_frame(void); +int acpi_gic_msi_init(struct acpi_table_header *table); +int acpi_gic_get_msi_frame(int index, struct acpi_madt_generic_msi_frame **p); + +int acpi_gic_get_num_its(void); +int acpi_gic_its_init(struct acpi_table_header *table); +int acpi_gic_get_its(int index, struct acpi_madt_generic_translator **p); + +void *acpi_gic_get_msi_token(struct device *dev); +#endif + +#endif /*__ACPI_GIC_H__*/ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 04dd0bb..5d58b61 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -44,6 +44,7 @@ #include #include +#include #include #include #include