aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Munsie <imunsie@au1.ibm.com>2016-07-13 17:17:04 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2016-07-14 06:26:52 -0400
commita19bd79e31769626d288cc016e21a31b6f47bf6f (patch)
treeda10b02e662c4541f75db8ded6ca65bc76efe3c5
parent62ccf2d2efefa01d0eb92cd6ecbb45ea0499fb1c (diff)
cxl: Allow a default context to be associated with an external pci_dev
The cxl kernel API has a concept of a default context associated with each PCI device under the virtual PHB. The Mellanox CX4 will also use the cxl kernel API, but it does not use a virtual PHB - rather, the AFU appears as a physical function as a peer to the networking functions. In order to allow the kernel API to work with those networking functions, we will need to associate a default context with them as well. To this end, refactor the corresponding code to do this in vphb.c and export it so that it can be called from the PHB code. Signed-off-by: Ian Munsie <imunsie@au1.ibm.com> Reviewed-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com> Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--drivers/misc/cxl/Makefile2
-rw-r--r--drivers/misc/cxl/base.c35
-rw-r--r--drivers/misc/cxl/cxl.h6
-rw-r--r--drivers/misc/cxl/main.c2
-rw-r--r--drivers/misc/cxl/phb.c44
-rw-r--r--drivers/misc/cxl/vphb.c30
-rw-r--r--include/misc/cxl-base.h6
7 files changed, 97 insertions, 28 deletions
diff --git a/drivers/misc/cxl/Makefile b/drivers/misc/cxl/Makefile
index 8a55c1aa11aa..56e9a4732ef0 100644
--- a/drivers/misc/cxl/Makefile
+++ b/drivers/misc/cxl/Makefile
@@ -3,7 +3,7 @@ ccflags-$(CONFIG_PPC_WERROR) += -Werror
3 3
4cxl-y += main.o file.o irq.o fault.o native.o 4cxl-y += main.o file.o irq.o fault.o native.o
5cxl-y += context.o sysfs.o debugfs.o pci.o trace.o 5cxl-y += context.o sysfs.o debugfs.o pci.o trace.o
6cxl-y += vphb.o api.o 6cxl-y += vphb.o phb.o api.o
7cxl-$(CONFIG_PPC_PSERIES) += flash.o guest.o of.o hcalls.o 7cxl-$(CONFIG_PPC_PSERIES) += flash.o guest.o of.o hcalls.o
8obj-$(CONFIG_CXL) += cxl.o 8obj-$(CONFIG_CXL) += cxl.o
9obj-$(CONFIG_CXL_BASE) += base.o 9obj-$(CONFIG_CXL_BASE) += base.o
diff --git a/drivers/misc/cxl/base.c b/drivers/misc/cxl/base.c
index 7557835cdfcd..e1e80cb99ad9 100644
--- a/drivers/misc/cxl/base.c
+++ b/drivers/misc/cxl/base.c
@@ -106,6 +106,41 @@ int cxl_update_properties(struct device_node *dn,
106} 106}
107EXPORT_SYMBOL_GPL(cxl_update_properties); 107EXPORT_SYMBOL_GPL(cxl_update_properties);
108 108
109/*
110 * API calls into the driver that may be called from the PHB code and must be
111 * built in.
112 */
113bool cxl_pci_associate_default_context(struct pci_dev *dev, struct cxl_afu *afu)
114{
115 bool ret;
116 struct cxl_calls *calls;
117
118 calls = cxl_calls_get();
119 if (!calls)
120 return false;
121
122 ret = calls->cxl_pci_associate_default_context(dev, afu);
123
124 cxl_calls_put(calls);
125
126 return ret;
127}
128EXPORT_SYMBOL_GPL(cxl_pci_associate_default_context);
129
130void cxl_pci_disable_device(struct pci_dev *dev)
131{
132 struct cxl_calls *calls;
133
134 calls = cxl_calls_get();
135 if (!calls)
136 return;
137
138 calls->cxl_pci_disable_device(dev);
139
140 cxl_calls_put(calls);
141}
142EXPORT_SYMBOL_GPL(cxl_pci_disable_device);
143
109static int __init cxl_base_init(void) 144static int __init cxl_base_init(void)
110{ 145{
111 struct device_node *np; 146 struct device_node *np;
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index d4aae6f855a8..b81f476a2b9f 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -719,9 +719,15 @@ static inline u64 cxl_p2n_read(struct cxl_afu *afu, cxl_p2n_reg_t reg)
719ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf, 719ssize_t cxl_pci_afu_read_err_buffer(struct cxl_afu *afu, char *buf,
720 loff_t off, size_t count); 720 loff_t off, size_t count);
721 721
722/* Internal functions wrapped in cxl_base to allow PHB to call them */
723bool _cxl_pci_associate_default_context(struct pci_dev *dev, struct cxl_afu *afu);
724void _cxl_pci_disable_device(struct pci_dev *dev);
722 725
723struct cxl_calls { 726struct cxl_calls {
724 void (*cxl_slbia)(struct mm_struct *mm); 727 void (*cxl_slbia)(struct mm_struct *mm);
728 bool (*cxl_pci_associate_default_context)(struct pci_dev *dev, struct cxl_afu *afu);
729 void (*cxl_pci_disable_device)(struct pci_dev *dev);
730
725 struct module *owner; 731 struct module *owner;
726}; 732};
727int register_cxl_calls(struct cxl_calls *calls); 733int register_cxl_calls(struct cxl_calls *calls);
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
index ae68c3201156..4e5474b00b28 100644
--- a/drivers/misc/cxl/main.c
+++ b/drivers/misc/cxl/main.c
@@ -110,6 +110,8 @@ static inline void cxl_slbia_core(struct mm_struct *mm)
110 110
111static struct cxl_calls cxl_calls = { 111static struct cxl_calls cxl_calls = {
112 .cxl_slbia = cxl_slbia_core, 112 .cxl_slbia = cxl_slbia_core,
113 .cxl_pci_associate_default_context = _cxl_pci_associate_default_context,
114 .cxl_pci_disable_device = _cxl_pci_disable_device,
113 .owner = THIS_MODULE, 115 .owner = THIS_MODULE,
114}; 116};
115 117
diff --git a/drivers/misc/cxl/phb.c b/drivers/misc/cxl/phb.c
new file mode 100644
index 000000000000..0935d44c1770
--- /dev/null
+++ b/drivers/misc/cxl/phb.c
@@ -0,0 +1,44 @@
1/*
2 * Copyright 2014-2016 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#include <linux/pci.h>
11#include "cxl.h"
12
13bool _cxl_pci_associate_default_context(struct pci_dev *dev, struct cxl_afu *afu)
14{
15 struct cxl_context *ctx;
16
17 /*
18 * Allocate a context to do cxl things to. This is used for interrupts
19 * in the peer model using a real phb, and if we eventually do DMA ops
20 * in the virtual phb, we'll need a default context to attach them to.
21 */
22 ctx = cxl_dev_context_init(dev);
23 if (!ctx)
24 return false;
25 dev->dev.archdata.cxl_ctx = ctx;
26
27 return (cxl_ops->afu_check_and_enable(afu) == 0);
28}
29/* exported via cxl_base */
30
31void _cxl_pci_disable_device(struct pci_dev *dev)
32{
33 struct cxl_context *ctx = cxl_get_context(dev);
34
35 if (ctx) {
36 if (ctx->status == STARTED) {
37 dev_err(&dev->dev, "Default context started\n");
38 return;
39 }
40 dev->dev.archdata.cxl_ctx = NULL;
41 cxl_release_context(ctx);
42 }
43}
44/* exported via cxl_base */
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
index 012b6aa9fb3e..c8a759f4ccfa 100644
--- a/drivers/misc/cxl/vphb.c
+++ b/drivers/misc/cxl/vphb.c
@@ -44,7 +44,6 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
44{ 44{
45 struct pci_controller *phb; 45 struct pci_controller *phb;
46 struct cxl_afu *afu; 46 struct cxl_afu *afu;
47 struct cxl_context *ctx;
48 47
49 phb = pci_bus_to_host(dev->bus); 48 phb = pci_bus_to_host(dev->bus);
50 afu = (struct cxl_afu *)phb->private_data; 49 afu = (struct cxl_afu *)phb->private_data;
@@ -57,30 +56,7 @@ static bool cxl_pci_enable_device_hook(struct pci_dev *dev)
57 set_dma_ops(&dev->dev, &dma_direct_ops); 56 set_dma_ops(&dev->dev, &dma_direct_ops);
58 set_dma_offset(&dev->dev, PAGE_OFFSET); 57 set_dma_offset(&dev->dev, PAGE_OFFSET);
59 58
60 /* 59 return _cxl_pci_associate_default_context(dev, afu);
61 * Allocate a context to do cxl things too. If we eventually do real
62 * DMA ops, we'll need a default context to attach them to
63 */
64 ctx = cxl_dev_context_init(dev);
65 if (!ctx)
66 return false;
67 dev->dev.archdata.cxl_ctx = ctx;
68
69 return (cxl_ops->afu_check_and_enable(afu) == 0);
70}
71
72static void cxl_pci_disable_device(struct pci_dev *dev)
73{
74 struct cxl_context *ctx = cxl_get_context(dev);
75
76 if (ctx) {
77 if (ctx->status == STARTED) {
78 dev_err(&dev->dev, "Default context started\n");
79 return;
80 }
81 dev->dev.archdata.cxl_ctx = NULL;
82 cxl_release_context(ctx);
83 }
84} 60}
85 61
86static resource_size_t cxl_pci_window_alignment(struct pci_bus *bus, 62static resource_size_t cxl_pci_window_alignment(struct pci_bus *bus,
@@ -197,8 +173,8 @@ static struct pci_controller_ops cxl_pci_controller_ops =
197{ 173{
198 .probe_mode = cxl_pci_probe_mode, 174 .probe_mode = cxl_pci_probe_mode,
199 .enable_device_hook = cxl_pci_enable_device_hook, 175 .enable_device_hook = cxl_pci_enable_device_hook,
200 .disable_device = cxl_pci_disable_device, 176 .disable_device = _cxl_pci_disable_device,
201 .release_device = cxl_pci_disable_device, 177 .release_device = _cxl_pci_disable_device,
202 .window_alignment = cxl_pci_window_alignment, 178 .window_alignment = cxl_pci_window_alignment,
203 .reset_secondary_bus = cxl_pci_reset_secondary_bus, 179 .reset_secondary_bus = cxl_pci_reset_secondary_bus,
204 .setup_msi_irqs = cxl_setup_msi_irqs, 180 .setup_msi_irqs = cxl_setup_msi_irqs,
diff --git a/include/misc/cxl-base.h b/include/misc/cxl-base.h
index f53808fa638a..bb7e629ae492 100644
--- a/include/misc/cxl-base.h
+++ b/include/misc/cxl-base.h
@@ -10,6 +10,8 @@
10#ifndef _MISC_CXL_BASE_H 10#ifndef _MISC_CXL_BASE_H
11#define _MISC_CXL_BASE_H 11#define _MISC_CXL_BASE_H
12 12
13#include <misc/cxl.h>
14
13#ifdef CONFIG_CXL_BASE 15#ifdef CONFIG_CXL_BASE
14 16
15#define CXL_IRQ_RANGES 4 17#define CXL_IRQ_RANGES 4
@@ -39,6 +41,8 @@ static inline void cxl_ctx_put(void)
39struct cxl_afu *cxl_afu_get(struct cxl_afu *afu); 41struct cxl_afu *cxl_afu_get(struct cxl_afu *afu);
40void cxl_afu_put(struct cxl_afu *afu); 42void cxl_afu_put(struct cxl_afu *afu);
41void cxl_slbia(struct mm_struct *mm); 43void cxl_slbia(struct mm_struct *mm);
44bool cxl_pci_associate_default_context(struct pci_dev *dev, struct cxl_afu *afu);
45void cxl_pci_disable_device(struct pci_dev *dev);
42 46
43#else /* CONFIG_CXL_BASE */ 47#else /* CONFIG_CXL_BASE */
44 48
@@ -46,6 +50,8 @@ static inline bool cxl_ctx_in_use(void) { return false; }
46static inline struct cxl_afu *cxl_afu_get(struct cxl_afu *afu) { return NULL; } 50static inline struct cxl_afu *cxl_afu_get(struct cxl_afu *afu) { return NULL; }
47static inline void cxl_afu_put(struct cxl_afu *afu) {} 51static inline void cxl_afu_put(struct cxl_afu *afu) {}
48static inline void cxl_slbia(struct mm_struct *mm) {} 52static inline void cxl_slbia(struct mm_struct *mm) {}
53static inline bool cxl_pci_associate_default_context(struct pci_dev *dev, struct cxl_afu *afu) { return false; }
54static inline void cxl_pci_disable_device(struct pci_dev *dev) {}
49 55
50#endif /* CONFIG_CXL_BASE */ 56#endif /* CONFIG_CXL_BASE */
51 57