Exemple #1
0
int pps_register_source(struct pps_source_info *info, int default_params)
{
	struct pps_device *pps;
	int id;
	int err;

	/* Sanity checks */
	if ((info->mode & default_params) != default_params) {
		printk(KERN_ERR "pps: %s: unsupported default parameters\n",
					info->name);
		err = -EINVAL;
		goto pps_register_source_exit;
	}
	if ((info->mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)) != 0 &&
			info->echo == NULL) {
		printk(KERN_ERR "pps: %s: echo function is not defined\n",
					info->name);
		err = -EINVAL;
		goto pps_register_source_exit;
	}
	if ((info->mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) {
		printk(KERN_ERR "pps: %s: unspecified time format\n",
					info->name);
		err = -EINVAL;
		goto pps_register_source_exit;
	}

	/* Allocate memory for the new PPS source struct */
	pps = kzalloc(sizeof(struct pps_device), GFP_KERNEL);
	if (pps == NULL) {
		err = -ENOMEM;
		goto pps_register_source_exit;
	}

	/* These initializations must be done before calling idr_get_new()
	 * in order to avoid reces into pps_event().
	 */
	pps->params.api_version = PPS_API_VERS;
	pps->params.mode = default_params;
	pps->info = *info;

	init_waitqueue_head(&pps->queue);
	spin_lock_init(&pps->lock);
	atomic_set(&pps->usage, 1);

	/* Get new ID for the new PPS source */
	if (idr_pre_get(&pps_idr, GFP_KERNEL) == 0) {
		err = -ENOMEM;
		goto kfree_pps;
	}

	spin_lock_irq(&pps_idr_lock);

	/* Now really allocate the PPS source.
	 * After idr_get_new() calling the new source will be freely available
	 * into the kernel.
	 */
	err = idr_get_new(&pps_idr, pps, &id);
	if (err < 0) {
		spin_unlock_irq(&pps_idr_lock);
		goto kfree_pps;
	}

	id = id & MAX_ID_MASK;
	if (id >= PPS_MAX_SOURCES) {
		spin_unlock_irq(&pps_idr_lock);

		printk(KERN_ERR "pps: %s: too many PPS sources in the system\n",
					info->name);
		err = -EBUSY;
		goto free_idr;
	}
	pps->id = id;

	spin_unlock_irq(&pps_idr_lock);

	/* Create the char device */
	err = pps_register_cdev(pps);
	if (err < 0) {
		printk(KERN_ERR "pps: %s: unable to create char device\n",
					info->name);
		goto free_idr;
	}

	pr_info("new PPS source %s at ID %d\n", info->name, id);

	return id;

free_idr:
	spin_lock_irq(&pps_idr_lock);
	idr_remove(&pps_idr, id);
	spin_unlock_irq(&pps_idr_lock);

kfree_pps:
	kfree(pps);

pps_register_source_exit:
	printk(KERN_ERR "pps: %s: unable to register source\n", info->name);

	return err;
}
Exemple #2
0
struct pps_device *pps_register_source(struct pps_source_info *info,
		int default_params)
{
	struct pps_device *pps;
	int err;

	/* Sanity checks */
	if ((info->mode & default_params) != default_params) {
		pr_err("%s: unsupported default parameters\n",
					info->name);
		err = -EINVAL;
		goto pps_register_source_exit;
	}
	if ((info->mode & (PPS_ECHOASSERT | PPS_ECHOCLEAR)) != 0 &&
			info->echo == NULL) {
		pr_err("%s: echo function is not defined\n",
					info->name);
		err = -EINVAL;
		goto pps_register_source_exit;
	}
	if ((info->mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) {
		pr_err("%s: unspecified time format\n",
					info->name);
		err = -EINVAL;
		goto pps_register_source_exit;
	}

	/* Allocate memory for the new PPS source struct */
	pps = kzalloc(sizeof(struct pps_device), GFP_KERNEL);
	if (pps == NULL) {
		err = -ENOMEM;
		goto pps_register_source_exit;
	}

	/* These initializations must be done before calling idr_get_new()
	 * in order to avoid reces into pps_event().
	 */
	pps->params.api_version = PPS_API_VERS;
	pps->params.mode = default_params;
	pps->info = *info;

	init_waitqueue_head(&pps->queue);
	spin_lock_init(&pps->lock);

	/* Create the char device */
	err = pps_register_cdev(pps);
	if (err < 0) {
		pr_err("%s: unable to create char device\n",
					info->name);
		goto kfree_pps;
	}

	dev_info(pps->dev, "new PPS source %s\n", info->name);

	return pps;

kfree_pps:
	kfree(pps);

pps_register_source_exit:
	pr_err("%s: unable to register source\n", info->name);

	return NULL;
}