LCOV - code coverage report
Current view: top level - drivers/dma - acpi-dma.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 118 0.0 %
Date: 2022-03-28 16:04:14 Functions: 0 10 0.0 %
Branches: 0 64 0.0 %

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

Generated by: LCOV version 1.14