diff options
Diffstat (limited to 'drivers/misc/cxl/native.c')
-rw-r--r-- | drivers/misc/cxl/native.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c index f2b37b41a0da..29185fc61276 100644 --- a/drivers/misc/cxl/native.c +++ b/drivers/misc/cxl/native.c | |||
@@ -18,24 +18,28 @@ | |||
18 | #include <misc/cxl.h> | 18 | #include <misc/cxl.h> |
19 | 19 | ||
20 | #include "cxl.h" | 20 | #include "cxl.h" |
21 | #include "trace.h" | ||
21 | 22 | ||
22 | static int afu_control(struct cxl_afu *afu, u64 command, | 23 | static int afu_control(struct cxl_afu *afu, u64 command, |
23 | u64 result, u64 mask, bool enabled) | 24 | u64 result, u64 mask, bool enabled) |
24 | { | 25 | { |
25 | u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An); | 26 | u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An); |
26 | unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); | 27 | unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); |
28 | int rc = 0; | ||
27 | 29 | ||
28 | spin_lock(&afu->afu_cntl_lock); | 30 | spin_lock(&afu->afu_cntl_lock); |
29 | pr_devel("AFU command starting: %llx\n", command); | 31 | pr_devel("AFU command starting: %llx\n", command); |
30 | 32 | ||
33 | trace_cxl_afu_ctrl(afu, command); | ||
34 | |||
31 | cxl_p2n_write(afu, CXL_AFU_Cntl_An, AFU_Cntl | command); | 35 | cxl_p2n_write(afu, CXL_AFU_Cntl_An, AFU_Cntl | command); |
32 | 36 | ||
33 | AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An); | 37 | AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An); |
34 | while ((AFU_Cntl & mask) != result) { | 38 | while ((AFU_Cntl & mask) != result) { |
35 | if (time_after_eq(jiffies, timeout)) { | 39 | if (time_after_eq(jiffies, timeout)) { |
36 | dev_warn(&afu->dev, "WARNING: AFU control timed out!\n"); | 40 | dev_warn(&afu->dev, "WARNING: AFU control timed out!\n"); |
37 | spin_unlock(&afu->afu_cntl_lock); | 41 | rc = -EBUSY; |
38 | return -EBUSY; | 42 | goto out; |
39 | } | 43 | } |
40 | pr_devel_ratelimited("AFU control... (0x%.16llx)\n", | 44 | pr_devel_ratelimited("AFU control... (0x%.16llx)\n", |
41 | AFU_Cntl | command); | 45 | AFU_Cntl | command); |
@@ -44,9 +48,11 @@ static int afu_control(struct cxl_afu *afu, u64 command, | |||
44 | }; | 48 | }; |
45 | pr_devel("AFU command complete: %llx\n", command); | 49 | pr_devel("AFU command complete: %llx\n", command); |
46 | afu->enabled = enabled; | 50 | afu->enabled = enabled; |
51 | out: | ||
52 | trace_cxl_afu_ctrl_done(afu, command, rc); | ||
47 | spin_unlock(&afu->afu_cntl_lock); | 53 | spin_unlock(&afu->afu_cntl_lock); |
48 | 54 | ||
49 | return 0; | 55 | return rc; |
50 | } | 56 | } |
51 | 57 | ||
52 | static int afu_enable(struct cxl_afu *afu) | 58 | static int afu_enable(struct cxl_afu *afu) |
@@ -91,6 +97,9 @@ int cxl_psl_purge(struct cxl_afu *afu) | |||
91 | u64 dsisr, dar; | 97 | u64 dsisr, dar; |
92 | u64 start, end; | 98 | u64 start, end; |
93 | unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); | 99 | unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); |
100 | int rc = 0; | ||
101 | |||
102 | trace_cxl_psl_ctrl(afu, CXL_PSL_SCNTL_An_Pc); | ||
94 | 103 | ||
95 | pr_devel("PSL purge request\n"); | 104 | pr_devel("PSL purge request\n"); |
96 | 105 | ||
@@ -107,7 +116,8 @@ int cxl_psl_purge(struct cxl_afu *afu) | |||
107 | == CXL_PSL_SCNTL_An_Ps_Pending) { | 116 | == CXL_PSL_SCNTL_An_Ps_Pending) { |
108 | if (time_after_eq(jiffies, timeout)) { | 117 | if (time_after_eq(jiffies, timeout)) { |
109 | dev_warn(&afu->dev, "WARNING: PSL Purge timed out!\n"); | 118 | dev_warn(&afu->dev, "WARNING: PSL Purge timed out!\n"); |
110 | return -EBUSY; | 119 | rc = -EBUSY; |
120 | goto out; | ||
111 | } | 121 | } |
112 | dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); | 122 | dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An); |
113 | pr_devel_ratelimited("PSL purging... PSL_CNTL: 0x%.16llx PSL_DSISR: 0x%.16llx\n", PSL_CNTL, dsisr); | 123 | pr_devel_ratelimited("PSL purging... PSL_CNTL: 0x%.16llx PSL_DSISR: 0x%.16llx\n", PSL_CNTL, dsisr); |
@@ -128,7 +138,9 @@ int cxl_psl_purge(struct cxl_afu *afu) | |||
128 | 138 | ||
129 | cxl_p1n_write(afu, CXL_PSL_SCNTL_An, | 139 | cxl_p1n_write(afu, CXL_PSL_SCNTL_An, |
130 | PSL_CNTL & ~CXL_PSL_SCNTL_An_Pc); | 140 | PSL_CNTL & ~CXL_PSL_SCNTL_An_Pc); |
131 | return 0; | 141 | out: |
142 | trace_cxl_psl_ctrl_done(afu, CXL_PSL_SCNTL_An_Pc, rc); | ||
143 | return rc; | ||
132 | } | 144 | } |
133 | 145 | ||
134 | static int spa_max_procs(int spa_size) | 146 | static int spa_max_procs(int spa_size) |
@@ -185,6 +197,7 @@ static int alloc_spa(struct cxl_afu *afu) | |||
185 | 197 | ||
186 | static void release_spa(struct cxl_afu *afu) | 198 | static void release_spa(struct cxl_afu *afu) |
187 | { | 199 | { |
200 | cxl_p1n_write(afu, CXL_PSL_SPAP_An, 0); | ||
188 | free_pages((unsigned long) afu->spa, afu->spa_order); | 201 | free_pages((unsigned long) afu->spa, afu->spa_order); |
189 | } | 202 | } |
190 | 203 | ||
@@ -278,6 +291,9 @@ static int do_process_element_cmd(struct cxl_context *ctx, | |||
278 | { | 291 | { |
279 | u64 state; | 292 | u64 state; |
280 | unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); | 293 | unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT); |
294 | int rc = 0; | ||
295 | |||
296 | trace_cxl_llcmd(ctx, cmd); | ||
281 | 297 | ||
282 | WARN_ON(!ctx->afu->enabled); | 298 | WARN_ON(!ctx->afu->enabled); |
283 | 299 | ||
@@ -289,12 +305,14 @@ static int do_process_element_cmd(struct cxl_context *ctx, | |||
289 | while (1) { | 305 | while (1) { |
290 | if (time_after_eq(jiffies, timeout)) { | 306 | if (time_after_eq(jiffies, timeout)) { |
291 | dev_warn(&ctx->afu->dev, "WARNING: Process Element Command timed out!\n"); | 307 | dev_warn(&ctx->afu->dev, "WARNING: Process Element Command timed out!\n"); |
292 | return -EBUSY; | 308 | rc = -EBUSY; |
309 | goto out; | ||
293 | } | 310 | } |
294 | state = be64_to_cpup(ctx->afu->sw_command_status); | 311 | state = be64_to_cpup(ctx->afu->sw_command_status); |
295 | if (state == ~0ULL) { | 312 | if (state == ~0ULL) { |
296 | pr_err("cxl: Error adding process element to AFU\n"); | 313 | pr_err("cxl: Error adding process element to AFU\n"); |
297 | return -1; | 314 | rc = -1; |
315 | goto out; | ||
298 | } | 316 | } |
299 | if ((state & (CXL_SPA_SW_CMD_MASK | CXL_SPA_SW_STATE_MASK | CXL_SPA_SW_LINK_MASK)) == | 317 | if ((state & (CXL_SPA_SW_CMD_MASK | CXL_SPA_SW_STATE_MASK | CXL_SPA_SW_LINK_MASK)) == |
300 | (cmd | (cmd >> 16) | ctx->pe)) | 318 | (cmd | (cmd >> 16) | ctx->pe)) |
@@ -309,7 +327,9 @@ static int do_process_element_cmd(struct cxl_context *ctx, | |||
309 | schedule(); | 327 | schedule(); |
310 | 328 | ||
311 | } | 329 | } |
312 | return 0; | 330 | out: |
331 | trace_cxl_llcmd_done(ctx, cmd, rc); | ||
332 | return rc; | ||
313 | } | 333 | } |
314 | 334 | ||
315 | static int add_process_element(struct cxl_context *ctx) | 335 | static int add_process_element(struct cxl_context *ctx) |
@@ -629,6 +649,8 @@ static inline int detach_process_native_afu_directed(struct cxl_context *ctx) | |||
629 | 649 | ||
630 | int cxl_detach_process(struct cxl_context *ctx) | 650 | int cxl_detach_process(struct cxl_context *ctx) |
631 | { | 651 | { |
652 | trace_cxl_detach(ctx); | ||
653 | |||
632 | if (ctx->afu->current_mode == CXL_MODE_DEDICATED) | 654 | if (ctx->afu->current_mode == CXL_MODE_DEDICATED) |
633 | return detach_process_native_dedicated(ctx); | 655 | return detach_process_native_dedicated(ctx); |
634 | 656 | ||
@@ -667,6 +689,7 @@ static void recover_psl_err(struct cxl_afu *afu, u64 errstat) | |||
667 | 689 | ||
668 | int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask) | 690 | int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask) |
669 | { | 691 | { |
692 | trace_cxl_psl_irq_ack(ctx, tfc); | ||
670 | if (tfc) | 693 | if (tfc) |
671 | cxl_p2n_write(ctx->afu, CXL_PSL_TFC_An, tfc); | 694 | cxl_p2n_write(ctx->afu, CXL_PSL_TFC_An, tfc); |
672 | if (psl_reset_mask) | 695 | if (psl_reset_mask) |