summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaiying Wang <Haiying.Wang@freescale.com>2013-05-29 16:29:00 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-07-12 20:24:10 (GMT)
commit0dae894a4a409c2a4f0f22f6565721ac5300a374 (patch)
tree2f867989c6df7b760286616c28bb02c8eda2b4d9
parent8424969f8e4b44b2810c1157a84de3594ba276ef (diff)
downloadlinux-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/Kconfig7
-rw-r--r--drivers/staging/fsl_qbman/Makefile1
-rw-r--r--drivers/staging/fsl_qbman/bman_driver.c11
-rw-r--r--drivers/staging/fsl_qbman/bman_private.h3
-rw-r--r--drivers/staging/fsl_qbman/qbman_driver.c75
-rw-r--r--drivers/staging/fsl_qbman/qman_driver.c11
-rw-r--r--drivers/staging/fsl_qbman/qman_private.h9
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;