From patchwork Fri May 15 21:23:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suravee Suthikulpanit X-Patchwork-Id: 6416421 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BB848C0432 for ; Fri, 15 May 2015 21:23:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8B59A20582 for ; Fri, 15 May 2015 21:23:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2F8192058A for ; Fri, 15 May 2015 21:23:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1946078AbbEOVXx (ORCPT ); Fri, 15 May 2015 17:23:53 -0400 Received: from mail-by2on0137.outbound.protection.outlook.com ([207.46.100.137]:14592 "EHLO na01-by2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1946049AbbEOVXv (ORCPT ); Fri, 15 May 2015 17:23:51 -0400 Received: from BY1PR0201CA0025.namprd02.prod.outlook.com (25.160.191.163) by CO1PR02MB080.namprd02.prod.outlook.com (10.242.164.17) with Microsoft SMTP Server (TLS) id 15.1.154.19; Fri, 15 May 2015 21:23:48 +0000 Received: from BN1BFFO11FD031.protection.gbl (2a01:111:f400:7c10::1:148) by BY1PR0201CA0025.outlook.office365.com (2a01:111:e400:4814::35) with Microsoft SMTP Server (TLS) id 15.1.160.19 via Frontend Transport; Fri, 15 May 2015 21:23:48 +0000 Authentication-Results: spf=none (sender IP is 165.204.84.221) smtp.mailfrom=amd.com; arm.com; dkim=none (message not signed) header.d=none; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) Received: from atltwp01.amd.com (165.204.84.221) by BN1BFFO11FD031.mail.protection.outlook.com (10.58.144.94) with Microsoft SMTP Server id 15.1.160.8 via Frontend Transport; Fri, 15 May 2015 21:23:46 +0000 X-WSS-ID: 0NOEU3L-07-0MA-02 X-M-MSG: Received: from satlvexedge02.amd.com (satlvexedge02.amd.com [10.177.96.29]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by atltwp01.amd.com (Axway MailGate 5.3.1) with ESMTPS id 2688612C003F; Fri, 15 May 2015 17:23:45 -0400 (EDT) Received: from SATLEXDAG04.amd.com (10.181.40.9) by SATLVEXEDGE02.amd.com (10.177.96.29) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 15 May 2015 16:23:52 -0500 Received: from ssuthiku-fedora-lt.amd.com (10.180.168.240) by satlexdag04.amd.com (10.181.40.9) with Microsoft SMTP Server id 14.3.195.1; Fri, 15 May 2015 17:23:44 -0400 From: Suravee Suthikulpanit To: , , , , , , , , CC: , , , , , , , , , , , "Suravee Suthikulpanit" Subject: [V4 PATCH 1/6] ACPI / scan: Parse _CCA and setup device coherency Date: Fri, 15 May 2015 16:23:09 -0500 Message-ID: <1431724994-21601-2-git-send-email-Suravee.Suthikulpanit@amd.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1431724994-21601-1-git-send-email-Suravee.Suthikulpanit@amd.com> References: <1431724994-21601-1-git-send-email-Suravee.Suthikulpanit@amd.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BN1BFFO11FD031; 1:KHetYVpNZnDCYqB3IJkpffXoO34pjrQnBZkYKjST15fVT5zZIpoKv+Rl0EQhfVRhBZsxLib3xyrKkTdijKo8l/RQkENz88775tCwpaLNpnoX2XBzR4SG4PKQYcc59BUylSJvDova867WO0Yza5sg1CAbqKZ8zS7/yBjh8GC8Dy6ns4LqW5iJRCTuQP+0Gar21Pbnr4MZ9ASqgt0AmdjFgR/brQrWk1Z7z+3DLDBKDZJg+UggFyp1MPygwDQ6z5YCSp1GzjMsmWJRvhHZio6uwuwCZDWzctRb0Jj4I9WKT5fjYWg0NDvZof1bmz2AltrY X-Forefront-Antispam-Report: CIP:165.204.84.221; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(428002)(189002)(199003)(2201001)(86362001)(106466001)(53416004)(50466002)(87936001)(46102003)(229853001)(48376002)(101416001)(189998001)(19580405001)(77096005)(5001770100001)(47776003)(2950100001)(19580395003)(50226001)(36756003)(105586002)(92566002)(77156002)(62966003)(76176999)(50986999); DIR:OUT; SFP:1102; SCL:1; SRVR:CO1PR02MB080; H:atltwp01.amd.com; FPR:; SPF:None; MLV:sfv; MX:1; A:1; LANG:en; X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CO1PR02MB080; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(3002001); SRVR:CO1PR02MB080; BCL:0; PCL:0; RULEID:; SRVR:CO1PR02MB080; X-Forefront-PRVS: 0577AD41D6 X-OriginatorOrg: amd4.onmicrosoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 May 2015 21:23:46.6440 (UTC) X-MS-Exchange-CrossTenant-Id: fde4dada-be84-483f-92cc-e026cbee8e96 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=fde4dada-be84-483f-92cc-e026cbee8e96; Ip=[165.204.84.221]; Helo=[atltwp01.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR02MB080 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch implements support for ACPI _CCA object, which is introduced in ACPIv5.1, can be used for specifying device DMA coherency attribute. The parsing logic traverses device namespace to parse coherency information, and stores it in acpi_device_flags. Then uses it to call arch_setup_dma_ops() when creating each device enumerated in DSDT during ACPI scan. This patch also introduces acpi_dma_is_coherent(), which provides an interface for device drivers to check the coherency information similarly to the of_dma_is_coherent(). Signed-off-by: Mark Salter Signed-off-by: Suravee Suthikulpanit CC: Rafael J. Wysocki CC: Arnd Bergmann CC: Will Deacon CC: Catalin Marinas --- drivers/acpi/Kconfig | 3 +++ drivers/acpi/acpi_platform.c | 10 +++++++--- drivers/acpi/scan.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/acpi/acpi_bus.h | 32 +++++++++++++++++++++++++++++++- include/linux/acpi.h | 10 ++++++++++ 5 files changed, 91 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index ab2cbb5..212735f 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -54,6 +54,9 @@ config ACPI_GENERIC_GSI config ACPI_SYSTEM_POWER_STATES_SUPPORT bool +config ACPI_CCA_REQUIRED + bool + config ACPI_SLEEP bool depends on SUSPEND || HIBERNATION diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 4bf7559..f6bc438 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -103,14 +103,18 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) pdevinfo.res = resources; pdevinfo.num_res = count; pdevinfo.fwnode = acpi_fwnode_handle(adev); - pdevinfo.dma_mask = DMA_BIT_MASK(32); + pdevinfo.dma_mask = acpi_dma_is_supported(adev) ? DMA_BIT_MASK(32) : 0; pdev = platform_device_register_full(&pdevinfo); - if (IS_ERR(pdev)) + if (IS_ERR(pdev)) { dev_err(&adev->dev, "platform device creation failed: %ld\n", PTR_ERR(pdev)); - else + } else { + if (acpi_dma_is_supported(adev)) + arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, + acpi_dma_is_coherent(adev)); dev_dbg(&adev->dev, "created platform device %s\n", dev_name(&pdev->dev)); + } kfree(resources); return pdev; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 849b699..c56e66a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -2137,6 +2138,44 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp) kfree(pnp->unique_id); } +static void acpi_init_coherency(struct acpi_device *adev) +{ + unsigned long long cca = 0; + acpi_status status; + struct acpi_device *parent = adev->parent; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + if (parent && parent->flags.cca_seen) { + /* + * From ACPI spec, OSPM will ignore _CCA if an ancestor + * already saw one. + */ + adev->flags.cca_seen = 1; + cca = acpi_dma_is_coherent(parent); + } else { + status = acpi_evaluate_integer(adev->handle, "_CCA", + NULL, &cca); + if (ACPI_SUCCESS(status)) { + adev->flags.cca_seen = 1; + } else if (!IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED)) { + /* + * If architecture does not specify that _CCA is + * required for DMA-able devices (e.g. x86), + * we default to _CCA=1. + */ + cca = 1; + } else { + acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, + &buffer); + pr_debug("ACPI device %s is missing _CCA.\n", + (char *) buffer.pointer); + kfree(buffer.pointer); + } + } + + adev->flags.is_coherent = cca; +} + void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, int type, unsigned long long sta) { @@ -2155,6 +2194,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, device->flags.visited = false; device_initialize(&device->dev); dev_set_uevent_suppress(&device->dev, true); + acpi_init_coherency(device); } void acpi_device_add_finalize(struct acpi_device *device) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 8de4fa9..2a05ffb 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -208,7 +208,9 @@ struct acpi_device_flags { u32 visited:1; u32 hotplug_notify:1; u32 is_dock_station:1; - u32 reserved:23; + u32 is_coherent:1; + u32 cca_seen:1; + u32 reserved:21; }; /* File System */ @@ -380,6 +382,34 @@ struct acpi_device { void (*remove)(struct acpi_device *); }; +static inline bool acpi_dma_is_supported(struct acpi_device *adev) +{ + /** + * Currently, we mainly support _CCA=1 (i.e. is_coherent=1) + * This should be equivalent to specifyig dma-coherent for + * a device in OF. + * + * For the case when _CCA=0 (i.e. is_coherent=0 && cca_seen=1), + * There are two approaches: + * 1. Do not support and disable DMA. + * 2. Support but rely on arch-specific cache maintenance for + * non-coherence DMA operations. ARM64 is one example. + * + * For the case when _CCA is missing (i.e. cca_seen=0) but + * platform specifies ACPI_CCA_REQUIRED, we do not support DMA, + * and fallback to arch-specific default handling. + * + * See acpi_init_coherency() for more info. + */ + return adev && (adev->flags.is_coherent || + (adev->flags.cca_seen && IS_ENABLED(CONFIG_ARM64))); +} + +static inline bool acpi_dma_is_coherent(struct acpi_device *adev) +{ + return adev && adev->flags.is_coherent; +} + static inline bool is_acpi_node(struct fwnode_handle *fwnode) { return fwnode && fwnode->type == FWNODE_ACPI; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b10c4a6..baccf3b 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -583,6 +583,16 @@ static inline int acpi_device_modalias(struct device *dev, return -ENODEV; } +static inline bool acpi_dma_is_supported(struct acpi_device *adev) +{ + return false; +} + +static inline bool acpi_dma_is_coherent(struct acpi_device *adev) +{ + return false; +} + #define ACPI_PTR(_ptr) (NULL) #endif /* !CONFIG_ACPI */