Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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