diff options
Diffstat (limited to 'drivers/staging/fsl-mc/bus/dprc-driver.c')
-rw-r--r-- | drivers/staging/fsl-mc/bus/dprc-driver.c | 82 |
1 files changed, 38 insertions, 44 deletions
diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c index 06df528f4cfc..b09075731e62 100644 --- a/drivers/staging/fsl-mc/bus/dprc-driver.c +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c @@ -1,12 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Freescale data path resource container (DPRC) driver * * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. * Author: German Rivera <German.Rivera@freescale.com> * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include <linux/module.h> @@ -15,7 +13,6 @@ #include <linux/msi.h> #include "../include/mc.h" -#include "dprc-cmd.h" #include "fsl-mc-private.h" #define FSL_MC_DPRC_DRIVER_NAME "fsl_mc_dprc" @@ -39,8 +36,6 @@ static int __fsl_mc_device_remove_if_not_in_mc(struct device *dev, void *data) struct fsl_mc_child_objs *objs; struct fsl_mc_device *mc_dev; - WARN_ON(!dev); - WARN_ON(!data); mc_dev = to_fsl_mc_device(dev); objs = data; @@ -60,8 +55,6 @@ static int __fsl_mc_device_remove_if_not_in_mc(struct device *dev, void *data) static int __fsl_mc_device_remove(struct device *dev, void *data) { - WARN_ON(!dev); - WARN_ON(data); fsl_mc_device_remove(to_fsl_mc_device(dev)); return 0; } @@ -206,7 +199,8 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev, * dprc_scan_objects - Discover objects in a DPRC * * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object - * @total_irq_count: total number of IRQs needed by objects in the DPRC. + * @total_irq_count: If argument is provided the function populates the + * total number of IRQs created by objects in the DPRC. * * Detects objects added and removed from a DPRC and synchronizes the * state of the Linux bus driver, MC by adding and removing @@ -228,6 +222,7 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, int error; unsigned int irq_count = mc_bus_dev->obj_desc.irq_count; struct fsl_mc_obj_desc *child_obj_desc_array = NULL; + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); error = dprc_get_obj_count(mc_bus_dev->mc_io, 0, @@ -297,7 +292,26 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, } } - *total_irq_count = irq_count; + /* + * Allocate IRQ's before binding the scanned devices with their + * respective drivers. + */ + if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) { + if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) { + dev_warn(&mc_bus_dev->dev, + "IRQs needed (%u) exceed IRQs preallocated (%u)\n", + irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); + } + + error = fsl_mc_populate_irq_pool(mc_bus, + FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); + if (error < 0) + return error; + } + + if (total_irq_count) + *total_irq_count = irq_count; + dprc_remove_devices(mc_bus_dev, child_obj_desc_array, num_child_objects); @@ -322,7 +336,6 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev) { int error; - unsigned int irq_count; struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); fsl_mc_init_all_resource_pools(mc_bus_dev); @@ -331,29 +344,14 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev) * Discover objects in the DPRC: */ mutex_lock(&mc_bus->scan_mutex); - error = dprc_scan_objects(mc_bus_dev, &irq_count); + error = dprc_scan_objects(mc_bus_dev, NULL); mutex_unlock(&mc_bus->scan_mutex); - if (error < 0) - goto error; - - if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) { - if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) { - dev_warn(&mc_bus_dev->dev, - "IRQs needed (%u) exceed IRQs preallocated (%u)\n", - irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); - } - - error = fsl_mc_populate_irq_pool( - mc_bus, - FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); - if (error < 0) - goto error; + if (error < 0) { + fsl_mc_cleanup_all_resource_pools(mc_bus_dev); + return error; } return 0; -error: - fsl_mc_cleanup_all_resource_pools(mc_bus_dev); - return error; } /** @@ -386,11 +384,11 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg) dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n", irq_num, smp_processor_id()); - if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC))) + if (!(mc_dev->flags & FSL_MC_IS_DPRC)) return IRQ_HANDLED; mutex_lock(&mc_bus->scan_mutex); - if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num)) + if (!msi_desc || msi_desc->irq != (u32)irq_num) goto out; status = 0; @@ -453,8 +451,6 @@ static int disable_dprc_irq(struct fsl_mc_device *mc_dev) int error; struct fsl_mc_io *mc_io = mc_dev->mc_io; - WARN_ON(mc_dev->obj_desc.irq_count != 1); - /* * Disable generation of interrupt, while we configure it: */ @@ -496,8 +492,6 @@ static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev) int error; struct fsl_mc_device_irq *irq = mc_dev->irqs[0]; - WARN_ON(mc_dev->obj_desc.irq_count != 1); - /* * NOTE: devm_request_threaded_irq() invokes the device-specific * function that programs the MSI physically in the device @@ -601,20 +595,20 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) bool msi_domain_set = false; u16 major_ver, minor_ver; - if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0)) + if (!is_fsl_mc_bus_dprc(mc_dev)) return -EINVAL; - if (WARN_ON(dev_get_msi_domain(&mc_dev->dev))) + if (dev_get_msi_domain(&mc_dev->dev)) return -EINVAL; if (!mc_dev->mc_io) { /* * This is a child DPRC: */ - if (WARN_ON(!dev_is_fsl_mc(parent_dev))) + if (!dev_is_fsl_mc(parent_dev)) return -EINVAL; - if (WARN_ON(mc_dev->obj_desc.region_count == 0)) + if (mc_dev->obj_desc.region_count == 0) return -EINVAL; region_size = resource_size(mc_dev->regions); @@ -642,7 +636,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) */ struct irq_domain *mc_msi_domain; - if (WARN_ON(dev_is_fsl_mc(parent_dev))) + if (dev_is_fsl_mc(parent_dev)) return -EINVAL; error = fsl_mc_find_msi_domain(parent_dev, @@ -753,12 +747,12 @@ static int dprc_remove(struct fsl_mc_device *mc_dev) int error; struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); - if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0)) + if (!is_fsl_mc_bus_dprc(mc_dev)) return -EINVAL; - if (WARN_ON(!mc_dev->mc_io)) + if (!mc_dev->mc_io) return -EINVAL; - if (WARN_ON(!mc_bus->irq_resources)) + if (!mc_bus->irq_resources) return -EINVAL; if (dev_get_msi_domain(&mc_dev->dev)) |