/* * 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; }
/* * 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; }