xref: /linux/drivers/soundwire/intel_init.c (revision 202779456dc5b75d07b214064161ef6a2421e8be)
1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2 // Copyright(c) 2015-17 Intel Corporation.
3 
4 /*
5  * SDW Intel Init Routines
6  *
7  * Initializes and creates SDW devices based on ACPI and Hardware values
8  */
9 
10 #include <linux/acpi.h>
11 #include <linux/export.h>
12 #include <linux/interrupt.h>
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/auxiliary_bus.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/soundwire/sdw_intel.h>
18 #include "cadence_master.h"
19 #include "intel.h"
20 #include "intel_auxdevice.h"
21 
22 static void intel_link_dev_release(struct device *dev)
23 {
24 	struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
25 	struct sdw_intel_link_dev *ldev = auxiliary_dev_to_sdw_intel_link_dev(auxdev);
26 
27 	kfree(ldev);
28 }
29 
30 /* alloc, init and add link devices */
31 static struct sdw_intel_link_dev *intel_link_dev_register(struct sdw_intel_res *res,
32 							  struct sdw_intel_ctx *ctx,
33 							  struct fwnode_handle *fwnode,
34 							  const char *name,
35 							  int link_id)
36 {
37 	struct sdw_intel_link_dev *ldev;
38 	struct sdw_intel_link_res *link;
39 	struct auxiliary_device *auxdev;
40 	int ret;
41 
42 	ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
43 	if (!ldev)
44 		return ERR_PTR(-ENOMEM);
45 
46 	auxdev = &ldev->auxdev;
47 	auxdev->name = name;
48 	auxdev->dev.parent = res->parent;
49 	auxdev->dev.fwnode = fwnode;
50 	auxdev->dev.release = intel_link_dev_release;
51 
52 	/* we don't use an IDA since we already have a link ID */
53 	auxdev->id = link_id;
54 
55 	/*
56 	 * keep a handle on the allocated memory, to be used in all other functions.
57 	 * Since the same pattern is used to skip links that are not enabled, there is
58 	 * no need to check if ctx->ldev[i] is NULL later on.
59 	 */
60 	ctx->ldev[link_id] = ldev;
61 
62 	/* Add link information used in the driver probe */
63 	link = &ldev->link_res;
64 	link->hw_ops = res->hw_ops;
65 	link->mmio_base = res->mmio_base;
66 	link->registers = res->mmio_base + SDW_LINK_BASE
67 		+ (SDW_LINK_SIZE * link_id);
68 	link->shim = res->mmio_base + res->shim_base;
69 	link->alh = res->mmio_base + res->alh_base;
70 
71 	link->ops = res->ops;
72 	link->dev = res->dev;
73 
74 	link->clock_stop_quirks = res->clock_stop_quirks;
75 	link->shim_lock = &ctx->shim_lock;
76 	link->shim_mask = &ctx->shim_mask;
77 	link->link_mask = ctx->link_mask;
78 
79 	/* now follow the two-step init/add sequence */
80 	ret = auxiliary_device_init(auxdev);
81 	if (ret < 0) {
82 		dev_err(res->parent, "failed to initialize link dev %s link_id %d\n",
83 			name, link_id);
84 		kfree(ldev);
85 		return ERR_PTR(ret);
86 	}
87 
88 	ret = auxiliary_device_add(&ldev->auxdev);
89 	if (ret < 0) {
90 		dev_err(res->parent, "failed to add link dev %s link_id %d\n",
91 			ldev->auxdev.name, link_id);
92 		/* ldev will be freed with the put_device() and .release sequence */
93 		auxiliary_device_uninit(&ldev->auxdev);
94 		return ERR_PTR(ret);
95 	}
96 
97 	return ldev;
98 }
99 
100 static void intel_link_dev_unregister(struct sdw_intel_link_dev *ldev)
101 {
102 	auxiliary_device_delete(&ldev->auxdev);
103 	auxiliary_device_uninit(&ldev->auxdev);
104 }
105 
106 static int sdw_intel_cleanup(struct sdw_intel_ctx *ctx)
107 {
108 	struct sdw_intel_link_dev *ldev;
109 	u32 link_mask;
110 	int i;
111 
112 	link_mask = ctx->link_mask;
113 
114 	for (i = 0; i < ctx->count; i++) {
115 		if (!(link_mask & BIT(i)))
116 			continue;
117 
118 		ldev = ctx->ldev[i];
119 
120 		pm_runtime_disable(&ldev->auxdev.dev);
121 		if (!ldev->link_res.clock_stop_quirks)
122 			pm_runtime_put_noidle(ldev->link_res.dev);
123 
124 		intel_link_dev_unregister(ldev);
125 	}
126 
127 	return 0;
128 }
129 
130 irqreturn_t sdw_intel_thread(int irq, void *dev_id)
131 {
132 	struct sdw_intel_ctx *ctx = dev_id;
133 	struct sdw_intel_link_res *link;
134 
135 	list_for_each_entry(link, &ctx->link_list, list)
136 		sdw_cdns_irq(irq, link->cdns);
137 
138 	return IRQ_HANDLED;
139 }
140 EXPORT_SYMBOL_NS(sdw_intel_thread, SOUNDWIRE_INTEL_INIT);
141 
142 static struct sdw_intel_ctx
143 *sdw_intel_probe_controller(struct sdw_intel_res *res)
144 {
145 	struct sdw_intel_link_res *link;
146 	struct sdw_intel_link_dev *ldev;
147 	struct sdw_intel_ctx *ctx;
148 	struct acpi_device *adev;
149 	struct sdw_slave *slave;
150 	struct list_head *node;
151 	struct sdw_bus *bus;
152 	u32 link_mask;
153 	int num_slaves = 0;
154 	int count;
155 	int i;
156 
157 	if (!res)
158 		return NULL;
159 
160 	adev = acpi_fetch_acpi_dev(res->handle);
161 	if (!adev)
162 		return NULL;
163 
164 	if (!res->count)
165 		return NULL;
166 
167 	count = res->count;
168 	dev_dbg(&adev->dev, "Creating %d SDW Link devices\n", count);
169 
170 	/*
171 	 * we need to alloc/free memory manually and can't use devm:
172 	 * this routine may be called from a workqueue, and not from
173 	 * the parent .probe.
174 	 * If devm_ was used, the memory might never be freed on errors.
175 	 */
176 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
177 	if (!ctx)
178 		return NULL;
179 
180 	ctx->count = count;
181 
182 	/*
183 	 * allocate the array of pointers. The link-specific data is allocated
184 	 * as part of the first loop below and released with the auxiliary_device_uninit().
185 	 * If some links are disabled, the link pointer will remain NULL. Given that the
186 	 * number of links is small, this is simpler than using a list to keep track of links.
187 	 */
188 	ctx->ldev = kcalloc(ctx->count, sizeof(*ctx->ldev), GFP_KERNEL);
189 	if (!ctx->ldev) {
190 		kfree(ctx);
191 		return NULL;
192 	}
193 
194 	ctx->mmio_base = res->mmio_base;
195 	ctx->shim_base = res->shim_base;
196 	ctx->alh_base = res->alh_base;
197 	ctx->link_mask = res->link_mask;
198 	ctx->handle = res->handle;
199 	mutex_init(&ctx->shim_lock);
200 
201 	link_mask = ctx->link_mask;
202 
203 	INIT_LIST_HEAD(&ctx->link_list);
204 
205 	for (i = 0; i < count; i++) {
206 		if (!(link_mask & BIT(i)))
207 			continue;
208 
209 		/*
210 		 * init and add a device for each link
211 		 *
212 		 * The name of the device will be soundwire_intel.link.[i],
213 		 * with the "soundwire_intel" module prefix automatically added
214 		 * by the auxiliary bus core.
215 		 */
216 		ldev = intel_link_dev_register(res,
217 					       ctx,
218 					       acpi_fwnode_handle(adev),
219 					       "link",
220 					       i);
221 		if (IS_ERR(ldev))
222 			goto err;
223 
224 		link = &ldev->link_res;
225 		link->cdns = auxiliary_get_drvdata(&ldev->auxdev);
226 
227 		if (!link->cdns) {
228 			dev_err(&adev->dev, "failed to get link->cdns\n");
229 			/*
230 			 * 1 will be subtracted from i in the err label, but we need to call
231 			 * intel_link_dev_unregister for this ldev, so plus 1 now
232 			 */
233 			i++;
234 			goto err;
235 		}
236 		list_add_tail(&link->list, &ctx->link_list);
237 		bus = &link->cdns->bus;
238 		/* Calculate number of slaves */
239 		list_for_each(node, &bus->slaves)
240 			num_slaves++;
241 	}
242 
243 	ctx->ids = kcalloc(num_slaves, sizeof(*ctx->ids), GFP_KERNEL);
244 	if (!ctx->ids)
245 		goto err;
246 
247 	ctx->num_slaves = num_slaves;
248 	i = 0;
249 	list_for_each_entry(link, &ctx->link_list, list) {
250 		bus = &link->cdns->bus;
251 		list_for_each_entry(slave, &bus->slaves, node) {
252 			ctx->ids[i].id = slave->id;
253 			ctx->ids[i].link_id = bus->link_id;
254 			i++;
255 		}
256 	}
257 
258 	return ctx;
259 
260 err:
261 	while (i--) {
262 		if (!(link_mask & BIT(i)))
263 			continue;
264 		ldev = ctx->ldev[i];
265 		intel_link_dev_unregister(ldev);
266 	}
267 	kfree(ctx->ldev);
268 	kfree(ctx);
269 	return NULL;
270 }
271 
272 static int
273 sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
274 {
275 	struct acpi_device *adev = acpi_fetch_acpi_dev(ctx->handle);
276 	struct sdw_intel_link_dev *ldev;
277 	u32 link_mask;
278 	int i;
279 
280 	if (!adev)
281 		return -EINVAL;
282 
283 	if (!ctx->ldev)
284 		return -EINVAL;
285 
286 	link_mask = ctx->link_mask;
287 
288 	/* Startup SDW Master devices */
289 	for (i = 0; i < ctx->count; i++) {
290 		if (!(link_mask & BIT(i)))
291 			continue;
292 
293 		ldev = ctx->ldev[i];
294 
295 		intel_link_startup(&ldev->auxdev);
296 
297 		if (!ldev->link_res.clock_stop_quirks) {
298 			/*
299 			 * we need to prevent the parent PCI device
300 			 * from entering pm_runtime suspend, so that
301 			 * power rails to the SoundWire IP are not
302 			 * turned off.
303 			 */
304 			pm_runtime_get_noresume(ldev->link_res.dev);
305 		}
306 	}
307 
308 	return 0;
309 }
310 
311 /**
312  * sdw_intel_probe() - SoundWire Intel probe routine
313  * @res: resource data
314  *
315  * This registers an auxiliary device for each Master handled by the controller,
316  * and SoundWire Master and Slave devices will be created by the auxiliary
317  * device probe. All the information necessary is stored in the context, and
318  * the res argument pointer can be freed after this step.
319  * This function will be called after sdw_intel_acpi_scan() by SOF probe.
320  */
321 struct sdw_intel_ctx
322 *sdw_intel_probe(struct sdw_intel_res *res)
323 {
324 	return sdw_intel_probe_controller(res);
325 }
326 EXPORT_SYMBOL_NS(sdw_intel_probe, SOUNDWIRE_INTEL_INIT);
327 
328 /**
329  * sdw_intel_startup() - SoundWire Intel startup
330  * @ctx: SoundWire context allocated in the probe
331  *
332  * Startup Intel SoundWire controller. This function will be called after
333  * Intel Audio DSP is powered up.
334  */
335 int sdw_intel_startup(struct sdw_intel_ctx *ctx)
336 {
337 	return sdw_intel_startup_controller(ctx);
338 }
339 EXPORT_SYMBOL_NS(sdw_intel_startup, SOUNDWIRE_INTEL_INIT);
340 /**
341  * sdw_intel_exit() - SoundWire Intel exit
342  * @ctx: SoundWire context allocated in the probe
343  *
344  * Delete the controller instances created and cleanup
345  */
346 void sdw_intel_exit(struct sdw_intel_ctx *ctx)
347 {
348 	sdw_intel_cleanup(ctx);
349 	kfree(ctx->ids);
350 	kfree(ctx->ldev);
351 	kfree(ctx);
352 }
353 EXPORT_SYMBOL_NS(sdw_intel_exit, SOUNDWIRE_INTEL_INIT);
354 
355 void sdw_intel_process_wakeen_event(struct sdw_intel_ctx *ctx)
356 {
357 	struct sdw_intel_link_dev *ldev;
358 	u32 link_mask;
359 	int i;
360 
361 	if (!ctx->ldev)
362 		return;
363 
364 	link_mask = ctx->link_mask;
365 
366 	/* Startup SDW Master devices */
367 	for (i = 0; i < ctx->count; i++) {
368 		if (!(link_mask & BIT(i)))
369 			continue;
370 
371 		ldev = ctx->ldev[i];
372 
373 		intel_link_process_wakeen_event(&ldev->auxdev);
374 	}
375 }
376 EXPORT_SYMBOL_NS(sdw_intel_process_wakeen_event, SOUNDWIRE_INTEL_INIT);
377 
378 MODULE_LICENSE("Dual BSD/GPL");
379 MODULE_DESCRIPTION("Intel Soundwire Init Library");
380