Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * ACPI helpers for DMA request / controller
  4 *
  5 * Based on of-dma.c
  6 *
  7 * Copyright (C) 2013, Intel Corporation
  8 * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
  9 *	    Mika Westerberg <mika.westerberg@linux.intel.com>
 10 */
 11
 12#include <linux/device.h>
 13#include <linux/dma-mapping.h>
 14#include <linux/err.h>
 15#include <linux/module.h>
 16#include <linux/kernel.h>
 17#include <linux/list.h>
 18#include <linux/mutex.h>
 19#include <linux/slab.h>
 20#include <linux/ioport.h>
 21#include <linux/acpi.h>
 22#include <linux/acpi_dma.h>
 23#include <linux/property.h>
 24
 25static LIST_HEAD(acpi_dma_list);
 26static DEFINE_MUTEX(acpi_dma_lock);
 27
 28/**
 29 * acpi_dma_parse_resource_group - match device and parse resource group
 30 * @grp:	CSRT resource group
 31 * @adev:	ACPI device to match with
 32 * @adma:	struct acpi_dma of the given DMA controller
 33 *
 34 * In order to match a device from DSDT table to the corresponding CSRT device
 35 * we use MMIO address and IRQ.
 36 *
 37 * Return:
 38 * 1 on success, 0 when no information is available, or appropriate errno value
 39 * on error.
 40 */
 41static int acpi_dma_parse_resource_group(const struct acpi_csrt_group *grp,
 42		struct acpi_device *adev, struct acpi_dma *adma)
 43{
 44	const struct acpi_csrt_shared_info *si;
 45	struct list_head resource_list;
 46	struct resource_entry *rentry;
 47	resource_size_t mem = 0, irq = 0;
 48	int ret;
 49
 50	if (grp->shared_info_length != sizeof(struct acpi_csrt_shared_info))
 51		return -ENODEV;
 52
 53	INIT_LIST_HEAD(&resource_list);
 54	ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL);
 55	if (ret <= 0)
 56		return 0;
 57
 58	list_for_each_entry(rentry, &resource_list, node) {
 59		if (resource_type(rentry->res) == IORESOURCE_MEM)
 60			mem = rentry->res->start;
 61		else if (resource_type(rentry->res) == IORESOURCE_IRQ)
 62			irq = rentry->res->start;
 63	}
 64
 65	acpi_dev_free_resource_list(&resource_list);
 66
 67	/* Consider initial zero values as resource not found */
 68	if (mem == 0 && irq == 0)
 69		return 0;
 70
 71	si = (const struct acpi_csrt_shared_info *)&grp[1];
 72
 73	/* Match device by MMIO */
 74	if (si->mmio_base_low != lower_32_bits(mem) ||
 75	    si->mmio_base_high != upper_32_bits(mem))
 76		return 0;
 77
 78	/* Match device by Linux vIRQ */
 79	ret = acpi_register_gsi(NULL, si->gsi_interrupt, si->interrupt_mode, si->interrupt_polarity);
 80	if (ret != irq)
 81		return 0;
 82
 83	dev_dbg(&adev->dev, "matches with %.4s%04X (rev %u)\n",
 84		(char *)&grp->vendor_id, grp->device_id, grp->revision);
 85
 86	/* Check if the request line range is available */
 87	if (si->base_request_line == 0 && si->num_handshake_signals == 0)
 88		return 0;
 89
 90	/* Set up DMA mask based on value from CSRT */
 91	ret = dma_coerce_mask_and_coherent(&adev->dev,
 92					   DMA_BIT_MASK(si->dma_address_width));
 93	if (ret)
 94		return 0;
 95
 96	adma->base_request_line = si->base_request_line;
 97	adma->end_request_line = si->base_request_line +
 98				 si->num_handshake_signals - 1;
 99
100	dev_dbg(&adev->dev, "request line base: 0x%04x end: 0x%04x\n",
101		adma->base_request_line, adma->end_request_line);
102
103	return 1;
104}
105
106/**
107 * acpi_dma_parse_csrt - parse CSRT to exctract additional DMA resources
108 * @adev:	ACPI device to match with
109 * @adma:	struct acpi_dma of the given DMA controller
110 *
111 * CSRT or Core System Resources Table is a proprietary ACPI table
112 * introduced by Microsoft. This table can contain devices that are not in
113 * the system DSDT table. In particular DMA controllers might be described
114 * here.
115 *
116 * We are using this table to get the request line range of the specific DMA
117 * controller to be used later.
118 */
119static void acpi_dma_parse_csrt(struct acpi_device *adev, struct acpi_dma *adma)
120{
121	struct acpi_csrt_group *grp, *end;
122	struct acpi_table_csrt *csrt;
123	acpi_status status;
124	int ret;
125
126	status = acpi_get_table(ACPI_SIG_CSRT, 0,
127				(struct acpi_table_header **)&csrt);
128	if (ACPI_FAILURE(status)) {
129		if (status != AE_NOT_FOUND)
130			dev_warn(&adev->dev, "failed to get the CSRT table\n");
131		return;
132	}
133
134	grp = (struct acpi_csrt_group *)(csrt + 1);
135	end = (struct acpi_csrt_group *)((void *)csrt + csrt->header.length);
136
137	while (grp < end) {
138		ret = acpi_dma_parse_resource_group(grp, adev, adma);
139		if (ret < 0) {
140			dev_warn(&adev->dev,
141				 "error in parsing resource group\n");
142			break;
143		}
144
145		grp = (struct acpi_csrt_group *)((void *)grp + grp->length);
146	}
147
148	acpi_put_table((struct acpi_table_header *)csrt);
149}
150
151/**
152 * acpi_dma_controller_register - Register a DMA controller to ACPI DMA helpers
153 * @dev:		struct device of DMA controller
154 * @acpi_dma_xlate:	translation function which converts a dma specifier
155 *			into a dma_chan structure
156 * @data:		pointer to controller specific data to be used by
157 *			translation function
158 *
159 * Allocated memory should be freed with appropriate acpi_dma_controller_free()
160 * call.
161 *
162 * Return:
163 * 0 on success or appropriate errno value on error.
164 */
165int acpi_dma_controller_register(struct device *dev,
166		struct dma_chan *(*acpi_dma_xlate)
167		(struct acpi_dma_spec *, struct acpi_dma *),
168		void *data)
169{
170	struct acpi_device *adev;
171	struct acpi_dma	*adma;
172
173	if (!dev || !acpi_dma_xlate)
174		return -EINVAL;
175
176	/* Check if the device was enumerated by ACPI */
177	adev = ACPI_COMPANION(dev);
178	if (!adev)
179		return -EINVAL;
180
181	adma = kzalloc(sizeof(*adma), GFP_KERNEL);
182	if (!adma)
183		return -ENOMEM;
184
185	adma->dev = dev;
186	adma->acpi_dma_xlate = acpi_dma_xlate;
187	adma->data = data;
188
189	acpi_dma_parse_csrt(adev, adma);
190
191	/* Now queue acpi_dma controller structure in list */
192	mutex_lock(&acpi_dma_lock);
193	list_add_tail(&adma->dma_controllers, &acpi_dma_list);
194	mutex_unlock(&acpi_dma_lock);
195
196	return 0;
197}
198EXPORT_SYMBOL_GPL(acpi_dma_controller_register);
199
200/**
201 * acpi_dma_controller_free - Remove a DMA controller from ACPI DMA helpers list
202 * @dev:	struct device of DMA controller
203 *
204 * Memory allocated by acpi_dma_controller_register() is freed here.
205 *
206 * Return:
207 * 0 on success or appropriate errno value on error.
208 */
209int acpi_dma_controller_free(struct device *dev)
210{
211	struct acpi_dma *adma;
212
213	if (!dev)
214		return -EINVAL;
215
216	mutex_lock(&acpi_dma_lock);
217
218	list_for_each_entry(adma, &acpi_dma_list, dma_controllers)
219		if (adma->dev == dev) {
220			list_del(&adma->dma_controllers);
221			mutex_unlock(&acpi_dma_lock);
222			kfree(adma);
223			return 0;
224		}
225
226	mutex_unlock(&acpi_dma_lock);
227	return -ENODEV;
228}
229EXPORT_SYMBOL_GPL(acpi_dma_controller_free);
230
231static void devm_acpi_dma_release(struct device *dev, void *res)
232{
233	acpi_dma_controller_free(dev);
234}
235
236/**
237 * devm_acpi_dma_controller_register - resource managed acpi_dma_controller_register()
238 * @dev:		device that is registering this DMA controller
239 * @acpi_dma_xlate:	translation function
240 * @data:		pointer to controller specific data
241 *
242 * Managed acpi_dma_controller_register(). DMA controller registered by this
243 * function are automatically freed on driver detach. See
244 * acpi_dma_controller_register() for more information.
245 *
246 * Return:
247 * 0 on success or appropriate errno value on error.
248 */
249int devm_acpi_dma_controller_register(struct device *dev,
250		struct dma_chan *(*acpi_dma_xlate)
251		(struct acpi_dma_spec *, struct acpi_dma *),
252		void *data)
253{
254	void *res;
255	int ret;
256
257	res = devres_alloc(devm_acpi_dma_release, 0, GFP_KERNEL);
258	if (!res)
259		return -ENOMEM;
260
261	ret = acpi_dma_controller_register(dev, acpi_dma_xlate, data);
262	if (ret) {
263		devres_free(res);
264		return ret;
265	}
266	devres_add(dev, res);
267	return 0;
268}
269EXPORT_SYMBOL_GPL(devm_acpi_dma_controller_register);
270
271/**
272 * devm_acpi_dma_controller_free - resource managed acpi_dma_controller_free()
273 * @dev:	device that is unregistering as DMA controller
274 *
275 * Unregister a DMA controller registered with
276 * devm_acpi_dma_controller_register(). Normally this function will not need to
277 * be called and the resource management code will ensure that the resource is
278 * freed.
279 */
280void devm_acpi_dma_controller_free(struct device *dev)
281{
282	WARN_ON(devres_release(dev, devm_acpi_dma_release, NULL, NULL));
283}
284EXPORT_SYMBOL_GPL(devm_acpi_dma_controller_free);
285
286/**
287 * acpi_dma_update_dma_spec - prepare dma specifier to pass to translation function
288 * @adma:	struct acpi_dma of DMA controller
289 * @dma_spec:	dma specifier to update
290 *
291 * Accordingly to ACPI 5.0 Specification Table 6-170 "Fixed DMA Resource
292 * Descriptor":
293 *	DMA Request Line bits is a platform-relative number uniquely
294 *	identifying the request line assigned. Request line-to-Controller
295 *	mapping is done in a controller-specific OS driver.
296 * That's why we can safely adjust slave_id when the appropriate controller is
297 * found.
298 *
299 * Return:
300 * 0, if no information is avaiable, -1 on mismatch, and 1 otherwise.
301 */
302static int acpi_dma_update_dma_spec(struct acpi_dma *adma,
303		struct acpi_dma_spec *dma_spec)
304{
305	/* Set link to the DMA controller device */
306	dma_spec->dev = adma->dev;
307
308	/* Check if the request line range is available */
309	if (adma->base_request_line == 0 && adma->end_request_line == 0)
310		return 0;
311
312	/* Check if slave_id falls to the range */
313	if (dma_spec->slave_id < adma->base_request_line ||
314	    dma_spec->slave_id > adma->end_request_line)
315		return -1;
316
317	/*
318	 * Here we adjust slave_id. It should be a relative number to the base
319	 * request line.
320	 */
321	dma_spec->slave_id -= adma->base_request_line;
322
323	return 1;
324}
325
326struct acpi_dma_parser_data {
327	struct acpi_dma_spec dma_spec;
328	size_t index;
329	size_t n;
330};
331
332/**
333 * acpi_dma_parse_fixed_dma - Parse FixedDMA ACPI resources to a DMA specifier
334 * @res:	struct acpi_resource to get FixedDMA resources from
335 * @data:	pointer to a helper struct acpi_dma_parser_data
336 */
337static int acpi_dma_parse_fixed_dma(struct acpi_resource *res, void *data)
338{
339	struct acpi_dma_parser_data *pdata = data;
340
341	if (res->type == ACPI_RESOURCE_TYPE_FIXED_DMA) {
342		struct acpi_resource_fixed_dma *dma = &res->data.fixed_dma;
343
344		if (pdata->n++ == pdata->index) {
345			pdata->dma_spec.chan_id = dma->channels;
346			pdata->dma_spec.slave_id = dma->request_lines;
347		}
348	}
349
350	/* Tell the ACPI core to skip this resource */
351	return 1;
352}
353
354/**
355 * acpi_dma_request_slave_chan_by_index - Get the DMA slave channel
356 * @dev:	struct device to get DMA request from
357 * @index:	index of FixedDMA descriptor for @dev
358 *
359 * Return:
360 * Pointer to appropriate dma channel on success or an error pointer.
361 */
362struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev,
363		size_t index)
364{
365	struct acpi_dma_parser_data pdata;
366	struct acpi_dma_spec *dma_spec = &pdata.dma_spec;
367	struct acpi_device *adev = ACPI_COMPANION(dev);
368	struct list_head resource_list;
369	struct acpi_dma *adma;
370	struct dma_chan *chan = NULL;
371	int found;
372	int ret;
373
374	memset(&pdata, 0, sizeof(pdata));
375	pdata.index = index;
376
377	/* Initial values for the request line and channel */
378	dma_spec->chan_id = -1;
379	dma_spec->slave_id = -1;
380
381	INIT_LIST_HEAD(&resource_list);
382	ret = acpi_dev_get_resources(adev, &resource_list,
383				     acpi_dma_parse_fixed_dma, &pdata);
384	acpi_dev_free_resource_list(&resource_list);
385	if (ret < 0)
386		return ERR_PTR(ret);
387
388	if (dma_spec->slave_id < 0 || dma_spec->chan_id < 0)
389		return ERR_PTR(-ENODEV);
390
391	mutex_lock(&acpi_dma_lock);
392
393	list_for_each_entry(adma, &acpi_dma_list, dma_controllers) {
394		/*
395		 * We are not going to call translation function if slave_id
396		 * doesn't fall to the request range.
397		 */
398		found = acpi_dma_update_dma_spec(adma, dma_spec);
399		if (found < 0)
400			continue;
401		chan = adma->acpi_dma_xlate(dma_spec, adma);
402		/*
403		 * Try to get a channel only from the DMA controller that
404		 * matches the slave_id. See acpi_dma_update_dma_spec()
405		 * description for the details.
406		 */
407		if (found > 0 || chan)
408			break;
409	}
410
411	mutex_unlock(&acpi_dma_lock);
412	return chan ? chan : ERR_PTR(-EPROBE_DEFER);
413}
414EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_index);
415
416/**
417 * acpi_dma_request_slave_chan_by_name - Get the DMA slave channel
418 * @dev:	struct device to get DMA request from
419 * @name:	represents corresponding FixedDMA descriptor for @dev
420 *
421 * In order to support both Device Tree and ACPI in a single driver we
422 * translate the names "tx" and "rx" here based on the most common case where
423 * the first FixedDMA descriptor is TX and second is RX.
424 *
425 * If the device has "dma-names" property the FixedDMA descriptor indices
426 * are retrieved based on those. Otherwise the function falls back using
427 * hardcoded indices.
428 *
429 * Return:
430 * Pointer to appropriate dma channel on success or an error pointer.
431 */
432struct dma_chan *acpi_dma_request_slave_chan_by_name(struct device *dev,
433		const char *name)
434{
435	int index;
436
437	index = device_property_match_string(dev, "dma-names", name);
438	if (index < 0) {
439		if (!strcmp(name, "tx"))
440			index = 0;
441		else if (!strcmp(name, "rx"))
442			index = 1;
443		else
444			return ERR_PTR(-ENODEV);
445	}
446
447	dev_dbg(dev, "Looking for DMA channel \"%s\" at index %d...\n", name, index);
448	return acpi_dma_request_slave_chan_by_index(dev, index);
449}
450EXPORT_SYMBOL_GPL(acpi_dma_request_slave_chan_by_name);
451
452/**
453 * acpi_dma_simple_xlate - Simple ACPI DMA engine translation helper
454 * @dma_spec: pointer to ACPI DMA specifier
455 * @adma: pointer to ACPI DMA controller data
456 *
457 * A simple translation function for ACPI based devices. Passes &struct
458 * dma_spec to the DMA controller driver provided filter function.
459 *
460 * Return:
461 * Pointer to the channel if found or %NULL otherwise.
462 */
463struct dma_chan *acpi_dma_simple_xlate(struct acpi_dma_spec *dma_spec,
464		struct acpi_dma *adma)
465{
466	struct acpi_dma_filter_info *info = adma->data;
467
468	if (!info || !info->filter_fn)
469		return NULL;
470
471	return dma_request_channel(info->dma_cap, info->filter_fn, dma_spec);
472}
473EXPORT_SYMBOL_GPL(acpi_dma_simple_xlate);