xref: /linux/drivers/misc/cxl/api.c (revision d601ea918b878582e60b773f2f943d8d292b2abf)
16f7f0b3dSMichael Neuling /*
26f7f0b3dSMichael Neuling  * Copyright 2014 IBM Corp.
36f7f0b3dSMichael Neuling  *
46f7f0b3dSMichael Neuling  * This program is free software; you can redistribute it and/or
56f7f0b3dSMichael Neuling  * modify it under the terms of the GNU General Public License
66f7f0b3dSMichael Neuling  * as published by the Free Software Foundation; either version
76f7f0b3dSMichael Neuling  * 2 of the License, or (at your option) any later version.
86f7f0b3dSMichael Neuling  */
96f7f0b3dSMichael Neuling 
106f7f0b3dSMichael Neuling #include <linux/pci.h>
116f7f0b3dSMichael Neuling #include <linux/slab.h>
126f7f0b3dSMichael Neuling #include <linux/anon_inodes.h>
136f7f0b3dSMichael Neuling #include <linux/file.h>
146f7f0b3dSMichael Neuling #include <misc/cxl.h>
1555e07668SIan Munsie #include <linux/fs.h>
166f7f0b3dSMichael Neuling 
176f7f0b3dSMichael Neuling #include "cxl.h"
186f7f0b3dSMichael Neuling 
196f7f0b3dSMichael Neuling struct cxl_context *cxl_dev_context_init(struct pci_dev *dev)
206f7f0b3dSMichael Neuling {
2155e07668SIan Munsie 	struct address_space *mapping;
226f7f0b3dSMichael Neuling 	struct cxl_afu *afu;
236f7f0b3dSMichael Neuling 	struct cxl_context  *ctx;
246f7f0b3dSMichael Neuling 	int rc;
256f7f0b3dSMichael Neuling 
266f7f0b3dSMichael Neuling 	afu = cxl_pci_to_afu(dev);
276f7f0b3dSMichael Neuling 
286f7f0b3dSMichael Neuling 	ctx = cxl_context_alloc();
29af2a50bbSIan Munsie 	if (IS_ERR(ctx)) {
30af2a50bbSIan Munsie 		rc = PTR_ERR(ctx);
31af2a50bbSIan Munsie 		goto err_dev;
32af2a50bbSIan Munsie 	}
336f7f0b3dSMichael Neuling 
3455e07668SIan Munsie 	ctx->kernelapi = true;
3555e07668SIan Munsie 
3655e07668SIan Munsie 	/*
3755e07668SIan Munsie 	 * Make our own address space since we won't have one from the
3855e07668SIan Munsie 	 * filesystem like the user api has, and even if we do associate a file
3955e07668SIan Munsie 	 * with this context we don't want to use the global anonymous inode's
4055e07668SIan Munsie 	 * address space as that can invalidate unrelated users:
4155e07668SIan Munsie 	 */
4255e07668SIan Munsie 	mapping = kmalloc(sizeof(struct address_space), GFP_KERNEL);
4355e07668SIan Munsie 	if (!mapping) {
4455e07668SIan Munsie 		rc = -ENOMEM;
45af2a50bbSIan Munsie 		goto err_ctx;
4655e07668SIan Munsie 	}
4755e07668SIan Munsie 	address_space_init_once(mapping);
4855e07668SIan Munsie 
4955e07668SIan Munsie 	/* Make it a slave context.  We can promote it later? */
5055e07668SIan Munsie 	rc = cxl_context_init(ctx, afu, false, mapping);
5155e07668SIan Munsie 	if (rc)
5255e07668SIan Munsie 		goto err_mapping;
5355e07668SIan Munsie 
546f7f0b3dSMichael Neuling 	return ctx;
55af2a50bbSIan Munsie 
5655e07668SIan Munsie err_mapping:
5755e07668SIan Munsie 	kfree(mapping);
58af2a50bbSIan Munsie err_ctx:
59af2a50bbSIan Munsie 	kfree(ctx);
60af2a50bbSIan Munsie err_dev:
61af2a50bbSIan Munsie 	return ERR_PTR(rc);
626f7f0b3dSMichael Neuling }
636f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_dev_context_init);
646f7f0b3dSMichael Neuling 
656f7f0b3dSMichael Neuling struct cxl_context *cxl_get_context(struct pci_dev *dev)
666f7f0b3dSMichael Neuling {
676f7f0b3dSMichael Neuling 	return dev->dev.archdata.cxl_ctx;
686f7f0b3dSMichael Neuling }
696f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_get_context);
706f7f0b3dSMichael Neuling 
716f7f0b3dSMichael Neuling struct device *cxl_get_phys_dev(struct pci_dev *dev)
726f7f0b3dSMichael Neuling {
736f7f0b3dSMichael Neuling 	struct cxl_afu *afu;
746f7f0b3dSMichael Neuling 
756f7f0b3dSMichael Neuling 	afu = cxl_pci_to_afu(dev);
766f7f0b3dSMichael Neuling 
776f7f0b3dSMichael Neuling 	return afu->adapter->dev.parent;
786f7f0b3dSMichael Neuling }
796f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_get_phys_dev);
806f7f0b3dSMichael Neuling 
816f7f0b3dSMichael Neuling int cxl_release_context(struct cxl_context *ctx)
826f7f0b3dSMichael Neuling {
837c26b9cfSAndrew Donnellan 	if (ctx->status >= STARTED)
846f7f0b3dSMichael Neuling 		return -EBUSY;
856f7f0b3dSMichael Neuling 
866f7f0b3dSMichael Neuling 	cxl_context_free(ctx);
876f7f0b3dSMichael Neuling 
886f7f0b3dSMichael Neuling 	return 0;
896f7f0b3dSMichael Neuling }
906f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_release_context);
916f7f0b3dSMichael Neuling 
926f7f0b3dSMichael Neuling static irq_hw_number_t cxl_find_afu_irq(struct cxl_context *ctx, int num)
936f7f0b3dSMichael Neuling {
946f7f0b3dSMichael Neuling 	__u16 range;
956f7f0b3dSMichael Neuling 	int r;
966f7f0b3dSMichael Neuling 
976f7f0b3dSMichael Neuling 	for (r = 0; r < CXL_IRQ_RANGES; r++) {
986f7f0b3dSMichael Neuling 		range = ctx->irqs.range[r];
996f7f0b3dSMichael Neuling 		if (num < range) {
1006f7f0b3dSMichael Neuling 			return ctx->irqs.offset[r] + num;
1016f7f0b3dSMichael Neuling 		}
1026f7f0b3dSMichael Neuling 		num -= range;
1036f7f0b3dSMichael Neuling 	}
1046f7f0b3dSMichael Neuling 	return 0;
1056f7f0b3dSMichael Neuling }
1066f7f0b3dSMichael Neuling 
107*d601ea91SFrederic Barrat int cxl_allocate_afu_irqs(struct cxl_context *ctx, int num)
108*d601ea91SFrederic Barrat {
109*d601ea91SFrederic Barrat 	int res;
110*d601ea91SFrederic Barrat 	irq_hw_number_t hwirq;
111*d601ea91SFrederic Barrat 
112*d601ea91SFrederic Barrat 	if (num == 0)
113*d601ea91SFrederic Barrat 		num = ctx->afu->pp_irqs;
114*d601ea91SFrederic Barrat 	res = afu_allocate_irqs(ctx, num);
115*d601ea91SFrederic Barrat 	if (!res && !cpu_has_feature(CPU_FTR_HVMODE)) {
116*d601ea91SFrederic Barrat 		/* In a guest, the PSL interrupt is not multiplexed. It was
117*d601ea91SFrederic Barrat 		 * allocated above, and we need to set its handler
118*d601ea91SFrederic Barrat 		 */
119*d601ea91SFrederic Barrat 		hwirq = cxl_find_afu_irq(ctx, 0);
120*d601ea91SFrederic Barrat 		if (hwirq)
121*d601ea91SFrederic Barrat 			cxl_map_irq(ctx->afu->adapter, hwirq, cxl_ops->psl_interrupt, ctx, "psl");
122*d601ea91SFrederic Barrat 	}
123*d601ea91SFrederic Barrat 	return res;
124*d601ea91SFrederic Barrat }
125*d601ea91SFrederic Barrat EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
126*d601ea91SFrederic Barrat 
127*d601ea91SFrederic Barrat void cxl_free_afu_irqs(struct cxl_context *ctx)
128*d601ea91SFrederic Barrat {
129*d601ea91SFrederic Barrat 	irq_hw_number_t hwirq;
130*d601ea91SFrederic Barrat 	unsigned int virq;
131*d601ea91SFrederic Barrat 
132*d601ea91SFrederic Barrat 	if (!cpu_has_feature(CPU_FTR_HVMODE)) {
133*d601ea91SFrederic Barrat 		hwirq = cxl_find_afu_irq(ctx, 0);
134*d601ea91SFrederic Barrat 		if (hwirq) {
135*d601ea91SFrederic Barrat 			virq = irq_find_mapping(NULL, hwirq);
136*d601ea91SFrederic Barrat 			if (virq)
137*d601ea91SFrederic Barrat 				cxl_unmap_irq(virq, ctx);
138*d601ea91SFrederic Barrat 		}
139*d601ea91SFrederic Barrat 	}
140*d601ea91SFrederic Barrat 	afu_irq_name_free(ctx);
141*d601ea91SFrederic Barrat 	cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
142*d601ea91SFrederic Barrat }
143*d601ea91SFrederic Barrat EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
144*d601ea91SFrederic Barrat 
1456f7f0b3dSMichael Neuling int cxl_map_afu_irq(struct cxl_context *ctx, int num,
1466f7f0b3dSMichael Neuling 		    irq_handler_t handler, void *cookie, char *name)
1476f7f0b3dSMichael Neuling {
1486f7f0b3dSMichael Neuling 	irq_hw_number_t hwirq;
1496f7f0b3dSMichael Neuling 
1506f7f0b3dSMichael Neuling 	/*
1516f7f0b3dSMichael Neuling 	 * Find interrupt we are to register.
1526f7f0b3dSMichael Neuling 	 */
1536f7f0b3dSMichael Neuling 	hwirq = cxl_find_afu_irq(ctx, num);
1546f7f0b3dSMichael Neuling 	if (!hwirq)
1556f7f0b3dSMichael Neuling 		return -ENOENT;
1566f7f0b3dSMichael Neuling 
1576f7f0b3dSMichael Neuling 	return cxl_map_irq(ctx->afu->adapter, hwirq, handler, cookie, name);
1586f7f0b3dSMichael Neuling }
1596f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_map_afu_irq);
1606f7f0b3dSMichael Neuling 
1616f7f0b3dSMichael Neuling void cxl_unmap_afu_irq(struct cxl_context *ctx, int num, void *cookie)
1626f7f0b3dSMichael Neuling {
1636f7f0b3dSMichael Neuling 	irq_hw_number_t hwirq;
1646f7f0b3dSMichael Neuling 	unsigned int virq;
1656f7f0b3dSMichael Neuling 
1666f7f0b3dSMichael Neuling 	hwirq = cxl_find_afu_irq(ctx, num);
1676f7f0b3dSMichael Neuling 	if (!hwirq)
1686f7f0b3dSMichael Neuling 		return;
1696f7f0b3dSMichael Neuling 
1706f7f0b3dSMichael Neuling 	virq = irq_find_mapping(NULL, hwirq);
1716f7f0b3dSMichael Neuling 	if (virq)
1726f7f0b3dSMichael Neuling 		cxl_unmap_irq(virq, cookie);
1736f7f0b3dSMichael Neuling }
1746f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_unmap_afu_irq);
1756f7f0b3dSMichael Neuling 
1766f7f0b3dSMichael Neuling /*
1776f7f0b3dSMichael Neuling  * Start a context
1786f7f0b3dSMichael Neuling  * Code here similar to afu_ioctl_start_work().
1796f7f0b3dSMichael Neuling  */
1806f7f0b3dSMichael Neuling int cxl_start_context(struct cxl_context *ctx, u64 wed,
1816f7f0b3dSMichael Neuling 		      struct task_struct *task)
1826f7f0b3dSMichael Neuling {
1836f7f0b3dSMichael Neuling 	int rc = 0;
1846f7f0b3dSMichael Neuling 	bool kernel = true;
1856f7f0b3dSMichael Neuling 
1866f7f0b3dSMichael Neuling 	pr_devel("%s: pe: %i\n", __func__, ctx->pe);
1876f7f0b3dSMichael Neuling 
1886f7f0b3dSMichael Neuling 	mutex_lock(&ctx->status_mutex);
1896f7f0b3dSMichael Neuling 	if (ctx->status == STARTED)
1906f7f0b3dSMichael Neuling 		goto out; /* already started */
1916f7f0b3dSMichael Neuling 
1926f7f0b3dSMichael Neuling 	if (task) {
1936f7f0b3dSMichael Neuling 		ctx->pid = get_task_pid(task, PIDTYPE_PID);
1947b8ad495SVaibhav Jain 		ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID);
1956f7f0b3dSMichael Neuling 		kernel = false;
1966f7f0b3dSMichael Neuling 	}
1976f7f0b3dSMichael Neuling 
1986f7f0b3dSMichael Neuling 	cxl_ctx_get();
1996f7f0b3dSMichael Neuling 
2005be587b1SFrederic Barrat 	if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
2016f7f0b3dSMichael Neuling 		put_pid(ctx->pid);
2026f7f0b3dSMichael Neuling 		cxl_ctx_put();
2036f7f0b3dSMichael Neuling 		goto out;
2046f7f0b3dSMichael Neuling 	}
2056f7f0b3dSMichael Neuling 
2066f7f0b3dSMichael Neuling 	ctx->status = STARTED;
2076f7f0b3dSMichael Neuling out:
2086f7f0b3dSMichael Neuling 	mutex_unlock(&ctx->status_mutex);
2096f7f0b3dSMichael Neuling 	return rc;
2106f7f0b3dSMichael Neuling }
2116f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_start_context);
2126f7f0b3dSMichael Neuling 
2136f7f0b3dSMichael Neuling int cxl_process_element(struct cxl_context *ctx)
2146f7f0b3dSMichael Neuling {
21514baf4d9SChristophe Lombard 	return ctx->external_pe;
2166f7f0b3dSMichael Neuling }
2176f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_process_element);
2186f7f0b3dSMichael Neuling 
2196f7f0b3dSMichael Neuling /* Stop a context.  Returns 0 on success, otherwise -Errno */
2206f7f0b3dSMichael Neuling int cxl_stop_context(struct cxl_context *ctx)
2216f7f0b3dSMichael Neuling {
2223f8dc44dSMichael Neuling 	return __detach_context(ctx);
2236f7f0b3dSMichael Neuling }
2246f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_stop_context);
2256f7f0b3dSMichael Neuling 
2266f7f0b3dSMichael Neuling void cxl_set_master(struct cxl_context *ctx)
2276f7f0b3dSMichael Neuling {
2286f7f0b3dSMichael Neuling 	ctx->master = true;
2296f7f0b3dSMichael Neuling }
2306f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_set_master);
2316f7f0b3dSMichael Neuling 
2326f7f0b3dSMichael Neuling /* wrappers around afu_* file ops which are EXPORTED */
2336f7f0b3dSMichael Neuling int cxl_fd_open(struct inode *inode, struct file *file)
2346f7f0b3dSMichael Neuling {
2356f7f0b3dSMichael Neuling 	return afu_open(inode, file);
2366f7f0b3dSMichael Neuling }
2376f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_fd_open);
2386f7f0b3dSMichael Neuling int cxl_fd_release(struct inode *inode, struct file *file)
2396f7f0b3dSMichael Neuling {
2406f7f0b3dSMichael Neuling 	return afu_release(inode, file);
2416f7f0b3dSMichael Neuling }
2426f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_fd_release);
2436f7f0b3dSMichael Neuling long cxl_fd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2446f7f0b3dSMichael Neuling {
2456f7f0b3dSMichael Neuling 	return afu_ioctl(file, cmd, arg);
2466f7f0b3dSMichael Neuling }
2476f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_fd_ioctl);
2486f7f0b3dSMichael Neuling int cxl_fd_mmap(struct file *file, struct vm_area_struct *vm)
2496f7f0b3dSMichael Neuling {
2506f7f0b3dSMichael Neuling 	return afu_mmap(file, vm);
2516f7f0b3dSMichael Neuling }
2526f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_fd_mmap);
2536f7f0b3dSMichael Neuling unsigned int cxl_fd_poll(struct file *file, struct poll_table_struct *poll)
2546f7f0b3dSMichael Neuling {
2556f7f0b3dSMichael Neuling 	return afu_poll(file, poll);
2566f7f0b3dSMichael Neuling }
2576f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_fd_poll);
2586f7f0b3dSMichael Neuling ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count,
2596f7f0b3dSMichael Neuling 			loff_t *off)
2606f7f0b3dSMichael Neuling {
2616f7f0b3dSMichael Neuling 	return afu_read(file, buf, count, off);
2626f7f0b3dSMichael Neuling }
2636f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_fd_read);
2646f7f0b3dSMichael Neuling 
2656f7f0b3dSMichael Neuling #define PATCH_FOPS(NAME) if (!fops->NAME) fops->NAME = afu_fops.NAME
2666f7f0b3dSMichael Neuling 
2676f7f0b3dSMichael Neuling /* Get a struct file and fd for a context and attach the ops */
2686f7f0b3dSMichael Neuling struct file *cxl_get_fd(struct cxl_context *ctx, struct file_operations *fops,
2696f7f0b3dSMichael Neuling 			int *fd)
2706f7f0b3dSMichael Neuling {
2716f7f0b3dSMichael Neuling 	struct file *file;
2726f7f0b3dSMichael Neuling 	int rc, flags, fdtmp;
2736f7f0b3dSMichael Neuling 
2746f7f0b3dSMichael Neuling 	flags = O_RDWR | O_CLOEXEC;
2756f7f0b3dSMichael Neuling 
2766f7f0b3dSMichael Neuling 	/* This code is similar to anon_inode_getfd() */
2776f7f0b3dSMichael Neuling 	rc = get_unused_fd_flags(flags);
2786f7f0b3dSMichael Neuling 	if (rc < 0)
2796f7f0b3dSMichael Neuling 		return ERR_PTR(rc);
2806f7f0b3dSMichael Neuling 	fdtmp = rc;
2816f7f0b3dSMichael Neuling 
2826f7f0b3dSMichael Neuling 	/*
2836f7f0b3dSMichael Neuling 	 * Patch the file ops.  Needs to be careful that this is rentrant safe.
2846f7f0b3dSMichael Neuling 	 */
2856f7f0b3dSMichael Neuling 	if (fops) {
2866f7f0b3dSMichael Neuling 		PATCH_FOPS(open);
2876f7f0b3dSMichael Neuling 		PATCH_FOPS(poll);
2886f7f0b3dSMichael Neuling 		PATCH_FOPS(read);
2896f7f0b3dSMichael Neuling 		PATCH_FOPS(release);
2906f7f0b3dSMichael Neuling 		PATCH_FOPS(unlocked_ioctl);
2916f7f0b3dSMichael Neuling 		PATCH_FOPS(compat_ioctl);
2926f7f0b3dSMichael Neuling 		PATCH_FOPS(mmap);
2936f7f0b3dSMichael Neuling 	} else /* use default ops */
2946f7f0b3dSMichael Neuling 		fops = (struct file_operations *)&afu_fops;
2956f7f0b3dSMichael Neuling 
2966f7f0b3dSMichael Neuling 	file = anon_inode_getfile("cxl", fops, ctx, flags);
2976f7f0b3dSMichael Neuling 	if (IS_ERR(file))
29855e07668SIan Munsie 		goto err_fd;
29955e07668SIan Munsie 
30055e07668SIan Munsie 	file->f_mapping = ctx->mapping;
30155e07668SIan Munsie 
3026f7f0b3dSMichael Neuling 	*fd = fdtmp;
3036f7f0b3dSMichael Neuling 	return file;
30455e07668SIan Munsie 
30555e07668SIan Munsie err_fd:
30655e07668SIan Munsie 	put_unused_fd(fdtmp);
30755e07668SIan Munsie 	return NULL;
3086f7f0b3dSMichael Neuling }
3096f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_get_fd);
3106f7f0b3dSMichael Neuling 
3116f7f0b3dSMichael Neuling struct cxl_context *cxl_fops_get_context(struct file *file)
3126f7f0b3dSMichael Neuling {
3136f7f0b3dSMichael Neuling 	return file->private_data;
3146f7f0b3dSMichael Neuling }
3156f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_fops_get_context);
3166f7f0b3dSMichael Neuling 
3176f7f0b3dSMichael Neuling int cxl_start_work(struct cxl_context *ctx,
3186f7f0b3dSMichael Neuling 		   struct cxl_ioctl_start_work *work)
3196f7f0b3dSMichael Neuling {
3206f7f0b3dSMichael Neuling 	int rc;
3216f7f0b3dSMichael Neuling 
3226f7f0b3dSMichael Neuling 	/* code taken from afu_ioctl_start_work */
3236f7f0b3dSMichael Neuling 	if (!(work->flags & CXL_START_WORK_NUM_IRQS))
3246f7f0b3dSMichael Neuling 		work->num_interrupts = ctx->afu->pp_irqs;
3256f7f0b3dSMichael Neuling 	else if ((work->num_interrupts < ctx->afu->pp_irqs) ||
3266f7f0b3dSMichael Neuling 		 (work->num_interrupts > ctx->afu->irqs_max)) {
3276f7f0b3dSMichael Neuling 		return -EINVAL;
3286f7f0b3dSMichael Neuling 	}
3296f7f0b3dSMichael Neuling 
3306f7f0b3dSMichael Neuling 	rc = afu_register_irqs(ctx, work->num_interrupts);
3316f7f0b3dSMichael Neuling 	if (rc)
3326f7f0b3dSMichael Neuling 		return rc;
3336f7f0b3dSMichael Neuling 
3346f7f0b3dSMichael Neuling 	rc = cxl_start_context(ctx, work->work_element_descriptor, current);
3356f7f0b3dSMichael Neuling 	if (rc < 0) {
3366f7f0b3dSMichael Neuling 		afu_release_irqs(ctx, ctx);
3376f7f0b3dSMichael Neuling 		return rc;
3386f7f0b3dSMichael Neuling 	}
3396f7f0b3dSMichael Neuling 
3406f7f0b3dSMichael Neuling 	return 0;
3416f7f0b3dSMichael Neuling }
3426f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_start_work);
3436f7f0b3dSMichael Neuling 
3446f7f0b3dSMichael Neuling void __iomem *cxl_psa_map(struct cxl_context *ctx)
3456f7f0b3dSMichael Neuling {
346cca44c01SFrederic Barrat 	if (ctx->status != STARTED)
3476f7f0b3dSMichael Neuling 		return NULL;
3486f7f0b3dSMichael Neuling 
3496f7f0b3dSMichael Neuling 	pr_devel("%s: psn_phys%llx size:%llx\n",
350cca44c01SFrederic Barrat 		__func__, ctx->psn_phys, ctx->psn_size);
3516f7f0b3dSMichael Neuling 	return ioremap(ctx->psn_phys, ctx->psn_size);
3526f7f0b3dSMichael Neuling }
3536f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_psa_map);
3546f7f0b3dSMichael Neuling 
3556f7f0b3dSMichael Neuling void cxl_psa_unmap(void __iomem *addr)
3566f7f0b3dSMichael Neuling {
3576f7f0b3dSMichael Neuling 	iounmap(addr);
3586f7f0b3dSMichael Neuling }
3596f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_psa_unmap);
3606f7f0b3dSMichael Neuling 
3616f7f0b3dSMichael Neuling int cxl_afu_reset(struct cxl_context *ctx)
3626f7f0b3dSMichael Neuling {
3636f7f0b3dSMichael Neuling 	struct cxl_afu *afu = ctx->afu;
3646f7f0b3dSMichael Neuling 	int rc;
3656f7f0b3dSMichael Neuling 
3665be587b1SFrederic Barrat 	rc = cxl_ops->afu_reset(afu);
3676f7f0b3dSMichael Neuling 	if (rc)
3686f7f0b3dSMichael Neuling 		return rc;
3696f7f0b3dSMichael Neuling 
3705be587b1SFrederic Barrat 	return cxl_ops->afu_check_and_enable(afu);
3716f7f0b3dSMichael Neuling }
3726f7f0b3dSMichael Neuling EXPORT_SYMBOL_GPL(cxl_afu_reset);
37313e68d8bSDaniel Axtens 
37413e68d8bSDaniel Axtens void cxl_perst_reloads_same_image(struct cxl_afu *afu,
37513e68d8bSDaniel Axtens 				  bool perst_reloads_same_image)
37613e68d8bSDaniel Axtens {
37713e68d8bSDaniel Axtens 	afu->adapter->perst_same_image = perst_reloads_same_image;
37813e68d8bSDaniel Axtens }
37913e68d8bSDaniel Axtens EXPORT_SYMBOL_GPL(cxl_perst_reloads_same_image);
380*d601ea91SFrederic Barrat 
381*d601ea91SFrederic Barrat ssize_t cxl_read_adapter_vpd(struct pci_dev *dev, void *buf, size_t count)
382*d601ea91SFrederic Barrat {
383*d601ea91SFrederic Barrat 	struct cxl_afu *afu = cxl_pci_to_afu(dev);
384*d601ea91SFrederic Barrat 
385*d601ea91SFrederic Barrat 	return cxl_ops->read_adapter_vpd(afu->adapter, buf, count);
386*d601ea91SFrederic Barrat }
387*d601ea91SFrederic Barrat EXPORT_SYMBOL_GPL(cxl_read_adapter_vpd);
388