powerpc/qe: update QE Serial Number
authorHaiying Wang <Haiying.Wang@freescale.com>
Fri, 1 May 2009 19:40:48 +0000 (15:40 -0400)
committerKumar Gala <galak@kernel.crashing.org>
Tue, 19 May 2009 05:50:24 +0000 (00:50 -0500)
The latest QE chip may have more Serial Number(SNUM)s of thread to use. We
will get the number of SNUMs from device tree by reading the new property
"fsl,qe-num-snums", and set 28 as the default number of SNUMs so that it is
compatible with the old QE chips' device trees which don't have this new
property. The macro QE_NUM_OF_SNUM is defined as the maximum number in QE
snum table which is 256.

Also we update the snum_init[] array with 18 more new SNUMs which are
confirmed to be useful on new chip.

Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
Acked-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
arch/powerpc/include/asm/qe.h
arch/powerpc/sysdev/qe_lib/qe.c

index 39b5d1f0bbe040ace382a6040652556d03f3a784..6e37be1eeb2d2cc190780db3d01829acabbf950f 100644 (file)
@@ -18,6 +18,8 @@ Required properties:
 - reg : offset and length of the device registers.
 - bus-frequency : the clock frequency for QUICC Engine.
 - fsl,qe-num-riscs: define how many RISC engines the QE has.
+- fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the
+  threads.
 
 Recommended properties
 - brg-frequency : the internal clock source frequency for baud-rate
index 60314ef58d1159193b14d189e44194d9890f4879..e0faf332c9c95c71774a7aefdb92df6462feb6ff 100644 (file)
@@ -22,7 +22,7 @@
 #include <asm/cpm.h>
 #include <asm/immap_qe.h>
 
-#define QE_NUM_OF_SNUM 28
+#define QE_NUM_OF_SNUM 256     /* There are 256 serial number in QE */
 #define QE_NUM_OF_BRGS 16
 #define QE_NUM_OF_PORTS        1024
 
@@ -153,6 +153,7 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
 int qe_get_snum(void);
 void qe_put_snum(u8 snum);
 unsigned int qe_get_num_of_risc(void);
+unsigned int qe_get_num_of_snums(void);
 
 /* we actually use cpm_muram implementation, define this for convenience */
 #define qe_muram_init cpm_muram_init
index 2533677ae5ebcd9a387daf5adf4b01f31f021df2..b28b0e512d67d91a2c1fb108f94cc9eea90e4b03 100644 (file)
@@ -61,6 +61,7 @@ struct qe_immap __iomem *qe_immr;
 EXPORT_SYMBOL(qe_immr);
 
 static struct qe_snum snums[QE_NUM_OF_SNUM];   /* Dynamically allocated SNUMs */
+static unsigned int qe_num_of_snum;
 
 static phys_addr_t qebase = -1;
 
@@ -264,10 +265,14 @@ static void qe_snums_init(void)
                0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
                0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
                0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
-               0xD8, 0xD9, 0xE8, 0xE9,
+               0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
+               0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
+               0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
        };
 
-       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+       qe_num_of_snum = qe_get_num_of_snums();
+
+       for (i = 0; i < qe_num_of_snum; i++) {
                snums[i].num = snum_init[i];
                snums[i].state = QE_SNUM_STATE_FREE;
        }
@@ -280,7 +285,7 @@ int qe_get_snum(void)
        int i;
 
        spin_lock_irqsave(&qe_lock, flags);
-       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+       for (i = 0; i < qe_num_of_snum; i++) {
                if (snums[i].state == QE_SNUM_STATE_FREE) {
                        snums[i].state = QE_SNUM_STATE_USED;
                        snum = snums[i].num;
@@ -297,7 +302,7 @@ void qe_put_snum(u8 snum)
 {
        int i;
 
-       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+       for (i = 0; i < qe_num_of_snum; i++) {
                if (snums[i].num == snum) {
                        snums[i].state = QE_SNUM_STATE_FREE;
                        break;
@@ -603,3 +608,37 @@ unsigned int qe_get_num_of_risc(void)
 }
 EXPORT_SYMBOL(qe_get_num_of_risc);
 
+unsigned int qe_get_num_of_snums(void)
+{
+       struct device_node *qe;
+       int size;
+       unsigned int num_of_snums;
+       const u32 *prop;
+
+       num_of_snums = 28; /* The default number of snum for threads is 28 */
+       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+       if (!qe) {
+               /* Older devices trees did not have an "fsl,qe"
+                * compatible property, so we need to look for
+                * the QE node by name.
+                */
+               qe = of_find_node_by_type(NULL, "qe");
+               if (!qe)
+                       return num_of_snums;
+       }
+
+       prop = of_get_property(qe, "fsl,qe-num-snums", &size);
+       if (prop && size == sizeof(*prop)) {
+               num_of_snums = *prop;
+               if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
+                       /* No QE ever has fewer than 28 SNUMs */
+                       pr_err("QE: number of snum is invalid\n");
+                       return -EINVAL;
+               }
+       }
+
+       of_node_put(qe);
+
+       return num_of_snums;
+}
+EXPORT_SYMBOL(qe_get_num_of_snums);