示例#1
0
/*
 * First routine called when the kernel module is loaded
 */
static int __init tf_device_register(void)
{
	int error;
	struct tf_device *dev = &g_tf_dev;

	dprintk(KERN_INFO "tf_device_register()\n");

	/*
	 * Initialize the device
	 */
	dev->dev_number = MKDEV(device_major_number,
		TF_DEVICE_MINOR_NUMBER);
	cdev_init(&dev->cdev, &g_tf_device_file_ops);
	dev->cdev.owner = THIS_MODULE;

	g_tf_sysdev.id = 0;
	g_tf_sysdev.cls = &g_tf_device_sys_class;

	INIT_LIST_HEAD(&dev->connection_list);
	spin_lock_init(&dev->connection_list_lock);

#if defined(MODULE) && defined(CONFIG_TF_ZEBRA)
	error = (*tf_comm_early_init)();
	if (error)
		goto module_early_init_failed;

	error = tf_device_mshield_init(smc_mem);
	if (error)
		goto mshield_init_failed;

#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	error = tf_crypto_hmac_module_init();
	if (error)
		goto hmac_init_failed;

	error = tf_self_test_register_device();
	if (error)
		goto self_test_register_device_failed;
#endif
#endif

	/* register the sysfs object driver stats */
	error = kobject_init_and_add(&dev->kobj,  &tf_ktype, NULL, "%s",
		 TF_DEVICE_BASE_NAME);
	if (error) {
		printk(KERN_ERR "tf_device_register(): "
			"kobject_init_and_add failed (error %d)!\n", error);
		kobject_put(&dev->kobj);
		goto kobject_init_and_add_failed;
	}

	/*
	 * Register the system device.
	 */

	error = sysdev_class_register(&g_tf_device_sys_class);
	if (error != 0) {
		printk(KERN_ERR "tf_device_register():"
			" sysdev_class_register failed (error %d)!\n",
			error);
		goto sysdev_class_register_failed;
	}

	error = sysdev_register(&g_tf_sysdev);
	if (error != 0) {
		dprintk(KERN_ERR "tf_device_register(): "
			"sysdev_register failed (error %d)!\n",
			error);
		goto sysdev_register_failed;
	}

	/*
	 * Register the char device.
	 */
	printk(KERN_INFO "Registering char device %s (%u:%u)\n",
		TF_DEVICE_BASE_NAME,
		MAJOR(dev->dev_number),
		MINOR(dev->dev_number));
	error = register_chrdev_region(dev->dev_number, 1,
		TF_DEVICE_BASE_NAME);
	if (error != 0) {
		printk(KERN_ERR "tf_device_register():"
			" register_chrdev_region failed (error %d)!\n",
			error);
		goto register_chrdev_region_failed;
	}

	error = cdev_add(&dev->cdev, dev->dev_number, 1);
	if (error != 0) {
		printk(KERN_ERR "tf_device_register(): "
			"cdev_add failed (error %d)!\n",
			error);
		goto cdev_add_failed;
	}

	/*
	 * Initialize the communication with the Secure World.
	 */
#ifdef CONFIG_TF_TRUSTZONE
	dev->sm.soft_int_irq = soft_interrupt;
#endif
	error = tf_init(&g_tf_dev.sm);
	if (error != S_SUCCESS) {
		dprintk(KERN_ERR "tf_device_register(): "
			"tf_init failed (error %d)!\n",
			error);
		goto init_failed;
	}

#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	error = tf_self_test_post_init(&(dev_stats->kobj));
	/* N.B. error > 0 indicates a POST failure, which will not
	   prevent the module from loading. */
	if (error < 0) {
		dprintk(KERN_ERR "tf_device_register(): "
			"tf_self_test_post_vectors failed (error %d)!\n",
			error);
		goto post_failed;
	}
#endif

#ifdef CONFIG_ANDROID
	tf_class = class_create(THIS_MODULE, TF_DEVICE_BASE_NAME);
	device_create(tf_class, NULL,
		dev->dev_number,
		NULL, TF_DEVICE_BASE_NAME);
#endif

#ifdef CONFIG_TF_ZEBRA
	/*
	 * Initializes the /dev/tf_ctrl device node.
	 */
	error = tf_ctrl_device_register();
	if (error)
		goto ctrl_failed;
#endif

#ifdef CONFIG_TF_DRIVER_DEBUG_SUPPORT
	address_cache_property((unsigned long) &tf_device_register);
#endif
	/*
	 * Successful completion.
	 */

	dprintk(KERN_INFO "tf_device_register(): Success\n");
	return 0;

	/*
	 * Error: undo all operations in the reverse order
	 */
#ifdef CONFIG_TF_ZEBRA
ctrl_failed:
#endif
#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	tf_self_test_post_exit();
post_failed:
#endif
init_failed:
	cdev_del(&dev->cdev);
cdev_add_failed:
	unregister_chrdev_region(dev->dev_number, 1);
register_chrdev_region_failed:
	sysdev_unregister(&g_tf_sysdev);
sysdev_register_failed:
	sysdev_class_unregister(&g_tf_device_sys_class);
sysdev_class_register_failed:
kobject_init_and_add_failed:
	kobject_del(&g_tf_dev.kobj);

#if defined(MODULE) && defined(CONFIG_TF_ZEBRA)
#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
	tf_self_test_unregister_device();
self_test_register_device_failed:
	tf_crypto_hmac_module_exit();
hmac_init_failed:
#endif
	tf_device_mshield_exit();
mshield_init_failed:
module_early_init_failed:
#endif
	dprintk(KERN_INFO "tf_device_register(): Failure (error %d)\n",
		error);
	return error;
}
示例#2
0
/*
 * First routine called when the kernel module is loaded
 */
static int __init tf_device_register(void)
{
    int error;
    struct tf_device *dev = &g_tf_dev;
    struct tf_device_stats *dev_stats = &dev->stats;

    dprintk(KERN_INFO "tf_device_register()\n");

    /*
     * Initialize the device
     */
    dev->dev_number = MKDEV(device_major_number,
                            TF_DEVICE_MINOR_NUMBER);
    cdev_init(&dev->cdev, &g_tf_device_file_ops);
    dev->cdev.owner = THIS_MODULE;

    INIT_LIST_HEAD(&dev->connection_list);
    spin_lock_init(&dev->connection_list_lock);

    /* register the sysfs object driver stats */
    dev_stats->kobj_type.sysfs_ops = &kobj_sysfs_operations;

    dev_stats->kobj_stat_attribute.name = "info";
    dev_stats->kobj_stat_attribute.mode = S_IRUGO;
    dev_stats->kobj_attribute_list[0] =
        &dev_stats->kobj_stat_attribute;

    dev_stats->kobj_type.default_attrs =
        dev_stats->kobj_attribute_list,
        error = kobject_init_and_add(&(dev_stats->kobj),
                                     &(dev_stats->kobj_type), NULL, "%s",
                                     TF_DEVICE_BASE_NAME);
    if (error) {
        kobject_put(&dev_stats->kobj);
        goto kobject_init_and_add_failed;
    }

    register_syscore_ops((struct syscore_ops *)&g_tf_syscore_ops);

    /*
     * Register the char device.
     */
    printk(KERN_INFO "Registering char device %s (%u:%u)\n",
           TF_DEVICE_BASE_NAME,
           MAJOR(dev->dev_number),
           MINOR(dev->dev_number));
    error = register_chrdev_region(dev->dev_number, 1,
                                   TF_DEVICE_BASE_NAME);
    if (error != 0) {
        printk(KERN_ERR "tf_device_register():"
               " register_chrdev_region failed (error %d)!\n",
               error);
        goto register_chrdev_region_failed;
    }

    error = cdev_add(&dev->cdev, dev->dev_number, 1);
    if (error != 0) {
        printk(KERN_ERR "tf_device_register(): "
               "cdev_add failed (error %d)!\n",
               error);
        goto cdev_add_failed;
    }

    /*
     * Initialize the communication with the Secure World.
     */
#ifdef CONFIG_TF_TRUSTZONE
    dev->sm.soft_int_irq = soft_interrupt;
#endif
    error = tf_init(&g_tf_dev.sm);
    if (error != S_SUCCESS) {
        dprintk(KERN_ERR "tf_device_register(): "
                "tf_init failed (error %d)!\n",
                error);
        goto init_failed;
    }

#ifdef CONFIG_ANDROID
#ifdef CONFIG_TF_DRIVER_CRYPTO_FIPS
    error = tf_self_test_post_init(&(g_tf_dev.kobj));
    /* N.B. error > 0 indicates a POST failure, which will not
       prevent the module from loading. */
    if (error < 0) {
        dprintk(KERN_ERR "tf_device_register(): "
                "tf_self_test_post_vectors failed (error %d)!\n",
                error);
        goto post_failed;
    }
#endif

    tf_class = class_create(THIS_MODULE, TF_DEVICE_BASE_NAME);
    device_create(tf_class, NULL,
                  dev->dev_number,
                  NULL, TF_DEVICE_BASE_NAME);
#endif

#ifdef CONFIG_TF_ZEBRA
    /*
     * Initializes the /dev/tf_ctrl device node.
     */
    error = tf_ctrl_device_register();
    if (error)
        goto init_failed;
#endif

#ifdef CONFIG_BENCH_SECURE_CYCLE
    run_bogo_mips();
    address_cache_property((unsigned long) &tf_device_register);
#endif
    /*
     * Successful completion.
     */

    dprintk(KERN_INFO "tf_device_register(): Success\n");
    return 0;

    /*
     * Error: undo all operations in the reverse order
     */
init_failed:
    cdev_del(&dev->cdev);
cdev_add_failed:
    unregister_chrdev_region(dev->dev_number, 1);
register_chrdev_region_failed:
    unregister_syscore_ops((struct syscore_ops *)&g_tf_syscore_ops);
kobject_init_and_add_failed:
    kobject_del(&g_tf_dev.stats.kobj);

    dprintk(KERN_INFO "tf_device_register(): Failure (error %d)\n",
            error);
    return error;
}