static int __init init_nsc()

in tpm/tpm_nsc.c [288:398]


static int __init init_nsc(void)
{
	int rc = 0;
	int lo, hi, err;
	int nscAddrBase = TPM_ADDR;
	struct tpm_chip *chip;
	unsigned long base;
	struct tpm_nsc_priv *priv;

	/* 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 = platform_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 = platform_device_alloc("tpm_nscl0", -1);
	if (!pdev) {
		rc = -ENOMEM;
		goto err_unreg_drv;
	}

	pdev->num_resources = 0;
	pdev->dev.driver = &nsc_drv.driver;
	pdev->dev.release = tpm_nsc_remove;

	if ((rc = platform_device_add(pdev)) < 0)
		goto err_put_dev;

	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		rc = -ENOMEM;
		goto err_del_dev;
	}

	priv->base = base;

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

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

	dev_set_drvdata(&chip->dev, priv);

	rc = tpm_chip_register(chip);
	if (rc)
		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);

	return 0;

err_rel_reg:
	release_region(base, 2);
err_del_dev:
	platform_device_del(pdev);
err_put_dev:
	platform_device_put(pdev);
err_unreg_drv:
	platform_driver_unregister(&nsc_drv);
	return rc;
}