static int cr50_i2c_probe(struct tpm_chip *chip, uint32_t *did_vid) { int retries; /* * 150 ms should be enough to synchronize with the TPM even under the * worst nested reset request conditions. In vast majority of cases * there would be no wait at all. */ printk(BIOS_INFO, "Probing TPM I2C: "); for (retries = 15; retries > 0; retries--) { int rc; rc = cr50_i2c_read(chip, TPM_DID_VID(0), (uint8_t *)did_vid, 4); /* Exit once DID and VID verified */ if (!rc && (*did_vid == CR50_DID_VID)) { printk(BIOS_INFO, "done! DID_VID 0x%08x\n", *did_vid); return 0; } /* TPM might be resetting, let's retry in a bit. */ mdelay(10); printk(BIOS_INFO, "."); } /* * I2C reads failed, or the DID and VID didn't match */ printk(BIOS_ERR, "DID_VID 0x%08x not recognized\n", *did_vid); return -1; }
static int tpm_tis_i2c_init(struct udevice *dev) { struct tpm_chip *chip = dev_get_priv(dev); u32 vendor; u32 expected_did_vid; int rc; chip->is_open = 1; /* Default timeouts - these could move to the device tree */ chip->timeout_a = TIS_SHORT_TIMEOUT_MS; chip->timeout_b = TIS_LONG_TIMEOUT_MS; chip->timeout_c = TIS_SHORT_TIMEOUT_MS; chip->timeout_d = TIS_SHORT_TIMEOUT_MS; rc = tpm_tis_i2c_request_locality(dev, 0); if (rc < 0) return rc; /* Read four bytes from DID_VID register */ if (tpm_tis_i2c_read(dev, TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) { tpm_tis_i2c_release_locality(dev, 0, 1); return -EIO; } if (chip->chip_type == SLB9635) { vendor = be32_to_cpu(vendor); expected_did_vid = TPM_TIS_I2C_DID_VID_9635; } else { /* device id and byte order has changed for newer i2c tpms */ expected_did_vid = TPM_TIS_I2C_DID_VID_9645; } if (chip->chip_type != UNKNOWN && vendor != expected_did_vid) { pr_err("Vendor id did not match! ID was %08x\n", vendor); return -ENODEV; } chip->vend_dev = vendor; debug("1.2 TPM (chip type %s device-id 0x%X)\n", chip_name[chip->chip_type], vendor >> 16); /* * A timeout query to TPM can be placed here. * Standard timeout values are used so far */ return 0; }
static int __devinit tpm_tis_i2c_init(struct device *dev) { u32 vendor; int rc = 0; struct tpm_chip *chip; chip = tpm_register_hardware(dev, &tpm_tis_i2c); if (!chip) { rc = -ENODEV; goto out_err; } /* Disable interrupts */ chip->vendor.irq = 0; /* Default timeouts */ chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT); chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); if (request_locality(chip, 0) != 0) { rc = -ENODEV; goto out_vendor; } /* read four bytes from DID_VID register */ if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) { rc = -EIO; goto out_release; } /* create DID_VID register value, after swapping to little-endian */ vendor = be32_to_cpu((__be32) vendor); if (vendor != TPM_TIS_I2C_DID_VID) { rc = -ENODEV; goto out_release; } dev_info(dev, "1.2 TPM (device-id 0x%X)\n", vendor >> 16); INIT_LIST_HEAD(&chip->vendor.list); tpm_dev.chip = chip; tpm_get_timeouts(chip); tpm_do_selftest(chip); return 0; out_release: release_locality(chip, chip->vendor.locality, 1); out_vendor: /* close file handles */ tpm_dev_vendor_release(chip); /* remove hardware */ tpm_remove_hardware(chip->dev); /* reset these pointers, otherwise we oops */ chip->dev->release = NULL; chip->release = NULL; tpm_dev.client = NULL; dev_set_drvdata(chip->dev, chip); out_err: return rc; }
struct tpm_chip* init_tpm_tis(unsigned long baseaddr, int localities, unsigned int irq) { int i; unsigned long addr; struct tpm_chip* tpm = NULL; uint32_t didvid; uint32_t intfcaps; uint32_t intmask; printk("============= Init TPM TIS Driver ==============\n"); /*Sanity check the localities input */ if(localities & ~TPM_TIS_EN_LOCLALL) { printk("init_tpm_tis() Invalid locality specification! %X\n", localities); goto abort_egress; } printk("IOMEM Machine Base Address: %lX\n", baseaddr); /* Create the tpm data structure */ tpm = malloc(sizeof(struct tpm_chip)); __init_tpm_chip(tpm); /* Set the enabled localities - if 0 we leave default as all enabled */ if(localities != 0) { tpm->enabled_localities = localities; } printk("Enabled Localities: "); for(i = 0; i < 5; ++i) { if(locality_enabled(tpm, i)) { printk("%d ", i); } } printk("\n"); /* Set the base machine address */ tpm->baseaddr = baseaddr; /* Set default timeouts */ tpm->timeout_a = MILLISECS(TIS_SHORT_TIMEOUT); tpm->timeout_b = MILLISECS(TIS_LONG_TIMEOUT); tpm->timeout_c = MILLISECS(TIS_SHORT_TIMEOUT); tpm->timeout_d = MILLISECS(TIS_SHORT_TIMEOUT); /*Map the mmio pages */ addr = tpm->baseaddr; for(i = 0; i < 5; ++i) { if(locality_enabled(tpm, i)) { /* Map the page in now */ if((tpm->pages[i] = ioremap_nocache(addr, PAGE_SIZE)) == NULL) { printk("Unable to map iomem page a address %p\n", addr); goto abort_egress; } /* Set default locality to the first enabled one */ if (tpm->locality < 0) { if(tpm_tis_request_locality(tpm, i) < 0) { printk("Unable to request locality %d??\n", i); goto abort_egress; } } } addr += PAGE_SIZE; } /* Get the vendor and device ids */ didvid = ioread32(TPM_DID_VID(tpm, tpm->locality)); tpm->did = didvid >> 16; tpm->vid = didvid & 0xFFFF; /* Get the revision id */ tpm->rid = ioread8(TPM_RID(tpm, tpm->locality)); printk("1.2 TPM (device-id=0x%X vendor-id = %X rev-id = %X)\n", tpm->did, tpm->vid, tpm->rid); intfcaps = ioread32(TPM_INTF_CAPS(tpm, tpm->locality)); printk("TPM interface capabilities (0x%x):\n", intfcaps); if (intfcaps & TPM_INTF_BURST_COUNT_STATIC) printk("\tBurst Count Static\n"); if (intfcaps & TPM_INTF_CMD_READY_INT) printk("\tCommand Ready Int Support\n"); if (intfcaps & TPM_INTF_INT_EDGE_FALLING) printk("\tInterrupt Edge Falling\n"); if (intfcaps & TPM_INTF_INT_EDGE_RISING) printk("\tInterrupt Edge Rising\n"); if (intfcaps & TPM_INTF_INT_LEVEL_LOW) printk("\tInterrupt Level Low\n"); if (intfcaps & TPM_INTF_INT_LEVEL_HIGH) printk("\tInterrupt Level High\n"); if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT) printk("\tLocality Change Int Support\n"); if (intfcaps & TPM_INTF_STS_VALID_INT) printk("\tSts Valid Int Support\n"); if (intfcaps & TPM_INTF_DATA_AVAIL_INT) printk("\tData Avail Int Support\n"); /*Interupt setup */ intmask = ioread32(TPM_INT_ENABLE(tpm, tpm->locality)); intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; iowrite32(TPM_INT_ENABLE(tpm, tpm->locality), intmask); /*If interupts are enabled, handle it */ if(irq) { if(irq != TPM_PROBE_IRQ) { tpm->irq = irq; } else { /*FIXME add irq probing feature later */ printk("IRQ probing not implemented\n"); } } if(tpm->irq) { iowrite8(TPM_INT_VECTOR(tpm, tpm->locality), tpm->irq); if(bind_pirq(tpm->irq, 1, tpm_tis_irq_handler, tpm) != 0) { printk("Unabled to request irq: %u for use\n", tpm->irq); printk("Will use polling mode\n"); tpm->irq = 0; } else { /* Clear all existing */ iowrite32(TPM_INT_STATUS(tpm, tpm->locality), ioread32(TPM_INT_STATUS(tpm, tpm->locality))); /* Turn on interrupts */ iowrite32(TPM_INT_ENABLE(tpm, tpm->locality), intmask | TPM_GLOBAL_INT_ENABLE); } } if(tpm_get_timeouts(tpm)) { printk("Could not get TPM timeouts and durations\n"); goto abort_egress; } tpm_continue_selftest(tpm); return tpm; abort_egress: if(tpm != NULL) { shutdown_tpm_tis(tpm); } return NULL; }