/* * tpm_st33_i2c_remove remove the TPM device * @param: client, the i2c_client drescription (TPM I2C description). clear_bit(0, &chip->is_open); * @return: 0 in case of success. */ static int tpm_st33_i2c_remove(struct i2c_client *client) { struct tpm_chip *chip = (struct tpm_chip *)i2c_get_clientdata(client); struct st33zp24_platform_data *pin_infos = ((struct i2c_client *) TPM_VPRIV(chip))->dev.platform_data; if (pin_infos != NULL) { free_irq(pin_infos->io_serirq, chip); gpio_free(pin_infos->io_serirq); gpio_free(pin_infos->io_lpcpd); tpm_remove_hardware(chip->dev); if (pin_infos->tpm_i2c_buffer[1] != NULL) { kzfree(pin_infos->tpm_i2c_buffer[1]); pin_infos->tpm_i2c_buffer[1] = NULL; } if (pin_infos->tpm_i2c_buffer[0] != NULL) { kzfree(pin_infos->tpm_i2c_buffer[0]); pin_infos->tpm_i2c_buffer[0] = NULL; } } return 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) { tpm_remove_hardware(&dev->dev); ring_free(priv); return rv; } tpm_get_timeouts(priv->chip); dev_set_drvdata(&dev->dev, priv->chip); return rv; }
/** * tpm_ibmvtpm_remove - ibm vtpm remove entry point * @vdev: vio device struct * * Return value: * 0 */ static int tpm_ibmvtpm_remove(struct vio_dev *vdev) { struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev); int rc = 0; free_irq(vdev->irq, ibmvtpm); do { if (rc) msleep(100); rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); dma_unmap_single(ibmvtpm->dev, ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE, DMA_BIDIRECTIONAL); free_page((unsigned long)ibmvtpm->crq_queue.crq_addr); if (ibmvtpm->rtce_buf) { dma_unmap_single(ibmvtpm->dev, ibmvtpm->rtce_dma_handle, ibmvtpm->rtce_size, DMA_BIDIRECTIONAL); kfree(ibmvtpm->rtce_buf); } tpm_remove_hardware(ibmvtpm->dev); kfree(ibmvtpm); return 0; }
void cleanup_vtpm(struct device *dev) { struct tpm_chip *chip = dev_get_drvdata(dev); struct vtpm_state *vtpms = (struct vtpm_state*)chip_get_private(chip); tpm_remove_hardware(dev); kfree(vtpms); }
static void tpm_nsc_remove(struct device *dev) { struct tpm_chip *chip = dev_get_drvdata(dev); if ( chip ) { release_region(chip->vendor.base, 2); tpm_remove_hardware(chip->dev); } }
static int tpmfront_remove(struct xenbus_device *dev) { struct tpm_chip *chip = dev_get_drvdata(&dev->dev); struct tpm_private *priv = TPM_VPRIV(chip); tpm_remove_hardware(&dev->dev); ring_free(priv); TPM_VPRIV(chip) = NULL; return 0; }
static int i2c_atmel_remove(struct i2c_client *client) { struct device *dev = &(client->dev); struct tpm_chip *chip = dev_get_drvdata(dev); if (chip) tpm_dev_vendor_release(chip); tpm_remove_hardware(dev); kfree(chip); return 0; }
static void atml_plat_remove(void) { struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); if (chip) { if (chip->vendor.have_region) atmel_release_region(chip->vendor.base, chip->vendor.region_size); atmel_put_base_addr(chip->vendor.iobase); tpm_remove_hardware(chip->dev); platform_device_unregister(pdev); } }
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; }
static int __devexit tpm_tis_i2c_remove(struct i2c_client *client) { struct tpm_chip *chip = tpm_dev.chip; release_locality(chip, chip->vendor.locality, 1); /* 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); 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; }
/* * 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; }
/** * 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; }