+/**
+ * cxlflash_chr_open() - character device open handler
+ * @inode: Device inode associated with this character device.
+ * @file: File pointer for this device.
+ *
+ * Only users with admin privileges are allowed to open the character device.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int cxlflash_chr_open(struct inode *inode, struct file *file)
+{
+ struct cxlflash_cfg *cfg;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ cfg = container_of(inode->i_cdev, struct cxlflash_cfg, cdev);
+ file->private_data = cfg;
+
+ return 0;
+}
+
+/*
+ * Character device file operations
+ */
+static const struct file_operations cxlflash_chr_fops = {
+ .owner = THIS_MODULE,
+ .open = cxlflash_chr_open,
+};
+
+/**
+ * init_chrdev() - initialize the character device for the host
+ * @cfg: Internal structure associated with the host.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+static int init_chrdev(struct cxlflash_cfg *cfg)
+{
+ struct device *dev = &cfg->dev->dev;
+ struct device *char_dev;
+ dev_t devno;
+ int minor;
+ int rc = 0;
+
+ minor = cxlflash_get_minor();
+ if (unlikely(minor < 0)) {
+ dev_err(dev, "%s: Exhausted allowed adapters\n", __func__);
+ rc = -ENOSPC;
+ goto out;
+ }
+
+ devno = MKDEV(cxlflash_major, minor);
+ cdev_init(&cfg->cdev, &cxlflash_chr_fops);
+
+ rc = cdev_add(&cfg->cdev, devno, 1);
+ if (rc) {
+ dev_err(dev, "%s: cdev_add failed rc=%d\n", __func__, rc);
+ goto err1;
+ }
+
+ char_dev = device_create(cxlflash_class, NULL, devno,
+ NULL, "cxlflash%d", minor);
+ if (IS_ERR(char_dev)) {
+ rc = PTR_ERR(char_dev);
+ dev_err(dev, "%s: device_create failed rc=%d\n",
+ __func__, rc);
+ goto err2;
+ }
+
+ cfg->chardev = char_dev;
+out:
+ dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
+ return rc;
+err2:
+ cdev_del(&cfg->cdev);
+err1:
+ cxlflash_put_minor(minor);
+ goto out;
+}
+