X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=drivers%2Ftpm%2Ftpm.c;h=24997f6702d7b9796d4e3ba8a5d8d660b819046b;hp=31761ec33814878f85d817ea4611e3efd2d28089;hb=0bfcc924552b8ec79a20b8b12557ff08742c4f0e;hpb=8bd60ccf532f0fec07609528c2b04a0725d83984 diff --git a/drivers/tpm/tpm.c b/drivers/tpm/tpm.c index 31761ec338..24997f6702 100644 --- a/drivers/tpm/tpm.c +++ b/drivers/tpm/tpm.c @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -48,10 +49,8 @@ DECLARE_GLOBAL_DATA_PTR; /* TPM configuration */ struct tpm { - int i2c_bus; - int slave_addr; + struct udevice *dev; char inited; - int old_bus; } tpm; /* Global structure for tpm chip data */ @@ -372,7 +371,7 @@ static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz) { - ssize_t rc; + int rc; u32 count, ordinal; unsigned long start, stop; @@ -391,9 +390,11 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz) return -E2BIG; } + debug("Calling send\n"); rc = chip->vendor.send(chip, (u8 *)buf, count); + debug(" ... done calling send\n"); if (rc < 0) { - error("tpm_transmit: tpm_send: error %zd\n", rc); + error("tpm_transmit: tpm_send: error %d\n", rc); goto out; } @@ -403,7 +404,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz) start = get_timer(0); stop = tpm_calc_ordinal_duration(chip, ordinal); do { - debug("waiting for status...\n"); + debug("waiting for status... %ld %ld\n", start, stop); u8 status = chip->vendor.status(chip); if ((status & chip->vendor.req_complete_mask) == chip->vendor.req_complete_val) { @@ -428,18 +429,20 @@ out_recv: debug("out_recv: reading response...\n"); rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE); if (rc < 0) - error("tpm_transmit: tpm_recv: error %zd\n", rc); + error("tpm_transmit: tpm_recv: error %d\n", rc); out: return rc; } -static int tpm_open(uint32_t dev_addr) +static int tpm_open_dev(struct udevice *dev) { int rc; + + debug("%s: start\n", __func__); if (g_chip.is_open) return -EBUSY; - rc = tpm_vendor_init(dev_addr); + rc = tpm_vendor_init(dev); if (rc < 0) g_chip.is_open = 0; return rc; @@ -453,38 +456,6 @@ static void tpm_close(void) } } -static int tpm_select(void) -{ - int ret; - - tpm.old_bus = i2c_get_bus_num(); - if (tpm.old_bus != tpm.i2c_bus) { - ret = i2c_set_bus_num(tpm.i2c_bus); - if (ret) { - debug("%s: Fail to set i2c bus %d\n", __func__, - tpm.i2c_bus); - return -1; - } - } - return 0; -} - -static int tpm_deselect(void) -{ - int ret; - - if (tpm.old_bus != i2c_get_bus_num()) { - ret = i2c_set_bus_num(tpm.old_bus); - if (ret) { - debug("%s: Fail to restore i2c bus %d\n", - __func__, tpm.old_bus); - return -1; - } - } - tpm.old_bus = -1; - return 0; -} - /** * Decode TPM configuration. * @@ -493,10 +464,12 @@ static int tpm_deselect(void) */ static int tpm_decode_config(struct tpm *dev) { -#ifdef CONFIG_OF_CONTROL const void *blob = gd->fdt_blob; - int node, parent; - int i2c_bus; + struct udevice *bus; + int chip_addr; + int parent; + int node; + int ret; node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM); if (node < 0) { @@ -512,15 +485,35 @@ static int tpm_decode_config(struct tpm *dev) debug("%s: Cannot find node parent\n", __func__); return -1; } - i2c_bus = i2c_get_bus_num_fdt(parent); - if (i2c_bus < 0) - return -1; - dev->i2c_bus = i2c_bus; - dev->slave_addr = fdtdec_get_addr(blob, node, "reg"); -#else - dev->i2c_bus = CONFIG_TPM_TIS_I2C_BUS_NUMBER; - dev->slave_addr = CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS; -#endif + + /* + * TODO(sjg@chromium.org): Remove this when driver model supports + * TPMs + */ + ret = uclass_get_device_by_of_offset(UCLASS_I2C, parent, &bus); + if (ret) { + debug("Cannot find bus for node '%s: ret=%d'\n", + fdt_get_name(blob, parent, NULL), ret); + return ret; + } + + chip_addr = fdtdec_get_int(blob, node, "reg", -1); + if (chip_addr == -1) { + debug("Cannot find reg property for node '%s: ret=%d'\n", + fdt_get_name(blob, node, NULL), ret); + return ret; + } + /* + * TODO(sjg@chromium.org): Older TPMs will need to use the older method + * in iic_tpm_read() so the offset length needs to be 0 here. + */ + ret = i2c_get_chip(bus, chip_addr, 1, &dev->dev); + if (ret) { + debug("Cannot find device for node '%s: ret=%d'\n", + fdt_get_name(blob, node, NULL), ret); + return ret; + } + return 0; } @@ -544,20 +537,7 @@ int tis_init(void) if (tpm_decode_config(&tpm)) return -1; - if (tpm_select()) - return -1; - - /* - * Probe TPM twice; the first probing might fail because TPM is asleep, - * and the probing can wake up TPM. - */ - if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) { - debug("%s: fail to probe i2c addr 0x%x\n", __func__, - tpm.slave_addr); - return -1; - } - - tpm_deselect(); + debug("%s: done\n", __func__); tpm.inited = 1; @@ -571,12 +551,7 @@ int tis_open(void) if (!tpm.inited) return -1; - if (tpm_select()) - return -1; - - rc = tpm_open(tpm.slave_addr); - - tpm_deselect(); + rc = tpm_open_dev(tpm.dev); return rc; } @@ -586,13 +561,8 @@ int tis_close(void) if (!tpm.inited) return -1; - if (tpm_select()) - return -1; - tpm_close(); - tpm_deselect(); - return 0; } @@ -610,13 +580,8 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, memcpy(buf, sendbuf, sbuf_size); - if (tpm_select()) - return -1; - len = tpm_transmit(buf, sbuf_size); - tpm_deselect(); - if (len < 10) { *rbuf_len = 0; return -1;