summaryrefslogtreecommitdiff
path: root/target/linux/layerscape/patches-4.4/7192-staging-fsl-mc-Propagate-driver_override-for-a-child.patch
blob: 20b952e5f3a969eed47d249dcd8146d56986ed65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
From 2b9110586a96afc0d0e246835da176c48ae7c973 Mon Sep 17 00:00:00 2001
From: "J. German Rivera" <German.Rivera@freescale.com>
Date: Fri, 13 Mar 2015 15:03:32 -0500
Subject: [PATCH 192/226] staging: fsl-mc: Propagate driver_override for a
 child DPRC's children

When a child DPRC is bound to the vfio_fsl_mc driver via driver_override,
its own children should not be bound to corresponding host kernel
drivers, but instead should be bound to the vfio_fsl_mc driver as
well.

Currently, when a child container is scanned by the vfio_fsl_mc driver,
child devices found are automatically bound to corresponding host kernel
drivers (e.g., DPMCP and DPBP objects are bound to the fsl_mc_allocator
driver, DPNI objects are bound to the ldpaa_eth driver, etc), Then,
the user has to manually unbind these child devices from their drivers,
set the driver_override sysfs attribute to vfio_fsl_mc driver, for each
of them and rebind them.

Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
 drivers/staging/fsl-mc/bus/dprc-driver.c    |   14 ++++++++++----
 drivers/staging/fsl-mc/bus/mc-bus.c         |   20 +++++++++++++++++---
 drivers/staging/fsl-mc/include/mc-private.h |    2 ++
 drivers/staging/fsl-mc/include/mc.h         |    2 ++
 4 files changed, 31 insertions(+), 7 deletions(-)

--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
+++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
@@ -152,6 +152,8 @@ static void check_plugged_state_change(s
  * dprc_add_new_devices - Adds devices to the logical bus for a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @driver_override: driver override to apply to new objects found in the DPRC,
+ * or NULL, if none.
  * @obj_desc_array: array of device descriptors for child devices currently
  * present in the physical DPRC.
  * @num_child_objects_in_mc: number of entries in obj_desc_array
@@ -161,6 +163,7 @@ static void check_plugged_state_change(s
  * in the physical DPRC.
  */
 static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
+				 const char *driver_override,
 				 struct dprc_obj_desc *obj_desc_array,
 				 int num_child_objects_in_mc)
 {
@@ -184,7 +187,7 @@ static void dprc_add_new_devices(struct
 		}
 
 		error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev,
-					  &child_dev);
+					  driver_override, &child_dev);
 		if (error < 0)
 			continue;
 	}
@@ -243,6 +246,8 @@ static void dprc_cleanup_all_resource_po
  * dprc_scan_objects - Discover objects in a DPRC
  *
  * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
+ * @driver_override: driver override to apply to new objects found in the DPRC,
+ * or NULL, if none.
  * @total_irq_count: total number of IRQs needed by objects in the DPRC.
  *
  * Detects objects added and removed from a DPRC and synchronizes the
@@ -258,6 +263,7 @@ static void dprc_cleanup_all_resource_po
  * of the device drivers for the non-allocatable devices.
  */
 int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+		      const char *driver_override,
 		      unsigned int *total_irq_count)
 {
 	int num_child_objects;
@@ -338,7 +344,7 @@ int dprc_scan_objects(struct fsl_mc_devi
 	dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
 			    num_child_objects);
 
-	dprc_add_new_devices(mc_bus_dev, child_obj_desc_array,
+	dprc_add_new_devices(mc_bus_dev, driver_override, child_obj_desc_array,
 			     num_child_objects);
 
 	if (child_obj_desc_array)
@@ -369,7 +375,7 @@ int dprc_scan_container(struct fsl_mc_de
 	 * Discover objects in the DPRC:
 	 */
 	mutex_lock(&mc_bus->scan_mutex);
-	error = dprc_scan_objects(mc_bus_dev, &irq_count);
+	error = dprc_scan_objects(mc_bus_dev, NULL, &irq_count);
 	mutex_unlock(&mc_bus->scan_mutex);
 	if (error < 0)
 		goto error;
@@ -456,7 +462,7 @@ static irqreturn_t dprc_irq0_handler_thr
 		      DPRC_IRQ_EVENT_OBJ_CREATED)) {
 		unsigned int irq_count;
 
-		error = dprc_scan_objects(mc_dev, &irq_count);
+		error = dprc_scan_objects(mc_dev, NULL, &irq_count);
 		if (error < 0) {
 			/*
 			 * If the error is -ENXIO, we ignore it, as it indicates
--- a/drivers/staging/fsl-mc/bus/mc-bus.c
+++ b/drivers/staging/fsl-mc/bus/mc-bus.c
@@ -116,7 +116,7 @@ static ssize_t rescan_store(struct devic
 
 	if (val) {
 		mutex_lock(&root_mc_bus->scan_mutex);
-		dprc_scan_objects(root_mc_dev, &irq_count);
+		dprc_scan_objects(root_mc_dev, NULL, &irq_count);
 		mutex_unlock(&root_mc_bus->scan_mutex);
 	}
 
@@ -149,7 +149,7 @@ static int scan_fsl_mc_bus(struct device
 		root_mc_dev = to_fsl_mc_device(dev);
 		root_mc_bus = to_fsl_mc_bus(root_mc_dev);
 		mutex_lock(&root_mc_bus->scan_mutex);
-		dprc_scan_objects(root_mc_dev, &irq_count);
+		dprc_scan_objects(root_mc_dev, NULL, &irq_count);
 		mutex_unlock(&root_mc_bus->scan_mutex);
 	}
 
@@ -503,6 +503,7 @@ bool fsl_mc_is_root_dprc(struct device *
 int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
 		      struct fsl_mc_io *mc_io,
 		      struct device *parent_dev,
+		      const char *driver_override,
 		      struct fsl_mc_device **new_mc_dev)
 {
 	int error;
@@ -535,6 +536,18 @@ int fsl_mc_device_add(struct dprc_obj_de
 
 	mc_dev->obj_desc = *obj_desc;
 	mc_dev->mc_io = mc_io;
+	if (driver_override) {
+		/*
+		 * We trust driver_override, so we don't need to use
+		 * kstrndup() here
+		 */
+		mc_dev->driver_override = kstrdup(driver_override, GFP_KERNEL);
+		if (!mc_dev->driver_override) {
+			error = -ENOMEM;
+			goto error_cleanup_dev;
+		}
+	}
+
 	device_initialize(&mc_dev->dev);
 	mc_dev->dev.parent = parent_dev;
 	mc_dev->dev.bus = &fsl_mc_bus_type;
@@ -858,7 +871,8 @@ static int fsl_mc_bus_probe(struct platf
 	obj_desc.irq_count = 1;
 	obj_desc.region_count = 0;
 
-	error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev);
+	error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, NULL,
+				  &mc_bus_dev);
 	if (error < 0)
 		goto error_cleanup_mc_io;
 
--- a/drivers/staging/fsl-mc/include/mc-private.h
+++ b/drivers/staging/fsl-mc/include/mc-private.h
@@ -110,6 +110,7 @@ struct fsl_mc_bus {
 int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
 				   struct fsl_mc_io *mc_io,
 				   struct device *parent_dev,
+				   const char *driver_override,
 				   struct fsl_mc_device **new_mc_dev);
 
 void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
@@ -117,6 +118,7 @@ void fsl_mc_device_remove(struct fsl_mc_
 int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);
 
 int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
+		      const char *driver_override,
 		      unsigned int *total_irq_count);
 
 int __init dprc_driver_init(void);
--- a/drivers/staging/fsl-mc/include/mc.h
+++ b/drivers/staging/fsl-mc/include/mc.h
@@ -129,6 +129,7 @@ struct fsl_mc_device_irq {
  * @regions: pointer to array of MMIO region entries
  * @irqs: pointer to array of pointers to interrupts allocated to this device
  * @resource: generic resource associated with this MC object device, if any.
+ * @driver_override: Driver name to force a match
  *
  * Generic device object for MC object devices that are "attached" to a
  * MC bus.
@@ -161,6 +162,7 @@ struct fsl_mc_device {
 	struct resource *regions;
 	struct fsl_mc_device_irq **irqs;
 	struct fsl_mc_resource *resource;
+	const char *driver_override;
 };
 
 #define to_fsl_mc_device(_dev) \