Example #1
0
/*
 * hl_device_release - release function for habanalabs device
 *
 * @inode: pointer to inode structure
 * @filp: pointer to file structure
 *
 * Called when process closes an habanalabs device
 */
static int hl_device_release(struct inode *inode, struct file *filp)
{
	struct hl_fpriv *hpriv = filp->private_data;

	hl_cb_mgr_fini(hpriv->hdev, &hpriv->cb_mgr);
	hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);

	filp->private_data = NULL;

	hl_hpriv_put(hpriv);

	return 0;
}
Example #2
0
/*
 * hl_device_open - open function for habanalabs device
 *
 * @inode: pointer to inode structure
 * @filp: pointer to file structure
 *
 * Called when process opens an habanalabs device.
 */
int hl_device_open(struct inode *inode, struct file *filp)
{
	struct hl_device *hdev;
	struct hl_fpriv *hpriv;
	int rc;

	mutex_lock(&hl_devs_idr_lock);
	hdev = idr_find(&hl_devs_idr, iminor(inode));
	mutex_unlock(&hl_devs_idr_lock);

	if (!hdev) {
		pr_err("Couldn't find device %d:%d\n",
			imajor(inode), iminor(inode));
		return -ENXIO;
	}

	mutex_lock(&hdev->fd_open_cnt_lock);

	if (hl_device_disabled_or_in_reset(hdev)) {
		dev_err_ratelimited(hdev->dev,
			"Can't open %s because it is disabled or in reset\n",
			dev_name(hdev->dev));
		mutex_unlock(&hdev->fd_open_cnt_lock);
		return -EPERM;
	}

	if (atomic_read(&hdev->fd_open_cnt)) {
		dev_info_ratelimited(hdev->dev,
			"Device %s is already attached to application\n",
			dev_name(hdev->dev));
		mutex_unlock(&hdev->fd_open_cnt_lock);
		return -EBUSY;
	}

	atomic_inc(&hdev->fd_open_cnt);

	mutex_unlock(&hdev->fd_open_cnt_lock);

	hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
	if (!hpriv) {
		rc = -ENOMEM;
		goto close_device;
	}

	hpriv->hdev = hdev;
	filp->private_data = hpriv;
	hpriv->filp = filp;
	mutex_init(&hpriv->restore_phase_mutex);
	kref_init(&hpriv->refcount);
	nonseekable_open(inode, filp);

	hl_cb_mgr_init(&hpriv->cb_mgr);
	hl_ctx_mgr_init(&hpriv->ctx_mgr);

	rc = hl_ctx_create(hdev, hpriv);
	if (rc) {
		dev_err(hdev->dev, "Failed to open FD (CTX fail)\n");
		goto out_err;
	}

	hpriv->taskpid = find_get_pid(current->pid);

	/*
	 * Device is IDLE at this point so it is legal to change PLLs. There
	 * is no need to check anything because if the PLL is already HIGH, the
	 * set function will return without doing anything
	 */
	hl_device_set_frequency(hdev, PLL_HIGH);

	hl_debugfs_add_file(hpriv);

	return 0;

out_err:
	filp->private_data = NULL;
	hl_ctx_mgr_fini(hpriv->hdev, &hpriv->ctx_mgr);
	hl_cb_mgr_fini(hpriv->hdev, &hpriv->cb_mgr);
	mutex_destroy(&hpriv->restore_phase_mutex);
	kfree(hpriv);

close_device:
	atomic_dec(&hdev->fd_open_cnt);
	return rc;
}