示例#1
0
static int tpmfront_probe(struct xenbus_device *dev,
		const struct xenbus_device_id *id)
{
	struct tpm_private *priv;
	int rv;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		xenbus_dev_fatal(dev, -ENOMEM, "allocating priv structure");
		return -ENOMEM;
	}

	rv = setup_chip(&dev->dev, priv);
	if (rv) {
		kfree(priv);
		return rv;
	}

	rv = setup_ring(dev, priv);
	if (rv) {
		ring_free(priv);
		return rv;
	}

	tpm_get_timeouts(priv->chip);

	return tpm_chip_register(priv->chip);
}
static int i2c_atmel_probe(struct i2c_client *client,
			   const struct i2c_device_id *id)
{
	int rc;
	struct tpm_chip *chip;
	struct device *dev = &client->dev;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		return -ENODEV;

	chip = tpm_register_hardware(dev, &i2c_atmel);
	if (!chip) {
		dev_err(dev, "%s() error in tpm_register_hardware\n", __func__);
		return -ENODEV;
	}

	chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data),
					 GFP_KERNEL);
	if (!chip->vendor.priv) {
		rc = -ENOMEM;
		goto out_err;
	}

	/* Default timeouts */
	chip->vendor.timeout_a = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT);
	chip->vendor.timeout_b = msecs_to_jiffies(TPM_I2C_LONG_TIMEOUT);
	chip->vendor.timeout_c = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT);
	chip->vendor.timeout_d = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT);
	chip->vendor.irq = 0;

	/* There is no known way to probe for this device, and all version
	 * information seems to be read via TPM commands. Thus we rely on the
	 * TPM startup process in the common code to detect the device. */
	if (tpm_get_timeouts(chip)) {
		rc = -ENODEV;
		goto out_err;
	}

	if (tpm_do_selftest(chip)) {
		rc = -ENODEV;
		goto out_err;
	}

	return 0;

out_err:
	tpm_dev_vendor_release(chip);
	tpm_remove_hardware(chip->dev);
	return rc;
}
示例#3
0
/**
 * tpm1_auto_startup - Perform the standard automatic TPM initialization
 *                     sequence
 * @chip: TPM chip to use
 *
 * Returns 0 on success, < 0 in case of fatal error.
 */
int tpm1_auto_startup(struct tpm_chip *chip)
{
	int rc;

	rc = tpm_get_timeouts(chip);
	if (rc)
		goto out;
	rc = tpm_do_selftest(chip);
	if (rc) {
		dev_err(&chip->dev, "TPM self test failed\n");
		goto out;
	}

	return rc;
out:
	if (rc > 0)
		rc = -ENODEV;
	return rc;
}
static int i2c_atmel_probe(struct i2c_client *client,
			   const struct i2c_device_id *id)
{
	struct tpm_chip *chip;
	struct device *dev = &client->dev;
	struct priv_data *priv;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		return -ENODEV;

	chip = tpmm_chip_alloc(dev, &i2c_atmel);
	if (IS_ERR(chip))
		return PTR_ERR(chip);

	priv = devm_kzalloc(dev, sizeof(struct priv_data), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	/* Default timeouts */
	chip->timeout_a = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT);
	chip->timeout_b = msecs_to_jiffies(TPM_I2C_LONG_TIMEOUT);
	chip->timeout_c = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT);
	chip->timeout_d = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT);

	dev_set_drvdata(&chip->dev, priv);

	/* There is no known way to probe for this device, and all version
	 * information seems to be read via TPM commands. Thus we rely on the
	 * TPM startup process in the common code to detect the device. */
	if (tpm_get_timeouts(chip))
		return -ENODEV;

	if (tpm_do_selftest(chip))
		return -ENODEV;

	return tpm_chip_register(chip);
}
示例#5
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;
}
示例#6
0
/*
 * tpm_st33_i2c_probe initialize the TPM device
 * @param: client, the i2c_client drescription (TPM I2C description).
 * @param: id, the i2c_device_id struct.
 * @return: 0 in case of success.
 *	 -1 in other case.
 */
static int
tpm_st33_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int err;
	u8 intmask;
	struct tpm_chip *chip;
	struct st33zp24_platform_data *platform_data;

	if (client == NULL) {
		pr_info("%s: i2c client is NULL. Device not accessible.\n",
			__func__);
		err = -ENODEV;
		goto end;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_info(&client->dev, "client not i2c capable\n");
		err = -ENODEV;
		goto end;
	}

	chip = tpm_register_hardware(&client->dev, &st_i2c_tpm);
	if (!chip) {
		dev_info(&client->dev, "fail chip\n");
		err = -ENODEV;
		goto end;
	}

	platform_data = client->dev.platform_data;

	if (!platform_data) {
		dev_info(&client->dev, "chip not available\n");
		err = -ENODEV;
		goto _tpm_clean_answer;
	}

	platform_data->tpm_i2c_buffer[0] =
	    kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
	if (platform_data->tpm_i2c_buffer[0] == NULL) {
		err = -ENOMEM;
		goto _tpm_clean_answer;
	}
	platform_data->tpm_i2c_buffer[1] =
	    kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
	if (platform_data->tpm_i2c_buffer[1] == NULL) {
		err = -ENOMEM;
		goto _tpm_clean_response1;
	}

	TPM_VPRIV(chip) = client;

	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);

	chip->vendor.locality = LOCALITY0;

	if (power_mgt) {
		err = gpio_request(platform_data->io_lpcpd, "TPM IO_LPCPD");
		if (err)
			goto _gpio_init1;
		gpio_set_value(platform_data->io_lpcpd, 1);
	}

	if (interrupts) {
		init_completion(&platform_data->irq_detection);
		if (request_locality(chip) != LOCALITY0) {
			err = -ENODEV;
			goto _tpm_clean_response2;
		}
		err = gpio_request(platform_data->io_serirq, "TPM IO_SERIRQ");
		if (err)
			goto _gpio_init2;

		clear_interruption(client);
		err = request_irq(gpio_to_irq(platform_data->io_serirq),
				&tpm_ioserirq_handler,
				IRQF_TRIGGER_HIGH,
				"TPM SERIRQ management", chip);
		if (err < 0) {
			dev_err(chip->dev , "TPM SERIRQ signals %d not available\n",
			gpio_to_irq(platform_data->io_serirq));
			goto _irq_set;
		}

		err = I2C_READ_DATA(client, TPM_INT_ENABLE, &intmask, 1);
		if (err < 0)
			goto _irq_set;

		intmask |= TPM_INTF_CMD_READY_INT
			|  TPM_INTF_FIFO_AVALAIBLE_INT
			|  TPM_INTF_WAKE_UP_READY_INT
			|  TPM_INTF_LOCALITY_CHANGE_INT
			|  TPM_INTF_STS_VALID_INT
			|  TPM_INTF_DATA_AVAIL_INT;

		err = I2C_WRITE_DATA(client, TPM_INT_ENABLE, &intmask, 1);
		if (err < 0)
			goto _irq_set;

		intmask = TPM_GLOBAL_INT_ENABLE;
		err = I2C_WRITE_DATA(client, (TPM_INT_ENABLE + 3), &intmask, 1);
		if (err < 0)
			goto _irq_set;

		err = I2C_READ_DATA(client, TPM_INT_STATUS, &intmask, 1);
		if (err < 0)
			goto _irq_set;

		chip->vendor.irq = interrupts;

		tpm_gen_interrupt(chip);
	}

	tpm_get_timeouts(chip);

	i2c_set_clientdata(client, chip);

	dev_info(chip->dev, "TPM I2C Initialized\n");
	return 0;
_irq_set:
	free_irq(gpio_to_irq(platform_data->io_serirq), (void *) chip);
_gpio_init2:
	if (interrupts)
		gpio_free(platform_data->io_serirq);
_gpio_init1:
	if (power_mgt)
		gpio_free(platform_data->io_lpcpd);
_tpm_clean_response2:
	kzfree(platform_data->tpm_i2c_buffer[1]);
	platform_data->tpm_i2c_buffer[1] = NULL;
_tpm_clean_response1:
	kzfree(platform_data->tpm_i2c_buffer[0]);
	platform_data->tpm_i2c_buffer[0] = NULL;
_tpm_clean_answer:
	tpm_remove_hardware(chip->dev);
end:
	pr_info("TPM I2C initialisation fail\n");
	return err;
}
示例#7
0
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;
}
示例#8
0
/*
 * tpm_stm_i2c_probe initialize the TPM device
 * @param: client, the i2c_client drescription (TPM I2C description).
 * @param: id, the i2c_device_id struct.
 * @return: 0 in case of success.
 *	 -1 in other case.
 */
static int
tpm_stm_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int ret;
	u8 intmask = 0;
	struct tpm_chip *chip;
	struct st33zp24_platform_data *platform_data;
	struct tpm_stm_dev *tpm_dev;

	if (!client) {
		pr_info("%s: i2c client is NULL. Device not accessible.\n",
			__func__);
		return -ENODEV;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_info(&client->dev, "client not i2c capable\n");
		return -ENODEV;
	}

	tpm_dev = devm_kzalloc(&client->dev, sizeof(struct tpm_stm_dev),
			       GFP_KERNEL);
	if (!tpm_dev)
		return -ENOMEM;

	chip = tpmm_chip_alloc(&client->dev, &st_i2c_tpm);
	if (IS_ERR(chip))
		return PTR_ERR(chip);

	TPM_VPRIV(chip) = tpm_dev;
	tpm_dev->client = client;

	platform_data = client->dev.platform_data;
	if (!platform_data && client->dev.of_node) {
		ret = tpm_stm_i2c_of_request_resources(chip);
		if (ret)
			goto _tpm_clean_answer;
	} else if (platform_data) {
		ret = tpm_stm_i2c_request_resources(client, chip);
		if (ret)
			goto _tpm_clean_answer;
	}

	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);

	chip->vendor.locality = LOCALITY0;

	if (client->irq) {
		/* INTERRUPT Setup */
		init_waitqueue_head(&chip->vendor.read_queue);
		tpm_dev->intrs = 0;

		if (request_locality(chip) != LOCALITY0) {
			ret = -ENODEV;
			goto _tpm_clean_answer;
		}

		clear_interruption(tpm_dev);
		ret = devm_request_irq(&client->dev, client->irq,
				tpm_ioserirq_handler,
				IRQF_TRIGGER_HIGH,
				"TPM SERIRQ management", chip);
		if (ret < 0) {
			dev_err(chip->pdev, "TPM SERIRQ signals %d not available\n",
				client->irq);
			goto _tpm_clean_answer;
		}

		intmask |= TPM_INTF_CMD_READY_INT
			|  TPM_INTF_STS_VALID_INT
			|  TPM_INTF_DATA_AVAIL_INT;

		ret = I2C_WRITE_DATA(tpm_dev, TPM_INT_ENABLE, &intmask, 1);
		if (ret < 0)
			goto _tpm_clean_answer;

		intmask = TPM_GLOBAL_INT_ENABLE;
		ret = I2C_WRITE_DATA(tpm_dev, (TPM_INT_ENABLE + 3),
				     &intmask, 1);
		if (ret < 0)
			goto _tpm_clean_answer;

		chip->vendor.irq = client->irq;

		disable_irq_nosync(chip->vendor.irq);

		tpm_gen_interrupt(chip);
	}

	tpm_get_timeouts(chip);
	tpm_do_selftest(chip);

	return tpm_chip_register(chip);
_tpm_clean_answer:
	dev_info(chip->pdev, "TPM I2C initialisation fail\n");
	return ret;
}