aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorAndrew Donnellan <ajd@linux.ibm.com>2025-02-19 18:00:06 +1100
committerMichael Ellerman <mpe@ellerman.id.au>2025-03-16 22:04:27 +1100
commit5a0fcb0ef5584caf7da3f31896e08650c532e4c1 (patch)
treeee0d8d91e3deb181cd97b8e7c89b72228e092ec9 /drivers/misc
parentff443fb402e95f5095dde3c64f7c3249d7c6f993 (diff)
cxl: Remove driver
Remove the cxl driver that provides support for the IBM Coherent Accelerator Processor Interface. Revert or clean up associated code in arch/powerpc that is no longer necessary. cxl has received minimal maintenance for several years, and is not supported on the Power10 processor. We aren't aware of any users who are likely to be using recent kernels. Thanks to Mikey Neuling, Ian Munsie, Daniel Axtens, Frederic Barrat, Christophe Lombard, Philippe Bergheaud, Vaibhav Jain and Alastair D'Silva for their work on this driver over the years. Signed-off-by: Andrew Donnellan <ajd@linux.ibm.com> Acked-by: Frederic Barrat <fbarrat@linux.ibm.com> Acked-by: Madhavan Srinivasan <maddy@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://patch.msgid.link/20250219070007.177725-2-ajd@linux.ibm.com
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/cxl/Kconfig28
-rw-r--r--drivers/misc/cxl/Makefile14
-rw-r--r--drivers/misc/cxl/api.c532
-rw-r--r--drivers/misc/cxl/base.c126
-rw-r--r--drivers/misc/cxl/context.c362
-rw-r--r--drivers/misc/cxl/cxl.h1135
-rw-r--r--drivers/misc/cxl/cxllib.c271
-rw-r--r--drivers/misc/cxl/debugfs.c134
-rw-r--r--drivers/misc/cxl/fault.c341
-rw-r--r--drivers/misc/cxl/file.c699
-rw-r--r--drivers/misc/cxl/flash.c538
-rw-r--r--drivers/misc/cxl/guest.c1208
-rw-r--r--drivers/misc/cxl/hcalls.c643
-rw-r--r--drivers/misc/cxl/hcalls.h200
-rw-r--r--drivers/misc/cxl/irq.c450
-rw-r--r--drivers/misc/cxl/main.c383
-rw-r--r--drivers/misc/cxl/native.c1592
-rw-r--r--drivers/misc/cxl/of.c346
-rw-r--r--drivers/misc/cxl/pci.c2103
-rw-r--r--drivers/misc/cxl/sysfs.c771
-rw-r--r--drivers/misc/cxl/trace.c9
-rw-r--r--drivers/misc/cxl/trace.h691
-rw-r--r--drivers/misc/cxl/vphb.c309
25 files changed, 0 insertions, 12887 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 56bc72c7ce4a..6b37d61150ee 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -641,7 +641,6 @@ source "drivers/misc/mei/Kconfig"
source "drivers/misc/vmw_vmci/Kconfig"
source "drivers/misc/genwqe/Kconfig"
source "drivers/misc/echo/Kconfig"
-source "drivers/misc/cxl/Kconfig"
source "drivers/misc/ocxl/Kconfig"
source "drivers/misc/bcm-vk/Kconfig"
source "drivers/misc/cardreader/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 545aad06d088..d6c917229c45 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -50,7 +50,6 @@ obj-$(CONFIG_SRAM) += sram.o
obj-$(CONFIG_SRAM_EXEC) += sram-exec.o
obj-$(CONFIG_GENWQE) += genwqe/
obj-$(CONFIG_ECHO) += echo/
-obj-$(CONFIG_CXL_BASE) += cxl/
obj-$(CONFIG_DW_XDATA_PCIE) += dw-xdata-pcie.o
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
obj-$(CONFIG_OCXL) += ocxl/
diff --git a/drivers/misc/cxl/Kconfig b/drivers/misc/cxl/Kconfig
deleted file mode 100644
index 15307f5e4307..000000000000
--- a/drivers/misc/cxl/Kconfig
+++ /dev/null
@@ -1,28 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# IBM Coherent Accelerator (CXL) compatible devices
-#
-
-config CXL_BASE
- bool
- select PPC_COPRO_BASE
- select PPC_64S_HASH_MMU
-
-config CXL
- tristate "Support for IBM Coherent Accelerators (CXL) (DEPRECATED)"
- depends on PPC_POWERNV && PCI_MSI && EEH
- select CXL_BASE
- help
- The cxl driver is deprecated and will be removed in a future
- kernel release.
-
- Select this option to enable driver support for IBM Coherent
- Accelerators (CXL). CXL is otherwise known as Coherent Accelerator
- Processor Interface (CAPI). CAPI allows accelerators in FPGAs to be
- coherently attached to a CPU via an MMU. This driver enables
- userspace programs to access these accelerators via /dev/cxl/afuM.N
- devices.
-
- CAPI adapters are found in POWER8 based systems.
-
- If unsure, say N.
diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile
deleted file mode 100644
index 5eea61b9584f..000000000000
--- a/drivers/misc/cxl/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-ccflags-y := $(call cc-disable-warning, unused-const-variable)
-ccflags-$(CONFIG_PPC_WERROR) += -Werror
-
-cxl-y += main.o file.o irq.o fault.o native.o
-cxl-y += context.o sysfs.o pci.o trace.o
-cxl-y += vphb.o api.o cxllib.o
-cxl-$(CONFIG_PPC_PSERIES) += flash.o guest.o of.o hcalls.o
-cxl-$(CONFIG_DEBUG_FS) += debugfs.o
-obj-$(CONFIG_CXL) += cxl.o
-obj-$(CONFIG_CXL_BASE) += base.o
-
-# For tracepoints to include our trace.h from tracepoint infrastructure:
-CFLAGS_trace.o := -I$(src)
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
deleted file mode 100644
index d85c56530863..000000000000
--- a/drivers/misc/cxl/api.c
+++ /dev/null
@@ -1,532 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/file.h>
-#include <misc/cxl.h>
-#include <linux/module.h>
-#include <linux/mount.h>
-#include <linux/pseudo_fs.h>
-#include <linux/sched/mm.h>
-#include <linux/mmu_context.h>
-#include <linux/irqdomain.h>
-
-#include "cxl.h"
-
-/*
- * Since we want to track memory mappings to be able to force-unmap
- * when the AFU is no longer reachable, we need an inode. For devices
- * opened through the cxl user API, this is not a problem, but a
- * userland process can also get a cxl fd through the cxl_get_fd()
- * API, which is used by the cxlflash driver.
- *
- * Therefore we implement our own simple pseudo-filesystem and inode
- * allocator. We don't use the anonymous inode, as we need the
- * meta-data associated with it (address_space) and it is shared by
- * other drivers/processes, so it could lead to cxl unmapping VMAs
- * from random processes.
- */
-
-#define CXL_PSEUDO_FS_MAGIC 0x1697697f
-
-static int cxl_fs_cnt;
-static struct vfsmount *cxl_vfs_mount;
-
-static int cxl_fs_init_fs_context(struct fs_context *fc)
-{
- return init_pseudo(fc, CXL_PSEUDO_FS_MAGIC) ? 0 : -ENOMEM;
-}
-
-static struct file_system_type cxl_fs_type = {
- .name = "cxl",
- .owner = THIS_MODULE,
- .init_fs_context = cxl_fs_init_fs_context,
- .kill_sb = kill_anon_super,
-};
-
-
-void cxl_release_mapping(struct cxl_context *ctx)
-{
- if (ctx->kernelapi && ctx->mapping)
- simple_release_fs(&cxl_vfs_mount, &cxl_fs_cnt);
-}
-
-static struct file *cxl_getfile(const char *name,
- const struct file_operations *fops,
- void *priv, int flags)
-{
- struct file *file;
- struct inode *inode;
- int rc;
-
- /* strongly inspired by anon_inode_getfile() */
-
- if (fops->owner && !try_module_get(fops->owner))
- return ERR_PTR(-ENOENT);
-
- rc = simple_pin_fs(&cxl_fs_type, &cxl_vfs_mount, &cxl_fs_cnt);
- if (rc < 0) {
- pr_err("Cannot mount cxl pseudo filesystem: %d\n", rc);
- file = ERR_PTR(rc);
- goto err_module;
- }
-
- inode = alloc_anon_inode(cxl_vfs_mount->mnt_sb);
- if (IS_ERR(inode)) {
- file = ERR_CAST(inode);
- goto err_fs;
- }
-
- file = alloc_file_pseudo(inode, cxl_vfs_mount, name,
- flags & (O_ACCMODE | O_NONBLOCK), fops);
- if (IS_ERR(file))
- goto err_inode;
-
- file->private_data = priv;
-
- return file;
-
-err_inode:
- iput(inode);
-err_fs:
- simple_release_fs(&cxl_vfs_mount, &cxl_fs_cnt);
-err_module:
- module_put(fops->owner);
- return file;
-}
-
-struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
-{
- struct cxl_afu *afu;
- struct cxl_context *ctx;
- int rc;
-
- afu = cxl_pci_to_afu(dev);
- if (IS_ERR(afu))
- return ERR_CAST(afu);
-
- ctx = cxl_context_alloc();
- if (!ctx)
- return ERR_PTR(-ENOMEM);
-
- ctx->kernelapi = true;
-
- /* Make it a slave context. We can promote it later? */
- rc = cxl_context_init(ctx, afu, false);
- if (rc)
- goto err_ctx;
-
- return ctx;
-
-err_ctx:
- kfree(ctx);
- return ERR_PTR(rc);
-}
-EXPORT_SYMBOL_GPL(cxl_dev_context_init);
-
-struct cxl_context *cxl_get_context(struct pci_dev *dev)
-{
- return dev->dev.archdata.cxl_ctx;
-}
-EXPORT_SYMBOL_GPL(cxl_get_context);
-
-int cxl_release_context(struct cxl_context *ctx)
-{
- if (ctx->status >= STARTED)
- return -EBUSY;
-
- cxl_context_free(ctx);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxl_release_context);
-
-static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num)
-{
- __u16 range;
- int r;
-
- for (r = 0; r < CXL_IRQ_RANGES; r++) {
- range = ctx->irqs.range[r];
- if (num < range) {
- return ctx->irqs.offset[r] + num;
- }
- num -= range;
- }
- return 0;
-}
-
-
-int cxl_set_priv(struct cxl_context *ctx, void *priv)
-{
- if (!ctx)
- return -EINVAL;
-
- ctx->priv = priv;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxl_set_priv);
-
-void *cxl_get_priv(struct cxl_context *ctx)
-{
- if (!ctx)
- return ERR_PTR(-EINVAL);
-
- return ctx->priv;
-}
-EXPORT_SYMBOL_GPL(cxl_get_priv);
-
-int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num)
-{
- int res;
- irq_hw_number_t hwirq;
-
- if (num == 0)
- num = ctx->afu->pp_irqs;
- res = afu_allocate_irqs(ctx, num);
- if (res)
- return res;
-
- if (!cpu_has_feature(CPU_FTR_HVMODE)) {
- /* In a guest, the PSL interrupt is not multiplexed. It was
- * allocated above, and we need to set its handler
- */
- hwirq = cxl_find_afu_irq(ctx, 0);
- if (hwirq)
- cxl_map_irq(ctx->afu->adapter, hwirq, cxl_ops->psl_interrupt, ctx, "psl");
- }
-
- if (ctx->status == STARTED) {
- if (cxl_ops->update_ivtes)
- cxl_ops->update_ivtes(ctx);
- else WARN(1, "BUG: cxl_allocate_afu_irqs must be called prior to starting the context on this platform\n");
- }
-
- return res;
-}
-EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
-
-void cxl_free_afu_irqs(struct cxl_context *ctx)
-{
- irq_hw_number_t hwirq;
- unsigned int virq;
-
- if (!cpu_has_feature(CPU_FTR_HVMODE)) {
- hwirq = cxl_find_afu_irq(ctx, 0);
- if (hwirq) {
- virq = irq_find_mapping(NULL, hwirq);
- if (virq)
- cxl_unmap_irq(virq, ctx);
- }
- }
- afu_irq_name_free(ctx);
- cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
-}
-EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
-
-int cxl_map_afu_irq(struct cxl_context *ctx, int num,
- irq_handler_t handler, void *cookie, char *name)
-{
- irq_hw_number_t hwirq;
-
- /*
- * Find interrupt we are to register.
- */
- hwirq = cxl_find_afu_irq(ctx, num);
- if (!hwirq)
- return -ENOENT;
-
- return cxl_map_irq(ctx->afu->adapter, hwirq, handler, cookie, name);
-}
-EXPORT_SYMBOL_GPL(cxl_map_afu_irq);
-
-void cxl_unmap_afu_irq(struct cxl_context *ctx, int num, void *cookie)
-{
- irq_hw_number_t hwirq;
- unsigned int virq;
-
- hwirq = cxl_find_afu_irq(ctx, num);
- if (!hwirq)
- return;
-
- virq = irq_find_mapping(NULL, hwirq);
- if (virq)
- cxl_unmap_irq(virq, cookie);
-}
-EXPORT_SYMBOL_GPL(cxl_unmap_afu_irq);
-
-/*
- * Start a context
- * Code here similar to afu_ioctl_start_work().
- */
-int cxl_start_context(struct cxl_context *ctx, u64 wed,
- struct task_struct *task)
-{
- int rc = 0;
- bool kernel = true;
-
- pr_devel("%s: pe: %i\n", __func__, ctx->pe);
-
- mutex_lock(&ctx->status_mutex);
- if (ctx->status == STARTED)
- goto out; /* already started */
-
- /*
- * Increment the mapped context count for adapter. This also checks
- * if adapter_context_lock is taken.
- */
- rc = cxl_adapter_context_get(ctx->afu->adapter);
- if (rc)
- goto out;
-
- if (task) {
- ctx->pid = get_task_pid(task, PIDTYPE_PID);
- kernel = false;
-
- /* acquire a reference to the task's mm */
- ctx->mm = get_task_mm(current);
-
- /* ensure this mm_struct can't be freed */
- cxl_context_mm_count_get(ctx);
-
- if (ctx->mm) {
- /* decrement the use count from above */
- mmput(ctx->mm);
- /* make TLBIs for this context global */
- mm_context_add_copro(ctx->mm);
- }
- }
-
- /*
- * Increment driver use count. Enables global TLBIs for hash
- * and callbacks to handle the segment table
- */
- cxl_ctx_get();
-
- /* See the comment in afu_ioctl_start_work() */
- smp_mb();
-
- if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
- put_pid(ctx->pid);
- ctx->pid = NULL;
- cxl_adapter_context_put(ctx->afu->adapter);
- cxl_ctx_put();
- if (task) {
- cxl_context_mm_count_put(ctx);
- if (ctx->mm)
- mm_context_remove_copro(ctx->mm);
- }
- goto out;
- }
-
- ctx->status = STARTED;
-out:
- mutex_unlock(&ctx->status_mutex);
- return rc;
-}
-EXPORT_SYMBOL_GPL(cxl_start_context);
-
-int cxl_process_element(struct cxl_context *ctx)
-{
- return ctx->external_pe;
-}
-EXPORT_SYMBOL_GPL(cxl_process_element);
-
-/* Stop a context. Returns 0 on success, otherwise -Errno */
-int cxl_stop_context(struct cxl_context *ctx)
-{
- return __detach_context(ctx);
-}
-EXPORT_SYMBOL_GPL(cxl_stop_context);
-
-void cxl_set_master(struct cxl_context *ctx)
-{
- ctx->master = true;
-}
-EXPORT_SYMBOL_GPL(cxl_set_master);
-
-/* wrappers around afu_* file ops which are EXPORTED */
-int cxl_fd_open(struct inode *inode, struct file *file)
-{
- return afu_open(inode, file);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_open);
-int cxl_fd_release(struct inode *inode, struct file *file)
-{
- return afu_release(inode, file);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_release);
-long cxl_fd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- return afu_ioctl(file, cmd, arg);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_ioctl);
-int cxl_fd_mmap(struct file *file, struct vm_area_struct *vm)
-{
- return afu_mmap(file, vm);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_mmap);
-__poll_t cxl_fd_poll(struct file *file, struct poll_table_struct *poll)
-{
- return afu_poll(file, poll);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_poll);
-ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count,
- loff_t *off)
-{
- return afu_read(file, buf, count, off);
-}
-EXPORT_SYMBOL_GPL(cxl_fd_read);
-
-#define PATCH_FOPS(NAME) if (!fops->NAME) fops->NAME = afu_fops.NAME
-
-/* Get a struct file and fd for a context and attach the ops */
-struct file *cxl_get_fd(struct cxl_context *ctx, struct file_operations *fops,
- int *fd)
-{
- struct file *file;
- int rc, flags, fdtmp;
- char *name = NULL;
-
- /* only allow one per context */
- if (ctx->mapping)
- return ERR_PTR(-EEXIST);
-
- flags = O_RDWR | O_CLOEXEC;
-
- /* This code is similar to anon_inode_getfd() */
- rc = get_unused_fd_flags(flags);
- if (rc < 0)
- return ERR_PTR(rc);
- fdtmp = rc;
-
- /*
- * Patch the file ops. Needs to be careful that this is rentrant safe.
- */
- if (fops) {
- PATCH_FOPS(open);
- PATCH_FOPS(poll);
- PATCH_FOPS(read);
- PATCH_FOPS(release);
- PATCH_FOPS(unlocked_ioctl);
- PATCH_FOPS(compat_ioctl);
- PATCH_FOPS(mmap);
- } else /* use default ops */
- fops = (struct file_operations *)&afu_fops;
-
- name = kasprintf(GFP_KERNEL, "cxl:%d", ctx->pe);
- file = cxl_getfile(name, fops, ctx, flags);
- kfree(name);
- if (IS_ERR(file))
- goto err_fd;
-
- cxl_context_set_mapping(ctx, file->f_mapping);
- *fd = fdtmp;
- return file;
-
-err_fd:
- put_unused_fd(fdtmp);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(cxl_get_fd);
-
-struct cxl_context *cxl_fops_get_context(struct file *file)
-{
- return file->private_data;
-}
-EXPORT_SYMBOL_GPL(cxl_fops_get_context);
-
-void cxl_set_driver_ops(struct cxl_context *ctx,
- struct cxl_afu_driver_ops *ops)
-{
- WARN_ON(!ops->fetch_event || !ops->event_delivered);
- atomic_set(&ctx->afu_driver_events, 0);
- ctx->afu_driver_ops = ops;
-}
-EXPORT_SYMBOL_GPL(cxl_set_driver_ops);
-
-void cxl_context_events_pending(struct cxl_context *ctx,
- unsigned int new_events)
-{
- atomic_add(new_events, &ctx->afu_driver_events);
- wake_up_all(&ctx->wq);
-}
-EXPORT_SYMBOL_GPL(cxl_context_events_pending);
-
-int cxl_start_work(struct cxl_context *ctx,
- struct cxl_ioctl_start_work *work)
-{
- int rc;
-
- /* code taken from afu_ioctl_start_work */
- if (!(work->flags & CXL_START_WORK_NUM_IRQS))
- work->num_interrupts = ctx->afu->pp_irqs;
- else if ((work->num_interrupts < ctx->afu->pp_irqs) ||
- (work->num_interrupts > ctx->afu->irqs_max)) {
- return -EINVAL;
- }
-
- rc = afu_register_irqs(ctx, work->num_interrupts);
- if (rc)
- return rc;
-
- rc = cxl_start_context(ctx, work->work_element_descriptor, current);
- if (rc < 0) {
- afu_release_irqs(ctx, ctx);
- return rc;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxl_start_work);
-
-void __iomem *cxl_psa_map(struct cxl_context *ctx)
-{
- if (ctx->status != STARTED)
- return NULL;
-
- pr_devel("%s: psn_phys%llx size:%llx\n",
- __func__, ctx->psn_phys, ctx->psn_size);
- return ioremap(ctx->psn_phys, ctx->psn_size);
-}
-EXPORT_SYMBOL_GPL(cxl_psa_map);
-
-void cxl_psa_unmap(void __iomem *addr)
-{
- iounmap(addr);
-}
-EXPORT_SYMBOL_GPL(cxl_psa_unmap);
-
-int cxl_afu_reset(struct cxl_context *ctx)
-{
- struct cxl_afu *afu = ctx->afu;
- int rc;
-
- rc = cxl_ops->afu_reset(afu);
- if (rc)
- return rc;
-
- return cxl_ops->afu_check_and_enable(afu);
-}
-EXPORT_SYMBOL_GPL(cxl_afu_reset);
-
-void cxl_perst_reloads_same_image(struct cxl_afu *afu,
- bool perst_reloads_same_image)
-{
- afu->adapter->perst_same_image = perst_reloads_same_image;
-}
-EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image);
-
-ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count)
-{
- struct cxl_afu *afu = cxl_pci_to_afu(dev);
- if (IS_ERR(afu))
- return -ENODEV;
-
- return cxl_ops->read_adapter_vpd(afu->adapter, buf, count);
-}
-EXPORT_SYMBOL_GPL(cxl_read_adapter_vpd);
diff --git a/drivers/misc/cxl/base.c b/drivers/misc/cxl/base.c
deleted file mode 100644
index b054562c046e..000000000000
--- a/drivers/misc/cxl/base.c
+++ /dev/null
@@ -1,126 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/module.h>
-#include <linux/rcupdate.h>
-#include <asm/errno.h>
-#include <misc/cxl-base.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include "cxl.h"
-
-/* protected by rcu */
-static struct cxl_calls *cxl_calls;
-
-atomic_t cxl_use_count = ATOMIC_INIT(0);
-EXPORT_SYMBOL(cxl_use_count);
-
-#ifdef CONFIG_CXL_MODULE
-
-static inline struct cxl_calls *cxl_calls_get(void)
-{
- struct cxl_calls *calls = NULL;
-
- rcu_read_lock();
- calls = rcu_dereference(cxl_calls);
- if (calls && !try_module_get(calls->owner))
- calls = NULL;
- rcu_read_unlock();
-
- return calls;
-}
-
-static inline void cxl_calls_put(struct cxl_calls *calls)
-{
- BUG_ON(calls != cxl_calls);
-
- /* we don't need to rcu this, as we hold a reference to the module */
- module_put(cxl_calls->owner);
-}
-
-#else /* !defined CONFIG_CXL_MODULE */
-
-static inline struct cxl_calls *cxl_calls_get(void)
-{
- return cxl_calls;
-}
-
-static inline void cxl_calls_put(struct cxl_calls *calls) { }
-
-#endif /* CONFIG_CXL_MODULE */
-
-/* AFU refcount management */
-struct cxl_afu *cxl_afu_get(struct cxl_afu *afu)
-{
- return (get_device(&afu->dev) == NULL) ? NULL : afu;
-}
-EXPORT_SYMBOL_GPL(cxl_afu_get);
-
-void cxl_afu_put(struct cxl_afu *afu)
-{
- put_device(&afu->dev);
-}
-EXPORT_SYMBOL_GPL(cxl_afu_put);
-
-void cxl_slbia(struct mm_struct *mm)
-{
- struct cxl_calls *calls;
-
- calls = cxl_calls_get();
- if (!calls)
- return;
-
- if (cxl_ctx_in_use())
- calls->cxl_slbia(mm);
-
- cxl_calls_put(calls);
-}
-
-int register_cxl_calls(struct cxl_calls *calls)
-{
- if (cxl_calls)
- return -EBUSY;
-
- rcu_assign_pointer(cxl_calls, calls);
- return 0;
-}
-EXPORT_SYMBOL_GPL(register_cxl_calls);
-
-void unregister_cxl_calls(struct cxl_calls *calls)
-{
- BUG_ON(cxl_calls->owner != calls->owner);
- RCU_INIT_POINTER(cxl_calls, NULL);
- synchronize_rcu();
-}
-EXPORT_SYMBOL_GPL(unregister_cxl_calls);
-
-int cxl_update_properties(struct device_node *dn,
- struct property *new_prop)
-{
- return of_update_property(dn, new_prop);
-}
-EXPORT_SYMBOL_GPL(cxl_update_properties);
-
-static int __init cxl_base_init(void)
-{
- struct device_node *np;
- struct platform_device *dev;
- int count = 0;
-
- /*
- * Scan for compatible devices in guest only
- */
- if (cpu_has_feature(CPU_FTR_HVMODE))
- return 0;
-
- for_each_compatible_node(np, NULL, "ibm,coherent-platform-facility") {
- dev = of_platform_device_create(np, NULL, NULL);
- if (dev)
- count++;
- }
- pr_devel("Found %d cxl device(s)\n", count);
- return 0;
-}
-device_initcall(cxl_base_init);
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
deleted file mode 100644
index 76b5ea66dfa1..000000000000
--- a/drivers/misc/cxl/context.c
+++ /dev/null
@@ -1,362 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 IBM Corp.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/bitmap.h>
-#include <linux/sched.h>
-#include <linux/pid.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-#include <linux/idr.h>
-#include <linux/sched/mm.h>
-#include <linux/mmu_context.h>
-#include <asm/cputable.h>
-#include <asm/current.h>
-#include <asm/copro.h>
-
-#include "cxl.h"
-
-/*
- * Allocates space for a CXL context.
- */
-struct cxl_context *cxl_context_alloc(void)
-{
- return kzalloc(sizeof(struct cxl_context), GFP_KERNEL);
-}
-
-/*
- * Initialises a CXL context.
- */
-int cxl_context_init(struct cxl_context *ctx, struct cxl_afu *afu, bool master)
-{
- int i;
-
- ctx->afu = afu;
- ctx->master = master;
- ctx->pid = NULL; /* Set in start work ioctl */
- mutex_init(&ctx->mapping_lock);
- ctx->mapping = NULL;
- ctx->tidr = 0;
- ctx->assign_tidr = false;
-
- if (cxl_is_power8()) {
- spin_lock_init(&ctx->sste_lock);
-
- /*
- * Allocate the segment table before we put it in the IDR so that we
- * can always access it when dereferenced from IDR. For the same
- * reason, the segment table is only destroyed after the context is
- * removed from the IDR. Access to this in the IOCTL is protected by
- * Linux filesystem semantics (can't IOCTL until open is complete).
- */
- i = cxl_alloc_sst(ctx);
- if (i)
- return i;
- }
-
- INIT_WORK(&ctx->fault_work, cxl_handle_fault);
-
- init_waitqueue_head(&ctx->wq);
- spin_lock_init(&ctx->lock);
-
- ctx->irq_bitmap = NULL;
- ctx->pending_irq = false;
- ctx->pending_fault = false;
- ctx->pending_afu_err = false;
-
- INIT_LIST_HEAD(&ctx->irq_names);
-
- /*
- * When we have to destroy all contexts in cxl_context_detach_all() we
- * end up with afu_release_irqs() called from inside a
- * idr_for_each_entry(). Hence we need to make sure that anything
- * dereferenced from this IDR is ok before we allocate the IDR here.
- * This clears out the IRQ ranges to ensure this.
- */
- for (i = 0; i < CXL_IRQ_RANGES; i++)
- ctx->irqs.range[i] = 0;
-
- mutex_init(&ctx->status_mutex);
-
- ctx->status = OPENED;
-
- /*
- * Allocating IDR! We better make sure everything's setup that
- * dereferences from it.
- */
- mutex_lock(&afu->contexts_lock);
- idr_preload(GFP_KERNEL);
- i = idr_alloc(&ctx->afu->contexts_idr, ctx, 0,
- ctx->afu->num_procs, GFP_NOWAIT);
- idr_preload_end();
- mutex_unlock(&afu->contexts_lock);
- if (i < 0)
- return i;
-
- ctx->pe = i;
- if (cpu_has_feature(CPU_FTR_HVMODE)) {
- ctx->elem = &ctx->afu->native->spa[i];
- ctx->external_pe = ctx->pe;
- } else {
- ctx->external_pe = -1; /* assigned when attaching */
- }
- ctx->pe_inserted = false;
-
- /*
- * take a ref on the afu so that it stays alive at-least till
- * this context is reclaimed inside reclaim_ctx.
- */
- cxl_afu_get(afu);
- return 0;
-}
-
-void cxl_context_set_mapping(struct cxl_context *ctx,
- struct address_space *mapping)
-{
- mutex_lock(&ctx->mapping_lock);
- ctx->mapping = mapping;
- mutex_unlock(&ctx->mapping_lock);
-}
-
-static vm_fault_t cxl_mmap_fault(struct vm_fault *vmf)
-{
- struct vm_area_struct *vma = vmf->vma;
- struct cxl_context *ctx = vma->vm_file->private_data;
- u64 area, offset;
- vm_fault_t ret;
-
- offset = vmf->pgoff << PAGE_SHIFT;
-
- pr_devel("%s: pe: %i address: 0x%lx offset: 0x%llx\n",
- __func__, ctx->pe, vmf->address, offset);
-
- if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
- area = ctx->afu->psn_phys;
- if (offset >= ctx->afu->adapter->ps_size)
- return VM_FAULT_SIGBUS;
- } else {
- area = ctx->psn_phys;
- if (offset >= ctx->psn_size)
- return VM_FAULT_SIGBUS;
- }
-
- mutex_lock(&ctx->status_mutex);
-
- if (ctx->status != STARTED) {
- mutex_unlock(&ctx->status_mutex);
- pr_devel("%s: Context not started, failing problem state access\n", __func__);
- if (ctx->mmio_err_ff) {
- if (!ctx->ff_page) {
- ctx->ff_page = alloc_page(GFP_USER);
- if (!ctx->ff_page)
- return VM_FAULT_OOM;
- memset(page_address(ctx->ff_page), 0xff, PAGE_SIZE);
- }
- get_page(ctx->ff_page);
- vmf->page = ctx->ff_page;
- vma->vm_page_prot = pgprot_cached(vma->vm_page_prot);
- return 0;
- }
- return VM_FAULT_SIGBUS;
- }
-
- ret = vmf_insert_pfn(vma, vmf->address, (area + offset) >> PAGE_SHIFT);
-
- mutex_unlock(&ctx->status_mutex);
-
- return ret;
-}
-
-static const struct vm_operations_struct cxl_mmap_vmops = {
- .fault = cxl_mmap_fault,
-};
-
-/*
- * Map a per-context mmio space into the given vma.
- */
-int cxl_context_iomap(struct cxl_context *ctx, struct vm_area_struct *vma)
-{
- u64 start = vma->vm_pgoff << PAGE_SHIFT;
- u64 len = vma->vm_end - vma->vm_start;
-
- if (ctx->afu->current_mode == CXL_MODE_DEDICATED) {
- if (start + len > ctx->afu->adapter->ps_size)
- return -EINVAL;
-
- if (cxl_is_power9()) {
- /*
- * Make sure there is a valid problem state
- * area space for this AFU.
- */
- if (ctx->master && !ctx->afu->psa) {
- pr_devel("AFU doesn't support mmio space\n");
- return -EINVAL;
- }
-
- /* Can't mmap until the AFU is enabled */
- if (!ctx->afu->enabled)
- return -EBUSY;
- }
- } else {
- if (start + len > ctx->psn_size)
- return -EINVAL;
-
- /* Make sure there is a valid per process space for this AFU */
- if ((ctx->master && !ctx->afu->psa) || (!ctx->afu->pp_psa)) {
- pr_devel("AFU doesn't support mmio space\n");
- return -EINVAL;
- }
-
- /* Can't mmap until the AFU is enabled */
- if (!ctx->afu->enabled)
- return -EBUSY;
- }
-
- pr_devel("%s: mmio physical: %llx pe: %i master:%i\n", __func__,
- ctx->psn_phys, ctx->pe , ctx->master);
-
- vm_flags_set(vma, VM_IO | VM_PFNMAP);
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- vma->vm_ops = &cxl_mmap_vmops;
- return 0;
-}
-