// SPDX-License-Identifier: GPL-2.0-or-later
/*
* CXL Flash Device Driver
*
* Written by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
* Uma Krishnan <ukrishn@linux.vnet.ibm.com>, IBM Corporation
*
* Copyright (C) 2018 IBM Corporation
*/
#include <linux/file.h>
#include <linux/idr.h>
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/pseudo_fs.h>
#include <linux/poll.h>
#include <linux/sched/signal.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <asm/xive.h>
#include <misc/ocxl.h>
#include <uapi/misc/cxl.h>
#include "backend.h"
#include "ocxl_hw.h"
/*
* Pseudo-filesystem to allocate inodes.
*/
#define OCXLFLASH_FS_MAGIC 0x1697698f
static int ocxlflash_fs_cnt;
static struct vfsmount *ocxlflash_vfs_mount;
static int ocxlflash_fs_init_fs_context(struct fs_context *fc)
{
return init_pseudo(fc, OCXLFLASH_FS_MAGIC) ? 0 : -ENOMEM;
}
static struct file_system_type ocxlflash_fs_type = {
.name = "ocxlflash",
.owner = THIS_MODULE,
.init_fs_context = ocxlflash_fs_init_fs_context,
.kill_sb = kill_anon_super,
};
/*
* ocxlflash_release_mapping() - release the memory mapping
* @ctx: Context whose mapping is to be released.
*/
static void ocxlflash_release_mapping(struct ocxlflash_context *ctx)
{
if (ctx->mapping)
simple_release_fs(&ocxlflash_vfs_mount, &ocxlflash_fs_cnt);
ctx->mapping = NULL;
}
/*
* ocxlflash_getfile() - allocate pseudo filesystem, inode, and the file
* @dev: Generic device of the host.
* @name: Name of the pseudo filesystem.
* @fops: File operations.
* @priv: Private data.
* @flags: Flags for the file.
*
* Return: pointer to the file on success, ERR_PTR on failure
*/
static struct file *ocxlflash_getfile(struct device *dev, const char *name,
const struct file_operations *fops,
void *priv, int flags)
{
struct file *file;
struct inode *inode;
int rc;
if (fops->owner && !try_module_get(fops->owner)) {
dev_err(dev, "%s: Owner does not exist\n", __func__);
rc = -ENOENT;
goto err1;
}
rc = simple_pin_fs(&ocxlflash_fs_type, &ocxlflash_vfs_mount,
&ocxlflash_fs_cnt