From patchwork Mon Aug 12 22:36:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 11090971 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A0F8313AC for ; Mon, 12 Aug 2019 22:36:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 91C5327F90 for ; Mon, 12 Aug 2019 22:36:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8636A28384; Mon, 12 Aug 2019 22:36:52 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 1E09927F90 for ; Mon, 12 Aug 2019 22:36:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727116AbfHLWg0 (ORCPT ); Mon, 12 Aug 2019 18:36:26 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:33195 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726488AbfHLWg0 (ORCPT ); Mon, 12 Aug 2019 18:36:26 -0400 Received: by mail-pg1-f194.google.com with SMTP id n190so9385547pgn.0 for ; Mon, 12 Aug 2019 15:36:25 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=DEVqEnZhQhVV35dLTE4fV+ZJ16fecFLxF4vVFu1o1hU=; b=BfJxQ05nyCUD2yykz83BYfJcO7SjUsLU4oEJou/mnS22Lte6HruK8O6ckupd9hUxw7 lUSbPWVbmOP2oeJbyjDnPoYCMKQpniyn/DegbKcbIWj+YwPj+9QuiQnm4VmvFL5KqLey KaKTAoNHbMYPrUFlRM+L1RzmsaJjWXSrNC7RI= 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:mime-version:content-transfer-encoding; bh=DEVqEnZhQhVV35dLTE4fV+ZJ16fecFLxF4vVFu1o1hU=; b=kDKiqh1yxwEmdyDQJVTqd4SC0IK29j0NrjZ4+731dja3cjDlqUx4OWzvOxJOqfTSkx ypXrLbQgpJWF5mLzLIi2FEB5PxjNIzyrHTc9OY35Cs4F1XvH3Mbsq+aPevJ86NMDEYS5 YsYtpZcCcq3X52AJr4BEKO0ZBKrDHCarGXD0C6cI7nFnbquhP7IWjiDyAe+snDp+A1Nr oAu09xLWmPFLi50JXEMfBlIG4MEx7EMZL0Asg+qmkGFmg8RY5I9Jd1SNNKzkXxm6hTbF 97wi0ccNJZNc8t+/SuIGR2wfnruqEY3h4tEy0BRc5fQIxQD4l2chjnM8TmVun2QDPM1Y v86A== X-Gm-Message-State: APjAAAXN4IHwPsZZXdz83ioIDMGt2SaT/8MBS55snoOFZLeKdbJNSZr4 ybraoM6Vn2+zou9TSzIwtM6zdw== X-Google-Smtp-Source: APXvYqz86X3o0dGJ23vCO1fyItdzE6+jO7gjy9ZsDTYcnR/UMFXR30FC+/Cmr/ihjD9Gny74O6ywfw== X-Received: by 2002:a62:8688:: with SMTP id x130mr9714539pfd.162.1565649385400; Mon, 12 Aug 2019 15:36:25 -0700 (PDT) Received: from smtp.gmail.com ([2620:15c:202:1:fa53:7765:582b:82b9]) by smtp.gmail.com with ESMTPSA id b6sm93911594pgq.26.2019.08.12.15.36.24 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 12 Aug 2019 15:36:24 -0700 (PDT) From: Stephen Boyd To: Peter Huewe , Jarkko Sakkinen Cc: linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org, Andrey Pronin , Duncan Laurie , Jason Gunthorpe , Arnd Bergmann , Greg Kroah-Hartman , Guenter Roeck , Alexander Steffen Subject: [PATCH v4 1/6] tpm: Add a flag to indicate TPM power is managed by firmware Date: Mon, 12 Aug 2019 15:36:17 -0700 Message-Id: <20190812223622.73297-2-swboyd@chromium.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812223622.73297-1-swboyd@chromium.org> References: <20190812223622.73297-1-swboyd@chromium.org> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On some platforms, the TPM power is managed by firmware and therefore we don't need to stop the TPM on suspend when going to a light version of suspend such as S0ix ("freeze" suspend state). Add a chip flag, TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED, to indicate this so that certain platforms can probe for the usage of this light suspend and avoid touching the TPM state across suspend/resume. Cc: Andrey Pronin Cc: Duncan Laurie Cc: Jason Gunthorpe Cc: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: Guenter Roeck Cc: Alexander Steffen Signed-off-by: Stephen Boyd Reviewed-by: Jarkko Sakkinen --- drivers/char/tpm/tpm-interface.c | 8 +++++++- drivers/char/tpm/tpm.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 1b4f95c13e00..0b3def8e8186 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -395,7 +396,11 @@ int tpm_pm_suspend(struct device *dev) return -ENODEV; if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED) - return 0; + goto suspended; + + if ((chip->flags & TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED) && + !pm_suspend_via_firmware()) + goto suspended; if (!tpm_chip_start(chip)) { if (chip->flags & TPM_CHIP_FLAG_TPM2) @@ -406,6 +411,7 @@ int tpm_pm_suspend(struct device *dev) tpm_chip_stop(chip); } +suspended: return rc; } EXPORT_SYMBOL_GPL(tpm_pm_suspend); diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index e503ffc3aa39..28f73331aa2e 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -162,6 +162,7 @@ enum tpm_chip_flags { TPM_CHIP_FLAG_VIRTUAL = BIT(3), TPM_CHIP_FLAG_HAVE_TIMEOUTS = BIT(4), TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), + TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED = BIT(6), }; #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev) From patchwork Mon Aug 12 22:36:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 11090969 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D48E813AC for ; Mon, 12 Aug 2019 22:36:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C335927F90 for ; Mon, 12 Aug 2019 22:36:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B70362823E; Mon, 12 Aug 2019 22:36:51 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 1D03B28384 for ; Mon, 12 Aug 2019 22:36:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727284AbfHLWgp (ORCPT ); Mon, 12 Aug 2019 18:36:45 -0400 Received: from mail-pg1-f193.google.com ([209.85.215.193]:38929 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727151AbfHLWg1 (ORCPT ); Mon, 12 Aug 2019 18:36:27 -0400 Received: by mail-pg1-f193.google.com with SMTP id u17so50192926pgi.6 for ; Mon, 12 Aug 2019 15:36:26 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=G1GyJeHxK3pLSUGiO0YqwSLuWrA1RPqBG46rl6iGQ1s=; b=geQsoQ49HygUno2jknhm/5tkiWZxIR99UnMgMqLmz+2kVJ+u+dULTQe2yvZxTIU9XE mYN8oyWmjYVz5J+35rcExedP4HNSIYZORXL933ibyeyrh9j4x94vN7/CD7tKIgylySye GV9xj5Og/JcK1Ve+R7xdxdJnaJCamxQnIY10w= 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:mime-version:content-transfer-encoding; bh=G1GyJeHxK3pLSUGiO0YqwSLuWrA1RPqBG46rl6iGQ1s=; b=pMWrjVx8t0/HTvMumqIV+pofwqilklhfoaue6tUzMLebjHBHCJFD9IMs4NjIXXX+97 KW/kJ+JjDWjpV2lFOAt3tIIAHTbASfSMevuUBf+wDrQBVKo2psAB0blpBe/WFwTGtc+s vN5EQSq0Ng9qCIheIrXCe9q7pWy2ZobFQ7b1KK22xrvb9wuXR/2J+ze4Dj9yvlAHCa1H 1zSZ5SWQiAFRaAMhn9qirjc8MCcvg5wXiNCJOePMHiRWzZCS7tQUDKXnV+DvvGqO0xDV 6Rd7XFUHvhCObzArB0bqNyZ0IwgkIodexR944XZge9iNFffmI5UC+326vSq30Ypa0z8d DlCQ== X-Gm-Message-State: APjAAAXL90QRTpN1gEo47vuXI38QkwrTrnouSyqAhiE2LITt31Vk0Stk YbYqgU0h+ywpNIi6EiJasIIL7w== X-Google-Smtp-Source: APXvYqySaV6YpLXAdPxlUhjGdH9PpCPLsa2Hp/dqfsVZSEg/dLbajPrX4bseW4PkHigNheTRFb11Zg== X-Received: by 2002:a17:90a:8c90:: with SMTP id b16mr1357627pjo.133.1565649386242; Mon, 12 Aug 2019 15:36:26 -0700 (PDT) Received: from smtp.gmail.com ([2620:15c:202:1:fa53:7765:582b:82b9]) by smtp.gmail.com with ESMTPSA id b6sm93911594pgq.26.2019.08.12.15.36.25 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 12 Aug 2019 15:36:25 -0700 (PDT) From: Stephen Boyd To: Peter Huewe , Jarkko Sakkinen Cc: linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org, Andrey Pronin , Duncan Laurie , Jason Gunthorpe , Arnd Bergmann , Greg Kroah-Hartman , Guenter Roeck , Alexander Steffen Subject: [PATCH v4 2/6] tpm: tpm_tis_spi: Introduce a flow control callback Date: Mon, 12 Aug 2019 15:36:18 -0700 Message-Id: <20190812223622.73297-3-swboyd@chromium.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812223622.73297-1-swboyd@chromium.org> References: <20190812223622.73297-1-swboyd@chromium.org> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Cr50 firmware has a different flow control protocol than the one used by this TPM PTP SPI driver. Introduce a flow control callback so we can override the standard sequence with the custom one that Cr50 uses. Cc: Andrey Pronin Cc: Duncan Laurie Cc: Jason Gunthorpe Cc: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: Guenter Roeck Cc: Alexander Steffen Signed-off-by: Stephen Boyd --- drivers/char/tpm/tpm_tis_spi.c | 55 +++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c index 19513e622053..819602e85b34 100644 --- a/drivers/char/tpm/tpm_tis_spi.c +++ b/drivers/char/tpm/tpm_tis_spi.c @@ -42,6 +42,8 @@ struct tpm_tis_spi_phy { struct tpm_tis_data priv; struct spi_device *spi_device; + int (*flow_control)(struct tpm_tis_spi_phy *phy, + struct spi_transfer *xfer); u8 *iobuf; }; @@ -50,12 +52,39 @@ static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *da return container_of(data, struct tpm_tis_spi_phy, priv); } +static int tpm_tis_spi_flow_control(struct tpm_tis_spi_phy *phy, + struct spi_transfer *spi_xfer) +{ + struct spi_message m; + int ret, i; + + if ((phy->iobuf[3] & 0x01) == 0) { + // handle SPI wait states + phy->iobuf[0] = 0; + + for (i = 0; i < TPM_RETRY; i++) { + spi_xfer->len = 1; + spi_message_init(&m); + spi_message_add_tail(spi_xfer, &m); + ret = spi_sync_locked(phy->spi_device, &m); + if (ret < 0) + return ret; + if (phy->iobuf[0] & 0x01) + break; + } + + if (i == TPM_RETRY) + return -ETIMEDOUT; + } + + return 0; +} + static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, u8 *in, const u8 *out) { struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); int ret = 0; - int i; struct spi_message m; struct spi_transfer spi_xfer; u8 transfer_len; @@ -82,26 +111,9 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, if (ret < 0) goto exit; - if ((phy->iobuf[3] & 0x01) == 0) { - // handle SPI wait states - phy->iobuf[0] = 0; - - for (i = 0; i < TPM_RETRY; i++) { - spi_xfer.len = 1; - spi_message_init(&m); - spi_message_add_tail(&spi_xfer, &m); - ret = spi_sync_locked(phy->spi_device, &m); - if (ret < 0) - goto exit; - if (phy->iobuf[0] & 0x01) - break; - } - - if (i == TPM_RETRY) { - ret = -ETIMEDOUT; - goto exit; - } - } + ret = phy->flow_control(phy, &spi_xfer); + if (ret < 0) + goto exit; spi_xfer.cs_change = 0; spi_xfer.len = transfer_len; @@ -207,6 +219,7 @@ static int tpm_tis_spi_probe(struct spi_device *dev) phy->iobuf = devm_kmalloc(&dev->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL); if (!phy->iobuf) return -ENOMEM; + phy->flow_control = tpm_tis_spi_flow_control; /* If the SPI device has an IRQ then use that */ if (dev->irq > 0) From patchwork Mon Aug 12 22:36:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 11090965 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 76FFC112C for ; Mon, 12 Aug 2019 22:36:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 682A72823E for ; Mon, 12 Aug 2019 22:36:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5CA312855D; Mon, 12 Aug 2019 22:36:51 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 F1FA42823E for ; Mon, 12 Aug 2019 22:36:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727296AbfHLWgp (ORCPT ); Mon, 12 Aug 2019 18:36:45 -0400 Received: from mail-pf1-f196.google.com ([209.85.210.196]:46630 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727160AbfHLWg1 (ORCPT ); Mon, 12 Aug 2019 18:36:27 -0400 Received: by mail-pf1-f196.google.com with SMTP id q139so2135522pfc.13 for ; Mon, 12 Aug 2019 15:36:27 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=ARqGVqps+UvD6gPycAavcJDE2CdT6bD5OYORFnIVyA4=; b=P9G6y5o0oRHI87G+Axh3H0Q0lFVxG69Ev11gPscknQxS++hpSgrVr+Dz6m6gko17ad ndY5JECMTxJve5nKky69rtBFiunmAm0EkOnERFYVcbyhmyFZL20WXAzpaT5zaevxqmZh ICi/9Scec6pPJIaFjZ4EY496D2VMLbQFWuVF0= 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:mime-version:content-transfer-encoding; bh=ARqGVqps+UvD6gPycAavcJDE2CdT6bD5OYORFnIVyA4=; b=EfY7rLsU4LdGA4zMt3uhStHqLSuA0DlYr1f0ZOk2Cs1O8kbKYHjHOwB/Bv3z7pyz8F 1RZTAjtxMe5Uhtv/ICpVzPY7aGGaSGMWygmU6K7/+nYpdCqnqEr3mpCEbzPF1I9g5yc7 OEyzzZWgMUJeJj7kTa+Qa66Udlv5noDukqhieEc+3sQJIjhkNdq4VAUKsxpx3CsK1OFG CQhMtXLi4ibck5URhShEJMoNNGxrCTFsvJeKDgMVnD1emjvXS2WE4tkuNJzvVD7VuFG7 NnMAgi/WHw7L3h8xxknOQDQ63TEWBgja6GJ4qvdWC7PuB1+tcvlk50+JZ5afqbkiwbY4 e1HA== X-Gm-Message-State: APjAAAXFke58SyoQWAn3k8RP1yZAG9j48HVOJiiAhY+WKCIByzKqTGxW mI0IkAcdowPi24zFsvRJmOq1mQ== X-Google-Smtp-Source: APXvYqzUWfHrQolgxy4D/V0dl/A2RBuv86RieLCSdSWbN9BhIfnP3A1Tjww9sDQhKmaZIUj7PkFxRQ== X-Received: by 2002:a62:db43:: with SMTP id f64mr21707438pfg.38.1565649387079; Mon, 12 Aug 2019 15:36:27 -0700 (PDT) Received: from smtp.gmail.com ([2620:15c:202:1:fa53:7765:582b:82b9]) by smtp.gmail.com with ESMTPSA id b6sm93911594pgq.26.2019.08.12.15.36.26 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 12 Aug 2019 15:36:26 -0700 (PDT) From: Stephen Boyd To: Peter Huewe , Jarkko Sakkinen Cc: linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org, Andrey Pronin , Duncan Laurie , Jason Gunthorpe , Arnd Bergmann , Greg Kroah-Hartman , Guenter Roeck , Alexander Steffen Subject: [PATCH v4 3/6] tpm: tpm_tis_spi: Add a pre-transfer callback Date: Mon, 12 Aug 2019 15:36:19 -0700 Message-Id: <20190812223622.73297-4-swboyd@chromium.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812223622.73297-1-swboyd@chromium.org> References: <20190812223622.73297-1-swboyd@chromium.org> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Cr50 firmware has a requirement to wait for the TPM to wakeup before sending commands over the SPI bus. Otherwise, the firmware could be in deep sleep and not respond. Add a hook to tpm_tis_spi_transfer() before we start a SPI transfer so we can keep track of the last time the TPM driver accessed the SPI bus. Cc: Andrey Pronin Cc: Duncan Laurie Cc: Jason Gunthorpe Cc: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: Guenter Roeck Cc: Alexander Steffen Signed-off-by: Stephen Boyd --- drivers/char/tpm/tpm_tis_spi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c index 819602e85b34..93f49b1941f0 100644 --- a/drivers/char/tpm/tpm_tis_spi.c +++ b/drivers/char/tpm/tpm_tis_spi.c @@ -44,6 +44,7 @@ struct tpm_tis_spi_phy { struct spi_device *spi_device; int (*flow_control)(struct tpm_tis_spi_phy *phy, struct spi_transfer *xfer); + void (*pre_transfer)(struct tpm_tis_spi_phy *phy); u8 *iobuf; }; @@ -129,6 +130,8 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, spi_message_init(&m); spi_message_add_tail(&spi_xfer, &m); + if (phy->pre_transfer) + phy->pre_transfer(phy); ret = spi_sync_locked(phy->spi_device, &m); if (ret < 0) goto exit; From patchwork Mon Aug 12 22:36:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 11090967 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 93FD813B1 for ; Mon, 12 Aug 2019 22:36:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 80FB127F90 for ; Mon, 12 Aug 2019 22:36:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 73C48285B8; Mon, 12 Aug 2019 22:36:51 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 C84D027F90 for ; Mon, 12 Aug 2019 22:36:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726710AbfHLWgk (ORCPT ); Mon, 12 Aug 2019 18:36:40 -0400 Received: from mail-pf1-f196.google.com ([209.85.210.196]:36029 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727188AbfHLWg3 (ORCPT ); Mon, 12 Aug 2019 18:36:29 -0400 Received: by mail-pf1-f196.google.com with SMTP id r7so50424556pfl.3 for ; Mon, 12 Aug 2019 15:36:28 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=0c9PwmTM9ltU5QnbUwiYR8+C/VbtsAVi1RzWAMtBrRs=; b=NSVNdUkTnYkW+V2DvGuJh+mIquZ2rsUpyqli1yFhBeJl1XeDySN2NQPqxaroQcm+7m /lc8OR8QNA2uSqZ4XWj4jcnAXoci1AswHQyzxpZKQKyzY2L+sfUYQMz5l33B3A2LlHm5 4bYXPSA++/AzcxL++LzN2BNxysR06xyhu1P9o= 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:mime-version:content-transfer-encoding; bh=0c9PwmTM9ltU5QnbUwiYR8+C/VbtsAVi1RzWAMtBrRs=; b=HvSyjBjcus+xZ86xbmRAavvZnJg4xYCsAyALYLLsvuGkqWRwpk7CpyRBjlhiYPrerk CInB5m7SyW/tIZvKxUmxN2cgwImsNBFvFZVdtxTWOWpblzzuQo8Oe4nNS1+opd6KNBB5 pAMOYYRELtsWiDnR8FKdq+cT6kPulygqyo8yg7j2sOFJIkamFo5Nekp+Cgk+QrTiweFJ N9brvYDNZdpL3D5uXivwn2RxRnwfgLUn/OVLW0ZBGqxFxDrMqRaTAwW4s/g1a7aTOM7q 9nb7vBUXmEXgamV/JG2ea00dbjmlRBP1Fxf5HPlThOYnqi8Rubem6DfJZTeiwQqpn9K1 1jEg== X-Gm-Message-State: APjAAAUSUzI8FSVuRRAmL9F5xMCKJJGrdMkmQOs2BDwZK0D38ormvZeM SgALZ1uyHDT0m9AOBhxZBBs0Bu172aXfyQ== X-Google-Smtp-Source: APXvYqzdYeQ+IDgSl0t3LCKduwWR6Vzyc0PPLvErKyjapSqGM173P9/NUNDxkIuv/5ftEGNmS02aoQ== X-Received: by 2002:aa7:8f2e:: with SMTP id y14mr8497036pfr.113.1565649387975; Mon, 12 Aug 2019 15:36:27 -0700 (PDT) Received: from smtp.gmail.com ([2620:15c:202:1:fa53:7765:582b:82b9]) by smtp.gmail.com with ESMTPSA id b6sm93911594pgq.26.2019.08.12.15.36.27 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 12 Aug 2019 15:36:27 -0700 (PDT) From: Stephen Boyd To: Peter Huewe , Jarkko Sakkinen Cc: linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org, Andrey Pronin , Duncan Laurie , Jason Gunthorpe , Arnd Bergmann , Greg Kroah-Hartman , Guenter Roeck , Alexander Steffen Subject: [PATCH v4 4/6] tpm: tpm_tis_spi: Export functionality to other drivers Date: Mon, 12 Aug 2019 15:36:20 -0700 Message-Id: <20190812223622.73297-5-swboyd@chromium.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812223622.73297-1-swboyd@chromium.org> References: <20190812223622.73297-1-swboyd@chromium.org> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Export a new function, tpm_tis_spi_init(), and the associated read/write/transfer APIs so that we can create variant drivers based on the core functionality of this TPM SPI driver. Variant drivers can wrap the tpm_tis_spi_phy struct with their own struct and override the behavior of tpm_tis_spi_transfer() by supplying their own flow control and pre-transfer hooks. This shares the most code between the core driver and any variants that want to override certain behavior without cluttering the core driver. Cc: Andrey Pronin Cc: Duncan Laurie Cc: Jason Gunthorpe Cc: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: Guenter Roeck Cc: Alexander Steffen Signed-off-by: Stephen Boyd --- drivers/char/tpm/tpm_tis_spi.c | 52 ++++++++++++++++------------------ drivers/char/tpm/tpm_tis_spi.h | 37 ++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 27 deletions(-) create mode 100644 drivers/char/tpm/tpm_tis_spi.h diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c index 93f49b1941f0..fd3fb4f9f506 100644 --- a/drivers/char/tpm/tpm_tis_spi.c +++ b/drivers/char/tpm/tpm_tis_spi.c @@ -36,23 +36,10 @@ #include #include "tpm.h" #include "tpm_tis_core.h" +#include "tpm_tis_spi.h" #define MAX_SPI_FRAMESIZE 64 -struct tpm_tis_spi_phy { - struct tpm_tis_data priv; - struct spi_device *spi_device; - int (*flow_control)(struct tpm_tis_spi_phy *phy, - struct spi_transfer *xfer); - void (*pre_transfer)(struct tpm_tis_spi_phy *phy); - u8 *iobuf; -}; - -static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data) -{ - return container_of(data, struct tpm_tis_spi_phy, priv); -} - static int tpm_tis_spi_flow_control(struct tpm_tis_spi_phy *phy, struct spi_transfer *spi_xfer) { @@ -81,7 +68,7 @@ static int tpm_tis_spi_flow_control(struct tpm_tis_spi_phy *phy, return 0; } -static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, +int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, u8 *in, const u8 *out) { struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); @@ -148,9 +135,10 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, spi_bus_unlock(phy->spi_device->master); return ret; } +EXPORT_SYMBOL_GPL(tpm_tis_spi_transfer); -static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr, - u16 len, u8 *result) +static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, + u8 *result) { return tpm_tis_spi_transfer(data, addr, len, result, NULL); } @@ -161,7 +149,7 @@ static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr, return tpm_tis_spi_transfer(data, addr, len, NULL, value); } -static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result) +int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result) { __le16 result_le; int rc; @@ -173,8 +161,9 @@ static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result) return rc; } +EXPORT_SYMBOL_GPL(tpm_tis_spi_read16); -static int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result) +int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result) { __le32 result_le; int rc; @@ -186,8 +175,9 @@ static int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result) return rc; } +EXPORT_SYMBOL_GPL(tpm_tis_spi_read32); -static int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value) +int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value) { __le32 value_le; int rc; @@ -198,6 +188,20 @@ static int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value) return rc; } +EXPORT_SYMBOL_GPL(tpm_tis_spi_write32); + +int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy, + int irq, const struct tpm_tis_phy_ops *phy_ops) +{ + phy->iobuf = devm_kmalloc(&spi->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL); + if (!phy->iobuf) + return -ENOMEM; + + phy->spi_device = spi; + + return tpm_tis_core_init(&spi->dev, &phy->priv, irq, phy_ops, NULL); +} +EXPORT_SYMBOL_GPL(tpm_tis_spi_init); static const struct tpm_tis_phy_ops tpm_spi_phy_ops = { .read_bytes = tpm_tis_spi_read_bytes, @@ -217,11 +221,6 @@ static int tpm_tis_spi_probe(struct spi_device *dev) if (!phy) return -ENOMEM; - phy->spi_device = dev; - - phy->iobuf = devm_kmalloc(&dev->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL); - if (!phy->iobuf) - return -ENOMEM; phy->flow_control = tpm_tis_spi_flow_control; /* If the SPI device has an IRQ then use that */ @@ -230,8 +229,7 @@ static int tpm_tis_spi_probe(struct spi_device *dev) else irq = -1; - return tpm_tis_core_init(&dev->dev, &phy->priv, irq, &tpm_spi_phy_ops, - NULL); + return tpm_tis_spi_init(dev, phy, irq, &tpm_spi_phy_ops); } static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); diff --git a/drivers/char/tpm/tpm_tis_spi.h b/drivers/char/tpm/tpm_tis_spi.h new file mode 100644 index 000000000000..48be5130794a --- /dev/null +++ b/drivers/char/tpm/tpm_tis_spi.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2015 Infineon Technologies AG + * Copyright (C) 2016 STMicroelectronics SAS + */ + +#ifndef TPM_TIS_SPI_H +#define TPM_TIS_SPI_H + +#include "tpm_tis_core.h" + +struct tpm_tis_spi_phy { + struct tpm_tis_data priv; + struct spi_device *spi_device; + int (*flow_control)(struct tpm_tis_spi_phy *phy, + struct spi_transfer *xfer); + void (*pre_transfer)(struct tpm_tis_spi_phy *phy); + + u8 *iobuf; +}; + +static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data) +{ + return container_of(data, struct tpm_tis_spi_phy, priv); +} + +extern int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy, + int irq, const struct tpm_tis_phy_ops *phy_ops); + +extern int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len, + u8 *in, const u8 *out); + +extern int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result); +extern int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result); +extern int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value); + +#endif From patchwork Mon Aug 12 22:36:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 11090961 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8B193112C for ; Mon, 12 Aug 2019 22:36:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7AD3327F90 for ; Mon, 12 Aug 2019 22:36:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6DDC628384; Mon, 12 Aug 2019 22:36:36 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 0E8B927F90 for ; Mon, 12 Aug 2019 22:36:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727205AbfHLWga (ORCPT ); Mon, 12 Aug 2019 18:36:30 -0400 Received: from mail-pg1-f196.google.com ([209.85.215.196]:41108 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727194AbfHLWg3 (ORCPT ); Mon, 12 Aug 2019 18:36:29 -0400 Received: by mail-pg1-f196.google.com with SMTP id x15so39852174pgg.8 for ; Mon, 12 Aug 2019 15:36:29 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=pbLJacb6MCh29sDmogMC5h9hCymvEateyvCVNbUfmp0=; b=AEbhrZIj9L570kQMqoryJFGF2aST4nMckbDoihfMAMRyTUCHFi6Ut0bR+e+RXtYm/U MXuKioSk/vI5utYPt24IRcbOVwc0DCsUn2PZKC7Ms5olCCzRtnYK5HcSKaVz06P1uSWr bZusf6mtHlyCAET4JMEufjD6pmZJ6MqwUKup8= 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:mime-version:content-transfer-encoding; bh=pbLJacb6MCh29sDmogMC5h9hCymvEateyvCVNbUfmp0=; b=CZwhhKEV2AnFvlREzF72ZkVj7VIPD2Z/WfdVwZuhygCa6a+vgkuSAvQ2JJfHMqRPKS BtxTECDXehBp9yslj6PljbZGNN7rR+adqSd5wmUTKg6sCwp904yLvQkiVwPy7W9up3wd NLEnWPmnpw6RuMbPQelppZ5VXImtT0hvL2gj8ve2p4y/9VnNzHZWpzaZen5zQPjYHamE KN0QI9gTEVKz0WaVBuLrV1C3NVJjiBW9ui16I5iGlqUtyNpnIS/NkG6iypH8PIDyzDHO EHCsVhwpmgUkmoPpJ3ZdvFHwVzuP12sVe2kcescDkGJM06qT+ApDGCnxMzoafGG5Vf6v r1Kg== X-Gm-Message-State: APjAAAUIvMJ8HWb4/7fhuEX3mrLTFyJBq825FWyBgJtoVLZ2+TKbhUuF ea/BogCf0cqs5ZxMPGHolVzvYg== X-Google-Smtp-Source: APXvYqzmmF4BEegcpnS/e+KMA+yvCSfeLCUG6UJMXyZthuybe6012WcUe4Lc93X5m141O03baC5izQ== X-Received: by 2002:a17:90a:c596:: with SMTP id l22mr1444056pjt.46.1565649388818; Mon, 12 Aug 2019 15:36:28 -0700 (PDT) Received: from smtp.gmail.com ([2620:15c:202:1:fa53:7765:582b:82b9]) by smtp.gmail.com with ESMTPSA id b6sm93911594pgq.26.2019.08.12.15.36.28 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 12 Aug 2019 15:36:28 -0700 (PDT) From: Stephen Boyd To: Peter Huewe , Jarkko Sakkinen Cc: Andrey Pronin , linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org, Duncan Laurie , Jason Gunthorpe , Arnd Bergmann , Greg Kroah-Hartman , Guenter Roeck , Alexander Steffen , Rob Herring Subject: [PATCH v4 5/6] dt-bindings: tpm: document properties for cr50 Date: Mon, 12 Aug 2019 15:36:21 -0700 Message-Id: <20190812223622.73297-6-swboyd@chromium.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812223622.73297-1-swboyd@chromium.org> References: <20190812223622.73297-1-swboyd@chromium.org> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Andrey Pronin Add TPM2.0 PTP FIFO compatible SPI interface for chips with Cr50 firmware. Cc: Andrey Pronin Cc: Duncan Laurie Cc: Jason Gunthorpe Cc: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: Guenter Roeck Cc: Alexander Steffen Signed-off-by: Andrey Pronin Reviewed-by: Rob Herring Signed-off-by: Stephen Boyd --- .../bindings/security/tpm/google,cr50.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 Documentation/devicetree/bindings/security/tpm/google,cr50.txt diff --git a/Documentation/devicetree/bindings/security/tpm/google,cr50.txt b/Documentation/devicetree/bindings/security/tpm/google,cr50.txt new file mode 100644 index 000000000000..7aa65224c8b9 --- /dev/null +++ b/Documentation/devicetree/bindings/security/tpm/google,cr50.txt @@ -0,0 +1,19 @@ +* H1 Secure Microcontroller with Cr50 Firmware on SPI Bus. + +H1 Secure Microcontroller running Cr50 firmware provides several +functions, including TPM-like functionality. It communicates over +SPI using the FIFO protocol described in the PTP Spec, section 6. + +Required properties: +- compatible: Should be "google,cr50". +- spi-max-frequency: Maximum SPI frequency. + +Example: + +&spi0 { + tpm@0 { + compatible = "google,cr50"; + reg = <0>; + spi-max-frequency = <800000>; + }; +}; From patchwork Mon Aug 12 22:36:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Boyd X-Patchwork-Id: 11090963 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B456D112C for ; Mon, 12 Aug 2019 22:36:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A125E27F90 for ; Mon, 12 Aug 2019 22:36:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9517E28384; Mon, 12 Aug 2019 22:36:37 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham 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 8B2ED2823E for ; Mon, 12 Aug 2019 22:36:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727184AbfHLWge (ORCPT ); Mon, 12 Aug 2019 18:36:34 -0400 Received: from mail-pf1-f196.google.com ([209.85.210.196]:41550 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727210AbfHLWga (ORCPT ); Mon, 12 Aug 2019 18:36:30 -0400 Received: by mail-pf1-f196.google.com with SMTP id 196so3256325pfz.8 for ; Mon, 12 Aug 2019 15:36:30 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=Qrp73fXN1Yecimm4jOuhlrZx9sZom7dIuI2rB8EzAMQ=; b=e9YOzvMoqGvTy/w3AqKHjoTT9kvQX9rXs636F1KGuXZHw/DyILcC+NRMuDeFwys3/1 yHExMAeqimr+yNYFA6+mJqtYm4FaGlAybXTbmaMjKoZu7wSk07xWqysNaqzKvqBVdK97 lY6UBIUDrptcFyfnSeRaDtbR3+ttVXHp1XxYc= 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:mime-version:content-transfer-encoding; bh=Qrp73fXN1Yecimm4jOuhlrZx9sZom7dIuI2rB8EzAMQ=; b=eKiuNXu8AvgJnofQdv4AbvJ3ccYJiF/uLSteSo6BtyXjF4ILS1++RWESUzugfI3CtW LX/r7BJ244GS5NaNXlsh6efL/bLJH2D2/D9+chy3LBSFt9y5KzdxbrfJTv/cAW0bo3OC 8m5fUW7rNa9WAUKL7XkazaZcjbVA3cmPyd/8snmVi7iWCKnbRxJ/IOf/wlHrV7BdW3xd g+h+x6lS9hqwREFHkPLHZKOfBy4zEX0xD+AzGPvQqo5U7mdFL9eyyeCNwy+vZSJHIr7+ 3a0S83qVtnzgnMRCZnqnhYRpasfkSj2p4tLUViOr21Y9D4isugERvVdIwNcb0x/fto+y Iblw== X-Gm-Message-State: APjAAAWMCn05Ns84wtI0ilh8OncpkgNCflPKjEYcEnNXRODflhpjAI3c PEjVo8xuDz0/ofuUE17HVfRGvtZCbLmYGw== X-Google-Smtp-Source: APXvYqyhP4sM6THnCEWTNQ0nYzfk9l6TrEKVMOMggtTk5qGcOxyOglgGE66XdTNu2JFmd3YnuIN/mg== X-Received: by 2002:aa7:9719:: with SMTP id a25mr11654929pfg.2.1565649389764; Mon, 12 Aug 2019 15:36:29 -0700 (PDT) Received: from smtp.gmail.com ([2620:15c:202:1:fa53:7765:582b:82b9]) by smtp.gmail.com with ESMTPSA id b6sm93911594pgq.26.2019.08.12.15.36.28 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 12 Aug 2019 15:36:29 -0700 (PDT) From: Stephen Boyd To: Peter Huewe , Jarkko Sakkinen Cc: Andrey Pronin , linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org, Duncan Laurie , Jason Gunthorpe , Arnd Bergmann , Greg Kroah-Hartman , Guenter Roeck , Alexander Steffen Subject: [PATCH v4 6/6] tpm: add driver for cr50 on SPI Date: Mon, 12 Aug 2019 15:36:22 -0700 Message-Id: <20190812223622.73297-7-swboyd@chromium.org> X-Mailer: git-send-email 2.23.0.rc1.153.gdeed80330f-goog In-Reply-To: <20190812223622.73297-1-swboyd@chromium.org> References: <20190812223622.73297-1-swboyd@chromium.org> MIME-Version: 1.0 Sender: linux-integrity-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Andrey Pronin Add TPM2.0 PTP FIFO compatible SPI interface for chips with Cr50 firmware. The firmware running on the currently supported H1 Secure Microcontroller requires a special driver to handle its specifics: - need to ensure a certain delay between spi transactions, or else the chip may miss some part of the next transaction; - if there is no spi activity for some time, it may go to sleep, and needs to be waken up before sending further commands; - access to vendor-specific registers. Signed-off-by: Andrey Pronin Cc: Andrey Pronin Cc: Duncan Laurie Cc: Jason Gunthorpe Cc: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: Guenter Roeck Cc: Alexander Steffen [swboyd@chromium.org: Replace boilerplate with SPDX tag, drop suspended bit and remove ifdef checks in cr50.h, push tpm.h include into cr50.c, migrate to functions exported from tpm_tis_spi.h] Signed-off-by: Stephen Boyd --- drivers/char/tpm/Kconfig | 9 + drivers/char/tpm/Makefile | 1 + drivers/char/tpm/cr50_spi.c | 372 ++++++++++++++++++++++++++++++++++++ 3 files changed, 382 insertions(+) create mode 100644 drivers/char/tpm/cr50_spi.c diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 88a3c06fc153..1fb23f145ef6 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig @@ -114,6 +114,15 @@ config TCG_ATMEL will be accessible from within Linux. To compile this driver as a module, choose M here; the module will be called tpm_atmel. +config TCG_CR50_SPI + tristate "Cr50 SPI Interface" + depends on TCG_TIS_SPI + ---help--- + If you have a H1 secure module running Cr50 firmware on SPI bus, + say Yes and it will be accessible from within Linux. To compile + this driver as a module, choose M here; the module will be called + cr50_spi. + config TCG_INFINEON tristate "Infineon Technologies TPM Interface" depends on PNP diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index a01c4cab902a..4713e52ce1b0 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o obj-$(CONFIG_TCG_TIS_I2C_NUVOTON) += tpm_i2c_nuvoton.o obj-$(CONFIG_TCG_NSC) += tpm_nsc.o obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o +obj-$(CONFIG_TCG_CR50_SPI) += cr50_spi.o obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o obj-$(CONFIG_TCG_IBMVTPM) += tpm_ibmvtpm.o obj-$(CONFIG_TCG_TIS_ST33ZP24) += st33zp24/ diff --git a/drivers/char/tpm/cr50_spi.c b/drivers/char/tpm/cr50_spi.c new file mode 100644 index 000000000000..a163864e9c63 --- /dev/null +++ b/drivers/char/tpm/cr50_spi.c @@ -0,0 +1,372 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2016 Google, Inc + * + * This device driver implements a TCG PTP FIFO interface over SPI for chips + * with Cr50 firmware. + * It is based on tpm_tis_spi driver by Peter Huewe and Christophe Ricard. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tpm_tis_core.h" +#include "tpm_tis_spi.h" + +/* + * Cr50 timing constants: + * - can go to sleep not earlier than after CR50_SLEEP_DELAY_MSEC. + * - needs up to CR50_WAKE_START_DELAY_USEC to wake after sleep. + * - requires waiting for "ready" IRQ, if supported; or waiting for at least + * CR50_NOIRQ_ACCESS_DELAY_MSEC between transactions, if IRQ is not supported. + * - waits for up to CR50_FLOW_CONTROL for flow control 'ready' indication. + */ +#define CR50_SLEEP_DELAY_MSEC 1000 +#define CR50_WAKE_START_DELAY_USEC 1000 +#define CR50_NOIRQ_ACCESS_DELAY msecs_to_jiffies(2) +#define CR50_READY_IRQ_TIMEOUT msecs_to_jiffies(TPM2_TIMEOUT_A) +#define CR50_FLOW_CONTROL msecs_to_jiffies(TPM2_TIMEOUT_A) +#define MAX_IRQ_CONFIRMATION_ATTEMPTS 3 + +#define TPM_CR50_FW_VER(l) (0x0f90 | ((l) << 12)) +#define TPM_CR50_MAX_FW_VER_LEN 64 + +struct cr50_spi_phy { + struct tpm_tis_spi_phy spi_phy; + + struct mutex time_track_mutex; + unsigned long last_access; + unsigned long wake_after; + + unsigned long access_delay; + + struct completion ready; + + unsigned int irq_confirmation_attempt; + bool irq_needs_confirmation; + bool irq_confirmed; +}; + +static inline struct cr50_spi_phy *to_cr50_spi_phy(struct tpm_tis_spi_phy *phy) +{ + return container_of(phy, struct cr50_spi_phy, spi_phy); +} + +/* + * The cr50 interrupt handler just signals waiting threads that the + * interrupt was asserted. It does not do any processing triggered + * by interrupts but is instead used to avoid fixed delays. + */ +static irqreturn_t cr50_spi_irq_handler(int dummy, void *dev_id) +{ + struct cr50_spi_phy *cr50_phy = dev_id; + + cr50_phy->irq_confirmed = true; + complete(&cr50_phy->ready); + + return IRQ_HANDLED; +} + +/* + * Cr50 needs to have at least some delay between consecutive + * transactions. Make sure we wait. + */ +static void cr50_ensure_access_delay(struct cr50_spi_phy *phy) +{ + unsigned long allowed_access = phy->last_access + phy->access_delay; + unsigned long time_now = jiffies; + struct device *dev = &phy->spi_phy.spi_device->dev; + + /* + * Note: There is a small chance, if Cr50 is not accessed in a few days, + * that time_in_range will not provide the correct result after the wrap + * around for jiffies. In this case, we'll have an unneeded short delay, + * which is fine. + */ + if (time_in_range_open(time_now, phy->last_access, allowed_access)) { + unsigned long remaining, timeout = allowed_access - time_now; + + remaining = wait_for_completion_timeout(&phy->ready, timeout); + if (!remaining && phy->irq_confirmed) + dev_warn(dev, "Timeout waiting for TPM ready IRQ\n"); + } + + if (phy->irq_needs_confirmation) { + unsigned int attempt = ++phy->irq_confirmation_attempt; + + if (phy->irq_confirmed) { + phy->irq_needs_confirmation = false; + phy->access_delay = CR50_READY_IRQ_TIMEOUT; + dev_info(dev, "TPM ready IRQ confirmed on attempt %u\n", + attempt); + } else if (attempt > MAX_IRQ_CONFIRMATION_ATTEMPTS) { + phy->irq_needs_confirmation = false; + dev_warn(dev, "IRQ not confirmed - will use delays\n"); + } + } +} + +/* + * Cr50 might go to sleep if there is no SPI activity for some time and + * miss the first few bits/bytes on the bus. In such case, wake it up + * by asserting CS and give it time to start up. + */ +static bool cr50_needs_waking(struct cr50_spi_phy *phy) +{ + /* + * Note: There is a small chance, if Cr50 is not accessed in a few days, + * that time_in_range will not provide the correct result after the wrap + * around for jiffies. In this case, we'll probably timeout or read + * incorrect value from TPM_STS and just retry the operation. + */ + return !time_in_range_open(jiffies, phy->last_access, phy->wake_after); +} + +static void cr50_wake_if_needed(struct cr50_spi_phy *cr50_phy) +{ + struct tpm_tis_spi_phy *phy = &cr50_phy->spi_phy; + + if (cr50_needs_waking(cr50_phy)) { + /* Assert CS, wait 1 msec, deassert CS */ + struct spi_transfer spi_cs_wake = { .delay_usecs = 1000 }; + + spi_sync_transfer(phy->spi_device, &spi_cs_wake, 1); + /* Wait for it to fully wake */ + usleep_range(CR50_WAKE_START_DELAY_USEC, + CR50_WAKE_START_DELAY_USEC * 2); + } + + /* Reset the time when we need to wake Cr50 again */ + cr50_phy->wake_after = jiffies + msecs_to_jiffies(CR50_SLEEP_DELAY_MSEC); +} + +/* + * Flow control: clock the bus and wait for cr50 to set LSB before + * sending/receiving data. TCG PTP spec allows it to happen during + * the last byte of header, but cr50 never does that in practice, + * and earlier versions had a bug when it was set too early, so don't + * check for it during header transfer. + */ +static int cr50_spi_flow_control(struct tpm_tis_spi_phy *phy, + struct spi_transfer *spi_xfer) +{ + struct device *dev = &phy->spi_device->dev; + unsigned long timeout = jiffies + CR50_FLOW_CONTROL; + struct spi_message m; + int ret; + + spi_xfer->len = 1; + + do { + spi_message_init(&m); + spi_message_add_tail(spi_xfer, &m); + ret = spi_sync_locked(phy->spi_device, &m); + if (ret < 0) + return ret; + + if (time_after(jiffies, timeout)) { + dev_warn(dev, "Timeout during flow control\n"); + return -EBUSY; + } + } while (!(phy->iobuf[0] & 0x01)); + + return 0; +} + +static void cr50_spi_reinit_completion(struct tpm_tis_spi_phy *phy) +{ + struct cr50_spi_phy *cr50_phy = to_cr50_spi_phy(phy); + reinit_completion(&cr50_phy->ready); +} + +static int tpm_tis_spi_cr50_transfer(struct tpm_tis_data *data, u32 addr, u16 len, + u8 *in, const u8 *out) +{ + struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); + struct cr50_spi_phy *cr50_phy = to_cr50_spi_phy(phy); + int ret; + + mutex_lock(&cr50_phy->time_track_mutex); + /* + * Do this outside of spi_bus_lock in case cr50 is not the + * only device on that spi bus. + */ + cr50_ensure_access_delay(cr50_phy); + cr50_wake_if_needed(cr50_phy); + + ret = tpm_tis_spi_transfer(data, addr, len, in, out); + + cr50_phy->last_access = jiffies; + mutex_unlock(&cr50_phy->time_track_mutex); + + return ret; +} + +static int tpm_tis_spi_cr50_read_bytes(struct tpm_tis_data *data, u32 addr, + u16 len, u8 *result) +{ + return tpm_tis_spi_cr50_transfer(data, addr, len, result, NULL); +} + +static int tpm_tis_spi_cr50_write_bytes(struct tpm_tis_data *data, u32 addr, + u16 len, const u8 *value) +{ + return tpm_tis_spi_cr50_transfer(data, addr, len, NULL, value); +} + +static const struct tpm_tis_phy_ops tpm_spi_cr50_phy_ops = { + .read_bytes = tpm_tis_spi_cr50_read_bytes, + .write_bytes = tpm_tis_spi_cr50_write_bytes, + .read16 = tpm_tis_spi_read16, + .read32 = tpm_tis_spi_read32, + .write32 = tpm_tis_spi_write32, +}; + +static void cr50_print_fw_version(struct tpm_tis_data *data) +{ + struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); + int i, len = 0; + char fw_ver[TPM_CR50_MAX_FW_VER_LEN + 1]; + char fw_ver_block[4]; + + /* + * Write anything to TPM_CR50_FW_VER to start from the beginning + * of the version string + */ + tpm_tis_write8(data, TPM_CR50_FW_VER(data->locality), 0); + + /* Read the string, 4 bytes at a time, until we get '\0' */ + do { + tpm_tis_read_bytes(data, TPM_CR50_FW_VER(data->locality), 4, + fw_ver_block); + for (i = 0; i < 4 && fw_ver_block[i]; ++len, ++i) + fw_ver[len] = fw_ver_block[i]; + } while (i == 4 && len < TPM_CR50_MAX_FW_VER_LEN); + fw_ver[len] = '\0'; + + dev_info(&phy->spi_device->dev, "Cr50 firmware version: %s\n", fw_ver); +} + +static int cr50_spi_probe(struct spi_device *spi) +{ + struct tpm_tis_spi_phy *phy; + struct cr50_spi_phy *cr50_phy; + int ret; + struct tpm_chip *chip; + + cr50_phy = devm_kzalloc(&spi->dev, sizeof(*cr50_phy), GFP_KERNEL); + if (!cr50_phy) + return -ENOMEM; + + phy = &cr50_phy->spi_phy; + phy->flow_control = cr50_spi_flow_control; + phy->pre_transfer = cr50_spi_reinit_completion; + + cr50_phy->access_delay = CR50_NOIRQ_ACCESS_DELAY; + + mutex_init(&cr50_phy->time_track_mutex); + cr50_phy->wake_after = jiffies; + cr50_phy->last_access = jiffies; + + init_completion(&cr50_phy->ready); + if (spi->irq > 0) { + ret = devm_request_irq(&spi->dev, spi->irq, cr50_spi_irq_handler, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "cr50_spi", cr50_phy); + if (ret < 0) { + if (ret == -EPROBE_DEFER) + return ret; + dev_warn(&spi->dev, "Requesting IRQ %d failed: %d\n", + spi->irq, ret); + /* + * This is not fatal, the driver will fall back to + * delays automatically, since ready will never + * be completed without a registered irq handler. + * So, just fall through. + */ + } else { + /* + * IRQ requested, let's verify that it is actually + * triggered, before relying on it. + */ + cr50_phy->irq_needs_confirmation = true; + } + } else { + dev_warn(&spi->dev, + "No IRQ - will use delays between transactions.\n"); + } + + ret = tpm_tis_spi_init(spi, phy, -1, &tpm_spi_cr50_phy_ops); + if (ret) + return ret; + + cr50_print_fw_version(&phy->priv); + + chip = dev_get_drvdata(&spi->dev); + chip->flags |= TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED; + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int cr50_spi_resume(struct device *dev) +{ + struct tpm_chip *chip = dev_get_drvdata(dev); + struct tpm_tis_data *data = dev_get_drvdata(&chip->dev); + struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); + struct cr50_spi_phy *cr50_phy = to_cr50_spi_phy(phy); + + /* + * Jiffies not increased during suspend, so we need to reset + * the time to wake Cr50 after resume. + */ + cr50_phy->wake_after = jiffies; + + return tpm_tis_resume(dev); +} +#endif + +static SIMPLE_DEV_PM_OPS(cr50_spi_pm, tpm_pm_suspend, cr50_spi_resume); + +static int cr50_spi_remove(struct spi_device *dev) +{ + struct tpm_chip *chip = spi_get_drvdata(dev); + + tpm_chip_unregister(chip); + tpm_tis_remove(chip); + return 0; +} + +static const struct spi_device_id cr50_spi_id[] = { + { "cr50", 0 }, + {} +}; +MODULE_DEVICE_TABLE(spi, cr50_spi_id); + +#ifdef CONFIG_OF +static const struct of_device_id of_cr50_spi_match[] = { + { .compatible = "google,cr50", }, + {} +}; +MODULE_DEVICE_TABLE(of, of_cr50_spi_match); +#endif + +static struct spi_driver cr50_spi_driver = { + .driver = { + .name = "cr50_spi", + .pm = &cr50_spi_pm, + .of_match_table = of_match_ptr(of_cr50_spi_match), + }, + .probe = cr50_spi_probe, + .remove = cr50_spi_remove, + .id_table = cr50_spi_id, +}; +module_spi_driver(cr50_spi_driver); + +MODULE_DESCRIPTION("Cr50 TCG PTP FIFO SPI driver"); +MODULE_LICENSE("GPL v2");