Commit 3d7a7bd7 authored by Kent Yoder's avatar Kent Yoder

tpm: STM i2c driver fixes

 Store the i2c_client struct in the vendor private pointer. Get rid of
the unnecessary include/linux/i2c/ header. Moved include files into the
driver c file. Fix smatch warnings. Make use of module_i2c_driver().
Removed unused code from the tpm_stm_st33_i2c.h file. Fix return
variable signedness in tpm_stm_i2c_send() and tpm_st33_i2c_probe().
Signed-off-by: default avatarKent Yoder <key@linux.vnet.ibm.com>
parent 775585e4
...@@ -30,8 +30,29 @@ ...@@ -30,8 +30,29 @@
lpc is used as model. lpc is used as model.
*/ */
#include <linux/i2c/tpm_stm_st33_i2c.h> #include <linux/pci.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/sysfs.h>
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include "tpm.h"
#include "tpm_stm_st33_i2c.h" #include "tpm_stm_st33_i2c.h"
enum stm33zp24_access { enum stm33zp24_access {
...@@ -164,7 +185,7 @@ static long _wait_for_interrupt_serirq_timeout(struct tpm_chip *chip, ...@@ -164,7 +185,7 @@ static long _wait_for_interrupt_serirq_timeout(struct tpm_chip *chip,
struct i2c_client *client; struct i2c_client *client;
struct st33zp24_platform_data *pin_infos; struct st33zp24_platform_data *pin_infos;
client = (struct i2c_client *) chip->vendor.iobase; client = (struct i2c_client *) TPM_VPRIV(chip);
pin_infos = client->dev.platform_data; pin_infos = client->dev.platform_data;
status = wait_for_completion_interruptible_timeout( status = wait_for_completion_interruptible_timeout(
...@@ -177,14 +198,14 @@ static long _wait_for_interrupt_serirq_timeout(struct tpm_chip *chip, ...@@ -177,14 +198,14 @@ static long _wait_for_interrupt_serirq_timeout(struct tpm_chip *chip,
return status; return status;
} /* wait_for_interrupt_serirq_timeout() */ } /* wait_for_interrupt_serirq_timeout() */
int wait_for_serirq_timeout(struct tpm_chip *chip, bool condition, static int wait_for_serirq_timeout(struct tpm_chip *chip, bool condition,
unsigned long timeout) unsigned long timeout)
{ {
int status = 2; int status = 2;
struct i2c_client *client; struct i2c_client *client;
struct st33zp24_platform_data *pin_infos; struct st33zp24_platform_data *pin_infos;
client = (struct i2c_client *) chip->vendor.iobase; client = (struct i2c_client *) TPM_VPRIV(chip);
pin_infos = client->dev.platform_data; pin_infos = client->dev.platform_data;
status = _wait_for_interrupt_serirq_timeout(chip, timeout); status = _wait_for_interrupt_serirq_timeout(chip, timeout);
...@@ -207,7 +228,7 @@ static void tpm_stm_i2c_cancel(struct tpm_chip *chip) ...@@ -207,7 +228,7 @@ static void tpm_stm_i2c_cancel(struct tpm_chip *chip)
struct i2c_client *client; struct i2c_client *client;
u8 data; u8 data;
client = (struct i2c_client *) chip->vendor.iobase; client = (struct i2c_client *) TPM_VPRIV(chip);
data = TPM_STS_COMMAND_READY; data = TPM_STS_COMMAND_READY;
I2C_WRITE_DATA(client, TPM_STS, &data, 1); I2C_WRITE_DATA(client, TPM_STS, &data, 1);
...@@ -224,7 +245,7 @@ static u8 tpm_stm_i2c_status(struct tpm_chip *chip) ...@@ -224,7 +245,7 @@ static u8 tpm_stm_i2c_status(struct tpm_chip *chip)
{ {
struct i2c_client *client; struct i2c_client *client;
u8 data; u8 data;
client = (struct i2c_client *) chip->vendor.iobase; client = (struct i2c_client *) TPM_VPRIV(chip);
I2C_READ_DATA(client, TPM_STS, &data, 1); I2C_READ_DATA(client, TPM_STS, &data, 1);
return data; return data;
...@@ -242,7 +263,7 @@ static int check_locality(struct tpm_chip *chip) ...@@ -242,7 +263,7 @@ static int check_locality(struct tpm_chip *chip)
u8 data; u8 data;
u8 status; u8 status;
client = (struct i2c_client *) chip->vendor.iobase; client = (struct i2c_client *) TPM_VPRIV(chip);
status = I2C_READ_DATA(client, TPM_ACCESS, &data, 1); status = I2C_READ_DATA(client, TPM_ACCESS, &data, 1);
if (status && (data & if (status && (data &
...@@ -266,7 +287,7 @@ static int request_locality(struct tpm_chip *chip) ...@@ -266,7 +287,7 @@ static int request_locality(struct tpm_chip *chip)
struct i2c_client *client; struct i2c_client *client;
u8 data; u8 data;
client = (struct i2c_client *) chip->vendor.iobase; client = (struct i2c_client *) TPM_VPRIV(chip);
if (check_locality(chip) == chip->vendor.locality) if (check_locality(chip) == chip->vendor.locality)
return chip->vendor.locality; return chip->vendor.locality;
...@@ -304,7 +325,7 @@ static void release_locality(struct tpm_chip *chip) ...@@ -304,7 +325,7 @@ static void release_locality(struct tpm_chip *chip)
struct i2c_client *client; struct i2c_client *client;
u8 data; u8 data;
client = (struct i2c_client *) chip->vendor.iobase; client = (struct i2c_client *) TPM_VPRIV(chip);
data = TPM_ACCESS_ACTIVE_LOCALITY; data = TPM_ACCESS_ACTIVE_LOCALITY;
I2C_WRITE_DATA(client, TPM_ACCESS, &data, 1); I2C_WRITE_DATA(client, TPM_ACCESS, &data, 1);
...@@ -321,7 +342,7 @@ static int get_burstcount(struct tpm_chip *chip) ...@@ -321,7 +342,7 @@ static int get_burstcount(struct tpm_chip *chip)
int burstcnt, status; int burstcnt, status;
u8 tpm_reg, temp; u8 tpm_reg, temp;
struct i2c_client *client = (struct i2c_client *) chip->vendor.iobase; struct i2c_client *client = (struct i2c_client *) TPM_VPRIV(chip);
stop = jiffies + chip->vendor.timeout_d; stop = jiffies + chip->vendor.timeout_d;
do { do {
...@@ -391,7 +412,7 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) ...@@ -391,7 +412,7 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
int size = 0, burstcnt, len; int size = 0, burstcnt, len;
struct i2c_client *client; struct i2c_client *client;
client = (struct i2c_client *) chip->vendor.iobase; client = (struct i2c_client *) TPM_VPRIV(chip);
while (size < count && while (size < count &&
wait_for_stat(chip, wait_for_stat(chip,
...@@ -421,7 +442,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) ...@@ -421,7 +442,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
disable_irq_nosync(irq); disable_irq_nosync(irq);
client = (struct i2c_client *) chip->vendor.iobase; client = (struct i2c_client *) TPM_VPRIV(chip);
pin_infos = client->dev.platform_data; pin_infos = client->dev.platform_data;
complete(&pin_infos->irq_detection); complete(&pin_infos->irq_detection);
...@@ -441,9 +462,10 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) ...@@ -441,9 +462,10 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf,
size_t len) size_t len)
{ {
u32 ret = 0, ordinal, u32 ordinal,
status, status,
burstcnt = 0, i, size; burstcnt = 0, i, size;
int ret;
u8 data; u8 data;
struct i2c_client *client; struct i2c_client *client;
struct st33zp24_platform_data *pin_infos; struct st33zp24_platform_data *pin_infos;
...@@ -453,7 +475,7 @@ static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf, ...@@ -453,7 +475,7 @@ static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf,
if (len < TPM_HEADER_SIZE) if (len < TPM_HEADER_SIZE)
return -EBUSY; return -EBUSY;
client = (struct i2c_client *)chip->vendor.iobase; client = (struct i2c_client *)TPM_VPRIV(chip);
pin_infos = client->dev.platform_data; pin_infos = client->dev.platform_data;
ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
...@@ -528,13 +550,12 @@ static int tpm_stm_i2c_recv(struct tpm_chip *chip, unsigned char *buf, ...@@ -528,13 +550,12 @@ static int tpm_stm_i2c_recv(struct tpm_chip *chip, unsigned char *buf,
struct i2c_client *client; struct i2c_client *client;
struct st33zp24_platform_data *pin_infos; struct st33zp24_platform_data *pin_infos;
client = (struct i2c_client *)chip->vendor.iobase;
pin_infos = client->dev.platform_data;
if (chip == NULL) if (chip == NULL)
return -EBUSY; return -EBUSY;
client = (struct i2c_client *)TPM_VPRIV(chip);
pin_infos = client->dev.platform_data;
if (count < TPM_HEADER_SIZE) { if (count < TPM_HEADER_SIZE) {
size = -EIO; size = -EIO;
goto out; goto out;
...@@ -629,7 +650,7 @@ MODULE_PARM_DESC(power_mgt, "Power Management"); ...@@ -629,7 +650,7 @@ MODULE_PARM_DESC(power_mgt, "Power Management");
static int static int
tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{ {
u32 err; int err;
u8 intmask; u8 intmask;
struct tpm_chip *chip; struct tpm_chip *chip;
struct st33zp24_platform_data *platform_data; struct st33zp24_platform_data *platform_data;
...@@ -666,10 +687,10 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -666,10 +687,10 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
if (platform_data->tpm_i2c_buffer[1] == NULL) { if (platform_data->tpm_i2c_buffer[1] == NULL) {
err = -ENOMEM; err = -ENOMEM;
goto _tpm_clean_response; goto _tpm_clean_response1;
} }
chip->vendor.iobase = client; TPM_VPRIV(chip) = client;
chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT); chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
...@@ -689,7 +710,7 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -689,7 +710,7 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
init_completion(&platform_data->irq_detection); init_completion(&platform_data->irq_detection);
if (request_locality(chip) != LOCALITY0) { if (request_locality(chip) != LOCALITY0) {
err = -ENODEV; err = -ENODEV;
goto _tpm_clean_response; goto _tpm_clean_response2;
} }
err = gpio_request(platform_data->io_serirq, "TPM IO_SERIRQ"); err = gpio_request(platform_data->io_serirq, "TPM IO_SERIRQ");
if (err) if (err)
...@@ -745,23 +766,19 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -745,23 +766,19 @@ tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
_irq_set: _irq_set:
free_irq(gpio_to_irq(platform_data->io_serirq), (void *) chip); free_irq(gpio_to_irq(platform_data->io_serirq), (void *) chip);
_gpio_init2: _gpio_init2:
if (platform_data && interrupts) if (interrupts)
gpio_free(platform_data->io_serirq); gpio_free(platform_data->io_serirq);
_gpio_init1: _gpio_init1:
if (platform_data && power_mgt) if (power_mgt)
gpio_free(platform_data->io_lpcpd); gpio_free(platform_data->io_lpcpd);
_tpm_clean_response: _tpm_clean_response2:
tpm_remove_hardware(chip->dev); kzfree(platform_data->tpm_i2c_buffer[1]);
if (platform_data->tpm_i2c_buffer[1] != NULL) { platform_data->tpm_i2c_buffer[1] = NULL;
kzfree(platform_data->tpm_i2c_buffer[1]); _tpm_clean_response1:
platform_data->tpm_i2c_buffer[1] = NULL; kzfree(platform_data->tpm_i2c_buffer[0]);
} platform_data->tpm_i2c_buffer[0] = NULL;
_tpm_clean_answer: _tpm_clean_answer:
if (platform_data->tpm_i2c_buffer[0] != NULL) { tpm_remove_hardware(chip->dev);
kzfree(platform_data->tpm_i2c_buffer[0]);
platform_data->tpm_i2c_buffer[0] = NULL;
}
platform_data->bChipF = true; platform_data->bChipF = true;
end: end:
pr_info("TPM I2C initialisation fail\n"); pr_info("TPM I2C initialisation fail\n");
...@@ -778,7 +795,7 @@ static __devexit int tpm_st33_i2c_remove(struct i2c_client *client) ...@@ -778,7 +795,7 @@ static __devexit int tpm_st33_i2c_remove(struct i2c_client *client)
{ {
struct tpm_chip *chip = (struct tpm_chip *)i2c_get_clientdata(client); struct tpm_chip *chip = (struct tpm_chip *)i2c_get_clientdata(client);
struct st33zp24_platform_data *pin_infos = struct st33zp24_platform_data *pin_infos =
((struct i2c_client *) chip->vendor.iobase)->dev.platform_data; ((struct i2c_client *) TPM_VPRIV(chip))->dev.platform_data;
if (pin_infos != NULL) { if (pin_infos != NULL) {
free_irq(pin_infos->io_serirq, chip); free_irq(pin_infos->io_serirq, chip);
...@@ -815,7 +832,7 @@ static int tpm_st33_i2c_pm_suspend(struct i2c_client *client, pm_message_t mesg) ...@@ -815,7 +832,7 @@ static int tpm_st33_i2c_pm_suspend(struct i2c_client *client, pm_message_t mesg)
struct tpm_chip *chip = struct tpm_chip *chip =
(struct tpm_chip *)i2c_get_clientdata(client); (struct tpm_chip *)i2c_get_clientdata(client);
struct st33zp24_platform_data *pin_infos = struct st33zp24_platform_data *pin_infos =
((struct i2c_client *)chip->vendor.iobase)->dev.platform_data; ((struct i2c_client *)TPM_VPRIV(chip))->dev.platform_data;
int ret = 0; int ret = 0;
if (power_mgt) if (power_mgt)
...@@ -838,14 +855,14 @@ static int tpm_st33_i2c_pm_resume(struct i2c_client *client) ...@@ -838,14 +855,14 @@ static int tpm_st33_i2c_pm_resume(struct i2c_client *client)
struct tpm_chip *chip = struct tpm_chip *chip =
(struct tpm_chip *)i2c_get_clientdata(client); (struct tpm_chip *)i2c_get_clientdata(client);
struct st33zp24_platform_data *pin_infos = struct st33zp24_platform_data *pin_infos =
((struct i2c_client *)chip->vendor.iobase)->dev.platform_data; ((struct i2c_client *)TPM_VPRIV(chip))->dev.platform_data;
int ret = 0; int ret = 0;
if (power_mgt) { if (power_mgt) {
gpio_set_value(pin_infos->io_lpcpd, 1); gpio_set_value(pin_infos->io_lpcpd, 1);
ret = wait_for_serirq_timeout(chip, ret = wait_for_serirq_timeout(chip,
(chip->vendor.status(chip) && (chip->vendor.status(chip) &
TPM_STS_VALID) == TPM_STS_VALID, TPM_STS_VALID) == TPM_STS_VALID,
chip->vendor.timeout_b); chip->vendor.timeout_b);
} else{ } else{
...@@ -877,27 +894,9 @@ static struct i2c_driver tpm_st33_i2c_driver = { ...@@ -877,27 +894,9 @@ static struct i2c_driver tpm_st33_i2c_driver = {
.id_table = tpm_st33_i2c_id .id_table = tpm_st33_i2c_id
}; };
/* module_i2c_driver(tpm_st33_i2c_driver);
* tpm_st33_i2c_init initialize driver
* @return: 0 if successful, else non zero value.
*/
static int __init tpm_st33_i2c_init(void)
{
return i2c_add_driver(&tpm_st33_i2c_driver);
}
/*
* tpm_st33_i2c_exit The kernel calls this function during unloading the
* module or during shut down process
*/
static void __exit tpm_st33_i2c_exit(void)
{
i2c_del_driver(&tpm_st33_i2c_driver);
}
module_init(tpm_st33_i2c_init);
module_exit(tpm_st33_i2c_exit);
MODULE_AUTHOR("Christophe Ricard (tpmsupport@st.com)"); MODULE_AUTHOR("Christophe Ricard (tpmsupport@st.com)");
MODULE_DESCRIPTION("STM TPM I2C ST33 Driver"); MODULE_DESCRIPTION("STM TPM I2C ST33 Driver");
MODULE_VERSION("1.2.0"); MODULE_VERSION("1.2.0");
MODULE_LICENSE("GPL");
...@@ -30,32 +30,6 @@ ...@@ -30,32 +30,6 @@
#ifndef __STM_ST33_TPM_I2C_MAIN_H__ #ifndef __STM_ST33_TPM_I2C_MAIN_H__
#define __STM_ST33_TPM_I2C_MAIN_H__ #define __STM_ST33_TPM_I2C_MAIN_H__
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/sysfs.h>
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include "tpm.h"
#define MINOR_NUM_I2C 224
#define TPM_ACCESS (0x0) #define TPM_ACCESS (0x0)
#define TPM_STS (0x18) #define TPM_STS (0x18)
#define TPM_HASH_END (0x20) #define TPM_HASH_END (0x20)
...@@ -73,9 +47,16 @@ ...@@ -73,9 +47,16 @@
#define LOCALITY0 0 #define LOCALITY0 0
struct st_tpm_hash { #define TPM_ST33_I2C "st33zp24_i2c"
int size;
u8 *data; struct st33zp24_platform_data {
int io_serirq;
int io_lpcpd;
struct i2c_client *client;
bool bChipF;
u8 *tpm_i2c_buffer[2]; /* 0 Request 1 Response */
struct completion irq_detection;
struct mutex lock;
}; };
#endif /* __STM_ST33_TPM_I2C_MAIN_H__ */ #endif /* __STM_ST33_TPM_I2C_MAIN_H__ */
/*
* STMicroelectronics TPM I2C Linux driver for TPM ST33ZP24
* Copyright (C) 2009, 2010 STMicroelectronics
* Christophe RICARD tpmsupport@st.com
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* STMicroelectronics version 1.2.0, Copyright (C) 2010
* STMicroelectronics comes with ABSOLUTELY NO WARRANTY.
* This is free software, and you are welcome to redistribute it
* under certain conditions.
*
* @File: stm_st33_tpm_i2c.h
*
* @Date: 06/15/2008
*/
#ifndef __STM_ST33_TPM_I2C_H__
#define __STM_ST33_TPM_I2C_H__
#include <linux/i2c.h>
#define TPM_ST33_I2C "st33zp24_i2c"
#define TPM_I2C_ST33_ADDR_WR_LOC0 (0x26 >> 1)
struct st33zp24_platform_data {
int io_serirq;
int io_lpcpd;
struct i2c_client *client;
bool bChipF;
u8 *tpm_i2c_buffer[2]; /* 0 Request 1 Response */
struct completion irq_detection;
struct mutex lock;
};
#endif /* __STM_ST33_TPM_I2C_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment