From patchwork Tue Oct 7 20:03:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Ricard X-Patchwork-Id: 397442 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 7B30D14011E for ; Wed, 8 Oct 2014 07:04:03 +1100 (EST) Received: from localhost ([127.0.0.1] helo=sfs-ml-2.v29.ch3.sourceforge.com) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1XbazJ-0000qq-1o; Tue, 07 Oct 2014 20:04:01 +0000 Received: from sog-mx-2.v43.ch3.sourceforge.com ([172.29.43.192] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1Xbaz8-0000oi-FT for tpmdd-devel@lists.sourceforge.net; Tue, 07 Oct 2014 20:03:50 +0000 Received-SPF: pass (sog-mx-2.v43.ch3.sourceforge.com: domain of gmail.com designates 209.85.212.176 as permitted sender) client-ip=209.85.212.176; envelope-from=christophe.ricard@gmail.com; helo=mail-wi0-f176.google.com; Received: from mail-wi0-f176.google.com ([209.85.212.176]) by sog-mx-2.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1Xbaz7-0004qA-At for tpmdd-devel@lists.sourceforge.net; Tue, 07 Oct 2014 20:03:50 +0000 Received: by mail-wi0-f176.google.com with SMTP id hi2so9023840wib.9 for ; Tue, 07 Oct 2014 13:03:43 -0700 (PDT) X-Received: by 10.180.8.73 with SMTP id p9mr6994742wia.32.1412712223174; Tue, 07 Oct 2014 13:03:43 -0700 (PDT) Received: from localhost.localdomain (ax113-6-78-236-204-66.fbx.proxad.net. [78.236.204.66]) by mx.google.com with ESMTPSA id lk6sm22017609wjb.26.2014.10.07.13.03.41 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 07 Oct 2014 13:03:42 -0700 (PDT) From: Christophe Ricard X-Google-Original-From: Christophe Ricard To: peterhuewe@gmx.de, ashley@ashleylai.com, tpmdd@selhorst.net Date: Tue, 7 Oct 2014 22:03:06 +0200 Message-Id: <1412712189-1234-14-git-send-email-christophe-h.ricard@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1412712189-1234-1-git-send-email-christophe-h.ricard@st.com> References: <1412712189-1234-1-git-send-email-christophe-h.ricard@st.com> X-Spam-Score: -1.6 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (christophe.ricard[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1Xbaz7-0004qA-At Cc: devicetree@vger.kernel.org, christophe.ricard@gmail.com, tpmdd-devel@lists.sourceforge.net, christophe-h.ricard@st.com, jean-luc.blanc@st.com Subject: [tpmdd-devel] [PATCH 13/16] tpm/tpm_i2c_stm_st33: Add tpm_lock mutex for safe irq management X-BeenThere: tpmdd-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Tpm Device Driver maintainance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: tpmdd-devel-bounces@lists.sourceforge.net Adding tpm_lock mutex in order to guarantee that a i2c_read_data or a i2c_write_data will not get interrupted by a threaded interrupt. Signed-off-by: Christophe Ricard --- drivers/char/tpm/tpm_i2c_stm_st33.c | 61 ++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index ab2a675..8d32ade 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -106,7 +105,7 @@ enum tis_defaults { struct tpm_stm_dev { struct i2c_client *client; - struct mutex lock; + struct mutex tpm_lock; struct tpm_chip *chip; u8 buf[TPM_BUFSIZE + 1]; int io_serirq; @@ -147,6 +146,7 @@ static int read8_reg(struct tpm_stm_dev *tpm_dev, u8 tpm_register, status = write8_reg(tpm_dev, tpm_register, &data, 1); if (status == 2) status = i2c_master_recv(tpm_dev->client, tpm_data, tpm_size); + return status; } /* read8_reg() */ @@ -163,6 +163,18 @@ static int read8_reg(struct tpm_stm_dev *tpm_dev, u8 tpm_register, (write8_reg(tpm_dev, tpm_register | \ TPM_WRITE_DIRECTION, tpm_data, tpm_size)) + +static int i2c_write_data(struct tpm_stm_dev *tpm_dev, u8 tpm_register, + u8 *tpm_data, u16 tpm_size) +{ + u8 status; + + mutex_lock(&tpm_dev->tpm_lock); + status = I2C_WRITE_DATA(tpm_dev, tpm_register, tpm_data, tpm_size); + mutex_unlock(&tpm_dev->tpm_lock); + + return status; +} /* i2c_write_data() */ /* * I2C_READ_DATA * Recv byte from the TIS register according to the ST33ZP24 I2C protocol. @@ -175,6 +187,18 @@ static int read8_reg(struct tpm_stm_dev *tpm_dev, u8 tpm_register, #define I2C_READ_DATA(tpm_dev, tpm_register, tpm_data, tpm_size) \ (read8_reg(tpm_dev, tpm_register, tpm_data, tpm_size)) +static int i2c_read_data(struct tpm_stm_dev *tpm_dev, u8 tpm_register, + u8 *tpm_data, u16 tpm_size) +{ + u8 status; + + mutex_lock(&tpm_dev->tpm_lock); + status = I2C_READ_DATA(tpm_dev, tpm_register, tpm_data, tpm_size); + mutex_unlock(&tpm_dev->tpm_lock); + + return status; +} /* i2c_read_data() */ + /* * clear_interruption * clear the TPM interrupt register. @@ -184,8 +208,8 @@ static u8 clear_interruption(struct tpm_stm_dev *tpm_dev) { u8 interrupt; - I2C_READ_DATA(tpm_dev, TPM_INT_STATUS, &interrupt, 1); - I2C_WRITE_DATA(tpm_dev, TPM_INT_STATUS, &interrupt, 1); + i2c_read_data(tpm_dev, TPM_INT_STATUS, &interrupt, 1); + i2c_write_data(tpm_dev, TPM_INT_STATUS, &interrupt, 1); return interrupt; } /* clear_interruption() */ @@ -202,7 +226,7 @@ static void tpm_stm_i2c_cancel(struct tpm_chip *chip) tpm_dev = (struct tpm_stm_dev *)TPM_VPRIV(chip); data = TPM_STS_COMMAND_READY; - I2C_WRITE_DATA(tpm_dev, TPM_STS, &data, 1); + i2c_write_data(tpm_dev, TPM_STS, &data, 1); } /* tpm_stm_i2c_cancel() */ /* @@ -217,7 +241,7 @@ static u8 tpm_stm_i2c_status(struct tpm_chip *chip) tpm_dev = (struct tpm_stm_dev *)TPM_VPRIV(chip); - I2C_READ_DATA(tpm_dev, TPM_STS, &data, 1); + i2c_read_data(tpm_dev, TPM_STS, &data, 1); return data; } /* tpm_stm_i2c_status() */ @@ -235,7 +259,7 @@ static int check_locality(struct tpm_chip *chip) tpm_dev = (struct tpm_stm_dev *)TPM_VPRIV(chip); - status = I2C_READ_DATA(tpm_dev, TPM_ACCESS, &data, 1); + status = i2c_read_data(tpm_dev, TPM_ACCESS, &data, 1); if (status && (data & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) @@ -263,7 +287,7 @@ static int request_locality(struct tpm_chip *chip) tpm_dev = (struct tpm_stm_dev *)TPM_VPRIV(chip); data = TPM_ACCESS_REQUEST_USE; - r = I2C_WRITE_DATA(tpm_dev, TPM_ACCESS, &data, 1); + r = i2c_write_data(tpm_dev, TPM_ACCESS, &data, 1); if (r < 0) goto end; @@ -308,7 +332,7 @@ static void release_locality(struct tpm_chip *chip) tpm_dev = (struct tpm_stm_dev *)TPM_VPRIV(chip); data = TPM_ACCESS_ACTIVE_LOCALITY; - I2C_WRITE_DATA(tpm_dev, TPM_ACCESS, &data, 1); + i2c_write_data(tpm_dev, TPM_ACCESS, &data, 1); } /* @@ -328,13 +352,13 @@ static int get_burstcount(struct tpm_chip *chip) stop = jiffies + chip->vendor.timeout_d; do { tpm_reg = TPM_STS + 1; - status = I2C_READ_DATA(tpm_dev, tpm_reg, &temp, 1); + status = i2c_read_data(tpm_dev, tpm_reg, &temp, 1); if (status < 0) goto end; tpm_reg = tpm_reg + 1; burstcnt = temp; - status = I2C_READ_DATA(tpm_dev, tpm_reg, &temp, 1); + status = i2c_read_data(tpm_dev, tpm_reg, &temp, 1); if (status < 0) goto end; @@ -366,12 +390,12 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) wait_for_tpm_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, chip->vendor.timeout_c, - &chip->vendor.read_queue, true) == 0) { + &chip->vendor.read_queue, false) == 0) { burstcnt = get_burstcount(chip); if (burstcnt < 0) return burstcnt; len = min_t(int, burstcnt, count - size); - I2C_READ_DATA(tpm_dev, TPM_DATA_FIFO, buf + size, len); + i2c_read_data(tpm_dev, TPM_DATA_FIFO, buf + size, len); size += len; } return size; @@ -456,7 +480,7 @@ static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, if (burstcnt < 0) return burstcnt; size = min_t(int, len - i - 1, burstcnt); - r = I2C_WRITE_DATA(tpm_dev, TPM_DATA_FIFO, buf, size); + r = i2c_write_data(tpm_dev, TPM_DATA_FIFO, buf, size); if (r < 0) goto out_err; @@ -469,7 +493,7 @@ static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, goto out_err; } - r = I2C_WRITE_DATA(tpm_dev, TPM_DATA_FIFO, buf + len - 1, 1); + r = i2c_write_data(tpm_dev, TPM_DATA_FIFO, buf + len - 1, 1); if (r < 0) goto out_err; @@ -480,7 +504,7 @@ static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, } data = TPM_STS_GO; - I2C_WRITE_DATA(tpm_dev, TPM_STS, &data, 1); + i2c_write_data(tpm_dev, TPM_STS, &data, 1); return len; out_err: @@ -730,6 +754,7 @@ tpm_stm_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); chip->vendor.locality = LOCALITY0; + mutex_init(&tpm_dev->tpm_lock); if (interrupts) { /* INTERRUPT Setup */ @@ -758,12 +783,12 @@ tpm_stm_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) | TPM_INTF_STS_VALID_INT | TPM_INTF_DATA_AVAIL_INT; - r = I2C_WRITE_DATA(tpm_dev, TPM_INT_ENABLE, &intmask, 1); + r = i2c_write_data(tpm_dev, TPM_INT_ENABLE, &intmask, 1); if (r < 0) goto _tpm_clean_answer; intmask = TPM_GLOBAL_INT_ENABLE; - r = I2C_WRITE_DATA(tpm_dev, (TPM_INT_ENABLE + 3), &intmask, 1); + r = i2c_write_data(tpm_dev, (TPM_INT_ENABLE + 3), &intmask, 1); if (r < 0) goto _tpm_clean_answer;