aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Barrat <fbarrat@linux.vnet.ibm.com>2016-03-04 06:26:28 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2016-03-08 21:05:43 -0500
commit5be587b1110132b4f05e0bc3515a145365e910fe (patch)
tree102af0ae101eef7c75f39bb696cda28ed45c8f65
parentcca44c0192b03d179786ec34b070e7de42966cc6 (diff)
cxl: Introduce implementation-specific API
The backend API (in cxl.h) lists some low-level functions whose implementation is different on bare-metal and in a guest. Each environment implements its own functions, and the common code uses them through function pointers, defined in cxl_backend_ops Co-authored-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Signed-off-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com> Signed-off-by: Christophe Lombard <clombard@linux.vnet.ibm.com> Reviewed-by: Manoj Kumar <manoj@linux.vnet.ibm.com> Acked-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--drivers/misc/cxl/api.c8
-rw-r--r--drivers/misc/cxl/context.c4
-rw-r--r--drivers/misc/cxl/cxl.h53
-rw-r--r--drivers/misc/cxl/fault.c6
-rw-r--r--drivers/misc/cxl/file.c15
-rw-r--r--drivers/misc/cxl/irq.c19
-rw-r--r--drivers/misc/cxl/main.c11
-rw-r--r--drivers/misc/cxl/native.c135
-rw-r--r--drivers/misc/cxl/pci.c16
-rw-r--r--drivers/misc/cxl/sysfs.c32
-rw-r--r--drivers/misc/cxl/vphb.c6
11 files changed, 185 insertions, 120 deletions
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
index b45d857b0207..31eb842ee6c0 100644
--- a/drivers/misc/cxl/api.c
+++ b/drivers/misc/cxl/api.c
@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
100void cxl_free_afu_irqs(struct cxl_context *ctx) 100void cxl_free_afu_irqs(struct cxl_context *ctx)
101{ 101{
102 afu_irq_name_free(ctx); 102 afu_irq_name_free(ctx);
103 cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); 103 cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
104} 104}
105EXPORT_SYMBOL_GPL(cxl_free_afu_irqs); 105EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
106 106
@@ -176,7 +176,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
176 176
177 cxl_ctx_get(); 177 cxl_ctx_get();
178 178
179 if ((rc = cxl_attach_process(ctx, kernel, wed , 0))) { 179 if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
180 put_pid(ctx->pid); 180 put_pid(ctx->pid);
181 cxl_ctx_put(); 181 cxl_ctx_put();
182 goto out; 182 goto out;
@@ -342,11 +342,11 @@ int cxl_afu_reset(struct cxl_context *ctx)
342 struct cxl_afu *afu = ctx->afu; 342 struct cxl_afu *afu = ctx->afu;
343 int rc; 343 int rc;
344 344
345 rc = __cxl_afu_reset(afu); 345 rc = cxl_ops->afu_reset(afu);
346 if (rc) 346 if (rc)
347 return rc; 347 return rc;
348 348
349 return cxl_afu_check_and_enable(afu); 349 return cxl_ops->afu_check_and_enable(afu);
350} 350}
351EXPORT_SYMBOL_GPL(cxl_afu_reset); 351EXPORT_SYMBOL_GPL(cxl_afu_reset);
352 352
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 262b88eac414..aa65262d4a32 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -214,8 +214,8 @@ int __detach_context(struct cxl_context *ctx)
214 /* Only warn if we detached while the link was OK. 214 /* Only warn if we detached while the link was OK.
215 * If detach fails when hw is down, we don't care. 215 * If detach fails when hw is down, we don't care.
216 */ 216 */
217 WARN_ON(cxl_detach_process(ctx) && 217 WARN_ON(cxl_ops->detach_process(ctx) &&
218 cxl_adapter_link_ok(ctx->afu->adapter)); 218 cxl_ops->link_ok(ctx->afu->adapter));
219 flush_work(&ctx->fault_work); /* Only needed for dedicated process */ 219 flush_work(&ctx->fault_work); /* Only needed for dedicated process */
220 220
221 /* release the reference to the group leader and mm handling pid */ 221 /* release the reference to the group leader and mm handling pid */
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 3b824e3d68d2..8233af305f8d 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -623,11 +623,6 @@ static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg)
623 return ~0ULL; 623 return ~0ULL;
624} 624}
625 625
626u64 cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off);
627u32 cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off);
628u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off);
629u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off);
630
631ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf, 626ssize_t cxl_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
632 loff_t off, size_t count); 627 loff_t off, size_t count);
633 628
@@ -666,10 +661,6 @@ void cxl_sysfs_afu_m_remove(struct cxl_afu *afu);
666 661
667struct cxl *cxl_alloc_adapter(void); 662struct cxl *cxl_alloc_adapter(void);
668struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice); 663struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice);
669
670int cxl_afu_activate_mode(struct cxl_afu *afu, int mode);
671int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode);
672int cxl_afu_deactivate_mode(struct cxl_afu *afu);
673int cxl_afu_select_best_mode(struct cxl_afu *afu); 664int cxl_afu_select_best_mode(struct cxl_afu *afu);
674 665
675int cxl_register_psl_irq(struct cxl_afu *afu); 666int cxl_register_psl_irq(struct cxl_afu *afu);
@@ -681,8 +672,6 @@ void cxl_release_serr_irq(struct cxl_afu *afu);
681int afu_register_irqs(struct cxl_context *ctx, u32 count); 672int afu_register_irqs(struct cxl_context *ctx, u32 count);
682void afu_release_irqs(struct cxl_context *ctx, void *cookie); 673void afu_release_irqs(struct cxl_context *ctx, void *cookie);
683void afu_irq_name_free(struct cxl_context *ctx); 674void afu_irq_name_free(struct cxl_context *ctx);
684irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr,
685 u64 errstat);
686 675
687int cxl_debugfs_init(void); 676int cxl_debugfs_init(void);
688void cxl_debugfs_exit(void); 677void cxl_debugfs_exit(void);
@@ -727,18 +716,10 @@ int cxl_register_one_irq(struct cxl *adapter, irq_handler_t handler,
727 void *cookie, irq_hw_number_t *dest_hwirq, 716 void *cookie, irq_hw_number_t *dest_hwirq,
728 unsigned int *dest_virq, const char *name); 717 unsigned int *dest_virq, const char *name);
729 718
730int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed,
731 u64 amr);
732int cxl_detach_process(struct cxl_context *ctx);
733
734int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
735
736int cxl_check_error(struct cxl_afu *afu); 719int cxl_check_error(struct cxl_afu *afu);
737int cxl_afu_slbia(struct cxl_afu *afu); 720int cxl_afu_slbia(struct cxl_afu *afu);
738int cxl_tlb_slb_invalidate(struct cxl *adapter); 721int cxl_tlb_slb_invalidate(struct cxl *adapter);
739int cxl_afu_disable(struct cxl_afu *afu); 722int cxl_afu_disable(struct cxl_afu *afu);
740int __cxl_afu_reset(struct cxl_afu *afu);
741int cxl_afu_check_and_enable(struct cxl_afu *afu);
742int cxl_psl_purge(struct cxl_afu *afu); 723int cxl_psl_purge(struct cxl_afu *afu);
743 724
744void cxl_stop_trace(struct cxl *cxl); 725void cxl_stop_trace(struct cxl *cxl);
@@ -757,4 +738,38 @@ unsigned int afu_poll(struct file *file, struct poll_table_struct *poll);
757ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off); 738ssize_t afu_read(struct file *file, char __user *buf, size_t count, loff_t *off);
758extern const struct file_operations afu_fops; 739extern const struct file_operations afu_fops;
759 740
741struct cxl_backend_ops {
742 struct module *module;
743 int (*adapter_reset)(struct cxl *adapter);
744 int (*alloc_one_irq)(struct cxl *adapter);
745 void (*release_one_irq)(struct cxl *adapter, int hwirq);
746 int (*alloc_irq_ranges)(struct cxl_irq_ranges *irqs,
747 struct cxl *adapter, unsigned int num);
748 void (*release_irq_ranges)(struct cxl_irq_ranges *irqs,
749 struct cxl *adapter);
750 int (*setup_irq)(struct cxl *adapter, unsigned int hwirq,
751 unsigned int virq);
752 irqreturn_t (*handle_psl_slice_error)(struct cxl_context *ctx,
753 u64 dsisr, u64 errstat);
754 irqreturn_t (*psl_interrupt)(int irq, void *data);
755 int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
756 int (*attach_process)(struct cxl_context *ctx, bool kernel,
757 u64 wed, u64 amr);
758 int (*detach_process)(struct cxl_context *ctx);
759 bool (*link_ok)(struct cxl *cxl);
760 void (*release_afu)(struct device *dev);
761 ssize_t (*afu_read_err_buffer)(struct cxl_afu *afu, char *buf,
762 loff_t off, size_t count);
763 int (*afu_check_and_enable)(struct cxl_afu *afu);
764 int (*afu_activate_mode)(struct cxl_afu *afu, int mode);
765 int (*afu_deactivate_mode)(struct cxl_afu *afu, int mode);
766 int (*afu_reset)(struct cxl_afu *afu);
767 int (*afu_cr_read8)(struct cxl_afu *afu, int cr_idx, u64 offset, u8 *val);
768 int (*afu_cr_read16)(struct cxl_afu *afu, int cr_idx, u64 offset, u16 *val);
769 int (*afu_cr_read32)(struct cxl_afu *afu, int cr_idx, u64 offset, u32 *val);
770 int (*afu_cr_read64)(struct cxl_afu *afu, int cr_idx, u64 offset, u64 *val);
771};
772extern const struct cxl_backend_ops cxl_native_ops;
773extern const struct cxl_backend_ops *cxl_ops;
774
760#endif 775#endif
diff --git a/drivers/misc/cxl/fault.c b/drivers/misc/cxl/fault.c
index 81c3f75b7330..ab740a19bd1e 100644
--- a/drivers/misc/cxl/fault.c
+++ b/drivers/misc/cxl/fault.c
@@ -101,7 +101,7 @@ static void cxl_ack_ae(struct cxl_context *ctx)
101{ 101{
102 unsigned long flags; 102 unsigned long flags;
103 103
104 cxl_ack_irq(ctx, CXL_PSL_TFC_An_AE, 0); 104 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_AE, 0);
105 105
106 spin_lock_irqsave(&ctx->lock, flags); 106 spin_lock_irqsave(&ctx->lock, flags);
107 ctx->pending_fault = true; 107 ctx->pending_fault = true;
@@ -125,7 +125,7 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx,
125 else { 125 else {
126 126
127 mb(); /* Order seg table write to TFC MMIO write */ 127 mb(); /* Order seg table write to TFC MMIO write */
128 cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0); 128 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
129 } 129 }
130 130
131 return IRQ_HANDLED; 131 return IRQ_HANDLED;
@@ -163,7 +163,7 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,
163 local_irq_restore(flags); 163 local_irq_restore(flags);
164 164
165 pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe); 165 pr_devel("Page fault successfully handled for pe: %i!\n", ctx->pe);
166 cxl_ack_irq(ctx, CXL_PSL_TFC_An_R, 0); 166 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_R, 0);
167} 167}
168 168
169/* 169/*
diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
index 783337d22f36..b8ce29bc52d5 100644
--- a/drivers/misc/cxl/file.c
+++ b/drivers/misc/cxl/file.c
@@ -79,7 +79,7 @@ static int __afu_open(struct inode *inode, struct file *file, bool master)
79 if (!afu->current_mode) 79 if (!afu->current_mode)
80 goto err_put_afu; 80 goto err_put_afu;
81 81
82 if (!cxl_adapter_link_ok(adapter)) { 82 if (!cxl_ops->link_ok(adapter)) {
83 rc = -EIO; 83 rc = -EIO;
84 goto err_put_afu; 84 goto err_put_afu;
85 } 85 }
@@ -210,8 +210,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
210 210
211 trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr); 211 trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
212 212
213 if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor, 213 if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
214 amr))) { 214 amr))) {
215 afu_release_irqs(ctx, ctx); 215 afu_release_irqs(ctx, ctx);
216 goto out; 216 goto out;
217 } 217 }
@@ -222,6 +222,7 @@ out:
222 mutex_unlock(&ctx->status_mutex); 222 mutex_unlock(&ctx->status_mutex);
223 return rc; 223 return rc;
224} 224}
225
225static long afu_ioctl_process_element(struct cxl_context *ctx, 226static long afu_ioctl_process_element(struct cxl_context *ctx,
226 int __user *upe) 227 int __user *upe)
227{ 228{
@@ -259,7 +260,7 @@ long afu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
259 if (ctx->status == CLOSED) 260 if (ctx->status == CLOSED)
260 return -EIO; 261 return -EIO;
261 262
262 if (!cxl_adapter_link_ok(ctx->afu->adapter)) 263 if (!cxl_ops->link_ok(ctx->afu->adapter))
263 return -EIO; 264 return -EIO;
264 265
265 pr_devel("afu_ioctl\n"); 266 pr_devel("afu_ioctl\n");
@@ -289,7 +290,7 @@ int afu_mmap(struct file *file, struct vm_area_struct *vm)
289 if (ctx->status != STARTED) 290 if (ctx->status != STARTED)
290 return -EIO; 291 return -EIO;
291 292
292 if (!cxl_adapter_link_ok(ctx->afu->adapter)) 293 if (!cxl_ops->link_ok(ctx->afu->adapter))
293 return -EIO; 294 return -EIO;
294 295
295 return cxl_context_iomap(ctx, vm); 296 return cxl_context_iomap(ctx, vm);
@@ -336,7 +337,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
336 int rc; 337 int rc;
337 DEFINE_WAIT(wait); 338 DEFINE_WAIT(wait);
338 339
339 if (!cxl_adapter_link_ok(ctx->afu->adapter)) 340 if (!cxl_ops->link_ok(ctx->afu->adapter))
340 return -EIO; 341 return -EIO;
341 342
342 if (count < CXL_READ_MIN_SIZE) 343 if (count < CXL_READ_MIN_SIZE)
@@ -349,7 +350,7 @@ ssize_t afu_read(struct file *file, char __user *buf, size_t count,
349 if (ctx_event_pending(ctx)) 350 if (ctx_event_pending(ctx))
350 break; 351 break;
351 352
352 if (!cxl_adapter_link_ok(ctx->afu->adapter)) { 353 if (!cxl_ops->link_ok(ctx->afu->adapter)) {
353 rc = -EIO; 354 rc = -EIO;
354 goto out; 355 goto out;
355 } 356 }
diff --git a/drivers/misc/cxl/irq.c b/drivers/misc/cxl/irq.c
index 16fd67ffb5ef..56ad301007b7 100644
--- a/drivers/misc/cxl/irq.c
+++ b/drivers/misc/cxl/irq.c
@@ -79,7 +79,8 @@ irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
79 if (dsisr & CXL_PSL_DSISR_An_UR) 79 if (dsisr & CXL_PSL_DSISR_An_UR)
80 pr_devel("CXL interrupt: AURP PTE not found\n"); 80 pr_devel("CXL interrupt: AURP PTE not found\n");
81 if (dsisr & CXL_PSL_DSISR_An_PE) 81 if (dsisr & CXL_PSL_DSISR_An_PE)
82 return handle_psl_slice_error(ctx, dsisr, irq_info->errstat); 82 return cxl_ops->handle_psl_slice_error(ctx, dsisr,
83 irq_info->errstat);
83 if (dsisr & CXL_PSL_DSISR_An_AE) { 84 if (dsisr & CXL_PSL_DSISR_An_AE) {
84 pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err); 85 pr_devel("CXL interrupt: AFU Error 0x%016llx\n", irq_info->afu_err);
85 86
@@ -103,7 +104,7 @@ irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
103 wake_up_all(&ctx->wq); 104 wake_up_all(&ctx->wq);
104 } 105 }
105 106
106 cxl_ack_irq(ctx, CXL_PSL_TFC_An_A, 0); 107 cxl_ops->ack_irq(ctx, CXL_PSL_TFC_An_A, 0);
107 return IRQ_HANDLED; 108 return IRQ_HANDLED;
108 } 109 }
109 if (dsisr & CXL_PSL_DSISR_An_OC) 110 if (dsisr & CXL_PSL_DSISR_An_OC)
@@ -167,7 +168,8 @@ unsigned int cxl_map_irq(struct cxl *adapter, irq_hw_number_t hwirq,
167 return 0; 168 return 0;
168 } 169 }
169 170
170 cxl_setup_irq(adapter, hwirq, virq); 171 if (cxl_ops->setup_irq)
172 cxl_ops->setup_irq(adapter, hwirq, virq);
171 173
172 pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq); 174 pr_devel("hwirq %#lx mapped to virq %u\n", hwirq, virq);
173 175
@@ -195,7 +197,7 @@ int cxl_register_one_irq(struct cxl *adapter,
195{ 197{
196 int hwirq, virq; 198 int hwirq, virq;
197 199
198 if ((hwirq = cxl_alloc_one_irq(adapter)) < 0) 200 if ((hwirq = cxl_ops->alloc_one_irq(adapter)) < 0)
199 return hwirq; 201 return hwirq;
200 202
201 if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name))) 203 if (!(virq = cxl_map_irq(adapter, hwirq, handler, cookie, name)))
@@ -207,7 +209,7 @@ int cxl_register_one_irq(struct cxl *adapter,
207 return 0; 209 return 0;
208 210
209err: 211err:
210 cxl_release_one_irq(adapter, hwirq); 212 cxl_ops->release_one_irq(adapter, hwirq);
211 return -ENOMEM; 213 return -ENOMEM;
212} 214}
213 215
@@ -230,7 +232,8 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
230 /* Initialize the list head to hold irq names */ 232 /* Initialize the list head to hold irq names */
231 INIT_LIST_HEAD(&ctx->irq_names); 233 INIT_LIST_HEAD(&ctx->irq_names);
232 234
233 if ((rc = cxl_alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter, count))) 235 if ((rc = cxl_ops->alloc_irq_ranges(&ctx->irqs, ctx->afu->adapter,
236 count)))
234 return rc; 237 return rc;
235 238
236 /* Multiplexed PSL Interrupt */ 239 /* Multiplexed PSL Interrupt */
@@ -268,7 +271,7 @@ int afu_allocate_irqs(struct cxl_context *ctx, u32 count)
268 return 0; 271 return 0;
269 272
270out: 273out:
271 cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); 274 cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
272 afu_irq_name_free(ctx); 275 afu_irq_name_free(ctx);
273 return -ENOMEM; 276 return -ENOMEM;
274} 277}
@@ -319,7 +322,7 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie)
319 } 322 }
320 323
321 afu_irq_name_free(ctx); 324 afu_irq_name_free(ctx);
322 cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); 325 cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
323 326
324 ctx->irq_count = 0; 327 ctx->irq_count = 0;
325} 328}
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
index 90933eb80fa3..a9051512198c 100644
--- a/drivers/misc/cxl/main.c
+++ b/drivers/misc/cxl/main.c
@@ -32,6 +32,8 @@ uint cxl_verbose;
32module_param_named(verbose, cxl_verbose, uint, 0600); 32module_param_named(verbose, cxl_verbose, uint, 0600);
33MODULE_PARM_DESC(verbose, "Enable verbose dmesg output"); 33MODULE_PARM_DESC(verbose, "Enable verbose dmesg output");
34 34
35const struct cxl_backend_ops *cxl_ops;
36
35int cxl_afu_slbia(struct cxl_afu *afu) 37int cxl_afu_slbia(struct cxl_afu *afu)
36{ 38{
37 unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); 39 unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
@@ -46,7 +48,7 @@ int cxl_afu_slbia(struct cxl_afu *afu)
46 /* If the adapter has gone down, we can assume that we 48 /* If the adapter has gone down, we can assume that we
47 * will PERST it and that will invalidate everything. 49 * will PERST it and that will invalidate everything.
48 */ 50 */
49 if (!cxl_adapter_link_ok(afu->adapter)) 51 if (!cxl_ops->link_ok(afu->adapter))
50 return -EIO; 52 return -EIO;
51 cpu_relax(); 53 cpu_relax();
52 } 54 }
@@ -228,7 +230,7 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
228 230
229 afu->adapter = adapter; 231 afu->adapter = adapter;
230 afu->dev.parent = &adapter->dev; 232 afu->dev.parent = &adapter->dev;
231 afu->dev.release = cxl_release_afu; 233 afu->dev.release = cxl_ops->release_afu;
232 afu->slice = slice; 234 afu->slice = slice;
233 idr_init(&afu->contexts_idr); 235 idr_init(&afu->contexts_idr);
234 mutex_init(&afu->contexts_lock); 236 mutex_init(&afu->contexts_lock);
@@ -244,10 +246,10 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
244int cxl_afu_select_best_mode(struct cxl_afu *afu) 246int cxl_afu_select_best_mode(struct cxl_afu *afu)
245{ 247{
246 if (afu->modes_supported & CXL_MODE_DIRECTED) 248 if (afu->modes_supported & CXL_MODE_DIRECTED)
247 return cxl_afu_activate_mode(afu, CXL_MODE_DIRECTED); 249 return cxl_ops->afu_activate_mode(afu, CXL_MODE_DIRECTED);
248 250
249 if (afu->modes_supported & CXL_MODE_DEDICATED) 251 if (afu->modes_supported & CXL_MODE_DEDICATED)
250 return cxl_afu_activate_mode(afu, CXL_MODE_DEDICATED); 252 return cxl_ops->afu_activate_mode(afu, CXL_MODE_DEDICATED);
251 253
252 dev_warn(&afu->dev, "No supported programming modes available\n"); 254 dev_warn(&afu->dev, "No supported programming modes available\n");
253 /* We don't fail this so the user can inspect sysfs */ 255 /* We don't fail this so the user can inspect sysfs */
@@ -269,6 +271,7 @@ static int __init init_cxl(void)
269 if ((rc = register_cxl_calls(&cxl_calls))) 271 if ((rc = register_cxl_calls(&cxl_calls)))
270 goto err; 272 goto err;
271 273
274 cxl_ops = &cxl_native_ops;
272 if ((rc = pci_register_driver(&cxl_pci_driver))) 275 if ((rc = pci_register_driver(&cxl_pci_driver)))
273 goto err1; 276 goto err1;
274 277
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 3103e3327ea6..16d3b1a7d62c 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -42,7 +42,7 @@ static int afu_control(struct cxl_afu *afu, u64 command,
42 goto out; 42 goto out;
43 } 43 }
44 44
45 if (!cxl_adapter_link_ok(afu->adapter)) { 45 if (!cxl_ops->link_ok(afu->adapter)) {
46 afu->enabled = enabled; 46 afu->enabled = enabled;
47 rc = -EIO; 47 rc = -EIO;
48 goto out; 48 goto out;
@@ -80,7 +80,7 @@ int cxl_afu_disable(struct cxl_afu *afu)
80} 80}
81 81
82/* This will disable as well as reset */ 82/* This will disable as well as reset */
83int __cxl_afu_reset(struct cxl_afu *afu) 83static int __cxl_afu_reset(struct cxl_afu *afu)
84{ 84{
85 pr_devel("AFU reset request\n"); 85 pr_devel("AFU reset request\n");
86 86
@@ -90,9 +90,9 @@ int __cxl_afu_reset(struct cxl_afu *afu)
90 false); 90 false);
91} 91}
92 92
93int cxl_afu_check_and_enable(struct cxl_afu *afu) 93static int cxl_afu_check_and_enable(struct cxl_afu *afu)
94{ 94{
95 if (!cxl_adapter_link_ok(afu->adapter)) { 95 if (!cxl_ops->link_ok(afu->adapter)) {
96 WARN(1, "Refusing to enable afu while link down!\n"); 96 WARN(1, "Refusing to enable afu while link down!\n");
97 return -EIO; 97 return -EIO;
98 } 98 }
@@ -114,7 +114,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
114 114
115 pr_devel("PSL purge request\n"); 115 pr_devel("PSL purge request\n");
116 116
117 if (!cxl_adapter_link_ok(afu->adapter)) { 117 if (!cxl_ops->link_ok(afu->adapter)) {
118 dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n"); 118 dev_warn(&afu->dev, "PSL Purge called with link down, ignoring\n");
119 rc = -EIO; 119 rc = -EIO;
120 goto out; 120 goto out;
@@ -136,7 +136,7 @@ int cxl_psl_purge(struct cxl_afu *afu)
136 rc = -EBUSY; 136 rc = -EBUSY;
137 goto out; 137 goto out;
138 } 138 }
139 if (!cxl_adapter_link_ok(afu->adapter)) { 139 if (!cxl_ops->link_ok(afu->adapter)) {
140 rc = -EIO; 140 rc = -EIO;
141 goto out; 141 goto out;
142 } 142 }
@@ -247,7 +247,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter)
247 dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n"); 247 dev_warn(&adapter->dev, "WARNING: CXL adapter wide TLBIA timed out!\n");
248 return -EBUSY; 248 return -EBUSY;
249 } 249 }
250 if (!cxl_adapter_link_ok(adapter)) 250 if (!cxl_ops->link_ok(adapter))
251 return -EIO; 251 return -EIO;
252 cpu_relax(); 252 cpu_relax();
253 } 253 }
@@ -258,7 +258,7 @@ int cxl_tlb_slb_invalidate(struct cxl *adapter)
258 dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n"); 258 dev_warn(&adapter->dev, "WARNING: CXL adapter wide SLBIA timed out!\n");
259 return -EBUSY; 259 return -EBUSY;
260 } 260 }
261 if (!cxl_adapter_link_ok(adapter)) 261 if (!cxl_ops->link_ok(adapter))
262 return -EIO; 262 return -EIO;
263 cpu_relax(); 263 cpu_relax();
264 } 264 }
@@ -299,7 +299,7 @@ static void slb_invalid(struct cxl_context *ctx)
299 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID); 299 cxl_p1_write(adapter, CXL_PSL_SLBIA, CXL_TLB_SLB_IQ_LPIDPID);
300 300
301 while (1) { 301 while (1) {
302 if (!cxl_adapter_link_ok(adapter)) 302 if (!cxl_ops->link_ok(adapter))
303 break; 303 break;
304 slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA); 304 slbia = cxl_p1_read(adapter, CXL_PSL_SLBIA);
305 if (!(slbia & CXL_TLB_SLB_P)) 305 if (!(slbia & CXL_TLB_SLB_P))
@@ -330,7 +330,7 @@ static int do_process_element_cmd(struct cxl_context *ctx,
330 rc = -EBUSY; 330 rc = -EBUSY;
331 goto out; 331 goto out;
332 } 332 }
333 if (!cxl_adapter_link_ok(ctx->afu->adapter)) { 333 if (!cxl_ops->link_ok(ctx->afu->adapter)) {
334 dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n"); 334 dev_warn(&ctx->afu->dev, "WARNING: Device link down, aborting Process Element Command!\n");
335 rc = -EIO; 335 rc = -EIO;
336 goto out; 336 goto out;
@@ -386,7 +386,7 @@ static int terminate_process_element(struct cxl_context *ctx)
386 * should always succeed: it's not running if the hw has gone 386 * should always succeed: it's not running if the hw has gone
387 * away and is being reset. 387 * away and is being reset.
388 */ 388 */
389 if (cxl_adapter_link_ok(ctx->afu->adapter)) 389 if (cxl_ops->link_ok(ctx->afu->adapter))
390 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE, 390 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_TERMINATE,
391 CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T); 391 CXL_PE_SOFTWARE_STATE_V | CXL_PE_SOFTWARE_STATE_T);
392 ctx->elem->software_state = 0; /* Remove Valid bit */ 392 ctx->elem->software_state = 0; /* Remove Valid bit */
@@ -405,7 +405,7 @@ static int remove_process_element(struct cxl_context *ctx)
405 /* We could be asked to remove when the hw is down. Again, if 405 /* We could be asked to remove when the hw is down. Again, if
406 * the hw is down, the PE is gone, so we succeed. 406 * the hw is down, the PE is gone, so we succeed.
407 */ 407 */
408 if (cxl_adapter_link_ok(ctx->afu->adapter)) 408 if (cxl_ops->link_ok(ctx->afu->adapter))
409 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0); 409 rc = do_process_element_cmd(ctx, CXL_SPA_SW_CMD_REMOVE, 0);
410 410
411 if (!rc) 411 if (!rc)
@@ -531,7 +531,7 @@ static int attach_afu_directed(struct cxl_context *ctx, u64 wed, u64 amr)
531 ctx->elem->common.wed = cpu_to_be64(wed); 531 ctx->elem->common.wed = cpu_to_be64(wed);
532 532
533 /* first guy needs to enable */ 533 /* first guy needs to enable */
534 if ((result = cxl_afu_check_and_enable(ctx->afu))) 534 if ((result = cxl_ops->afu_check_and_enable(ctx->afu)))
535 return result; 535 return result;
536 536
537 return add_process_element(ctx); 537 return add_process_element(ctx);
@@ -547,7 +547,7 @@ static int deactivate_afu_directed(struct cxl_afu *afu)
547 cxl_sysfs_afu_m_remove(afu); 547 cxl_sysfs_afu_m_remove(afu);
548 cxl_chardev_afu_remove(afu); 548 cxl_chardev_afu_remove(afu);
549 549
550 __cxl_afu_reset(afu); 550 cxl_ops->afu_reset(afu);
551 cxl_afu_disable(afu); 551 cxl_afu_disable(afu);
552 cxl_psl_purge(afu); 552 cxl_psl_purge(afu);
553 553
@@ -611,7 +611,7 @@ static int attach_dedicated(struct cxl_context *ctx, u64 wed, u64 amr)
611 /* master only context for dedicated */ 611 /* master only context for dedicated */
612 cxl_assign_psn_space(ctx); 612 cxl_assign_psn_space(ctx);
613 613
614 if ((rc = __cxl_afu_reset(afu))) 614 if ((rc = cxl_ops->afu_reset(afu)))
615 return rc; 615 return rc;
616 616
617 cxl_p2n_write(afu, CXL_PSL_WED_An, wed); 617 cxl_p2n_write(afu, CXL_PSL_WED_An, wed);
@@ -631,7 +631,7 @@ static int deactivate_dedicated_process(struct cxl_afu *afu)
631 return 0; 631 return 0;
632} 632}
633 633
634int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode) 634static int cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode)
635{ 635{
636 if (mode == CXL_MODE_DIRECTED) 636 if (mode == CXL_MODE_DIRECTED)
637 return deactivate_afu_directed(afu); 637 return deactivate_afu_directed(afu);
@@ -640,19 +640,14 @@ int _cxl_afu_deactivate_mode(struct cxl_afu *afu, int mode)
640 return 0; 640 return 0;
641} 641}
642 642
643int cxl_afu_deactivate_mode(struct cxl_afu *afu) 643static int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
644{
645 return _cxl_afu_deactivate_mode(afu, afu->current_mode);
646}
647
648int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
649{ 644{
650 if (!mode) 645 if (!mode)
651 return 0; 646 return 0;
652 if (!(mode & afu->modes_supported)) 647 if (!(mode & afu->modes_supported))
653 return -EINVAL; 648 return -EINVAL;
654 649
655 if (!cxl_adapter_link_ok(afu->adapter)) { 650 if (!cxl_ops->link_ok(afu->adapter)) {
656 WARN(1, "Device link is down, refusing to activate!\n"); 651 WARN(1, "Device link is down, refusing to activate!\n");
657 return -EIO; 652 return -EIO;
658 } 653 }
@@ -665,9 +660,9 @@ int cxl_afu_activate_mode(struct cxl_afu *afu, int mode)
665 return -EINVAL; 660 return -EINVAL;
666} 661}
667 662
668int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr) 663static int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
669{ 664{
670 if (!cxl_adapter_link_ok(ctx->afu->adapter)) { 665 if (!cxl_ops->link_ok(ctx->afu->adapter)) {
671 WARN(1, "Device link is down, refusing to attach process!\n"); 666 WARN(1, "Device link is down, refusing to attach process!\n");
672 return -EIO; 667 return -EIO;
673 } 668 }
@@ -684,7 +679,7 @@ int cxl_attach_process(struct cxl_context *ctx, bool kernel, u64 wed, u64 amr)
684 679
685static inline int detach_process_native_dedicated(struct cxl_context *ctx) 680static inline int detach_process_native_dedicated(struct cxl_context *ctx)
686{ 681{
687 __cxl_afu_reset(ctx->afu); 682 cxl_ops->afu_reset(ctx->afu);
688 cxl_afu_disable(ctx->afu); 683 cxl_afu_disable(ctx->afu);
689 cxl_psl_purge(ctx->afu); 684 cxl_psl_purge(ctx->afu);
690 return 0; 685 return 0;
@@ -702,7 +697,7 @@ static inline int detach_process_native_afu_directed(struct cxl_context *ctx)
702 return 0; 697 return 0;
703} 698}
704 699
705int cxl_detach_process(struct cxl_context *ctx) 700static int cxl_detach_process(struct cxl_context *ctx)
706{ 701{
707 trace_cxl_detach(ctx); 702 trace_cxl_detach(ctx);
708 703
@@ -719,7 +714,7 @@ static int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info)
719 /* If the adapter has gone away, we can't get any meaningful 714 /* If the adapter has gone away, we can't get any meaningful
720 * information. 715 * information.
721 */ 716 */
722 if (!cxl_adapter_link_ok(afu->adapter)) 717 if (!cxl_ops->link_ok(afu->adapter))
723 return -EIO; 718 return -EIO;
724 719
725 info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); 720 info->dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
@@ -734,7 +729,7 @@ static int cxl_get_irq(struct cxl_afu *afu, struct cxl_irq_info *info)
734 return 0; 729 return 0;
735} 730}
736 731
737irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errstat) 732static irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errstat)
738{ 733{
739 u64 fir1, fir2, fir_slice, serr, afu_debug; 734 u64 fir1, fir2, fir_slice, serr, afu_debug;
740 735
@@ -754,7 +749,7 @@ irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errst
754 dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n"); 749 dev_crit(&ctx->afu->dev, "STOPPING CXL TRACE\n");
755 cxl_stop_trace(ctx->afu->adapter); 750 cxl_stop_trace(ctx->afu->adapter);
756 751
757 return cxl_ack_irq(ctx, 0, errstat); 752 return cxl_ops->ack_irq(ctx, 0, errstat);
758} 753}
759 754
760static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info) 755static irqreturn_t fail_psl_irq(struct cxl_afu *afu, struct cxl_irq_info *irq_info)
@@ -868,7 +863,7 @@ void cxl_release_psl_err_irq(struct cxl *adapter)
868 863
869 cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000); 864 cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000);
870 cxl_unmap_irq(adapter->err_virq, adapter); 865 cxl_unmap_irq(adapter->err_virq, adapter);
871 cxl_release_one_irq(adapter, adapter->err_hwirq); 866 cxl_ops->release_one_irq(adapter, adapter->err_hwirq);
872 kfree(adapter->irq_name); 867 kfree(adapter->irq_name);
873} 868}
874 869
@@ -904,7 +899,7 @@ void cxl_release_serr_irq(struct cxl_afu *afu)
904 899
905 cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000); 900 cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000);
906 cxl_unmap_irq(afu->serr_virq, afu); 901 cxl_unmap_irq(afu->serr_virq, afu);
907 cxl_release_one_irq(afu->adapter, afu->serr_hwirq); 902 cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq);
908 kfree(afu->err_irq_name); 903 kfree(afu->err_irq_name);
909} 904}
910 905
@@ -932,7 +927,7 @@ void cxl_release_psl_irq(struct cxl_afu *afu)
932 return; 927 return;
933 928
934 cxl_unmap_irq(afu->psl_virq, afu); 929 cxl_unmap_irq(afu->psl_virq, afu);
935 cxl_release_one_irq(afu->adapter, afu->psl_hwirq); 930 cxl_ops->release_one_irq(afu->adapter, afu->psl_hwirq);
936 kfree(afu->psl_irq_name); 931 kfree(afu->psl_irq_name);
937} 932}
938 933
@@ -950,7 +945,7 @@ static void recover_psl_err(struct cxl_afu *afu, u64 errstat)
950 cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat); 945 cxl_p2n_write(afu, CXL_PSL_ErrStat_An, errstat);
951} 946}
952 947
953int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask) 948static int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
954{ 949{
955 trace_cxl_psl_irq_ack(ctx, tfc); 950 trace_cxl_psl_irq_ack(ctx, tfc);
956 if (tfc) 951 if (tfc)
@@ -966,38 +961,74 @@ int cxl_check_error(struct cxl_afu *afu)
966 return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL); 961 return (cxl_p1n_read(afu, CXL_PSL_SCNTL_An) == ~0ULL);
967} 962}
968 963
969u64 cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off) 964static int cxl_afu_cr_read64(struct cxl_afu *afu, int cr, u64 off, u64 *out)
970{ 965{
971 if (likely(cxl_adapter_link_ok(afu->adapter))) 966 if (unlikely(!cxl_ops->link_ok(afu->adapter)))
972 return in_le64((afu)->afu_desc_mmio + (afu)->crs_offset + 967 return -EIO;
973 ((cr) * (afu)->crs_len) + (off)); 968 if (unlikely(off >= afu->crs_len))
974 else 969 return -ERANGE;
975 return ~0ULL; 970 *out = in_le64(afu->afu_desc_mmio + afu->crs_offset +
971 (cr * afu->crs_len) + off);
972 return 0;
976} 973}
977 974
978u32 cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off) 975static int cxl_afu_cr_read32(struct cxl_afu *afu, int cr, u64 off, u32 *out)
979{ 976{
980 if (likely(cxl_adapter_link_ok(afu->adapter))) 977 if (unlikely(!cxl_ops->link_ok(afu->adapter)))
981 return in_le32((afu)->afu_desc_mmio + (afu)->crs_offset + 978 return -EIO;
982 ((cr) * (afu)->crs_len) + (off)); 979 if (unlikely(off >= afu->crs_len))
983 else 980 return -ERANGE;
984 return 0xffffffff; 981 *out = in_le32(afu->afu_desc_mmio + afu->crs_offset +
982 (cr * afu->crs_len) + off);
983 return 0;
985} 984}
986 985
987u16 cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off) 986static int cxl_afu_cr_read16(struct cxl_afu *afu, int cr, u64 off, u16 *out)
988{ 987{
989 u64 aligned_off = off & ~0x3L; 988 u64 aligned_off = off & ~0x3L;
990 u32 val; 989 u32 val;
990 int rc;
991 991
992 val = cxl_afu_cr_read32(afu, cr, aligned_off); 992 rc = cxl_afu_cr_read32(afu, cr, aligned_off, &val);
993 return (val >> ((off & 0x2) * 8)) & 0xffff; 993 if (!rc)
994 *out = (val >> ((off & 0x3) * 8)) & 0xffff;
995 return rc;
994} 996}
995 997
996u8 cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off) 998static int cxl_afu_cr_read8(struct cxl_afu *afu, int cr, u64 off, u8 *out)
997{ 999{
998 u64 aligned_off = off & ~0x3L; 1000 u64 aligned_off = off & ~0x3L;
999 u32 val; 1001 u32 val;
1002 int rc;
1000 1003
1001 val = cxl_afu_cr_read32(afu, cr, aligned_off); 1004 rc = cxl_afu_cr_read32(afu, cr, aligned_off, &val);
1002 return (val >> ((off & 0x3) * 8)) & 0xff; 1005 if (!rc)
1006 *out = (val >> ((off & 0x3) * 8)) & 0xff;
1007 return rc;
1003} 1008}
1009
1010const struct cxl_backend_ops cxl_native_ops = {
1011 .module = THIS_MODULE,
1012 .adapter_reset = cxl_reset,
1013 .alloc_one_irq = cxl_alloc_one_irq,
1014 .release_one_irq = cxl_release_one_irq,
1015 .alloc_irq_ranges = cxl_alloc_irq_ranges,
1016 .release_irq_ranges = cxl_release_irq_ranges,
1017 .setup_irq = cxl_setup_irq,
1018 .handle_psl_slice_error = handle_psl_slice_error,
1019 .psl_interrupt = NULL,
1020 .ack_irq = cxl_ack_irq,
1021 .attach_process = cxl_attach_process,
1022 .detach_process = cxl_detach_process,
1023 .link_ok = cxl_adapter_link_ok,
1024 .release_afu = cxl_release_afu,
1025 .afu_read_err_buffer = cxl_afu_read_err_buffer,
1026 .afu_check_and_enable = cxl_afu_check_and_enable,
1027 .afu_activate_mode = cxl_afu_activate_mode,
1028 .afu_deactivate_mode = cxl_afu_deactivate_mode,
1029 .afu_reset = __cxl_afu_reset,
1030 .afu_cr_read8 = cxl_afu_cr_read8,
1031 .afu_cr_read16 = cxl_afu_cr_read16,
1032 .afu_cr_read32 = cxl_afu_cr_read32,
1033 .afu_cr_read64 = cxl_afu_cr_read64,
1034};
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index c6279e5068b2..6e2c2748dd4f 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -646,7 +646,8 @@ static int cxl_read_afu_descriptor(struct cxl_afu *afu)
646 646
647static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu) 647static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu)
648{ 648{
649 int i; 649 int i, rc;
650 u32 val;
650 651
651 if (afu->psa && afu->adapter->ps_size < 652 if (afu->psa && afu->adapter->ps_size <
652 (afu->pp_offset + afu->pp_size*afu->max_procs_virtualised)) { 653 (afu->pp_offset + afu->pp_size*afu->max_procs_virtualised)) {
@@ -658,7 +659,8 @@ static int cxl_afu_descriptor_looks_ok(struct cxl_afu *afu)
658 dev_warn(&afu->dev, "AFU uses < PAGE_SIZE per-process PSA!"); 659 dev_warn(&afu->dev, "AFU uses < PAGE_SIZE per-process PSA!");
659 660
660 for (i = 0; i < afu->crs_num; i++) { 661 for (i = 0; i < afu->crs_num; i++) {
661 if ((cxl_afu_cr_read32(afu, i, 0) == 0)) { 662 rc = cxl_ops->afu_cr_read32(afu, i, 0, &val);
663 if (rc || val == 0) {
662 dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i); 664 dev_err(&afu->dev, "ABORTING: AFU configuration record %i is invalid\n", i);
663 return -EINVAL; 665 return -EINVAL;
664 } 666 }
@@ -679,7 +681,7 @@ static int sanitise_afu_regs(struct cxl_afu *afu)
679 reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An); 681 reg = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
680 if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) { 682 if ((reg & CXL_AFU_Cntl_An_ES_MASK) != CXL_AFU_Cntl_An_ES_Disabled) {
681 dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg); 683 dev_warn(&afu->dev, "WARNING: AFU was not disabled: %#016llx\n", reg);
682 if (__cxl_afu_reset(afu)) 684 if (cxl_ops->afu_reset(afu))
683 return -EIO; 685 return -EIO;
684 if (cxl_afu_disable(afu)) 686 if (cxl_afu_disable(afu))
685 return -EIO; 687 return -EIO;
@@ -775,7 +777,7 @@ static int cxl_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc
775 goto err1; 777 goto err1;
776 778
777 /* We need to reset the AFU before we can read the AFU descriptor */ 779 /* We need to reset the AFU before we can read the AFU descriptor */
778 if ((rc = __cxl_afu_reset(afu))) 780 if ((rc = cxl_ops->afu_reset(afu)))
779 goto err1; 781 goto err1;
780 782
781 if (cxl_verbose) 783 if (cxl_verbose)
@@ -876,7 +878,7 @@ static void cxl_remove_afu(struct cxl_afu *afu)
876 spin_unlock(&afu->adapter->afu_list_lock); 878 spin_unlock(&afu->adapter->afu_list_lock);
877 879
878 cxl_context_detach_all(afu); 880 cxl_context_detach_all(afu);
879 cxl_afu_deactivate_mode(afu); 881 cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
880 882
881 cxl_deconfigure_afu(afu); 883 cxl_deconfigure_afu(afu);
882 device_unregister(&afu->dev); 884 device_unregister(&afu->dev);
@@ -1398,7 +1400,7 @@ static pci_ers_result_t cxl_pci_error_detected(struct pci_dev *pdev,
1398 return result; 1400 return result;
1399 1401
1400 cxl_context_detach_all(afu); 1402 cxl_context_detach_all(afu);
1401 cxl_afu_deactivate_mode(afu); 1403 cxl_ops->afu_deactivate_mode(afu, afu->current_mode);
1402 cxl_deconfigure_afu(afu); 1404 cxl_deconfigure_afu(afu);
1403 } 1405 }
1404 cxl_deconfigure_adapter(adapter); 1406 cxl_deconfigure_adapter(adapter);
@@ -1445,7 +1447,7 @@ static pci_ers_result_t cxl_pci_slot_reset(struct pci_dev *pdev)
1445 1447
1446 afu_dev->dev.archdata.cxl_ctx = ctx; 1448 afu_dev->dev.archdata.cxl_ctx = ctx;
1447 1449
1448 if (cxl_afu_check_and_enable(afu)) 1450 if (cxl_ops->afu_check_and_enable(afu))
1449 goto err; 1451 goto err;
1450 1452
1451 afu_dev->error_state = pci_channel_io_normal; 1453 afu_dev->error_state = pci_channel_io_normal;
diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c
index 02006f7109a8..300eafe4ed43 100644
--- a/drivers/misc/cxl/sysfs.c
+++ b/drivers/misc/cxl/sysfs.c
@@ -69,7 +69,7 @@ static ssize_t reset_adapter_store(struct device *device,
69 if ((rc != 1) || (val != 1)) 69 if ((rc != 1) || (val != 1))
70 return -EINVAL; 70 return -EINVAL;
71 71
72 if ((rc = cxl_reset(adapter))) 72 if ((rc = cxl_ops->adapter_reset(adapter)))
73 return rc; 73 return rc;
74 return count; 74 return count;
75} 75}
@@ -211,7 +211,7 @@ static ssize_t reset_store_afu(struct device *device,
211 goto err; 211 goto err;
212 } 212 }
213 213
214 if ((rc = __cxl_afu_reset(afu))) 214 if ((rc = cxl_ops->afu_reset(afu)))
215 goto err; 215 goto err;
216 216
217 rc = count; 217 rc = count;
@@ -348,7 +348,7 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr,
348 } 348 }
349 349
350 /* 350 /*
351 * cxl_afu_deactivate_mode needs to be done outside the lock, prevent 351 * afu_deactivate_mode needs to be done outside the lock, prevent
352 * other contexts coming in before we are ready: 352 * other contexts coming in before we are ready:
353 */ 353 */
354 old_mode = afu->current_mode; 354 old_mode = afu->current_mode;
@@ -357,9 +357,9 @@ static ssize_t mode_store(struct device *device, struct device_attribute *attr,
357 357
358 mutex_unlock(&afu->contexts_lock); 358 mutex_unlock(&afu->contexts_lock);
359 359
360 if ((rc = _cxl_afu_deactivate_mode(afu, old_mode))) 360 if ((rc = cxl_ops->afu_deactivate_mode(afu, old_mode)))
361 return rc; 361 return rc;
362 if ((rc = cxl_afu_activate_mode(afu, mode))) 362 if ((rc = cxl_ops->afu_activate_mode(afu, mode)))
363 return rc; 363 return rc;
364 364
365 return count; 365 return count;
@@ -389,7 +389,7 @@ static ssize_t afu_eb_read(struct file *filp, struct kobject *kobj,
389 struct cxl_afu *afu = to_cxl_afu(container_of(kobj, 389 struct cxl_afu *afu = to_cxl_afu(container_of(kobj,
390 struct device, kobj)); 390 struct device, kobj));
391 391
392 return cxl_afu_read_err_buffer(afu, buf, off, count); 392 return cxl_ops->afu_read_err_buffer(afu, buf, off, count);
393} 393}
394 394
395static struct device_attribute afu_attrs[] = { 395static struct device_attribute afu_attrs[] = {
@@ -469,10 +469,12 @@ static ssize_t afu_read_config(struct file *filp, struct kobject *kobj,
469 struct afu_config_record *cr = to_cr(kobj); 469 struct afu_config_record *cr = to_cr(kobj);
470 struct cxl_afu *afu = to_cxl_afu(container_of(kobj->parent, struct device, kobj)); 470 struct cxl_afu *afu = to_cxl_afu(container_of(kobj->parent, struct device, kobj));
471 471
472 u64 i, j, val; 472 u64 i, j, val, rc;
473 473
474 for (i = 0; i < count;) { 474 for (i = 0; i < count;) {
475 val = cxl_afu_cr_read64(afu, cr->cr, off & ~0x7); 475 rc = cxl_ops->afu_cr_read64(afu, cr->cr, off & ~0x7, &val);
476 if (rc)
477 val = ~0ULL;
476 for (j = off & 0x7; j < 8 && i < count; i++, j++, off++) 478 for (j = off & 0x7; j < 8 && i < count; i++, j++, off++)
477 buf[i] = (val >> (j * 8)) & 0xff; 479 buf[i] = (val >> (j * 8)) & 0xff;
478 } 480 }
@@ -517,9 +519,17 @@ static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int c
517 return ERR_PTR(-ENOMEM); 519 return ERR_PTR(-ENOMEM);
518 520
519 cr->cr = cr_idx; 521 cr->cr = cr_idx;
520 cr->device = cxl_afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID); 522
521 cr->vendor = cxl_afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID); 523 rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID, &cr->device);
522 cr->class = cxl_afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION) >> 8; 524 if (rc)
525 goto err;
526 rc = cxl_ops->afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID, &cr->vendor);
527 if (rc)
528 goto err;
529 rc = cxl_ops->afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION, &cr->class);
530 if (rc)
531 goto err;
532 cr->class >>= 8;
523 533
524 /* 534 /*
525 * Export raw AFU PCIe like config record. For now this is read only by 535 * Export raw AFU PCIe like config record. For now this is read only by
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
index cbd4331fb45c..e8a8eed6f006 100644
--- a/drivers/misc/cxl/vphb.c
+++ b/drivers/misc/cxl/vphb.c
@@ -49,7 +49,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
49 phb = pci_bus_to_host(dev->bus); 49 phb = pci_bus_to_host(dev->bus);
50 afu = (struct cxl_afu *)phb->private_data; 50 afu = (struct cxl_afu *)phb->private_data;
51 51
52 if (!cxl_adapter_link_ok(afu->adapter)) { 52 if (!cxl_ops->link_ok(afu->adapter)) {
53 dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__); 53 dev_warn(&dev->dev, "%s: Device link is down, refusing to enable AFU\n", __func__);
54 return false; 54 return false;
55 } 55 }
@@ -66,7 +66,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
66 return false; 66 return false;
67 dev->dev.archdata.cxl_ctx = ctx; 67 dev->dev.archdata.cxl_ctx = ctx;
68 68
69 return (cxl_afu_check_and_enable(afu) == 0); 69 return (cxl_ops->afu_check_and_enable(afu) == 0);
70} 70}
71 71
72static void cxl_pci_disable_device(struct pci_dev *dev) 72static void cxl_pci_disable_device(struct pci_dev *dev)
@@ -161,7 +161,7 @@ static inline bool cxl_config_link_ok(struct pci_bus *bus)
161 if (phb == NULL) 161 if (phb == NULL)
162 return false; 162 return false;
163 afu = (struct cxl_afu *)phb->private_data; 163 afu = (struct cxl_afu *)phb->private_data;
164 return cxl_adapter_link_ok(afu->adapter); 164 return cxl_ops->link_ok(afu->adapter);
165} 165}
166 166
167static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn, 167static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,