From 9b894c91a95b13b51846f83ee4fa4b086a874c72 Mon Sep 17 00:00:00 2001 From: Florian Larysch Date: Thu, 17 Nov 2016 11:23:24 +0100 Subject: DT: i2c: W83793 is a trivial device Signed-off-by: Florian Larysch Acked-by: Rob Herring Signed-off-by: Scott Wood --- Documentation/devicetree/bindings/i2c/trivial-devices.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index fbbad6446741..c65aff0edf56 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -158,4 +158,5 @@ ti,tsc2003 I2C Touch-Screen Controller ti,tmp102 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface ti,tmp103 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface ti,tmp275 Digital Temperature Sensor +winbond,w83793 Winbond/Nuvoton H/W Monitor winbond,wpct301 i2c trusted platform module (TPM) -- cgit v1.2.3 From 8ba1baabde85bfc27ab486422dc8fca3092bb9df Mon Sep 17 00:00:00 2001 From: Florian Larysch Date: Thu, 17 Nov 2016 11:23:23 +0100 Subject: powerpc/dts: add device tree entry for W83793 on T4240RDB The T4240RDB contains a W83793 hardware monitoring chip. Add a device tree entry to make the driver attach to it, as the i2c-mpc bus driver dropped support for class-based instantiation of devices a long time ago. Signed-off-by: Florian Larysch Signed-off-by: Scott Wood --- arch/powerpc/boot/dts/fsl/t4240rdb.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/powerpc/boot/dts/fsl/t4240rdb.dts b/arch/powerpc/boot/dts/fsl/t4240rdb.dts index cc0a264b8acb..8166c660712a 100644 --- a/arch/powerpc/boot/dts/fsl/t4240rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t4240rdb.dts @@ -125,6 +125,10 @@ }; i2c@118000 { + hwmon@2f { + compatible = "winbond,w83793"; + reg = <0x2f>; + }; eeprom@52 { compatible = "at24,24c256"; reg = <0x52>; -- cgit v1.2.3 From 57907a73e0ff7ccd561d0202acaabe5537ed359e Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 12 Nov 2016 17:01:30 +0000 Subject: soc/fsl: fix spelling mistakes in critical error messages Trivial fix to spelling mistake "uncommited" to "uncommitted" in critical error messages. Signed-off-by: Colin Ian King Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/bman.c | 2 +- drivers/soc/fsl/qbman/qman.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/fsl/qbman/bman.c b/drivers/soc/fsl/qbman/bman.c index ffa48fdbb1a9..48b7eb698689 100644 --- a/drivers/soc/fsl/qbman/bman.c +++ b/drivers/soc/fsl/qbman/bman.c @@ -391,7 +391,7 @@ static void bm_rcr_finish(struct bm_portal *portal) i = bm_in(portal, BM_REG_RCR_PI_CINH) & (BM_RCR_SIZE - 1); if (i != rcr_ptr2idx(rcr->cursor)) - pr_crit("losing uncommited RCR entries\n"); + pr_crit("losing uncommitted RCR entries\n"); i = bm_in(portal, BM_REG_RCR_CI_CINH) & (BM_RCR_SIZE - 1); if (i != rcr->ci) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 119054bc922b..deeacd5d123e 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -443,7 +443,7 @@ static inline void qm_eqcr_finish(struct qm_portal *portal) DPAA_ASSERT(!eqcr->busy); if (pi != eqcr_ptr2idx(eqcr->cursor)) - pr_crit("losing uncommited EQCR entries\n"); + pr_crit("losing uncommitted EQCR entries\n"); if (ci != eqcr->ci) pr_crit("missing existing EQCR completions\n"); if (eqcr->ci != eqcr_ptr2idx(eqcr->cursor)) -- cgit v1.2.3 From 00b6cfc4c4ee32c6031d1645548f1bf4e6104c45 Mon Sep 17 00:00:00 2001 From: David Engraf Date: Tue, 15 Nov 2016 09:24:27 +0100 Subject: powerpc/85xx/qemu: Enable CONFIG_E500 and CONFIG_PPC_E500MC The QEMU e500 board needs to enable CONFIG_E500 to correctly boot. QEMU for ppc64 uses e5500/e6500 emulation, thus CONFIG_PPC_E500MC is required as well. Signed-off-by: David Engraf Signed-off-by: Scott Wood --- arch/powerpc/platforms/85xx/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 9dc1d28975b9..47b389dc4938 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -253,6 +253,8 @@ endif # PPC32 config PPC_QEMU_E500 bool "QEMU generic e500 platform" select DEFAULT_UIMAGE + select E500 + select PPC_E500MC if PPC64 help This option enables support for running as a QEMU guest using QEMU's generic e500 machine. This is not required if you're -- cgit v1.2.3 From 5bda6c0eb7cddc9e109c9f79d500288af0704e7a Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 29 Oct 2016 16:27:14 +0200 Subject: powerpc/fsl_soc: improve and simplify fsl_get_sys_freq Use of_property_read_u32 instead of the generic of_get_property to simplify the code. In addition move the declaration of sysfreq into fsl_get_sys_freq because it's private to this function. Signed-off-by: Heiner Kallweit Signed-off-by: Scott Wood --- arch/powerpc/sysdev/fsl_soc.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index d93056eedcb0..48fc36b3851f 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -77,13 +77,10 @@ phys_addr_t get_immrbase(void) EXPORT_SYMBOL(get_immrbase); -static u32 sysfreq = -1; - u32 fsl_get_sys_freq(void) { + static u32 sysfreq = -1; struct device_node *soc; - const u32 *prop; - int size; if (sysfreq != -1) return sysfreq; @@ -92,12 +89,9 @@ u32 fsl_get_sys_freq(void) if (!soc) return -1; - prop = of_get_property(soc, "clock-frequency", &size); - if (!prop || size != sizeof(*prop) || *prop == 0) - prop = of_get_property(soc, "bus-frequency", &size); - - if (prop && size == sizeof(*prop)) - sysfreq = *prop; + of_property_read_u32(soc, "clock-frequency", &sysfreq); + if (sysfreq == -1 || !sysfreq) + of_property_read_u32(soc, "bus-frequency", &sysfreq); of_node_put(soc); return sysfreq; -- cgit v1.2.3 From 47a48a92102b7e5a33356f87ca1b4873d2fce2f1 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 29 Oct 2016 16:28:25 +0200 Subject: powerpc/fsl_soc: improve and simplify get_brgfreq Use of_property_read_u32 instead of the generic of_get_property to simplify the code. In addition move the declaration of brgfreq into get_brgfreq because it's private to this function. Signed-off-by: Heiner Kallweit [scottwood: minor whitespace fixes] Signed-off-by: Scott Wood --- arch/powerpc/sysdev/fsl_soc.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 48fc36b3851f..ebccf0bad4a1 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -100,23 +100,17 @@ EXPORT_SYMBOL(fsl_get_sys_freq); #if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx) -static u32 brgfreq = -1; - u32 get_brgfreq(void) { + static u32 brgfreq = -1; struct device_node *node; - const unsigned int *prop; - int size; if (brgfreq != -1) return brgfreq; node = of_find_compatible_node(NULL, NULL, "fsl,cpm-brg"); if (node) { - prop = of_get_property(node, "clock-frequency", &size); - if (prop && size == 4) - brgfreq = *prop; - + of_property_read_u32(node, "clock-frequency", &brgfreq); of_node_put(node); return brgfreq; } @@ -129,15 +123,11 @@ u32 get_brgfreq(void) node = of_find_node_by_type(NULL, "qe"); if (node) { - prop = of_get_property(node, "brg-frequency", &size); - if (prop && size == 4) - brgfreq = *prop; - - if (brgfreq == -1 || brgfreq == 0) { - prop = of_get_property(node, "bus-frequency", &size); - if (prop && size == 4) - brgfreq = *prop / 2; - } + of_property_read_u32(node, "brg-frequency", &brgfreq); + if (brgfreq == -1 || !brgfreq) + if (!of_property_read_u32(node, "bus-frequency", + &brgfreq)) + brgfreq /= 2; of_node_put(node); } -- cgit v1.2.3 From 0f236988e9ec13d0ee49f580f945d594bd7989a7 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 29 Oct 2016 16:29:04 +0200 Subject: powerpc/fsl_soc: improve and simplify get_baudrate Use of_property_read_u32 instead of the generic of_get_property to simplify the code. In addition move the declaration of fs_baudrate into get_baudrate because it's private to this function. Signed-off-by: Heiner Kallweit Signed-off-by: Scott Wood --- arch/powerpc/sysdev/fsl_soc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index ebccf0bad4a1..19101f9cfcfc 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -136,10 +136,9 @@ u32 get_brgfreq(void) EXPORT_SYMBOL(get_brgfreq); -static u32 fs_baudrate = -1; - u32 get_baudrate(void) { + static u32 fs_baudrate = -1; struct device_node *node; if (fs_baudrate != -1) @@ -147,12 +146,7 @@ u32 get_baudrate(void) node = of_find_node_by_type(NULL, "serial"); if (node) { - int size; - const unsigned int *prop = of_get_property(node, - "current-speed", &size); - - if (prop) - fs_baudrate = *prop; + of_property_read_u32(node, "current-speed", &fs_baudrate); of_node_put(node); } -- cgit v1.2.3 From ee3dd586f163413548de0f0021ef1ff6ca0354d4 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Sun, 23 Oct 2016 18:48:38 -0500 Subject: powerpc/85xx: Enable gpio power/reset driver These config changes build: drivers/power/reset/gpio-poweroff.c drivers/power/reset/gpio-restart.c Signed-off-by: Andy Fleming Signed-off-by: Scott Wood --- arch/powerpc/configs/fsl-emb-nonhw.config | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/configs/fsl-emb-nonhw.config b/arch/powerpc/configs/fsl-emb-nonhw.config index 1a61e81ab0cd..cc49c95494da 100644 --- a/arch/powerpc/configs/fsl-emb-nonhw.config +++ b/arch/powerpc/configs/fsl-emb-nonhw.config @@ -44,6 +44,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAME_WARN=1024 CONFIG_FTL=y +CONFIG_GPIO_GENERIC_PLATFORM=y CONFIG_HFS_FS=m CONFIG_HFSPLUS_FS=m CONFIG_HIGH_RES_TIMERS=y @@ -104,8 +105,13 @@ CONFIG_PACKET=y CONFIG_PARTITION_ADVANCED=y CONFIG_PERF_EVENTS=y CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y CONFIG_QNX4FS_FS=m CONFIG_RCU_TRACE=y +CONFIG_RESET_CONTROLLER=y CONFIG_ROOT_NFS=y CONFIG_SYSV_FS=m CONFIG_SYSVIPC=y -- cgit v1.2.3 From 02b7d2a833b007bae45be8d4adbae0f2a43d8dc4 Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Wed, 16 Nov 2016 16:40:14 +0200 Subject: soc/qman: Check ioremap return value Signed-off-by: Madalin Bucur Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman_ccsr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/soc/fsl/qbman/qman_ccsr.c b/drivers/soc/fsl/qbman/qman_ccsr.c index 0cace9e0077e..f4e6e70de259 100644 --- a/drivers/soc/fsl/qbman/qman_ccsr.c +++ b/drivers/soc/fsl/qbman/qman_ccsr.c @@ -444,6 +444,9 @@ static int zero_priv_mem(struct device *dev, struct device_node *node, /* map as cacheable, non-guarded */ void __iomem *tmpp = ioremap_prot(addr, sz, 0); + if (!tmpp) + return -ENOMEM; + memset_io(tmpp, 0, sz); flush_dcache_range((unsigned long)tmpp, (unsigned long)tmpp + sz); -- cgit v1.2.3 From 2f28d218d4b82e0eb5c437f25004a4d36e32ab35 Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Wed, 16 Nov 2016 16:40:15 +0200 Subject: soc/qman: Replace of_get_property() with portable equivalent Use arch portable of_property_read_u32() instead, which takes care of endianness conversions. Signed-off-by: Madalin Bucur Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/dpaa_sys.h | 1 + drivers/soc/fsl/qbman/qman_portal.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/soc/fsl/qbman/dpaa_sys.h b/drivers/soc/fsl/qbman/dpaa_sys.h index b63fd72295c6..2eaf3184f61d 100644 --- a/drivers/soc/fsl/qbman/dpaa_sys.h +++ b/drivers/soc/fsl/qbman/dpaa_sys.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/soc/fsl/qbman/qman_portal.c b/drivers/soc/fsl/qbman/qman_portal.c index 148614388fca..0c3e8adae647 100644 --- a/drivers/soc/fsl/qbman/qman_portal.c +++ b/drivers/soc/fsl/qbman/qman_portal.c @@ -238,9 +238,9 @@ static int qman_portal_probe(struct platform_device *pdev) struct device_node *node = dev->of_node; struct qm_portal_config *pcfg; struct resource *addr_phys[2]; - const u32 *channel; void __iomem *va; - int irq, len, cpu; + int irq, cpu, err; + u32 val; pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL); if (!pcfg) @@ -264,13 +264,13 @@ static int qman_portal_probe(struct platform_device *pdev) return -ENXIO; } - channel = of_get_property(node, "cell-index", &len); - if (!channel || (len != 4)) { + err = of_property_read_u32(node, "cell-index", &val); + if (err) { dev_err(dev, "Can't get %s property 'cell-index'\n", node->full_name); - return -ENXIO; + return err; } - pcfg->channel = *channel; + pcfg->channel = val; pcfg->cpu = -1; irq = platform_get_irq(pdev, 0); if (irq <= 0) { -- cgit v1.2.3 From d95cb0d361d509bda3c351c5933904477b103af0 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:16 +0200 Subject: soc/qman: Fix h/w resource cleanup error path handling qman_query_fq*() may return other error codes apart from -ERANGE, in which cases the error handling done by the resource cleanup callers would be wrong. The patch fixes the handling of those cases, and cleans up related code inside the resource cleanup & release handlers (i.e. replace hardcoded fqid value with corresponding define). Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index deeacd5d123e..e350ed6450ae 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -2789,15 +2789,18 @@ static int qpool_cleanup(u32 qp) struct qm_mcr_queryfq_np np; err = qman_query_fq_np(&fq, &np); - if (err) + if (err == -ERANGE) /* FQID range exceeded, found no problems */ return 0; + else if (WARN_ON(err)) + return err; + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) { struct qm_fqd fqd; err = qman_query_fq(&fq, &fqd); if (WARN_ON(err)) - return 0; + return err; if (qm_fqd_get_chan(&fqd) == qp) { /* The channel is the FQ's target, clean it */ err = qman_shutdown_fq(fq.fqid); @@ -2836,7 +2839,7 @@ static int cgr_cleanup(u32 cgrid) * error, looking for non-OOS FQDs whose CGR is the CGR being released */ struct qman_fq fq = { - .fqid = 1 + .fqid = QM_FQID_RANGE_START }; int err; @@ -2844,15 +2847,18 @@ static int cgr_cleanup(u32 cgrid) struct qm_mcr_queryfq_np np; err = qman_query_fq_np(&fq, &np); - if (err) + if (err == -ERANGE) /* FQID range exceeded, found no problems */ return 0; + else if (WARN_ON(err)) + return err; + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) { struct qm_fqd fqd; err = qman_query_fq(&fq, &fqd); if (WARN_ON(err)) - return 0; + return err; if ((fqd.fq_ctrl & QM_FQCTRL_CGE) && fqd.cgid == cgrid) { pr_err("CRGID 0x%x is being used by FQID 0x%x, CGR will be leaked\n", -- cgit v1.2.3 From 333e72cf475065a42b7bf33d76214eca45b9acbb Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:17 +0200 Subject: soc/qbman: Fix resource leak on portal probing error path In case init_pcfg() returns with error the CI region must be unmapped too. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/bman_portal.c | 17 ++++++++++++----- drivers/soc/fsl/qbman/qman_portal.c | 17 ++++++++++++----- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/drivers/soc/fsl/qbman/bman_portal.c b/drivers/soc/fsl/qbman/bman_portal.c index 6579cc18811a..dd3f5d7617d2 100644 --- a/drivers/soc/fsl/qbman/bman_portal.c +++ b/drivers/soc/fsl/qbman/bman_portal.c @@ -146,15 +146,19 @@ static int bman_portal_probe(struct platform_device *pdev) pcfg->irq = irq; va = ioremap_prot(addr_phys[0]->start, resource_size(addr_phys[0]), 0); - if (!va) + if (!va) { + dev_err(dev, "ioremap::CE failed\n"); goto err_ioremap1; + } pcfg->addr_virt[DPAA_PORTAL_CE] = va; va = ioremap_prot(addr_phys[1]->start, resource_size(addr_phys[1]), _PAGE_GUARDED | _PAGE_NO_CACHE); - if (!va) + if (!va) { + dev_err(dev, "ioremap::CI failed\n"); goto err_ioremap2; + } pcfg->addr_virt[DPAA_PORTAL_CI] = va; @@ -170,8 +174,10 @@ static int bman_portal_probe(struct platform_device *pdev) spin_unlock(&bman_lock); pcfg->cpu = cpu; - if (!init_pcfg(pcfg)) - goto err_ioremap2; + if (!init_pcfg(pcfg)) { + dev_err(dev, "portal init failed\n"); + goto err_portal_init; + } /* clear irq affinity if assigned cpu is offline */ if (!cpu_online(cpu)) @@ -179,10 +185,11 @@ static int bman_portal_probe(struct platform_device *pdev) return 0; +err_portal_init: + iounmap(pcfg->addr_virt[DPAA_PORTAL_CI]); err_ioremap2: iounmap(pcfg->addr_virt[DPAA_PORTAL_CE]); err_ioremap1: - dev_err(dev, "ioremap failed\n"); return -ENXIO; } diff --git a/drivers/soc/fsl/qbman/qman_portal.c b/drivers/soc/fsl/qbman/qman_portal.c index 0c3e8adae647..6651168333e1 100644 --- a/drivers/soc/fsl/qbman/qman_portal.c +++ b/drivers/soc/fsl/qbman/qman_portal.c @@ -280,15 +280,19 @@ static int qman_portal_probe(struct platform_device *pdev) pcfg->irq = irq; va = ioremap_prot(addr_phys[0]->start, resource_size(addr_phys[0]), 0); - if (!va) + if (!va) { + dev_err(dev, "ioremap::CE failed\n"); goto err_ioremap1; + } pcfg->addr_virt[DPAA_PORTAL_CE] = va; va = ioremap_prot(addr_phys[1]->start, resource_size(addr_phys[1]), _PAGE_GUARDED | _PAGE_NO_CACHE); - if (!va) + if (!va) { + dev_err(dev, "ioremap::CI failed\n"); goto err_ioremap2; + } pcfg->addr_virt[DPAA_PORTAL_CI] = va; @@ -306,8 +310,10 @@ static int qman_portal_probe(struct platform_device *pdev) spin_unlock(&qman_lock); pcfg->cpu = cpu; - if (!init_pcfg(pcfg)) - goto err_ioremap2; + if (!init_pcfg(pcfg)) { + dev_err(dev, "portal init failed\n"); + goto err_portal_init; + } /* clear irq affinity if assigned cpu is offline */ if (!cpu_online(cpu)) @@ -315,10 +321,11 @@ static int qman_portal_probe(struct platform_device *pdev) return 0; +err_portal_init: + iounmap(pcfg->addr_virt[DPAA_PORTAL_CI]); err_ioremap2: iounmap(pcfg->addr_virt[DPAA_PORTAL_CE]); err_ioremap1: - dev_err(dev, "ioremap failed\n"); return -ENXIO; } -- cgit v1.2.3 From 9f3670e8f6df6557fefe3ae0e626189c8c30c74c Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:18 +0200 Subject: soc/qman: Fix struct qm_fqd set accessor for context_a context_a.hi is 32bit Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- include/soc/fsl/qman.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h index 37f3eb001a16..1405810e4050 100644 --- a/include/soc/fsl/qman.h +++ b/include/soc/fsl/qman.h @@ -411,7 +411,7 @@ static inline void qm_fqd_stashing_set64(struct qm_fqd *fqd, u64 addr) static inline void qm_fqd_context_a_set64(struct qm_fqd *fqd, u64 addr) { - fqd->context_a.hi = cpu_to_be16(upper_32_bits(addr)); + fqd->context_a.hi = cpu_to_be32(upper_32_bits(addr)); fqd->context_a.lo = cpu_to_be32(lower_32_bits(addr)); } -- cgit v1.2.3 From b6e969dbaec0fe6633a756468e74151ebb1e6c49 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:19 +0200 Subject: soc/qman: Fix direct access to fd's addr_lo, use proper accesor Use the proper accessor to get the FD address. Accessing the internal field "addr_lo" directly is not portable and error prone. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index e350ed6450ae..96b0f004e007 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -1239,8 +1239,8 @@ static int qman_create_portal(struct qman_portal *portal, /* special handling, drain just in case it's a few FQRNIs */ const union qm_mr_entry *e = qm_mr_current(p); - dev_err(c->dev, "MR dirty, VB 0x%x, rc 0x%x\n, addr 0x%x", - e->verb, e->ern.rc, e->ern.fd.addr_lo); + dev_err(c->dev, "MR dirty, VB 0x%x, rc 0x%x, addr 0x%llx\n", + e->verb, e->ern.rc, qm_fd_addr_get64(&e->ern.fd)); goto fail_dqrr_mr_empty; } /* Success */ -- cgit v1.2.3 From 57e68a5e23570ff3ab76772a974724c226fcee7d Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:20 +0200 Subject: soc/qman: test: Fix implementation of fd_cmp() This function must only return the truth value of whether two frame descriptors are different or not. It does NOT have to compute some obscure difference between fd fields and return it as an int, making sparse complain about type conversions in the process. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman_test_api.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman_test_api.c b/drivers/soc/fsl/qbman/qman_test_api.c index 6880ff17f45e..dba6a80622ed 100644 --- a/drivers/soc/fsl/qbman/qman_test_api.c +++ b/drivers/soc/fsl/qbman/qman_test_api.c @@ -90,22 +90,15 @@ static void fd_inc(struct qm_fd *fd) } /* The only part of the 'fd' we can't memcmp() is the ppid */ -static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b) +static bool fd_neq(const struct qm_fd *a, const struct qm_fd *b) { - int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1; + bool neq = qm_fd_addr_get64(a) != qm_fd_addr_get64(b); - if (!r) { - enum qm_fd_format fmt_a, fmt_b; + neq |= qm_fd_get_format(a) != qm_fd_get_format(b); + neq |= a->cfg != b->cfg; + neq |= a->cmd != b->cmd; - fmt_a = qm_fd_get_format(a); - fmt_b = qm_fd_get_format(b); - r = fmt_a - fmt_b; - } - if (!r) - r = a->cfg - b->cfg; - if (!r) - r = a->cmd - b->cmd; - return r; + return neq; } /* test */ @@ -217,12 +210,12 @@ static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p, struct qman_fq *fq, const struct qm_dqrr_entry *dq) { - if (WARN_ON(fd_cmp(&fd_dq, &dq->fd))) { + if (WARN_ON(fd_neq(&fd_dq, &dq->fd))) { pr_err("BADNESS: dequeued frame doesn't match;\n"); return qman_cb_dqrr_consume; } fd_inc(&fd_dq); - if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) { + if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_neq(&fd_dq, &fd)) { sdqcr_complete = 1; wake_up(&waitqueue); } -- cgit v1.2.3 From 0fbeac3b0f67a50d45e8a7d72ee3e0301ac7e9a9 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:21 +0200 Subject: soc/qman: Don't add a new platform device for dma mapping The qman portals are platform devices themselves, so they should handle dma mappings. Creating a dummy platform device in order to support dma mapping operations is not justified (and not portable). Instead, do the mapping against the first portal that has been initialised. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 31 ++++++++++--------------------- drivers/soc/fsl/qbman/qman_portal.c | 11 +++++++++++ drivers/soc/fsl/qbman/qman_priv.h | 1 + 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 96b0f004e007..4ceb9a1da7ee 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -962,8 +962,6 @@ struct qman_portal { u32 sdqcr; /* probing time config params for cpu-affine portals */ const struct qm_portal_config *config; - /* needed for providing a non-NULL device to dma_map_***() */ - struct platform_device *pdev; /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */ struct qman_cgrs *cgrs; /* linked-list of CSCN handlers. */ @@ -1133,7 +1131,6 @@ static int qman_create_portal(struct qman_portal *portal, const struct qman_cgrs *cgrs) { struct qm_portal *p; - char buf[16]; int ret; u32 isdr; @@ -1196,15 +1193,6 @@ static int qman_create_portal(struct qman_portal *portal, portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 | QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS | QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED; - sprintf(buf, "qportal-%d", c->channel); - portal->pdev = platform_device_alloc(buf, -1); - if (!portal->pdev) - goto fail_devalloc; - if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) - goto fail_devadd; - ret = platform_device_add(portal->pdev); - if (ret) - goto fail_devadd; isdr = 0xffffffff; qm_out(p, QM_REG_ISDR, isdr); portal->irq_sources = 0; @@ -1256,10 +1244,6 @@ fail_eqcr_empty: fail_affinity: free_irq(c->irq, portal); fail_irq: - platform_device_del(portal->pdev); -fail_devadd: - platform_device_put(portal->pdev); -fail_devalloc: kfree(portal->cgrs); fail_cgrs: qm_mc_finish(p); @@ -1321,9 +1305,6 @@ static void qman_destroy_portal(struct qman_portal *qm) qm_dqrr_finish(&qm->p); qm_eqcr_finish(&qm->p); - platform_device_del(qm->pdev); - platform_device_put(qm->pdev); - qm->config = NULL; } @@ -1817,8 +1798,16 @@ int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts) memset(&mcc->initfq.fqd.context_a, 0, sizeof(mcc->initfq.fqd.context_a)); } else { - phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq), - DMA_TO_DEVICE); + struct qman_portal *p = qman_dma_portal; + + phys_fq = dma_map_single(p->config->dev, fq, + sizeof(*fq), DMA_TO_DEVICE); + if (dma_mapping_error(p->config->dev, phys_fq)) { + dev_err(p->config->dev, "dma_mapping failed\n"); + ret = -EIO; + goto out; + } + qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq); } } diff --git a/drivers/soc/fsl/qbman/qman_portal.c b/drivers/soc/fsl/qbman/qman_portal.c index 6651168333e1..e6da2ea78554 100644 --- a/drivers/soc/fsl/qbman/qman_portal.c +++ b/drivers/soc/fsl/qbman/qman_portal.c @@ -30,6 +30,8 @@ #include "qman_priv.h" +struct qman_portal *qman_dma_portal; + /* Enable portal interupts (as opposed to polling mode) */ #define CONFIG_FSL_DPA_PIRQ_SLOW 1 #define CONFIG_FSL_DPA_PIRQ_FAST 1 @@ -150,6 +152,10 @@ static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg) /* all assigned portals are initialized now */ qman_init_cgr_all(); } + + if (!qman_dma_portal) + qman_dma_portal = p; + spin_unlock(&qman_lock); dev_info(pcfg->dev, "Portal initialised, cpu %d\n", pcfg->cpu); @@ -310,6 +316,11 @@ static int qman_portal_probe(struct platform_device *pdev) spin_unlock(&qman_lock); pcfg->cpu = cpu; + if (dma_set_mask(dev, DMA_BIT_MASK(40))) { + dev_err(dev, "dma_set_mask() failed\n"); + goto err_portal_init; + } + if (!init_pcfg(pcfg)) { dev_err(dev, "portal init failed\n"); goto err_portal_init; diff --git a/drivers/soc/fsl/qbman/qman_priv.h b/drivers/soc/fsl/qbman/qman_priv.h index 5cf821e623a9..59b4b463d884 100644 --- a/drivers/soc/fsl/qbman/qman_priv.h +++ b/drivers/soc/fsl/qbman/qman_priv.h @@ -367,5 +367,6 @@ int qman_alloc_fq_table(u32 num_fqids); #define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI) extern struct qman_portal *affine_portals[NR_CPUS]; +extern struct qman_portal *qman_dma_portal; const struct qm_portal_config *qman_get_qm_portal_config( struct qman_portal *portal); -- cgit v1.2.3 From 021ba010663146305b0ba51246a41223d38943af Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:22 +0200 Subject: soc/qman: test: Don't use dummy platform device for dma mapping Replace dummy platform device hack with a reference to a portal's platform device, in order to dma map the test frame for this small unit test. The 2 qman symbols need to be exported because this self test is a kernel module. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 1 + drivers/soc/fsl/qbman/qman_portal.c | 1 + drivers/soc/fsl/qbman/qman_test_stash.c | 31 ++++++++++++++++++++----------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 4ceb9a1da7ee..307c818e14ab 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -2711,6 +2711,7 @@ const struct qm_portal_config *qman_get_qm_portal_config( { return portal->config; } +EXPORT_SYMBOL(qman_get_qm_portal_config); struct gen_pool *qm_fqalloc; /* FQID allocator */ struct gen_pool *qm_qpalloc; /* pool-channel allocator */ diff --git a/drivers/soc/fsl/qbman/qman_portal.c b/drivers/soc/fsl/qbman/qman_portal.c index e6da2ea78554..c9a9bcb1aea2 100644 --- a/drivers/soc/fsl/qbman/qman_portal.c +++ b/drivers/soc/fsl/qbman/qman_portal.c @@ -31,6 +31,7 @@ #include "qman_priv.h" struct qman_portal *qman_dma_portal; +EXPORT_SYMBOL(qman_dma_portal); /* Enable portal interupts (as opposed to polling mode) */ #define CONFIG_FSL_DPA_PIRQ_SLOW 1 diff --git a/drivers/soc/fsl/qbman/qman_test_stash.c b/drivers/soc/fsl/qbman/qman_test_stash.c index 43cf66ba42f5..f8d25faf4d8a 100644 --- a/drivers/soc/fsl/qbman/qman_test_stash.c +++ b/drivers/soc/fsl/qbman/qman_test_stash.c @@ -191,6 +191,9 @@ static void *__frame_ptr; static u32 *frame_ptr; static dma_addr_t frame_dma; +/* needed for dma_map*() */ +static const struct qm_portal_config *pcfg; + /* the main function waits on this */ static DECLARE_WAIT_QUEUE_HEAD(queue); @@ -210,16 +213,14 @@ static int allocate_frame_data(void) { u32 lfsr = HP_FIRST_WORD; int loop; - struct platform_device *pdev = platform_device_alloc("foobar", -1); - if (!pdev) { - pr_crit("platform_device_alloc() failed"); - return -EIO; - } - if (platform_device_add(pdev)) { - pr_crit("platform_device_add() failed"); + if (!qman_dma_portal) { + pr_crit("portal not available\n"); return -EIO; } + + pcfg = qman_get_qm_portal_config(qman_dma_portal); + __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL); if (!__frame_ptr) return -ENOMEM; @@ -229,15 +230,22 @@ static int allocate_frame_data(void) frame_ptr[loop] = lfsr; lfsr = do_lfsr(lfsr); } - frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS, + + frame_dma = dma_map_single(pcfg->dev, frame_ptr, 4 * HP_NUM_WORDS, DMA_BIDIRECTIONAL); - platform_device_del(pdev); - platform_device_put(pdev); + if (dma_mapping_error(pcfg->dev, frame_dma)) { + pr_crit("dma mapping failure\n"); + kfree(__frame_ptr); + return -EIO; + } + return 0; } static void deallocate_frame_data(void) { + dma_unmap_single(pcfg->dev, frame_dma, 4 * HP_NUM_WORDS, + DMA_BIDIRECTIONAL); kfree(__frame_ptr); } @@ -249,7 +257,8 @@ static inline int process_frame_data(struct hp_handler *handler, int loop; if (qm_fd_addr_get64(fd) != handler->addr) { - pr_crit("bad frame address"); + pr_crit("bad frame address, [%llX != %llX]\n", + qm_fd_addr_get64(fd), handler->addr); return -EIO; } for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) { -- cgit v1.2.3 From e5caf693ac6ac498ef05c7c1947024d5b678626f Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:23 +0200 Subject: soc/qman: Remove redundant checks from qman_create_cgr() opts is checked redundantly. Move local_opts declaration inside its usage scope. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 307c818e14ab..4a1697eefcdf 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -2294,7 +2294,6 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags, struct qm_mcc_initcgr *opts) { struct qm_mcr_querycgr cgr_state; - struct qm_mcc_initcgr local_opts = {}; int ret; struct qman_portal *p; @@ -2316,11 +2315,12 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags, spin_lock(&p->cgr_lock); if (opts) { + struct qm_mcc_initcgr local_opts = *opts; + ret = qman_query_cgr(cgr, &cgr_state); if (ret) goto out; - if (opts) - local_opts = *opts; + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) local_opts.cgr.cscn_targ_upd_ctrl = QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p); @@ -2331,7 +2331,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags, local_opts.we_mask |= QM_CGR_WE_CSCN_TARG; /* send init if flags indicate so */ - if (opts && (flags & QMAN_CGR_FLAG_USE_INIT)) + if (flags & QMAN_CGR_FLAG_USE_INIT) ret = qm_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts); else -- cgit v1.2.3 From 7ff07da015c290cd2b0627c53267fbc1336cf055 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:24 +0200 Subject: soc/qman: Remove unused struct qm_mcc* layouts 1. qm_mcc_querywq layout not used for now, so drop it; 2. queryfq, queryfq_np and alterfq are used only for accesses to the 'fqid' field, so replace these with a generic 'fq' layout. As a consequence, 'querycgr' turns into 'cgr' following the same reasoning above and for consistent naming. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 58 ++++++++++++--------------------------- drivers/soc/fsl/qbman/qman_priv.h | 6 ---- 2 files changed, 18 insertions(+), 46 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 4a1697eefcdf..0d2e3bcaaf9e 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -183,41 +183,22 @@ struct qm_mr { }; /* MC (Management Command) command */ -/* "Query FQ" */ -struct qm_mcc_queryfq { +/* "FQ" command layout */ +struct qm_mcc_fq { u8 _ncw_verb; u8 __reserved1[3]; u32 fqid; /* 24-bit */ u8 __reserved2[56]; } __packed; -/* "Alter FQ State Commands " */ -struct qm_mcc_alterfq { - u8 _ncw_verb; - u8 __reserved1[3]; - u32 fqid; /* 24-bit */ - u8 __reserved2; - u8 count; /* number of consecutive FQID */ - u8 __reserved3[10]; - u32 context_b; /* frame queue context b */ - u8 __reserved4[40]; -} __packed; -/* "Query CGR" */ -struct qm_mcc_querycgr { +/* "CGR" command layout */ +struct qm_mcc_cgr { u8 _ncw_verb; u8 __reserved1[30]; u8 cgid; u8 __reserved2[32]; }; -struct qm_mcc_querywq { - u8 _ncw_verb; - u8 __reserved; - /* select channel if verb != QUERYWQ_DEDICATED */ - u16 channel_wq; /* ignores wq (3 lsbits): _res[0-2] */ - u8 __reserved2[60]; -} __packed; - #define QM_MCC_VERB_VBIT 0x80 #define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */ #define QM_MCC_VERB_INITFQ_PARKED 0x40 @@ -243,12 +224,9 @@ union qm_mc_command { u8 __reserved[63]; }; struct qm_mcc_initfq initfq; - struct qm_mcc_queryfq queryfq; - struct qm_mcc_alterfq alterfq; struct qm_mcc_initcgr initcgr; - struct qm_mcc_querycgr querycgr; - struct qm_mcc_querywq querywq; - struct qm_mcc_queryfq_np queryfq_np; + struct qm_mcc_fq fq; + struct qm_mcc_cgr cgr; }; /* MC (Management Command) result */ @@ -1777,7 +1755,7 @@ int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts) mcc = qm_mc_start(&p->p); if (opts) mcc->initfq = *opts; - mcc->initfq.fqid = fq->fqid; + mcc->fq.fqid = fq->fqid; mcc->initfq.count = 0; /* * If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a @@ -1873,7 +1851,7 @@ int qman_schedule_fq(struct qman_fq *fq) goto out; } mcc = qm_mc_start(&p->p); - mcc->alterfq.fqid = fq->fqid; + mcc->fq.fqid = fq->fqid; qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_err(p->config->dev, "ALTER_SCHED timeout\n"); @@ -1916,7 +1894,7 @@ int qman_retire_fq(struct qman_fq *fq, u32 *flags) goto out; } mcc = qm_mc_start(&p->p); - mcc->alterfq.fqid = fq->fqid; + mcc->fq.fqid = fq->fqid; qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_crit(p->config->dev, "ALTER_RETIRE timeout\n"); @@ -1995,7 +1973,7 @@ int qman_oos_fq(struct qman_fq *fq) goto out; } mcc = qm_mc_start(&p->p); - mcc->alterfq.fqid = fq->fqid; + mcc->fq.fqid = fq->fqid; qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; @@ -2021,7 +1999,7 @@ int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd) int ret = 0; mcc = qm_mc_start(&p->p); - mcc->queryfq.fqid = fq->fqid; + mcc->fq.fqid = fq->fqid; qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; @@ -2047,7 +2025,7 @@ static int qman_query_fq_np(struct qman_fq *fq, int ret = 0; mcc = qm_mc_start(&p->p); - mcc->queryfq.fqid = fq->fqid; + mcc->fq.fqid = fq->fqid; qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; @@ -2075,7 +2053,7 @@ static int qman_query_cgr(struct qman_cgr *cgr, int ret = 0; mcc = qm_mc_start(&p->p); - mcc->querycgr.cgid = cgr->cgrid; + mcc->cgr.cgid = cgr->cgrid; qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; @@ -2526,7 +2504,7 @@ static int qman_shutdown_fq(u32 fqid) dev = p->config->dev; /* Determine the state of the FQID */ mcc = qm_mc_start(&p->p); - mcc->queryfq_np.fqid = fqid; + mcc->fq.fqid = fqid; qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_err(dev, "QUERYFQ_NP timeout\n"); @@ -2541,7 +2519,7 @@ static int qman_shutdown_fq(u32 fqid) /* Query which channel the FQ is using */ mcc = qm_mc_start(&p->p); - mcc->queryfq.fqid = fqid; + mcc->fq.fqid = fqid; qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_err(dev, "QUERYFQ timeout\n"); @@ -2561,7 +2539,7 @@ static int qman_shutdown_fq(u32 fqid) case QM_MCR_NP_STATE_PARKED: orl_empty = 0; mcc = qm_mc_start(&p->p); - mcc->alterfq.fqid = fqid; + mcc->fq.fqid = fqid; qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_err(dev, "QUERYFQ_NP timeout\n"); @@ -2656,7 +2634,7 @@ static int qman_shutdown_fq(u32 fqid) cpu_relax(); } mcc = qm_mc_start(&p->p); - mcc->alterfq.fqid = fqid; + mcc->fq.fqid = fqid; qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; @@ -2676,7 +2654,7 @@ static int qman_shutdown_fq(u32 fqid) case QM_MCR_NP_STATE_RETIRED: /* Send OOS Command */ mcc = qm_mc_start(&p->p); - mcc->alterfq.fqid = fqid; + mcc->fq.fqid = fqid; qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; diff --git a/drivers/soc/fsl/qbman/qman_priv.h b/drivers/soc/fsl/qbman/qman_priv.h index 59b4b463d884..5606d74c21d4 100644 --- a/drivers/soc/fsl/qbman/qman_priv.h +++ b/drivers/soc/fsl/qbman/qman_priv.h @@ -90,12 +90,6 @@ static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q) } /* "Query FQ Non-Programmable Fields" */ -struct qm_mcc_queryfq_np { - u8 _ncw_verb; - u8 __reserved1[3]; - u32 fqid; /* 24-bit */ - u8 __reserved2[56]; -} __packed; struct qm_mcr_queryfq_np { u8 verb; -- cgit v1.2.3 From d6753c7e65e70e90ea991797059f4204b66cf523 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:25 +0200 Subject: soc/qman: Fix accesses to fqid, cleanup Preventively mask every access to the 'fqid' h/w field, since it is defined as a 24-bit field, for every h/w descriptor. Add generic accessors for this field to ensure correct access. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 32 ++++++++++++++++---------------- include/soc/fsl/qman.h | 5 +++++ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 0d2e3bcaaf9e..06626bee0e7e 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -471,7 +471,7 @@ static inline void eqcr_commit_checks(struct qm_eqcr *eqcr) { DPAA_ASSERT(eqcr->busy); DPAA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0x00ffffff)); - DPAA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0x00ffffff)); + DPAA_ASSERT(!(eqcr->cursor->fqid & ~QM_FQID_MASK)); DPAA_ASSERT(eqcr->available >= 1); } @@ -1387,7 +1387,7 @@ static void qm_mr_process_task(struct work_struct *work) case QM_MR_VERB_FQRN: case QM_MR_VERB_FQRL: /* Lookup in the retirement table */ - fq = fqid_to_fq(msg->fq.fqid); + fq = fqid_to_fq(qm_fqid_get(&msg->fq)); if (WARN_ON(!fq)) break; fq_state_change(p, fq, msg, verb); @@ -1755,7 +1755,7 @@ int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts) mcc = qm_mc_start(&p->p); if (opts) mcc->initfq = *opts; - mcc->fq.fqid = fq->fqid; + qm_fqid_set(&mcc->fq, fq->fqid); mcc->initfq.count = 0; /* * If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a @@ -1851,7 +1851,7 @@ int qman_schedule_fq(struct qman_fq *fq) goto out; } mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fq->fqid; + qm_fqid_set(&mcc->fq, fq->fqid); qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_err(p->config->dev, "ALTER_SCHED timeout\n"); @@ -1894,7 +1894,7 @@ int qman_retire_fq(struct qman_fq *fq, u32 *flags) goto out; } mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fq->fqid; + qm_fqid_set(&mcc->fq, fq->fqid); qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_crit(p->config->dev, "ALTER_RETIRE timeout\n"); @@ -1937,7 +1937,7 @@ int qman_retire_fq(struct qman_fq *fq, u32 *flags) msg.verb = QM_MR_VERB_FQRNI; msg.fq.fqs = mcr->alterfq.fqs; - msg.fq.fqid = fq->fqid; + qm_fqid_set(&msg.fq, fq->fqid); msg.fq.contextB = fq_to_tag(fq); fq->cb.fqs(p, fq, &msg); } @@ -1973,7 +1973,7 @@ int qman_oos_fq(struct qman_fq *fq) goto out; } mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fq->fqid; + qm_fqid_set(&mcc->fq, fq->fqid); qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; @@ -1999,7 +1999,7 @@ int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd) int ret = 0; mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fq->fqid; + qm_fqid_set(&mcc->fq, fq->fqid); qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; @@ -2025,7 +2025,7 @@ static int qman_query_fq_np(struct qman_fq *fq, int ret = 0; mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fq->fqid; + qm_fqid_set(&mcc->fq, fq->fqid); qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; @@ -2206,7 +2206,7 @@ int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd) if (unlikely(!eq)) goto out; - eq->fqid = fq->fqid; + qm_fqid_set(eq, fq->fqid); eq->tag = fq_to_tag(fq); eq->fd = *fd; @@ -2468,7 +2468,7 @@ static int _qm_dqrr_consume_and_match(struct qm_portal *p, u32 fqid, int s, } while (wait && !dqrr); while (dqrr) { - if (dqrr->fqid == fqid && (dqrr->stat & s)) + if (qm_fqid_get(dqrr) == fqid && (dqrr->stat & s)) found = 1; qm_dqrr_cdc_consume_1ptr(p, dqrr, 0); qm_dqrr_pvb_update(p); @@ -2504,7 +2504,7 @@ static int qman_shutdown_fq(u32 fqid) dev = p->config->dev; /* Determine the state of the FQID */ mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fqid; + qm_fqid_set(&mcc->fq, fqid); qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_err(dev, "QUERYFQ_NP timeout\n"); @@ -2519,7 +2519,7 @@ static int qman_shutdown_fq(u32 fqid) /* Query which channel the FQ is using */ mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fqid; + qm_fqid_set(&mcc->fq, fqid); qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_err(dev, "QUERYFQ timeout\n"); @@ -2539,7 +2539,7 @@ static int qman_shutdown_fq(u32 fqid) case QM_MCR_NP_STATE_PARKED: orl_empty = 0; mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fqid; + qm_fqid_set(&mcc->fq, fqid); qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE); if (!qm_mc_result_timeout(&p->p, &mcr)) { dev_err(dev, "QUERYFQ_NP timeout\n"); @@ -2634,7 +2634,7 @@ static int qman_shutdown_fq(u32 fqid) cpu_relax(); } mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fqid; + qm_fqid_set(&mcc->fq, fqid); qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; @@ -2654,7 +2654,7 @@ static int qman_shutdown_fq(u32 fqid) case QM_MCR_NP_STATE_RETIRED: /* Send OOS Command */ mcc = qm_mc_start(&p->p); - mcc->fq.fqid = fqid; + qm_fqid_set(&mcc->fq, fqid); qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS); if (!qm_mc_result_timeout(&p->p, &mcr)) { ret = -ETIMEDOUT; diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h index 1405810e4050..f3fa53fef421 100644 --- a/include/soc/fsl/qman.h +++ b/include/soc/fsl/qman.h @@ -262,6 +262,11 @@ struct qm_dqrr_entry { #define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */ #define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/ +/* 'fqid' is a 24-bit field in every h/w descriptor */ +#define QM_FQID_MASK GENMASK(23, 0) +#define qm_fqid_set(p, v) ((p)->fqid = ((v) & QM_FQID_MASK)) +#define qm_fqid_get(p) ((p)->fqid & QM_FQID_MASK) + /* "ERN Message Response" */ /* "FQ State Change Notification" */ union qm_mr_entry { -- cgit v1.2.3 From b539945286bdd2d7c4cb92ef1237873b1c00c778 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:26 +0200 Subject: soc/qman: Drop unused field from eqcr/dqrr descriptors ORP ("Order Restoration Point") mechanism not supported. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 3 +-- include/soc/fsl/qman.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 06626bee0e7e..c679e0285ccd 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -141,7 +141,7 @@ struct qm_eqcr_entry { u8 _ncw_verb; /* writes to this are non-coherent */ u8 dca; u16 seqnum; - u32 orp; /* 24-bit */ + u8 __reserved[4]; u32 fqid; /* 24-bit */ u32 tag; struct qm_fd fd; @@ -470,7 +470,6 @@ static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal static inline void eqcr_commit_checks(struct qm_eqcr *eqcr) { DPAA_ASSERT(eqcr->busy); - DPAA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0x00ffffff)); DPAA_ASSERT(!(eqcr->cursor->fqid & ~QM_FQID_MASK)); DPAA_ASSERT(eqcr->available >= 1); } diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h index f3fa53fef421..20bbc716a6a8 100644 --- a/include/soc/fsl/qman.h +++ b/include/soc/fsl/qman.h @@ -279,8 +279,7 @@ union qm_mr_entry { u8 dca; u16 seqnum; u8 rc; /* Rej Code: 8-bit */ - u8 orp_hi; /* ORP: 24-bit */ - u16 orp_lo; + u8 __reserved[3]; u32 fqid; /* 24-bit */ u32 tag; struct qm_fd fd; -- cgit v1.2.3 From 5a42f1ecb304789f75a017b2a36bc6d1dac6dcf2 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:27 +0200 Subject: soc/qbman: Handle endianness of qm/bm_in/out() Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/bman.c | 6 +++--- drivers/soc/fsl/qbman/qman.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/soc/fsl/qbman/bman.c b/drivers/soc/fsl/qbman/bman.c index 48b7eb698689..a3d6d7cfa929 100644 --- a/drivers/soc/fsl/qbman/bman.c +++ b/drivers/soc/fsl/qbman/bman.c @@ -167,12 +167,12 @@ struct bm_portal { /* Cache-inhibited register access. */ static inline u32 bm_in(struct bm_portal *p, u32 offset) { - return __raw_readl(p->addr.ci + offset); + return be32_to_cpu(__raw_readl(p->addr.ci + offset)); } static inline void bm_out(struct bm_portal *p, u32 offset, u32 val) { - __raw_writel(val, p->addr.ci + offset); + __raw_writel(cpu_to_be32(val), p->addr.ci + offset); } /* Cache Enabled Portal Access */ @@ -188,7 +188,7 @@ static inline void bm_cl_touch_ro(struct bm_portal *p, u32 offset) static inline u32 bm_ce_in(struct bm_portal *p, u32 offset) { - return __raw_readl(p->addr.ce + offset); + return be32_to_cpu(__raw_readl(p->addr.ce + offset)); } struct bman_portal { diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index c679e0285ccd..936aee19747d 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -321,12 +321,12 @@ struct qm_portal { /* Cache-inhibited register access. */ static inline u32 qm_in(struct qm_portal *p, u32 offset) { - return __raw_readl(p->addr.ci + offset); + return be32_to_cpu(__raw_readl(p->addr.ci + offset)); } static inline void qm_out(struct qm_portal *p, u32 offset, u32 val) { - __raw_writel(val, p->addr.ci + offset); + __raw_writel(cpu_to_be32(val), p->addr.ci + offset); } /* Cache Enabled Portal Access */ @@ -342,7 +342,7 @@ static inline void qm_cl_touch_ro(struct qm_portal *p, u32 offset) static inline u32 qm_ce_in(struct qm_portal *p, u32 offset) { - return __raw_readl(p->addr.ce + offset); + return be32_to_cpu(__raw_readl(p->addr.ce + offset)); } /* --- EQCR API --- */ -- cgit v1.2.3 From efe848cdb724be2d0cc61f6329997f9a7cd7948f Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:28 +0200 Subject: soc/qman: Change remaining contextB into context_b There are multiple occurences of both contextB and context_b in different h/w descriptors, referring to the same descriptor field known as "Context B". Stick with the "context_b" naming, for obvious reasons including consistency (see also context_a). Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 12 ++++++------ include/soc/fsl/qman.h | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 936aee19747d..8386acc1d37d 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -1395,7 +1395,7 @@ static void qm_mr_process_task(struct work_struct *work) break; case QM_MR_VERB_FQPN: /* Parked */ - fq = tag_to_fq(msg->fq.contextB); + fq = tag_to_fq(msg->fq.context_b); fq_state_change(p, fq, msg, verb); if (fq->cb.fqs) fq->cb.fqs(p, fq, msg); @@ -1494,7 +1494,7 @@ static inline unsigned int __poll_portal_fast(struct qman_portal *p, if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) { /* - * VDQCR: don't trust contextB as the FQ may have + * VDQCR: don't trust context_b as the FQ may have * been configured for h/w consumption and we're * draining it post-retirement. */ @@ -1520,8 +1520,8 @@ static inline unsigned int __poll_portal_fast(struct qman_portal *p, if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED) clear_vdqcr(p, fq); } else { - /* SDQCR: contextB points to the FQ */ - fq = tag_to_fq(dq->contextB); + /* SDQCR: context_b points to the FQ */ + fq = tag_to_fq(dq->context_b); /* Now let the callback do its stuff */ res = fq->cb.dqrr(p, fq, dq); /* @@ -1757,7 +1757,7 @@ int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts) qm_fqid_set(&mcc->fq, fq->fqid); mcc->initfq.count = 0; /* - * If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a + * If the FQ does *not* have the TO_DCPORTAL flag, context_b is set as a * demux pointer. Otherwise, the caller-provided value is allowed to * stand, don't overwrite it. */ @@ -1937,7 +1937,7 @@ int qman_retire_fq(struct qman_fq *fq, u32 *flags) msg.verb = QM_MR_VERB_FQRNI; msg.fq.fqs = mcr->alterfq.fqs; qm_fqid_set(&msg.fq, fq->fqid); - msg.fq.contextB = fq_to_tag(fq); + msg.fq.context_b = fq_to_tag(fq); fq->cb.fqs(p, fq, &msg); } } else if (res == QM_MCR_RESULT_PENDING) { diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h index 20bbc716a6a8..c80eccac64f6 100644 --- a/include/soc/fsl/qman.h +++ b/include/soc/fsl/qman.h @@ -248,7 +248,7 @@ struct qm_dqrr_entry { u8 tok; u8 __reserved2[3]; u32 fqid; /* 24-bit */ - u32 contextB; + u32 context_b; struct qm_fd fd; u8 __reserved4[32]; } __packed; @@ -290,7 +290,7 @@ union qm_mr_entry { u8 fqs; /* Frame Queue Status */ u8 __reserved1[6]; u32 fqid; /* 24-bit */ - u32 contextB; + u32 context_b; u8 __reserved2[48]; } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */ }; @@ -658,7 +658,7 @@ struct qman_cgr; /* * This enum, and the callback type that returns it, are used when handling * dequeued frames via DQRR. Note that for "null" callbacks registered with the - * portal object (for handling dequeues that do not demux because contextB is + * portal object (for handling dequeues that do not demux because context_b is * NULL), the return value *MUST* be qman_cb_dqrr_consume. */ enum qman_cb_dqrr_result { @@ -863,11 +863,11 @@ void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools); * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to * pre-existing frame-queues that aren't to be otherwise interfered with, it * prevents all other modifications to the frame queue. The TO_DCPORTAL flag - * causes the driver to honour any contextB modifications requested in the + * causes the driver to honour any context_b modifications requested in the * qm_init_fq() API, as this indicates the frame queue will be consumed by a * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by - * software portals, the contextB field is controlled by the driver and can't be - * modified by the caller. + * software portals, the context_b field is controlled by the driver and can't + * be modified by the caller. */ int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq); -- cgit v1.2.3 From 496bfa11de2e6805b63168d45c2f92edbeae54e2 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:29 +0200 Subject: soc/qman: Clean up CGR CSCN target update operations Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 37 +++++++++++++++++++++++-------------- include/soc/fsl/qman.h | 4 ++-- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 8386acc1d37d..acee99da71a7 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -2248,7 +2248,23 @@ out: } #define PORTAL_IDX(n) (n->config->channel - QM_CHANNEL_SWPORTAL0) -#define TARG_MASK(n) (BIT(31) >> PORTAL_IDX(n)) + +/* congestion state change notification target update control */ +static void qm_cgr_cscn_targ_set(struct __qm_mc_cgr *cgr, int pi, u32 val) +{ + if (qman_ip_rev >= QMAN_REV30) + cgr->cscn_targ_upd_ctrl = QM_CGR_TARG_UDP_CTRL_WRITE_BIT | pi; + else + cgr->cscn_targ = val | QM_CGR_TARG_PORTAL(pi); +} + +static void qm_cgr_cscn_targ_clear(struct __qm_mc_cgr *cgr, int pi, u32 val) +{ + if (qman_ip_rev >= QMAN_REV30) + cgr->cscn_targ_upd_ctrl = pi; + else + cgr->cscn_targ = val & ~QM_CGR_TARG_PORTAL(pi); +} static u8 qman_cgr_cpus[CGR_NUM]; @@ -2298,13 +2314,8 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags, if (ret) goto out; - if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) - local_opts.cgr.cscn_targ_upd_ctrl = - QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p); - else - /* Overwrite TARG */ - local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ | - TARG_MASK(p); + qm_cgr_cscn_targ_set(&local_opts.cgr, PORTAL_IDX(p), + cgr_state.cgr.cscn_targ); local_opts.we_mask |= QM_CGR_WE_CSCN_TARG; /* send init if flags indicate so */ @@ -2371,13 +2382,11 @@ int qman_delete_cgr(struct qman_cgr *cgr) list_add(&cgr->node, &p->cgr_cbs); goto release_lock; } - /* Overwrite TARG */ + local_opts.we_mask = QM_CGR_WE_CSCN_TARG; - if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) - local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p); - else - local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ & - ~(TARG_MASK(p)); + qm_cgr_cscn_targ_clear(&local_opts.cgr, PORTAL_IDX(p), + cgr_state.cgr.cscn_targ); + ret = qm_modify_cgr(cgr, 0, &local_opts); if (ret) /* add back to the list */ diff --git a/include/soc/fsl/qman.h b/include/soc/fsl/qman.h index c80eccac64f6..d01d5a358945 100644 --- a/include/soc/fsl/qman.h +++ b/include/soc/fsl/qman.h @@ -553,8 +553,8 @@ struct __qm_mc_cgr { u8 cscn_en; /* boolean, use QM_CGR_EN */ union { struct { - u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */ - u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */ + u16 cscn_targ_upd_ctrl; /* use QM_CGR_TARG_UDP_* */ + u16 cscn_targ_dcp_low; }; u32 cscn_targ; /* use QM_CGR_TARG_* */ }; -- cgit v1.2.3 From 18058822768f4665e2132ddd1cb413a9033edf09 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Wed, 16 Nov 2016 16:40:30 +0200 Subject: soc/qman: Handle endianness of h/w descriptors The hardware descriptors have big endian (BE) format. Provide proper endianness handling for the remaining descriptor fields, to ensure they are correctly accessed by non-BE CPUs too. Signed-off-by: Claudiu Manoil Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 65 ++++++++++++++++++--------------- drivers/soc/fsl/qbman/qman_priv.h | 10 ++--- drivers/soc/fsl/qbman/qman_test_api.c | 4 +- drivers/soc/fsl/qbman/qman_test_stash.c | 5 ++- include/soc/fsl/qman.h | 48 ++++++++++++------------ 5 files changed, 70 insertions(+), 62 deletions(-) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index acee99da71a7..6f509f68085e 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -140,10 +140,10 @@ enum qm_mr_cmode { /* matches QCSP_CFG::MM */ struct qm_eqcr_entry { u8 _ncw_verb; /* writes to this are non-coherent */ u8 dca; - u16 seqnum; + __be16 seqnum; u8 __reserved[4]; - u32 fqid; /* 24-bit */ - u32 tag; + __be32 fqid; /* 24-bit */ + __be32 tag; struct qm_fd fd; u8 __reserved3[32]; } __packed; @@ -187,7 +187,7 @@ struct qm_mr { struct qm_mcc_fq { u8 _ncw_verb; u8 __reserved1[3]; - u32 fqid; /* 24-bit */ + __be32 fqid; /* 24-bit */ u8 __reserved2[56]; } __packed; @@ -470,7 +470,7 @@ static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal static inline void eqcr_commit_checks(struct qm_eqcr *eqcr) { DPAA_ASSERT(eqcr->busy); - DPAA_ASSERT(!(eqcr->cursor->fqid & ~QM_FQID_MASK)); + DPAA_ASSERT(!(be32_to_cpu(eqcr->cursor->fqid) & ~QM_FQID_MASK)); DPAA_ASSERT(eqcr->available >= 1); } @@ -1395,7 +1395,7 @@ static void qm_mr_process_task(struct work_struct *work) break; case QM_MR_VERB_FQPN: /* Parked */ - fq = tag_to_fq(msg->fq.context_b); + fq = tag_to_fq(be32_to_cpu(msg->fq.context_b)); fq_state_change(p, fq, msg, verb); if (fq->cb.fqs) fq->cb.fqs(p, fq, msg); @@ -1409,7 +1409,7 @@ static void qm_mr_process_task(struct work_struct *work) } } else { /* Its a software ERN */ - fq = tag_to_fq(msg->ern.tag); + fq = tag_to_fq(be32_to_cpu(msg->ern.tag)); fq->cb.ern(p, fq, msg); } num++; @@ -1521,7 +1521,7 @@ static inline unsigned int __poll_portal_fast(struct qman_portal *p, clear_vdqcr(p, fq); } else { /* SDQCR: context_b points to the FQ */ - fq = tag_to_fq(dq->context_b); + fq = tag_to_fq(be32_to_cpu(dq->context_b)); /* Now let the callback do its stuff */ res = fq->cb.dqrr(p, fq, dq); /* @@ -1738,9 +1738,9 @@ int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts) if (fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)) return -EINVAL; #endif - if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) { + if (opts && (be16_to_cpu(opts->we_mask) & QM_INITFQ_WE_OAC)) { /* And can't be set at the same time as TDTHRESH */ - if (opts->we_mask & QM_INITFQ_WE_TDTHRESH) + if (be16_to_cpu(opts->we_mask) & QM_INITFQ_WE_TDTHRESH) return -EINVAL; } /* Issue an INITFQ_[PARKED|SCHED] management command */ @@ -1764,14 +1764,16 @@ int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts) if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) { dma_addr_t phys_fq; - mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB; - mcc->initfq.fqd.context_b = fq_to_tag(fq); + mcc->initfq.we_mask |= cpu_to_be16(QM_INITFQ_WE_CONTEXTB); + mcc->initfq.fqd.context_b = cpu_to_be32(fq_to_tag(fq)); /* * and the physical address - NB, if the user wasn't trying to * set CONTEXTA, clear the stashing settings. */ - if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) { - mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA; + if (!(be16_to_cpu(mcc->initfq.we_mask) & + QM_INITFQ_WE_CONTEXTA)) { + mcc->initfq.we_mask |= + cpu_to_be16(QM_INITFQ_WE_CONTEXTA); memset(&mcc->initfq.fqd.context_a, 0, sizeof(mcc->initfq.fqd.context_a)); } else { @@ -1791,8 +1793,10 @@ int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts) if (flags & QMAN_INITFQ_FLAG_LOCAL) { int wq = 0; - if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) { - mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ; + if (!(be16_to_cpu(mcc->initfq.we_mask) & + QM_INITFQ_WE_DESTWQ)) { + mcc->initfq.we_mask |= + cpu_to_be16(QM_INITFQ_WE_DESTWQ); wq = 4; } qm_fqd_set_destwq(&mcc->initfq.fqd, p->config->channel, wq); @@ -1811,13 +1815,13 @@ int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts) goto out; } if (opts) { - if (opts->we_mask & QM_INITFQ_WE_FQCTRL) { - if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE) + if (be16_to_cpu(opts->we_mask) & QM_INITFQ_WE_FQCTRL) { + if (be16_to_cpu(opts->fqd.fq_ctrl) & QM_FQCTRL_CGE) fq_set(fq, QMAN_FQ_STATE_CGR_EN); else fq_clear(fq, QMAN_FQ_STATE_CGR_EN); } - if (opts->we_mask & QM_INITFQ_WE_CGID) + if (be16_to_cpu(opts->we_mask) & QM_INITFQ_WE_CGID) fq->cgr_groupid = opts->fqd.cgid; } fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ? @@ -1937,7 +1941,7 @@ int qman_retire_fq(struct qman_fq *fq, u32 *flags) msg.verb = QM_MR_VERB_FQRNI; msg.fq.fqs = mcr->alterfq.fqs; qm_fqid_set(&msg.fq, fq->fqid); - msg.fq.context_b = fq_to_tag(fq); + msg.fq.context_b = cpu_to_be32(fq_to_tag(fq)); fq->cb.fqs(p, fq, &msg); } } else if (res == QM_MCR_RESULT_PENDING) { @@ -2206,7 +2210,7 @@ int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd) goto ou