Back to home page

OSCL-LXR

 
 

    


0001 /* Copyright 2017 NXP Semiconductor, Inc.
0002  *
0003  * Redistribution and use in source and binary forms, with or without
0004  * modification, are permitted provided that the following conditions are met:
0005  *     * Redistributions of source code must retain the above copyright
0006  *   notice, this list of conditions and the following disclaimer.
0007  *     * Redistributions in binary form must reproduce the above copyright
0008  *   notice, this list of conditions and the following disclaimer in the
0009  *   documentation and/or other materials provided with the distribution.
0010  *     * Neither the name of NXP Semiconductor nor the
0011  *   names of its contributors may be used to endorse or promote products
0012  *   derived from this software without specific prior written permission.
0013  *
0014  * ALTERNATIVELY, this software may be distributed under the terms of the
0015  * GNU General Public License ("GPL") as published by the Free Software
0016  * Foundation, either version 2 of that License or (at your option) any
0017  * later version.
0018  *
0019  * THIS SOFTWARE IS PROVIDED BY NXP Semiconductor ``AS IS'' AND ANY
0020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
0021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0022  * DISCLAIMED. IN NO EVENT SHALL NXP Semiconductor BE LIABLE FOR ANY
0023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029  */
0030 
0031 #include <linux/dma-mapping.h>
0032 #include "dpaa_sys.h"
0033 
0034 /*
0035  * Initialize a devices private memory region
0036  */
0037 int qbman_init_private_mem(struct device *dev, int idx, dma_addr_t *addr,
0038                 size_t *size)
0039 {
0040     struct device_node *mem_node;
0041     struct reserved_mem *rmem;
0042     struct property *prop;
0043     int len, err;
0044     __be32 *res_array;
0045 
0046     mem_node = of_parse_phandle(dev->of_node, "memory-region", idx);
0047     if (!mem_node) {
0048         dev_err(dev, "No memory-region found for index %d\n", idx);
0049         return -ENODEV;
0050     }
0051 
0052     rmem = of_reserved_mem_lookup(mem_node);
0053     if (!rmem) {
0054         dev_err(dev, "of_reserved_mem_lookup() returned NULL\n");
0055         return -ENODEV;
0056     }
0057     *addr = rmem->base;
0058     *size = rmem->size;
0059 
0060     /*
0061      * Check if the reg property exists - if not insert the node
0062      * so upon kexec() the same memory region address will be preserved.
0063      * This is needed because QBMan HW does not allow the base address/
0064      * size to be modified once set.
0065      */
0066     prop = of_find_property(mem_node, "reg", &len);
0067     if (!prop) {
0068         prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL);
0069         if (!prop)
0070             return -ENOMEM;
0071         prop->value = res_array = devm_kzalloc(dev, sizeof(__be32) * 4,
0072                                GFP_KERNEL);
0073         if (!prop->value)
0074             return -ENOMEM;
0075         res_array[0] = cpu_to_be32(upper_32_bits(*addr));
0076         res_array[1] = cpu_to_be32(lower_32_bits(*addr));
0077         res_array[2] = cpu_to_be32(upper_32_bits(*size));
0078         res_array[3] = cpu_to_be32(lower_32_bits(*size));
0079         prop->length = sizeof(__be32) * 4;
0080         prop->name = devm_kstrdup(dev, "reg", GFP_KERNEL);
0081         if (!prop->name)
0082             return -ENOMEM;
0083         err = of_add_property(mem_node, prop);
0084         if (err)
0085             return err;
0086     }
0087 
0088     return 0;
0089 }