コード例 #1
0
ファイル: tpm_vtpm.c プロジェクト: cywzl/spice4xen
struct tpm_chip *init_vtpm(struct device *dev,
                           struct tpm_private *tp)
{
	long rc;
	struct tpm_chip *chip;
	struct vtpm_state *vtpms;

	vtpms = kzalloc(sizeof(struct vtpm_state), GFP_KERNEL);
	if (!vtpms)
		return ERR_PTR(-ENOMEM);

	vtpm_state_init(vtpms);
	vtpms->tpm_private = tp;

	chip = tpm_register_hardware(dev, &tpm_vtpm);
	if (!chip) {
		rc = -ENODEV;
		goto err_free_mem;
	}

	chip_set_private(chip, vtpms);

	return chip;

err_free_mem:
	kfree(vtpms);

	return ERR_PTR(rc);
}
コード例 #2
0
static int __init init_atmel(void)
{
	int rc = 0;
	void __iomem *iobase = NULL;
	int have_region, region_size;
	unsigned long base;
	struct  tpm_chip *chip;

	rc = platform_driver_register(&atml_drv);
	if (rc)
		return rc;

	if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
		rc = -ENODEV;
		goto err_unreg_drv;
	}

	have_region =
	    (atmel_request_region
	     (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;

	pdev = platform_device_register_simple("tpm_atmel", -1, NULL, 0);
	if (IS_ERR(pdev)) {
		rc = PTR_ERR(pdev);
		goto err_rel_reg;
	}

	if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
		rc = -ENODEV;
		goto err_unreg_dev;
	}

	chip->vendor.iobase = iobase;
	chip->vendor.base = base;
	chip->vendor.have_region = have_region;
	chip->vendor.region_size = region_size;

	return 0;

err_unreg_dev:
	platform_device_unregister(pdev);
err_rel_reg:
	atmel_put_base_addr(iobase);
	if (have_region)
		atmel_release_region(base,
				     region_size);
err_unreg_drv:
	platform_driver_unregister(&atml_drv);
	return rc;
}
コード例 #3
0
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;
}
コード例 #4
0
static int setup_chip(struct device *dev, struct tpm_private *priv)
{
	struct tpm_chip *chip;

	chip = tpm_register_hardware(dev, &tpm_vtpm);
	if (!chip)
		return -ENODEV;

	init_waitqueue_head(&chip->vendor.read_queue);

	priv->chip = chip;
	TPM_VPRIV(chip) = priv;

	return 0;
}
コード例 #5
0
ファイル: tpm_i2c_infineon.c プロジェクト: AllenDou/linux
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_nsc.c プロジェクト: 274914765/C
static int __init init_nsc(void)
{
    int rc = 0;
    int lo, hi, err;
    int nscAddrBase = TPM_ADDR;
    struct tpm_chip *chip;
    unsigned long base;

    /* verify that it is a National part (SID) */
    if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
        nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
            (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
        if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6)
            return -ENODEV;
    }

    err = driver_register(&nsc_drv);
    if (err)
        return err;

    hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
    lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
    base = (hi<<8) | lo;

    /* enable the DPM module */
    tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);

    pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
    if (!pdev) {
        rc = -ENOMEM;
        goto err_unreg_drv;
    }

    pdev->name = "tpm_nscl0";
    pdev->id = -1;
    pdev->num_resources = 0;
    pdev->dev.release = tpm_nsc_remove;
    pdev->dev.driver = &nsc_drv;

    if ((rc = platform_device_register(pdev)) < 0)
        goto err_free_dev;

    if (request_region(base, 2, "tpm_nsc0") == NULL ) {
        rc = -EBUSY;
        goto err_unreg_dev;
    }

    if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
        rc = -ENODEV;
        goto err_rel_reg;
    }

    dev_dbg(&pdev->dev, "NSC TPM detected\n");
    dev_dbg(&pdev->dev,
        "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
        tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
        tpm_read_index(nscAddrBase,0x27));
    dev_dbg(&pdev->dev,
        "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
        tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
        tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
    dev_dbg(&pdev->dev, "NSC IO Base0 0x%x\n",
        (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
    dev_dbg(&pdev->dev, "NSC IO Base1 0x%x\n",
        (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
    dev_dbg(&pdev->dev, "NSC Interrupt number and wakeup 0x%x\n",
        tpm_read_index(nscAddrBase,0x70));
    dev_dbg(&pdev->dev, "NSC IRQ type select 0x%x\n",
        tpm_read_index(nscAddrBase,0x71));
    dev_dbg(&pdev->dev,
        "NSC DMA channel select0 0x%x, select1 0x%x\n",
        tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
    dev_dbg(&pdev->dev,
        "NSC Config "
        "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
        tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
        tpm_read_index(nscAddrBase,0xF2), tpm_read_index(nscAddrBase,0xF3),
        tpm_read_index(nscAddrBase,0xF4), tpm_read_index(nscAddrBase,0xF5),
        tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
        tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));

    dev_info(&pdev->dev,
         "NSC TPM revision %d\n",
         tpm_read_index(nscAddrBase, 0x27) & 0x1F);

    chip->vendor.base = base;

    return 0;

err_rel_reg:
    release_region(base, 2);
err_unreg_dev:
    platform_device_unregister(pdev);
err_free_dev:
    kfree(pdev);
err_unreg_drv:
    driver_unregister(&nsc_drv);
    return rc;
}
コード例 #7
0
ファイル: tpm_i2c_stm_st33.c プロジェクト: AiWinters/linux
/*
 * 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;
}
コード例 #8
0
/**
 * tpm_ibmvtpm_probe - ibm vtpm initialize entry point
 * @vio_dev:	vio device struct
 * @id:		vio device id struct
 *
 * Return value:
 *	0 - Success
 *	Non-zero - Failure
 */
static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
				   const struct vio_device_id *id)
{
	struct ibmvtpm_dev *ibmvtpm;
	struct device *dev = &vio_dev->dev;
	struct ibmvtpm_crq_queue *crq_q;
	struct tpm_chip *chip;
	int rc = -ENOMEM, rc1;

	chip = tpm_register_hardware(dev, &tpm_ibmvtpm);
	if (!chip) {
		dev_err(dev, "tpm_register_hardware failed\n");
		return -ENODEV;
	}

	ibmvtpm = kzalloc(sizeof(struct ibmvtpm_dev), GFP_KERNEL);
	if (!ibmvtpm) {
		dev_err(dev, "kzalloc for ibmvtpm failed\n");
		goto cleanup;
	}

	crq_q = &ibmvtpm->crq_queue;
	crq_q->crq_addr = (struct ibmvtpm_crq *)get_zeroed_page(GFP_KERNEL);
	if (!crq_q->crq_addr) {
		dev_err(dev, "Unable to allocate memory for crq_addr\n");
		goto cleanup;
	}

	crq_q->num_entry = CRQ_RES_BUF_SIZE / sizeof(*crq_q->crq_addr);
	ibmvtpm->crq_dma_handle = dma_map_single(dev, crq_q->crq_addr,
						 CRQ_RES_BUF_SIZE,
						 DMA_BIDIRECTIONAL);

	if (dma_mapping_error(dev, ibmvtpm->crq_dma_handle)) {
		dev_err(dev, "dma mapping failed\n");
		goto cleanup;
	}

	rc = plpar_hcall_norets(H_REG_CRQ, vio_dev->unit_address,
				ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE);
	if (rc == H_RESOURCE)
		rc = ibmvtpm_reset_crq(ibmvtpm);

	if (rc) {
		dev_err(dev, "Unable to register CRQ rc=%d\n", rc);
		goto reg_crq_cleanup;
	}

	rc = request_irq(vio_dev->irq, ibmvtpm_interrupt, 0,
			 tpm_ibmvtpm_driver_name, ibmvtpm);
	if (rc) {
		dev_err(dev, "Error %d register irq 0x%x\n", rc, vio_dev->irq);
		goto init_irq_cleanup;
	}

	rc = vio_enable_interrupts(vio_dev);
	if (rc) {
		dev_err(dev, "Error %d enabling interrupts\n", rc);
		goto init_irq_cleanup;
	}

	init_waitqueue_head(&ibmvtpm->wq);

	crq_q->index = 0;

	ibmvtpm->dev = dev;
	ibmvtpm->vdev = vio_dev;
	chip->vendor.data = (void *)ibmvtpm;

	spin_lock_init(&ibmvtpm->rtce_lock);

	rc = ibmvtpm_crq_send_init(ibmvtpm);
	if (rc)
		goto init_irq_cleanup;

	rc = ibmvtpm_crq_get_version(ibmvtpm);
	if (rc)
		goto init_irq_cleanup;

	rc = ibmvtpm_crq_get_rtce_size(ibmvtpm);
	if (rc)
		goto init_irq_cleanup;

	return rc;
init_irq_cleanup:
	do {
		rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address);
	} while (rc1 == H_BUSY || H_IS_LONG_BUSY(rc1));
reg_crq_cleanup:
	dma_unmap_single(dev, ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE,
			 DMA_BIDIRECTIONAL);
cleanup:
	if (ibmvtpm) {
		if (crq_q->crq_addr)
			free_page((unsigned long)crq_q->crq_addr);
		kfree(ibmvtpm);
	}

	tpm_remove_hardware(dev);

	return rc;
}