diff options
author | Haiying Wang <Haiying.Wang@freescale.com> | 2013-05-29 16:29:00 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-07-12 20:24:10 (GMT) |
commit | 0dae894a4a409c2a4f0f22f6565721ac5300a374 (patch) | |
tree | 2f867989c6df7b760286616c28bb02c8eda2b4d9 | |
parent | 8424969f8e4b44b2810c1157a84de3594ba276ef (diff) | |
download | linux-fsl-qoriq-0dae894a4a409c2a4f0f22f6565721ac5300a374.tar.xz |
qbman: unify qman and bman init in a sysinit_call
and differ the initialization order for different partitions, e.g. the partition
without qman/bman devices will wait till qman/bman devices are initialized or
timeout setting expires.
Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
Signed-off-by: Geoff Thorpe <Geoff.Thorpe@freescale.com>
Change-Id: If4f1e213609d1a093c009330fbf206a5deb99c5a
Reviewed-on: http://git.am.freescale.net:8181/2818
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
-rw-r--r-- | drivers/staging/fsl_qbman/Kconfig | 7 | ||||
-rw-r--r-- | drivers/staging/fsl_qbman/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/fsl_qbman/bman_driver.c | 11 | ||||
-rw-r--r-- | drivers/staging/fsl_qbman/bman_private.h | 3 | ||||
-rw-r--r-- | drivers/staging/fsl_qbman/qbman_driver.c | 75 | ||||
-rw-r--r-- | drivers/staging/fsl_qbman/qman_driver.c | 11 | ||||
-rw-r--r-- | drivers/staging/fsl_qbman/qman_private.h | 9 |
7 files changed, 113 insertions, 4 deletions
diff --git a/drivers/staging/fsl_qbman/Kconfig b/drivers/staging/fsl_qbman/Kconfig index d5adc5a..dee570f 100644 --- a/drivers/staging/fsl_qbman/Kconfig +++ b/drivers/staging/fsl_qbman/Kconfig @@ -218,6 +218,13 @@ config QMAN_CEETM_UPDATE_PERIOD Unless you know what you are doing, leave this value at its default. +config FSL_QMAN_INIT_TIMEOUT + int "timeout for qman init stage, in seconds" + default 10 + ---help--- + The timeout setting to quit the initialization loop for non-control + partition in case the control partition fails to boot-up. + endif # FSL_QMAN endmenu diff --git a/drivers/staging/fsl_qbman/Makefile b/drivers/staging/fsl_qbman/Makefile index 2975e28..91b01a2 100644 --- a/drivers/staging/fsl_qbman/Makefile +++ b/drivers/staging/fsl_qbman/Makefile @@ -1,5 +1,6 @@ # Common obj-$(CONFIG_FSL_DPA) += dpa_alloc.o +obj-$(CONFIG_HAS_FSL_QBMAN) += qbman_driver.o # Bman obj-$(CONFIG_FSL_BMAN) += bman_high.o diff --git a/drivers/staging/fsl_qbman/bman_driver.c b/drivers/staging/fsl_qbman/bman_driver.c index 06b77ed..35e690b 100644 --- a/drivers/staging/fsl_qbman/bman_driver.c +++ b/drivers/staging/fsl_qbman/bman_driver.c @@ -297,7 +297,7 @@ __setup("bportals=", parse_bportals); * which are selected in a round-robin fashion. * Any portal configs left unused are available for USDPAA allocation. */ -static __init int bman_init(void) +__init int bman_init(void) { struct cpumask slave_cpus; struct cpumask unshared_cpus = *cpu_none_mask; @@ -404,6 +404,14 @@ static __init int bman_init(void) for_each_cpu(cpu, &slave_cpus) init_slave(cpu); pr_info("Bman portals initialised\n"); + return 0; +} + +__init int bman_resource_init(void) +{ + struct device_node *dn; + int ret; + /* Initialise BPID allocation ranges */ for_each_compatible_node(dn, NULL, "fsl,bpid-range") { ret = fsl_bpid_range_init(dn); @@ -412,4 +420,3 @@ static __init int bman_init(void) } return 0; } -subsys_initcall(bman_init); diff --git a/drivers/staging/fsl_qbman/bman_private.h b/drivers/staging/fsl_qbman/bman_private.h index e57ca68..9114308 100644 --- a/drivers/staging/fsl_qbman/bman_private.h +++ b/drivers/staging/fsl_qbman/bman_private.h @@ -151,4 +151,7 @@ int bm_pool_set(u32 bpid, const u32 *thresholds); /* Read the free buffer count for a given buffer */ u32 bm_pool_free_buffers(u32 bpid); +__init int bman_init(void); +__init int bman_resource_init(void); + #endif /* CONFIG_FSL_BMAN_CONFIG */ diff --git a/drivers/staging/fsl_qbman/qbman_driver.c b/drivers/staging/fsl_qbman/qbman_driver.c new file mode 100644 index 0000000..814db34 --- /dev/null +++ b/drivers/staging/fsl_qbman/qbman_driver.c @@ -0,0 +1,75 @@ +/* Copyright 2013 Freescale Semiconductor, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <linux/time.h> +#include "qman_private.h" +#include "bman_private.h" + +static __init int qbman_init(void) +{ + + bman_init(); + qman_init(); + if (!qman_have_ccsr()) { + struct qman_fq fq = { + .fqid = 1 + }; + struct qm_mcr_queryfq_np np; + int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT; + struct timespec nowts, diffts, startts = current_kernel_time(); + /* Loop while querying given fqid succeeds or time out */ + while (1) { + err = qman_query_fq_np(&fq, &np); + if (!err) { + /* success, control-plane has configured QMan */ + break; + } else if (err != -ERANGE) { + pr_err("QMan: I/O error, continuing anyway\n"); + break; + } + nowts = current_kernel_time(); + diffts = timespec_sub(nowts, startts); + if (diffts.tv_sec > 0) { + if (!retry--) { + pr_err("QMan: time out, control-plane" + " dead?\n"); + break; + } + pr_warn("QMan: polling for the control-plane" + " (%d)\n", retry); + } + } + } + bman_resource_init(); + qman_resource_init(); + return 0; +} +subsys_initcall(qbman_init); diff --git a/drivers/staging/fsl_qbman/qman_driver.c b/drivers/staging/fsl_qbman/qman_driver.c index 4c9f6c6..c40e24a 100644 --- a/drivers/staging/fsl_qbman/qman_driver.c +++ b/drivers/staging/fsl_qbman/qman_driver.c @@ -609,7 +609,7 @@ static int __init parse_qportals(char *str) } __setup("qportals=", parse_qportals); -static __init int qman_init(void) +__init int qman_init(void) { struct cpumask slave_cpus; struct cpumask unshared_cpus = *cpu_none_mask; @@ -732,6 +732,14 @@ static __init int qman_init(void) for_each_cpu(cpu, &slave_cpus) init_slave(cpu); pr_info("Qman portals initialised\n"); + return 0; +} + +__init int qman_resource_init(void) +{ + struct device_node *dn; + int ret; + /* Initialise FQID allocation ranges */ for_each_compatible_node(dn, NULL, "fsl,fqid-range") { ret = fsl_fqid_range_init(dn); @@ -762,4 +770,3 @@ static __init int qman_init(void) } return 0; } -subsys_initcall(qman_init); diff --git a/drivers/staging/fsl_qbman/qman_private.h b/drivers/staging/fsl_qbman/qman_private.h index b21efe6..6738b02 100644 --- a/drivers/staging/fsl_qbman/qman_private.h +++ b/drivers/staging/fsl_qbman/qman_private.h @@ -363,6 +363,15 @@ int qman_setup_fq_lookup_table(size_t num_entries); #define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1) #define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0) +#ifdef CONFIG_FSL_QMAN_CONFIG +int qman_have_ccsr(void); +#else +#define qman_have_ccsr 0 +#endif + +__init int qman_init(void); +__init int qman_resource_init(void); + /* CEETM related */ #define QMAN_CEETM_MAX 2 extern u8 num_ceetms; |