From patchwork Wed Sep 8 11:34:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas tanure X-Patchwork-Id: 508217 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5EEACC433FE for ; Wed, 8 Sep 2021 11:35:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 42CE261074 for ; Wed, 8 Sep 2021 11:35:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349307AbhIHLgM (ORCPT ); Wed, 8 Sep 2021 07:36:12 -0400 Received: from mx0b-001ae601.pphosted.com ([67.231.152.168]:24582 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349197AbhIHLgG (ORCPT ); Wed, 8 Sep 2021 07:36:06 -0400 Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 188696pD006454; Wed, 8 Sep 2021 06:34:55 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=lYP8FSmBUjs8SycWJ3rt3zCuR4OjzNIaYSJ1r1nSyW8=; b=TNGVljtyZLgj1zHbe1uRGDCGb3yxi0eYM115eITXLV0VljQY7bfSdJwAgPOTx6OtLmVf kNXqcI83VH+Z3XGWSaoteTBjdO/t35MZzA+hFU6mYh4yVo89HenxGUXzdkqO/EU9+avQ fTArRU8E2ScvgB+VsStDI6NvVDYR+PtyMXn/Una73fRZi0etI4m1mLOno8cNUcwas1JM Uf+n3YX3yI+VOLeP5RXpJB+++SYk3xlFLUMNRQEukYTkJGdRZJ7sqiJ+jqfqIcmlhXq0 +XWkYCIplVpJSJ/7rKLwW4y3R2KWg20uXvKw1Ct5oUo3VEAODcrzWvgjPIesxxJdBIF4 Iw== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3axcp997pg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 08 Sep 2021 06:34:55 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Wed, 8 Sep 2021 12:34:54 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.12 via Frontend Transport; Wed, 8 Sep 2021 12:34:54 +0100 Received: from aryzen.ad.cirrus.com (unknown [198.61.64.231]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id CEBBC2BA; Wed, 8 Sep 2021 11:34:53 +0000 (UTC) From: Lucas Tanure To: Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Sanjay R Mehta , Nehal Bakulchandra Shah CC: , , , Lucas Tanure Subject: [PATCH 01/10] regmap: spi: Set regmap max raw r/w from max_transfer_size Date: Wed, 8 Sep 2021 12:34:42 +0100 Message-ID: <20210908113450.788452-2-tanureal@opensource.cirrus.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210908113450.788452-1-tanureal@opensource.cirrus.com> References: <20210908113450.788452-1-tanureal@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: 5JH76MzFIRS97VJE7QeL0SPHl6wuzbYF X-Proofpoint-ORIG-GUID: 5JH76MzFIRS97VJE7QeL0SPHl6wuzbYF X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Set regmap raw read/write from spi max_transfer_size so regmap_raw_read/write can split the access into chunks Signed-off-by: Lucas Tanure --- drivers/base/regmap/regmap-spi.c | 36 ++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index c1894e93c378..0e6552e57ecf 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c @@ -109,13 +109,37 @@ static const struct regmap_bus regmap_spi = { .val_format_endian_default = REGMAP_ENDIAN_BIG, }; +static const struct regmap_bus *regmap_get_spi_bus(struct spi_device *spi, + const struct regmap_config *config) +{ + struct spi_master *master = spi->master; + struct regmap_bus *bus = NULL; + size_t max_size = spi_max_transfer_size(spi); + + if (max_size != SIZE_MAX) { + bus = kmemdup(®map_spi, sizeof(*bus), GFP_KERNEL); + if (!bus) + return ERR_PTR(-ENOMEM); + bus->free_on_exit = true; + bus->max_raw_read = max_size; + bus->max_raw_write = max_size; + return bus; + } + + return ®map_spi; +} + struct regmap *__regmap_init_spi(struct spi_device *spi, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { - return __regmap_init(&spi->dev, ®map_spi, &spi->dev, config, - lock_key, lock_name); + const struct regmap_bus *bus = regmap_get_spi_bus(spi, config); + + if (IS_ERR(bus)) + return ERR_CAST(bus); + + return __regmap_init(&spi->dev, bus, &spi->dev, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__regmap_init_spi); @@ -124,8 +148,12 @@ struct regmap *__devm_regmap_init_spi(struct spi_device *spi, struct lock_class_key *lock_key, const char *lock_name) { - return __devm_regmap_init(&spi->dev, ®map_spi, &spi->dev, config, - lock_key, lock_name); + const struct regmap_bus *bus = regmap_get_spi_bus(spi, config); + + if (IS_ERR(bus)) + return ERR_CAST(bus); + + return __devm_regmap_init(&spi->dev, bus, &spi->dev, config, lock_key, lock_name); } EXPORT_SYMBOL_GPL(__devm_regmap_init_spi); From patchwork Wed Sep 8 11:34:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas tanure X-Patchwork-Id: 508218 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3A55C433F5 for ; Wed, 8 Sep 2021 11:35:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CC78861074 for ; Wed, 8 Sep 2021 11:35:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349286AbhIHLgL (ORCPT ); Wed, 8 Sep 2021 07:36:11 -0400 Received: from mx0b-001ae601.pphosted.com ([67.231.152.168]:30360 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349200AbhIHLgG (ORCPT ); Wed, 8 Sep 2021 07:36:06 -0400 Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 18858Mnu005982; Wed, 8 Sep 2021 06:34:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=QjOOiJsJyu51IX6wxFev1VBwtRJSWCphxb41J5pTuhU=; b=owh6B204/vpLCeMAVtlmj0IioGVPRFobkotDSAWyxC6diDYTMpl9V5ipNAg7tADLWF4a WRWqCMOjSp0NcUFuAtHY8MTvWZsIwcOQE93oqYq/Hp2DO5EA1UTZ9QgsL9nEShyklUAR FIdTi9TJZs9ta9LdiIzSuj/Kp5mGVk6UhLpFC/pouJGgTEQJG7GqwfM4Br8om268csig lQAJIugOjer9qjHzQJ985kmmxIjBhneHlXNfenzOefE/yTTLm5esQhP0p8/L17Vy6ely rt6w0UAoZ8UhnRtWfBs6FayW+g1Njq39/A12a8qFFZo8Mp+aF4F59pkAj/1QjnStAFQ3 KA== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3axcp997pf-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 08 Sep 2021 06:34:55 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Wed, 8 Sep 2021 12:34:54 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.12 via Frontend Transport; Wed, 8 Sep 2021 12:34:54 +0100 Received: from aryzen.ad.cirrus.com (unknown [198.61.64.231]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 1EB52B2F; Wed, 8 Sep 2021 11:34:54 +0000 (UTC) From: Lucas Tanure To: Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Sanjay R Mehta , Nehal Bakulchandra Shah CC: , , , Lucas Tanure Subject: [PATCH 02/10] regmap: spi: Check raw_[read|write] against max message size Date: Wed, 8 Sep 2021 12:34:43 +0100 Message-ID: <20210908113450.788452-3-tanureal@opensource.cirrus.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210908113450.788452-1-tanureal@opensource.cirrus.com> References: <20210908113450.788452-1-tanureal@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: DzaAA0zDnKaCbhqbc9cc3h5VkjOWhMIZ X-Proofpoint-ORIG-GUID: DzaAA0zDnKaCbhqbc9cc3h5VkjOWhMIZ X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org regmap-spi will split data and address between two transfers in the same message, so max_[read|write] must include space for the address and padding Signed-off-by: Lucas Tanure --- drivers/base/regmap/regmap-spi.c | 4 ++++ drivers/base/regmap/regmap.c | 15 +++++++++++++++ include/linux/regmap.h | 3 +++ 3 files changed, 22 insertions(+) diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 0e6552e57ecf..1434c502e340 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c @@ -123,6 +123,10 @@ static const struct regmap_bus *regmap_get_spi_bus(struct spi_device *spi, bus->free_on_exit = true; bus->max_raw_read = max_size; bus->max_raw_write = max_size; + + if (spi_max_message_size(spi) != SIZE_MAX) + bus->max_combined_rw = spi_max_message_size(spi); + return bus; } diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index fe3e38dd5324..1cd936e097b0 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -718,6 +718,7 @@ struct regmap *__regmap_init(struct device *dev, struct regmap *map; int ret = -EINVAL; enum regmap_endian reg_endian, val_endian; + size_t reg_pad_size; int i, j; if (!config) @@ -815,6 +816,20 @@ struct regmap *__regmap_init(struct device *dev, if (bus) { map->max_raw_read = bus->max_raw_read; map->max_raw_write = bus->max_raw_write; + if (bus->max_combined_rw) { + reg_pad_size = map->format.reg_bytes + map->format.pad_bytes; + + if (map->max_raw_read + reg_pad_size > bus->max_combined_rw) + map->max_raw_read -= reg_pad_size; + if (map->max_raw_write + reg_pad_size > bus->max_combined_rw) + map->max_raw_write -= reg_pad_size; + + if (map->max_raw_read < map->format.buf_size || + map->max_raw_write < map->format.buf_size) { + ret = -EINVAL; + goto err_hwlock; + } + } } map->dev = dev; map->bus = bus; diff --git a/include/linux/regmap.h b/include/linux/regmap.h index f5f08dd0a116..53620c70ae5e 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -504,6 +504,8 @@ typedef void (*regmap_hw_free_context)(void *context); * @max_raw_read: Max raw read size that can be used on the bus. * @max_raw_write: Max raw write size that can be used on the bus. * @free_on_exit: kfree this on exit of regmap + * @max_combined_rw: Max size for raw_read + raw_write, when they are issued + * together as part of the same message */ struct regmap_bus { bool fast_io; @@ -521,6 +523,7 @@ struct regmap_bus { enum regmap_endian val_format_endian_default; size_t max_raw_read; size_t max_raw_write; + size_t max_combined_rw; bool free_on_exit; }; From patchwork Wed Sep 8 11:34:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas tanure X-Patchwork-Id: 508216 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96316C433F5 for ; Wed, 8 Sep 2021 11:35:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7C92161157 for ; Wed, 8 Sep 2021 11:35:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351494AbhIHLgO (ORCPT ); Wed, 8 Sep 2021 07:36:14 -0400 Received: from mx0b-001ae601.pphosted.com ([67.231.152.168]:4132 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230001AbhIHLgH (ORCPT ); Wed, 8 Sep 2021 07:36:07 -0400 Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 18858Mnw005982; Wed, 8 Sep 2021 06:34:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=MoiIevtL85Y16R9q8xqo8FIaL+3c11Wqy6V7xvcx3nQ=; b=RR7nKv+N0pZPRY4vr5MJpZHzfMwzkS5Hyts8I0NJRNbjM00Zk4nJdh7ZcicvAuZ/kQnK YqSrt5NFewUQDRCLGQlf4kDOWiiaJbkCU7TNKeuLNlp81NFQfchQsK2anK4e6ZxwraSh hw2dVdj6XE/wKjCd+hPDxjrnZVa8cmE9m8yHBf9V737Y7YN777K18KP2okN6CWKYuCe9 y6yUJ3DBYNQX4zm/RJkMZAWXUuFqehsX7sz++jMVK/mVqHHEmS0jXXOgZyvJ2nGLlPBn FDQOHDHuisvyJdNU4bxUf3iBi5wh2VwYvCfaC+APrPo+mnzHRfOKS7rLJYez2MdG2P55 VA== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3axcp997pf-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 08 Sep 2021 06:34:57 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Wed, 8 Sep 2021 12:34:55 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.12 via Frontend Transport; Wed, 8 Sep 2021 12:34:55 +0100 Received: from aryzen.ad.cirrus.com (unknown [198.61.64.231]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 85B752BA; Wed, 8 Sep 2021 11:34:55 +0000 (UTC) From: Lucas Tanure To: Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Sanjay R Mehta , Nehal Bakulchandra Shah CC: , , , Lucas Tanure Subject: [PATCH 07/10] spi: amd: Check for idle bus before execute opcode Date: Wed, 8 Sep 2021 12:34:48 +0100 Message-ID: <20210908113450.788452-8-tanureal@opensource.cirrus.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210908113450.788452-1-tanureal@opensource.cirrus.com> References: <20210908113450.788452-1-tanureal@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: FpF_I13L5b940pH3xbIhmrQ2qs6bdQVV X-Proofpoint-ORIG-GUID: FpF_I13L5b940pH3xbIhmrQ2qs6bdQVV X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Check if the bus is not in use before starting the transfer Signed-off-by: Lucas Tanure --- drivers/spi/spi-amd.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c index 97838b57871c..99b2b0ccff08 100644 --- a/drivers/spi/spi-amd.c +++ b/drivers/spi/spi-amd.c @@ -115,11 +115,18 @@ static int amd_spi_busy_wait(struct amd_spi *amd_spi) return 0; } -static void amd_spi_execute_opcode(struct amd_spi *amd_spi) +static int amd_spi_execute_opcode(struct amd_spi *amd_spi) { + int ret; + + ret = amd_spi_busy_wait(amd_spi); + if (ret) + return ret; + /* Set ExecuteOpCode bit in the CTRL0 register */ amd_spi_setclear_reg32(amd_spi, AMD_SPI_CTRL0_REG, AMD_SPI_EXEC_CMD, AMD_SPI_EXEC_CMD); - amd_spi_busy_wait(amd_spi); + + return 0; } static int amd_spi_master_setup(struct spi_device *spi) From patchwork Wed Sep 8 11:34:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas tanure X-Patchwork-Id: 508214 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D0DDC433EF for ; Wed, 8 Sep 2021 11:35:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 35A0561157 for ; Wed, 8 Sep 2021 11:35:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351509AbhIHLgP (ORCPT ); Wed, 8 Sep 2021 07:36:15 -0400 Received: from mx0b-001ae601.pphosted.com ([67.231.152.168]:10332 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349260AbhIHLgI (ORCPT ); Wed, 8 Sep 2021 07:36:08 -0400 Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 18858Mnx005982; Wed, 8 Sep 2021 06:34:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=r8rlPxkjnx4t2zjv5bpgb48oXydfc5StSuoYQheuYG0=; b=FZrQHj/U+A0twoHgNbRNqv1ig0tfPKL7MBt+dhbHc5YosBfOhCIx3BRtLhVsZpWvunnS WkAbqVIGxzLffpWQ1w9NuWl2Vc/I+29Aj32apC8VcxRYgpbrZN6HAV/5eF2R8zISZqim qDQTh5yDC/3+/ovoyt1fuKmLzUih6rczJcqxXZ/svNCLPtgJqCEvy15wZhO6FnHdI0ES 7x9/C56aN6dTnusu5kMbJA7KluPSDprThKvHdBYewndOTbyNr9MXtShCNJXzmKhKv4S3 tt389u1g3Kq3S1heU9D80ZPsgzd11QF4LQ6beEbv+kajj71ZQ8kklGPCJLZqAWo36fNr mQ== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3axcp997pf-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 08 Sep 2021 06:34:57 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Wed, 8 Sep 2021 12:34:56 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.12 via Frontend Transport; Wed, 8 Sep 2021 12:34:56 +0100 Received: from aryzen.ad.cirrus.com (unknown [198.61.64.231]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id CFD26B13; Wed, 8 Sep 2021 11:34:55 +0000 (UTC) From: Lucas Tanure To: Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Sanjay R Mehta , Nehal Bakulchandra Shah CC: , , , Lucas Tanure Subject: [PATCH 08/10] spi: amd: Fill FIFO buffer with the whole message Date: Wed, 8 Sep 2021 12:34:49 +0100 Message-ID: <20210908113450.788452-9-tanureal@opensource.cirrus.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210908113450.788452-1-tanureal@opensource.cirrus.com> References: <20210908113450.788452-1-tanureal@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: u7UwV8Zb2IVpBDCO9pd_puPIv6WND8cs X-Proofpoint-ORIG-GUID: u7UwV8Zb2IVpBDCO9pd_puPIv6WND8cs X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org The controller is half-duplex, in that it cannot read data while it is sending data. But the FIFO is full-duplex, the writes and reads must be queued and executed together, and the read data will be offset in the FIFO by the length of the initial write data (as it would in a full-duplex SPI). And the controller has an automatic CS which can only be activated during the transmission of the FIFO, which can make read|write data lose meaning as the CS will be toggle after the required read|write address. To avoid that set the max transfer and message size as AMD_SPI_FIFO_SIZE ensuring that incoming messages always fit inside a FIFO buffer Signed-off-by: Lucas Tanure --- drivers/spi/spi-amd.c | 193 +++++++++++++++++++++++++++--------------- 1 file changed, 125 insertions(+), 68 deletions(-) diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c index 99b2b0ccff08..0face11740ea 100644 --- a/drivers/spi/spi-amd.c +++ b/drivers/spi/spi-amd.c @@ -4,7 +4,8 @@ // // Copyright (c) 2020, Advanced Micro Devices, Inc. // -// Author: Sanjay R Mehta +// Authors: Sanjay R Mehta +// Lucas Tanure #include #include @@ -28,6 +29,7 @@ #define AMD_SPI_RX_COUNT_REG 0x4B #define AMD_SPI_STATUS_REG 0x4C +#define AMD_SPI_FIFO_SIZE 70 #define AMD_SPI_MEM_SIZE 200 /* M_CMD OP codes for SPI */ @@ -38,6 +40,13 @@ struct amd_spi { void __iomem *io_remap_addr; unsigned long io_base_addr; u32 rom_addr; + struct list_head rbuf_head; +}; + +struct amd_spi_read_buffer { + struct list_head node; + u8 *buf; + u8 len; }; static inline u8 amd_spi_readreg8(struct amd_spi *amd_spi, int idx) @@ -138,83 +147,127 @@ static int amd_spi_master_setup(struct spi_device *spi) return 0; } -static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, - struct spi_master *master, - struct spi_message *message) +static void amd_spi_clear_list(struct amd_spi *amd_spi) { - struct spi_transfer *xfer = NULL; - u8 cmd_opcode; - u8 *buf = NULL; - u32 m_cmd = 0; - u32 i = 0; - u32 tx_len = 0, rx_len = 0; - - list_for_each_entry(xfer, &message->transfers, - transfer_list) { - if (xfer->rx_buf) - m_cmd = AMD_SPI_XFER_RX; - if (xfer->tx_buf) - m_cmd = AMD_SPI_XFER_TX; - - if (m_cmd & AMD_SPI_XFER_TX) { - buf = (u8 *)xfer->tx_buf; - tx_len = xfer->len - 1; - cmd_opcode = *(u8 *)xfer->tx_buf; - buf++; - amd_spi_set_opcode(amd_spi, cmd_opcode); - - /* Write data into the FIFO. */ - for (i = 0; i < tx_len; i++) { - iowrite8(buf[i], ((u8 __iomem *)amd_spi->io_remap_addr + - AMD_SPI_FIFO_BASE + i)); - } + struct amd_spi_read_buffer *rbuf, *tmp; - amd_spi_set_tx_count(amd_spi, tx_len); - amd_spi_clear_fifo_ptr(amd_spi); - /* Execute command */ - amd_spi_execute_opcode(amd_spi); - } - if (m_cmd & AMD_SPI_XFER_RX) { - /* - * Store no. of bytes to be received from - * FIFO - */ - rx_len = xfer->len; - buf = (u8 *)xfer->rx_buf; - amd_spi_set_rx_count(amd_spi, rx_len); - amd_spi_clear_fifo_ptr(amd_spi); - /* Execute command */ - amd_spi_execute_opcode(amd_spi); - /* Read data from FIFO to receive buffer */ - for (i = 0; i < rx_len; i++) - buf[i] = amd_spi_readreg8(amd_spi, AMD_SPI_FIFO_BASE + tx_len + i); - } + list_for_each_entry_safe(rbuf, tmp, &amd_spi->rbuf_head, node) { + list_del(&rbuf->node); + kfree(rbuf); } +} - /* Update statistics */ - message->actual_length = tx_len + rx_len + 1; - /* complete the transaction */ - message->status = 0; - spi_finalize_current_message(master); +static int amd_spi_transfer(struct amd_spi *amd_spi, u8 opcode, u8 tx_len, u8 rx_len, u8 fifo_pos) +{ + struct amd_spi_read_buffer *rbuf; + struct list_head *p; + int ret, i; + + amd_spi_set_opcode(amd_spi, opcode); + amd_spi_set_tx_count(amd_spi, tx_len); + amd_spi_set_rx_count(amd_spi, rx_len); + + ret = amd_spi_execute_opcode(amd_spi); + if (ret) + return ret; + + if (!list_empty(&amd_spi->rbuf_head)) { + ret = amd_spi_busy_wait(amd_spi); + if (ret) + return ret; + list_for_each(p, &amd_spi->rbuf_head) { + rbuf = list_entry(p, struct amd_spi_read_buffer, node); + for (i = 0; i < rbuf->len; i++) + rbuf->buf[i] = amd_spi_readreg8(amd_spi, fifo_pos++); + } + amd_spi_clear_list(amd_spi); + } return 0; } -static int amd_spi_master_transfer(struct spi_master *master, - struct spi_message *msg) +/* amd_spi_master_transfer expects a spi_message with no more than AMD_SPI_FIFO_SIZE and no TX after + * a RX in the same CS + * The CS can not be held between two amd_spi_execute_opcode so fill the FIFO with all transfers + * until the first RX transfer + */ +static int amd_spi_transfer_one_message(struct spi_controller *ctrl, struct spi_message *msg) { - struct amd_spi *amd_spi = spi_master_get_devdata(master); - struct spi_device *spi = msg->spi; + struct amd_spi *amd_spi = spi_master_get_devdata(ctrl); + u8 tx_len = 0, rx_len = 0, opcode = 0, fifo_pos = AMD_SPI_FIFO_BASE; + struct amd_spi_read_buffer *rbuf; + struct spi_transfer *xfer; + u8 *tx_buf; + int ret, i; + + amd_spi_select_chip(amd_spi, msg->spi->chip_select); + + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + if (xfer->tx_buf) { + tx_buf = (u8 *)xfer->tx_buf; + if (!tx_len) { + opcode = tx_buf[0]; + xfer->len--; + tx_buf++; + } + tx_len += xfer->len; + for (i = 0; i < xfer->len; i++) + amd_spi_writereg8(amd_spi, fifo_pos++, tx_buf[i]); + } - amd_spi_select_chip(amd_spi, spi->chip_select); + if (xfer->rx_buf) { + rx_len += xfer->len; + rbuf = kmalloc(sizeof(*rbuf), GFP_KERNEL); + if (!rbuf) { + ret = -ENOMEM; + goto complete; + } - /* - * Extract spi_transfers from the spi message and - * program the controller. - */ - amd_spi_fifo_xfer(amd_spi, master, msg); + rbuf->buf = (u8 *)xfer->rx_buf; + rbuf->len = xfer->len; + list_add(&rbuf->node, &amd_spi->rbuf_head); + } - return 0; + if (xfer->cs_change) { + ret = amd_spi_transfer(amd_spi, opcode, tx_len, rx_len, fifo_pos); + if (ret) + goto complete; + + msg->actual_length += rx_len; + if (tx_len) + msg->actual_length += tx_len + 1; + + fifo_pos = AMD_SPI_FIFO_BASE; + opcode = 0; + tx_len = 0; + rx_len = 0; + } + } + + if (tx_len || rx_len) { + ret = amd_spi_transfer(amd_spi, opcode, tx_len, rx_len, fifo_pos); + if (ret) + goto complete; + + msg->actual_length += rx_len; + if (tx_len) + msg->actual_length += tx_len + 1; + } + ret = 0; + +complete: + if (!list_empty(&amd_spi->rbuf_head)) + amd_spi_clear_list(amd_spi); + /* complete the transaction */ + msg->status = ret; + spi_finalize_current_message(ctrl); + + return ret; +} + +static size_t amd_spi_max_transfer_size(struct spi_device *spi) +{ + return AMD_SPI_FIFO_SIZE; } static int amd_spi_probe(struct platform_device *pdev) @@ -244,9 +297,13 @@ static int amd_spi_probe(struct platform_device *pdev) master->bus_num = 0; master->num_chipselect = 4; master->mode_bits = 0; - master->flags = SPI_MASTER_HALF_DUPLEX; + master->flags = SPI_CONTROLLER_HALF_DUPLEX | SPI_CONTROLLER_NO_TX_RX_CS; master->setup = amd_spi_master_setup; - master->transfer_one_message = amd_spi_master_transfer; + master->max_transfer_size = amd_spi_max_transfer_size; + master->max_message_size = amd_spi_max_transfer_size; + master->transfer_one_message = amd_spi_transfer_one_message; + + INIT_LIST_HEAD(&amd_spi->rbuf_head); /* Register the controller with SPI framework */ err = devm_spi_register_master(dev, master); From patchwork Wed Sep 8 11:34:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas tanure X-Patchwork-Id: 508215 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 36C7BC433EF for ; Wed, 8 Sep 2021 11:35:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2232E61157 for ; Wed, 8 Sep 2021 11:35:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1351501AbhIHLgO (ORCPT ); Wed, 8 Sep 2021 07:36:14 -0400 Received: from mx0b-001ae601.pphosted.com ([67.231.152.168]:63010 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349250AbhIHLgI (ORCPT ); Wed, 8 Sep 2021 07:36:08 -0400 Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 188696pH006454; Wed, 8 Sep 2021 06:34:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=LPzaIAxW5XbFVS/aMf6K6BQPMF1FbSUIgIEO42VpVCI=; b=hXobeoKXFNdP+nXAZN8BFjw7CkInAcjp57ynGCiPxLmZfchBp+1TI+gAm07j5da42JZq 5v4Xo2dKb4TyYTZzYNLExfWkty1qdhwxfGuN+uRMKVFndgGtptxuSMRFmnhDSvrWlrQ+ /BWIeKkQ90WwRME+7m9OvGNKhR53dHCJPGC6klZRPjmoLZrC1z8pKb7VmtO/brLJVEL4 ubPRecDjD+WzykA2fLok8rm388rZ6Z+4yWNFqoQT9wrEzCglOysgYIv/JsFBNoFidxIQ /nOuh3FBgIUNU4bWI1RenqYIekFjOcjAdBPnu0rGLnxFlYWitFdW2e2kUTra24dVlUQy FQ== Received: from ediex01.ad.cirrus.com ([87.246.76.36]) by mx0b-001ae601.pphosted.com with ESMTP id 3axcp997pg-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Wed, 08 Sep 2021 06:34:58 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Wed, 8 Sep 2021 12:34:56 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.12 via Frontend Transport; Wed, 8 Sep 2021 12:34:56 +0100 Received: from aryzen.ad.cirrus.com (unknown [198.61.64.231]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 1F1B22BA; Wed, 8 Sep 2021 11:34:56 +0000 (UTC) From: Lucas Tanure To: Mark Brown , Greg Kroah-Hartman , "Rafael J . Wysocki" , Sanjay R Mehta , Nehal Bakulchandra Shah CC: , , , Lucas Tanure Subject: [PATCH 09/10] spi: amd: Add support for latest platform Date: Wed, 8 Sep 2021 12:34:50 +0100 Message-ID: <20210908113450.788452-10-tanureal@opensource.cirrus.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210908113450.788452-1-tanureal@opensource.cirrus.com> References: <20210908113450.788452-1-tanureal@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-GUID: 4Rhr8vUr20dffprQCcGupmOFbl7JxjDO X-Proofpoint-ORIG-GUID: 4Rhr8vUr20dffprQCcGupmOFbl7JxjDO X-Proofpoint-Spam-Reason: safe Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org From: Nehal Bakulchandra Shah Add support for AMDI0062 controller Signed-off-by: Nehal Bakulchandra Shah Signed-off-by: Lucas Tanure --- drivers/spi/spi-amd.c | 128 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 24 deletions(-) diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c index 0face11740ea..788a5c42d811 100644 --- a/drivers/spi/spi-amd.c +++ b/drivers/spi/spi-amd.c @@ -2,9 +2,10 @@ // // AMD SPI controller driver // -// Copyright (c) 2020, Advanced Micro Devices, Inc. +// Copyright (c) 2020-2021, Advanced Micro Devices, Inc. // // Authors: Sanjay R Mehta +// Nehal Bakulchandra Shah // Lucas Tanure #include @@ -14,33 +15,48 @@ #include #include -#define AMD_SPI_CTRL0_REG 0x00 -#define AMD_SPI_EXEC_CMD BIT(16) -#define AMD_SPI_FIFO_CLEAR BIT(20) -#define AMD_SPI_BUSY BIT(31) +#define AMD_SPI_CTRL0_REG 0x00 +#define AMD_SPI_EXEC_CMD BIT(16) +#define AMD_SPI_FIFO_CLEAR BIT(20) +#define AMD_SPI_BUSY BIT(31) +#define AMD_SPI_ENABLE_REG 0x20 -#define AMD_SPI_OPCODE_MASK 0xFF +#define AMD_SPI_DUMMY_CYCL_REG 0x32 +#define AMD_SPI_OPCODE_REG 0x45 +#define AMD_SPI_CMD_TRIGGER_REG 0x47 +#define AMD_SPI_TRIGGER_CMD BIT(7) +#define AMD_SPI_OPCODE_MASK 0xFF -#define AMD_SPI_ALT_CS_REG 0x1D -#define AMD_SPI_ALT_CS_MASK 0x3 +#define AMD_SPI_ALT_CS_REG 0x1D +#define AMD_SPI_ALT_CS_MASK GENMASK(1, 0) -#define AMD_SPI_FIFO_BASE 0x80 -#define AMD_SPI_TX_COUNT_REG 0x48 -#define AMD_SPI_RX_COUNT_REG 0x4B -#define AMD_SPI_STATUS_REG 0x4C +#define AMD_SPI_FIFO_BASE 0x80 +#define AMD_SPI_TX_COUNT_REG 0x48 +#define AMD_SPI_RX_COUNT_REG 0x4B +#define AMD_SPI_STATUS_REG 0x4C -#define AMD_SPI_FIFO_SIZE 70 -#define AMD_SPI_MEM_SIZE 200 +#define AMD_SPI_FIFO_SIZE 70 +#define AMD_SPI_MEM_SIZE 200 /* M_CMD OP codes for SPI */ -#define AMD_SPI_XFER_TX 1 -#define AMD_SPI_XFER_RX 2 +#define AMD_SPI_XFER_TX 1 +#define AMD_SPI_XFER_RX 2 struct amd_spi { void __iomem *io_remap_addr; unsigned long io_base_addr; u32 rom_addr; struct list_head rbuf_head; + const struct amd_spi_devtype_data *devtype_data; + struct spi_device *spi_dev; + struct spi_master *master; +}; + +struct amd_spi_devtype_data { + u8 version; + int (*exec_op)(struct amd_spi *amd_spi); + void (*set_op)(struct amd_spi *amd_spi, u8 cmd_opcode); + int (*busy_wait)(struct amd_spi *amd_spi); }; struct amd_spi_read_buffer { @@ -90,16 +106,26 @@ static void amd_spi_select_chip(struct amd_spi *amd_spi, u8 cs) amd_spi_setclear_reg8(amd_spi, AMD_SPI_ALT_CS_REG, cs, AMD_SPI_ALT_CS_MASK); } +static inline void amd_spi_clear_chip(struct amd_spi *amd_spi, u8 chip_select) +{ + amd_spi_writereg8(amd_spi, AMD_SPI_ALT_CS_REG, chip_select & ~AMD_SPI_ALT_CS_MASK); +} + static void amd_spi_clear_fifo_ptr(struct amd_spi *amd_spi) { amd_spi_setclear_reg32(amd_spi, AMD_SPI_CTRL0_REG, AMD_SPI_FIFO_CLEAR, AMD_SPI_FIFO_CLEAR); } -static void amd_spi_set_opcode(struct amd_spi *amd_spi, u8 cmd_opcode) +static void amd_spi_set_opcode_v1(struct amd_spi *amd_spi, u8 cmd_opcode) { amd_spi_setclear_reg32(amd_spi, AMD_SPI_CTRL0_REG, cmd_opcode, AMD_SPI_OPCODE_MASK); } +static void amd_spi_set_opcode_v2(struct amd_spi *amd_spi, u8 cmd_opcode) +{ + amd_spi_writereg8(amd_spi, AMD_SPI_OPCODE_REG, cmd_opcode); +} + static inline void amd_spi_set_rx_count(struct amd_spi *amd_spi, u8 rx_count) { amd_spi_setclear_reg8(amd_spi, AMD_SPI_RX_COUNT_REG, rx_count, 0xff); @@ -110,7 +136,7 @@ static inline void amd_spi_set_tx_count(struct amd_spi *amd_spi, u8 tx_count) amd_spi_setclear_reg8(amd_spi, AMD_SPI_TX_COUNT_REG, tx_count, 0xff); } -static int amd_spi_busy_wait(struct amd_spi *amd_spi) +static int amd_spi_busy_wait_v1(struct amd_spi *amd_spi) { int timeout = 100000; @@ -124,11 +150,11 @@ static int amd_spi_busy_wait(struct amd_spi *amd_spi) return 0; } -static int amd_spi_execute_opcode(struct amd_spi *amd_spi) +static int amd_spi_execute_opcode_v1(struct amd_spi *amd_spi) { int ret; - ret = amd_spi_busy_wait(amd_spi); + ret = amd_spi_busy_wait_v1(amd_spi); if (ret) return ret; @@ -138,6 +164,33 @@ static int amd_spi_execute_opcode(struct amd_spi *amd_spi) return 0; } +static int amd_spi_busy_wait_v2(struct amd_spi *amd_spi) +{ + int timeout = 100000; + + while (amd_spi_readreg32(amd_spi, AMD_SPI_STATUS_REG) & AMD_SPI_BUSY) { + usleep_range(10, 20); + if (timeout-- < 0) + return -ETIMEDOUT; + } + + return 0; +} + +static int amd_spi_execute_opcode_v2(struct amd_spi *amd_spi) +{ + int ret; + + ret = amd_spi_busy_wait_v2(amd_spi); + if (ret) + return ret; + + amd_spi_setclear_reg8(amd_spi, AMD_SPI_CMD_TRIGGER_REG, AMD_SPI_TRIGGER_CMD, + AMD_SPI_TRIGGER_CMD); + + return 0; +} + static int amd_spi_master_setup(struct spi_device *spi) { struct amd_spi *amd_spi = spi_master_get_devdata(spi->master); @@ -159,20 +212,21 @@ static void amd_spi_clear_list(struct amd_spi *amd_spi) static int amd_spi_transfer(struct amd_spi *amd_spi, u8 opcode, u8 tx_len, u8 rx_len, u8 fifo_pos) { + const struct amd_spi_devtype_data *priv = amd_spi->devtype_data; struct amd_spi_read_buffer *rbuf; struct list_head *p; int ret, i; - amd_spi_set_opcode(amd_spi, opcode); + priv->set_op(amd_spi, opcode); amd_spi_set_tx_count(amd_spi, tx_len); amd_spi_set_rx_count(amd_spi, rx_len); - ret = amd_spi_execute_opcode(amd_spi); + ret = priv->exec_op(amd_spi); if (ret) return ret; if (!list_empty(&amd_spi->rbuf_head)) { - ret = amd_spi_busy_wait(amd_spi); + ret = priv->busy_wait(amd_spi); if (ret) return ret; list_for_each(p, &amd_spi->rbuf_head) { @@ -262,6 +316,9 @@ static int amd_spi_transfer_one_message(struct spi_controller *ctrl, struct spi_ msg->status = ret; spi_finalize_current_message(ctrl); + if (amd_spi->devtype_data->version) + amd_spi_clear_chip(amd_spi, msg->spi->chip_select); + return ret; } @@ -293,6 +350,12 @@ static int amd_spi_probe(struct platform_device *pdev) } dev_dbg(dev, "io_remap_address: %p\n", amd_spi->io_remap_addr); + amd_spi->devtype_data = device_get_match_data(dev); + if (!amd_spi->devtype_data) { + err = -ENODEV; + goto err_free_master; + } + /* Initialize the spi_master fields */ master->bus_num = 0; master->num_chipselect = 4; @@ -320,9 +383,25 @@ static int amd_spi_probe(struct platform_device *pdev) return err; } +static const struct amd_spi_devtype_data spi_v1 = { + .exec_op = amd_spi_execute_opcode_v1, + .set_op = amd_spi_set_opcode_v1, + .busy_wait = amd_spi_busy_wait_v1, +}; + +static const struct amd_spi_devtype_data spi_v2 = { + .version = 1, + .exec_op = amd_spi_execute_opcode_v2, + .set_op = amd_spi_set_opcode_v2, + .busy_wait = amd_spi_busy_wait_v2, +}; + #ifdef CONFIG_ACPI static const struct acpi_device_id spi_acpi_match[] = { - { "AMDI0061", 0 }, + { "AMDI0061", + .driver_data = (kernel_ulong_t)&spi_v1 }, + { "AMDI0062", + .driver_data = (kernel_ulong_t)&spi_v2 }, {}, }; MODULE_DEVICE_TABLE(acpi, spi_acpi_match); @@ -340,4 +419,5 @@ module_platform_driver(amd_spi_driver); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Sanjay Mehta "); +MODULE_AUTHOR("Nehal Bakulchandra Shah "); MODULE_DESCRIPTION("AMD SPI Master Controller Driver");