From patchwork Wed Jul 8 16:00:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ross Zwisler X-Patchwork-Id: 6749381 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 51ED8C05AC for ; Wed, 8 Jul 2015 16:01:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 57DE320689 for ; Wed, 8 Jul 2015 16:01:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5BE0D2064C for ; Wed, 8 Jul 2015 16:01:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759118AbbGHQBI (ORCPT ); Wed, 8 Jul 2015 12:01:08 -0400 Received: from mga03.intel.com ([134.134.136.65]:17704 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759059AbbGHQAk (ORCPT ); Wed, 8 Jul 2015 12:00:40 -0400 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP; 08 Jul 2015 09:00:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,432,1432623600"; d="scan'208";a="520876297" Received: from theros.lm.intel.com ([10.232.112.65]) by FMSMGA003.fm.intel.com with ESMTP; 08 Jul 2015 09:00:39 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , linux-nvdimm@lists.01.org, linux-acpi@vger.kernel.org, "Rafael J. Wysocki" , Dan Williams , Len Brown , Christoph Hellwig , Jeff Moyer , Toshi Kani Subject: [PATCH 3/3] nfit: add support for NVDIMM "latch" flag Date: Wed, 8 Jul 2015 10:00:21 -0600 Message-Id: <1436371221-30296-4-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1436371221-30296-1-git-send-email-ross.zwisler@linux.intel.com> References: <1436371221-30296-1-git-send-email-ross.zwisler@linux.intel.com> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 Add support in the NFIT BLK I/O path for the "latch" flag defined in the "Get Block NVDIMM Flags" _DSM function: http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf This flag requires the driver to read back the command register after it is written in the block I/O path. This ensures that the hardware has fully processed the new command and moved the aperture appropriately. Signed-off-by: Ross Zwisler Cc: linux-nvdimm@lists.01.org Cc: linux-acpi@vger.kernel.org Cc: "Rafael J. Wysocki" Cc: Dan Williams Cc: Len Brown Cc: Christoph Hellwig Cc: Jeff Moyer Cc: Toshi Kani --- drivers/acpi/nfit.c | 33 ++++++++++++++++++++++++++++++++- drivers/acpi/nfit.h | 6 ++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c index b3c446412f61..9062c11c1062 100644 --- a/drivers/acpi/nfit.c +++ b/drivers/acpi/nfit.c @@ -1059,7 +1059,9 @@ static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw, writeq(cmd, mmio->base + offset); wmb_blk(nfit_blk); - /* FIXME: conditionally perform read-back if mandated by firmware */ + + if (nfit_blk->dimm_flags & ND_BLK_DCR_LATCH) + readq(mmio->base + offset); } static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk, @@ -1258,6 +1260,28 @@ static int nfit_blk_init_interleave(struct nfit_blk_mmio *mmio, return 0; } +static int acpi_nfit_blk_get_flags(struct nvdimm_bus_descriptor *nd_desc, + struct nvdimm *nvdimm, struct nfit_blk *nfit_blk) +{ + struct nd_cmd_dimm_flags flags; + int rc; + + memset(&flags, 0, sizeof(flags)); + rc = nd_desc->ndctl(nd_desc, nvdimm, ND_CMD_DIMM_FLAGS, &flags, + sizeof(flags)); + + if (rc >= 0) { + if (!flags.status) + nfit_blk->dimm_flags = flags.flags; + else if (flags.status == ND_DSM_STATUS_NOT_SUPPORTED) + nfit_blk->dimm_flags = 0; /* as per the _DSM spec */ + else + rc = -EINVAL; + } + + return rc; +} + static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus, struct device *dev) { @@ -1333,6 +1357,13 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus, return rc; } + rc = acpi_nfit_blk_get_flags(nd_desc, nvdimm, nfit_blk); + if (rc < 0) { + dev_dbg(dev, "%s: %s failed get DIMM flags\n", + __func__, nvdimm_name(nvdimm)); + return rc; + } + nfit_flush = nfit_mem->nfit_flush; if (nfit_flush && nfit_flush->flush->hint_count != 0) { struct acpi_nfit_flush_address *flush = nfit_flush->flush; diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h index d284729cc37c..98e36ca0dfc2 100644 --- a/drivers/acpi/nfit.h +++ b/drivers/acpi/nfit.h @@ -40,6 +40,11 @@ enum nfit_uuids { NFIT_UUID_MAX, }; +enum { + ND_BLK_DCR_LATCH = 2, + ND_DSM_STATUS_NOT_SUPPORTED = 1, +}; + struct nfit_spa { struct acpi_nfit_system_address *spa; struct list_head list; @@ -131,6 +136,7 @@ struct nfit_blk { u64 stat_offset; u64 cmd_offset; void __iomem *nvdimm_flush; + u32 dimm_flags; }; struct nfit_spa_mapping {