* [PATCH V3 4/4] arm64: boot: dts: entries for APM X-Gene SoC QMTM
From: Ravi Patel @ 2014-02-15 2:22 UTC (permalink / raw)
To: arnd, gregkh, davem
Cc: netdev, linux-kernel, devicetree, linux-arm-kernel, jcm, patches,
Ravi Patel, Keyur Chudgar
In-Reply-To: <1392430922-24643-1-git-send-email-rapatel@apm.com>
This patch adds APM X-Gene SoC Queue Manager/Traffic Manager DTS entries.
Signed-off-by: Ravi Patel <rapatel@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
arch/arm64/boot/dts/apm-storm.dtsi | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi
index d37d736..70b2725 100644
--- a/arch/arm64/boot/dts/apm-storm.dtsi
+++ b/arch/arm64/boot/dts/apm-storm.dtsi
@@ -148,10 +148,15 @@
compatible = "apm,xgene-device-clock";
#clock-cells = <1>;
clocks = <&socplldiv2 0>;
- clock-names = "qmlclk";
+ clock-names = "socplldiv2";
reg = <0x0 0x1703C000 0x0 0x1000>;
reg-names = "csr-reg";
clock-output-names = "qmlclk";
+ status = "ok";
+ csr-offset = <0x0>;
+ csr-mask = <0x3>;
+ enable-offset = <0x8>;
+ enable-mask = <0x3>;
};
ethclk: ethclk {
@@ -187,5 +192,16 @@
interrupt-parent = <&gic>;
interrupts = <0x0 0x4c 0x4>;
};
+
+ qmlite: mailbox@17030000 {
+ compatible = "apm,xgene-qmtm";
+ #mailbox-cells = <4>;
+ status = "ok";
+ reg = <0x0 0x17030000 0x0 0x10000>,
+ <0x0 0x10000000 0x0 0x400000>;
+ interrupts = <0x0 0x40 0x4>,
+ <0x0 0x3c 0x4>;
+ clocks = <&qmlclk 0>;
+ };
};
};
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 3/4] mailbox: xgene: base driver for APM X-Gene SoC QMTM
From: Ravi Patel @ 2014-02-15 2:22 UTC (permalink / raw)
To: arnd, gregkh, davem
Cc: netdev, linux-kernel, devicetree, linux-arm-kernel, jcm, patches,
Ravi Patel, Keyur Chudgar
In-Reply-To: <1392430922-24643-1-git-send-email-rapatel@apm.com>
This patch adds APM X-Gene SoC Queue Manager/Traffic Manager base driver.
QMTM is requried by Ethernet, PktDMA (XOR Engine) and Security subsystems.
Signed-off-by: Ravi Patel <rapatel@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
MAINTAINERS | 9 +
drivers/mailbox/Kconfig | 2 +
drivers/mailbox/Makefile | 1 +
drivers/mailbox/xgene/Kconfig | 9 +
drivers/mailbox/xgene/Makefile | 7 +
drivers/mailbox/xgene/xgene_qmtm_main.c | 516 ++++++++++++++++++++++++++++++
drivers/mailbox/xgene/xgene_qmtm_main.h | 112 +++++++
drivers/mailbox/xgene/xgene_qmtm_storm.c | 358 +++++++++++++++++++++
include/linux/platform_data/xgene_qmtm.h | 300 +++++++++++++++++
9 files changed, 1314 insertions(+)
create mode 100644 drivers/mailbox/xgene/Kconfig
create mode 100644 drivers/mailbox/xgene/Makefile
create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.c
create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.h
create mode 100644 drivers/mailbox/xgene/xgene_qmtm_storm.c
create mode 100644 include/linux/platform_data/xgene_qmtm.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 2507f38..3e09f39 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -678,6 +678,15 @@ S: Maintained
F: drivers/net/appletalk/
F: net/appletalk/
+APPLIEDMICRO (APM) X-GENE SOC QUEUE MANAGER/TRAFFIC MANAGER (QMTM) DRIVER
+M: Ravi Patel <rapatel@apm.com>
+M: Keyur Chudgar <kchudgar@apm.com>
+S: Maintained
+F: drivers/mailbox/xgene/
+F: include/linux/platform_data/xgene_qmtm.h
+F: Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
+F: Documentation/mailbox/apm-xgene-qmtm
+
APTINA CAMERA SENSOR PLL
M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
L: linux-media@vger.kernel.org
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index c8b5c13..52653d4 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -50,4 +50,6 @@ config OMAP_MBOX_KFIFO_SIZE
Specify the default size of mailbox's kfifo buffers (bytes).
This can also be changed at runtime (via the mbox_kfifo_size
module parameter).
+
+source "drivers/mailbox/xgene/Kconfig"
endif
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index e0facb3..6faee7e 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_OMAP1_MBOX) += mailbox_omap1.o
mailbox_omap1-objs := mailbox-omap1.o
obj-$(CONFIG_OMAP2PLUS_MBOX) += mailbox_omap2.o
mailbox_omap2-objs := mailbox-omap2.o
+obj-$(CONFIG_XGENE_MBOX) += xgene/
diff --git a/drivers/mailbox/xgene/Kconfig b/drivers/mailbox/xgene/Kconfig
new file mode 100644
index 0000000..0843303
--- /dev/null
+++ b/drivers/mailbox/xgene/Kconfig
@@ -0,0 +1,9 @@
+config XGENE_MBOX
+ tristate "APM X-Gene Queue Manager/Traffic Manager Mailbox"
+ depends on ARM64 || COMPILE_TEST
+ default y
+ help
+ This option enables APM X-Gene Queue Manager Traffic Manager (QMTM)
+ mailbox support.
+ QMTM is required for Ethernet, PktDMA (XOR Engine) and Security
+ Engine.
diff --git a/drivers/mailbox/xgene/Makefile b/drivers/mailbox/xgene/Makefile
new file mode 100644
index 0000000..574e1b8
--- /dev/null
+++ b/drivers/mailbox/xgene/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for APM X-GENE Queue Manager Traffic Manager mailbox
+#
+
+obj-$(CONFIG_XGENE_MBOX) += xgene-qmtm.o
+
+xgene-qmtm-objs := xgene_qmtm_main.o xgene_qmtm_storm.o
diff --git a/drivers/mailbox/xgene/xgene_qmtm_main.c b/drivers/mailbox/xgene/xgene_qmtm_main.c
new file mode 100644
index 0000000..bc50cd9
--- /dev/null
+++ b/drivers/mailbox/xgene/xgene_qmtm_main.c
@@ -0,0 +1,516 @@
+/*
+ * AppliedMicro X-Gene SoC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include "xgene_qmtm_main.h"
+
+#define XGENE_QMTM_DRIVER_VER "1.0"
+#define XGENE_QMTM_DRIVER_NAME "xgene-qmtm"
+#define XGENE_QMTM_DRIVER_DESC "APM X-Gene QMTM driver"
+
+/* CSR Address Macros */
+#define CSR_QM_CONFIG_ADDR 0x00000004
+#define QM_ENABLE_WR(src) (((u32)(src)<<31) & 0x80000000)
+
+#define CSR_PBM_ADDR 0x00000008
+#define OVERWRITE_WR(src) (((u32)(src)<<31) & 0x80000000)
+#define SLVID_PBN_WR(src) (((u32)(src)) & 0x000003ff)
+
+#define CSR_PBM_BUF_WR_ADDR 0x0000000c
+#define CSR_PBM_BUF_RD_ADDR 0x00000010
+#define PB_SIZE_WR(src) (((u32)(src)<<31) & 0x80000000)
+#define PREFETCH_BUF_EN_SET(dst, src) \
+ (((dst) & ~0x00200000) | (((u32)(src)<<21) & 0x00200000))
+#define IS_FREE_POOL_SET(dst, src) \
+ (((dst) & ~0x00100000) | (((u32)(src)<<20) & 0x00100000))
+#define TLVQ_SET(dst, src) \
+ (((dst) & ~0x00080000) | (((u32)(src)<<19) & 0x00080000))
+#define CORRESPONDING_QNUM_SET(dst, src) \
+ (((dst) & ~0x0007fe00) | (((u32)(src)<<9) & 0x0007fe00))
+
+#define CSR_THRESHOLD0_SET1_ADDR 0x00000030
+#define CSR_THRESHOLD1_SET1_ADDR 0x00000034
+#define CSR_HYSTERESIS_ADDR 0x00000068
+#define CSR_QM_MBOX_NE_INT_MODE_ADDR 0x0000017c
+#define CSR_QMLITE_PBN_MAP_0_ADDR 0x00000228
+
+#define CSR_RECOMB_CTRL_0_ADDR 0x00000230
+#define RECOMB_EN0_SET(dst, src) \
+ (((dst) & ~0x00000001) | (((u32)(src)) & 0x00000001))
+
+/* QMTM Diag CSR */
+#define QM_GLBL_DIAG_CSR_BASE_ADDR_OFFSET 0xd000
+#define QM_CFG_MEM_RAM_SHUTDOWN_ADDR 0x00000070
+#define QM_CFG_MEM_RAM_SHUTDOWN_DEFAULT 0xffffffff
+
+static struct of_device_id xgene_qmtm_match[] = {
+ {
+ .compatible = "apm,xgene-qmtm",
+ .data = &storm_qmtm_ops,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, xgene_qmtm_match);
+
+void xgene_qmtm_wr32(struct xgene_qmtm *qmtm, u32 offset, u32 data)
+{
+ writel(data, qmtm->csr_vaddr + offset);
+}
+
+void xgene_qmtm_rd32(struct xgene_qmtm *qmtm, u32 offset, u32 *data)
+{
+ *data = readl(qmtm->csr_vaddr + offset);
+}
+
+static void xgene_qmtm_pbm_get(struct xgene_mbox *mbox)
+{
+ u16 is_fp = QMTM_QTYPE_FP(mbox);
+ u16 is_vq = QMTM_QTYPE_VQ(mbox);
+ u32 val = 0;
+ u32 pbm = SLVID_PBN_WR(mbox->pbm) | OVERWRITE_WR(1);
+
+ if (mbox->qmtm->qmtm_ip == QMTM0 || mbox->qmtm->qmtm_ip == QMTM2)
+ val |= PB_SIZE_WR(1);
+
+ val = CORRESPONDING_QNUM_SET(val, mbox->qid);
+ val = IS_FREE_POOL_SET(val, is_fp);
+ val = TLVQ_SET(val, is_vq);
+ val = PREFETCH_BUF_EN_SET(val, 1);
+ xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_ADDR, pbm);
+ xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_BUF_WR_ADDR, val);
+}
+
+static void xgene_qmtm_pbm_put(struct xgene_mbox *mbox)
+{
+ u32 pbm = SLVID_PBN_WR(mbox->pbm) | OVERWRITE_WR(1);
+ xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_ADDR, pbm);
+ xgene_qmtm_wr32(mbox->qmtm, CSR_PBM_BUF_WR_ADDR, 0);
+}
+
+/**
+ * xgene_mbox_get - Create and configure a queue
+ * @dev: device that requests this queue
+ * @s: the queue name string as given in the dt data
+ *
+ * This API will be called by APM X-Gene SoC Ethernet, PktDMA (XOR Engine),
+ * and Security Engine subsystems to create and configure a queue.
+ *
+ * Returns the mbox associated with the given phandle value,
+ * after getting a refcount to it, -ENODEV if there is no such queue,
+ * -ENOMEM if out of memory or -EINVAL for other error conditions.
+ * The caller is responsible for calling xgene_mbox_put() to release
+ * that count.
+ */
+struct xgene_mbox *xgene_mbox_get(struct device *dev, const char *s)
+{
+ struct module *module = THIS_MODULE;
+ struct xgene_mbox *mbox = ERR_PTR(-EINVAL);
+ struct xgene_qmtm *qmtm;
+ int ret;
+ struct of_phandle_args args;
+ u64 qfabric_paddr;
+ u32 qsize = 0;
+ u16 qid = 0;
+ u8 cfgqsize;
+
+ if (!dev->of_node) {
+ dev_err(dev, "Invalid device tree\n");
+ goto _err_mbox_get;
+ }
+
+ ret = of_property_match_string(dev->of_node, "mailbox-names", s);
+ if (ret < 0) {
+ mbox = ERR_PTR(-ENODEV);
+ goto _err_mbox_get;
+ }
+
+ memset(&args, 0, sizeof(args));
+ ret = of_parse_phandle_with_args(dev->of_node, "mailboxes",
+ "#mailbox-cells", ret, &args);
+ if (ret || !args.np) {
+ dev_err(dev, "failed to get mailbox in %s node\n",
+ dev->of_node->full_name);
+ goto _err_mbox_get;
+ }
+
+ if (!try_module_get(module))
+ goto _err_mbox_get;
+
+ qmtm = platform_get_drvdata(of_find_device_by_node(args.np));
+ if (qmtm == NULL) {
+ dev_err(dev, "failed to get QMTM for %s node\n",
+ dev->of_node->full_name);
+ goto _module_put;
+ }
+
+ qfabric_paddr = ((u64)args.args[0] << 32) | args.args[1];
+ if (qfabric_paddr > (qmtm->fabric_paddr |
+ ((u64)(QMTM_MAX_QUEUES - 1) << 6)) ||
+ qfabric_paddr < qmtm->fabric_paddr) {
+ dev_err(dev, "Invalid qfabric address for %s node\n",
+ dev->of_node->full_name);
+ goto _module_put;
+ }
+ qid = (qfabric_paddr - qmtm->fabric_paddr) >> 6;
+
+ qsize = args.args[2];
+ switch (qsize) {
+ case 0x00200:
+ cfgqsize = QSIZE_512B;
+ break;
+ case 0x00800:
+ cfgqsize = QSIZE_2KB;
+ break;
+ case 0x04000:
+ cfgqsize = QSIZE_16KB;
+ break;
+ case 0x10000:
+ cfgqsize = QSIZE_64KB;
+ break;
+ case 0x80000:
+ cfgqsize = QSIZE_512KB;
+ break;
+ default:
+ dev_err(dev, "Unsupported queue size %d\n", qsize);
+ goto _module_put;
+ }
+
+ mbox = kzalloc(sizeof(struct xgene_mbox), GFP_KERNEL);
+ if (mbox == NULL) {
+ dev_err(dev, "Unable to allocate mbox\n");
+ goto _module_put;
+ }
+
+ mbox->qaddr = dma_zalloc_coherent(&qmtm->pdev->dev, qsize,
+ &mbox->dma, GFP_KERNEL);
+ if (mbox->qaddr == NULL) {
+ dev_err(dev, "Unable to allocate qaddr\n");
+ kfree(mbox);
+ mbox = NULL;
+ goto _module_put;
+ }
+ mbox->qsize = qsize;
+ mbox->pbm = args.args[3];
+ mbox->qid = qid;
+ mbox->slots = cfgqsize;
+ mbox->qfabric = qmtm->fabric_vaddr + (qid << 6);
+ mbox->level = mbox->qfabric + 0x2C;
+ mbox->qmtm = qmtm;
+ qmtm->ops.set_qstate(mbox);
+ xgene_qmtm_pbm_get(mbox);
+ mbox->slots = QMTM_QTYPE_FP(mbox) ? qsize / 16 : qsize / 32;
+ mbox->qstate[6] = qmtm->qmtm_ip;
+
+ if (QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_CPU &&
+ !QMTM_QTYPE_FP(mbox) &&
+ !QMTM_QTYPE_VQ(mbox)) {
+ u32 s, data;
+ for (s = 0; s < mbox->slots; s++) {
+ u32 *slot = (u32 *)&mbox->msg32[s];
+ slot[EMPTY_SLOT_INDEX] = EMPTY_SLOT;
+ }
+ xgene_qmtm_rd32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, &data);
+ data |= (u32) (1 << (31 - QMTM_PBN(mbox)));
+ xgene_qmtm_wr32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, data);
+ mbox->irq = qmtm->dequeue_irq[QMTM_PBN(mbox)];
+ }
+
+ qmtm->mbox[qid] = mbox;
+ return mbox;
+
+_module_put:
+ module_put(module);
+
+_err_mbox_get:
+ return mbox;
+}
+EXPORT_SYMBOL_GPL(xgene_mbox_get);
+
+/**
+ * xgene_mbox_put - Unconfigure and delete a queue
+ * @mbox: the mbox returned by xgene_mbox_get()
+ *
+ * This API will be called by APM X-Gene SoC Ethernet, PktDMA (XOR Engine),
+ * and Security Engine subsystems to unconfigure and delete a queue.
+ *
+ * Releases a refcount the caller received from xgene_mbox_get().
+ */
+void xgene_mbox_put(struct xgene_mbox *mbox)
+{
+ struct xgene_qmtm *qmtm = mbox->qmtm;
+ struct module *module = THIS_MODULE;
+
+ if (QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_CPU &&
+ !QMTM_QTYPE_FP(mbox) &&
+ !QMTM_QTYPE_VQ(mbox)) {
+ u32 data;
+ xgene_qmtm_rd32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, &data);
+ data &= ~(u32) (1 << (31 - QMTM_PBN(mbox)));
+ xgene_qmtm_wr32(qmtm, CSR_QM_MBOX_NE_INT_MODE_ADDR, data);
+ }
+
+ xgene_qmtm_pbm_put(mbox);
+ qmtm->ops.clr_qstate(mbox);
+ dma_free_coherent(&qmtm->pdev->dev, mbox->qsize,
+ mbox->qaddr, mbox->dma);
+ qmtm->mbox[mbox->qid] = NULL;
+ kfree(mbox);
+ module_put(module);
+}
+EXPORT_SYMBOL_GPL(xgene_mbox_put);
+
+/**
+ * xgene_mbox_level - Read number of message in queue
+ * @mbox: read number of message for mbox
+ *
+ * This API will be called by APM X-Gene SoC Ethernet, PktDMA (XOR Engine),
+ * and Security Engine subsystems to read number of message for mbox.
+ *
+ * Returns number of messages in mbox
+ */
+u32 xgene_mbox_level(struct xgene_mbox *mbox)
+{
+ return mbox->qmtm->ops.read_level(mbox->qfabric);
+}
+EXPORT_SYMBOL_GPL(xgene_mbox_level);
+
+static int xgene_qmtm_enable(struct xgene_qmtm *qmtm)
+{
+ struct xgene_mbox mbox;
+ struct device *dev = &qmtm->pdev->dev;
+ int rc, mwait = 0, inum = 1;
+ u32 val;
+ u32 qid;
+
+ qmtm->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(qmtm->clk)) {
+ dev_err(dev, "can't get clock\n");
+ return PTR_ERR(qmtm->clk);
+ }
+
+ rc = clk_prepare_enable(qmtm->clk);
+ if (rc < 0) {
+ dev_err(dev, "clock prepare enable failed\n");
+ return rc;
+ }
+
+ xgene_qmtm_wr32(qmtm, QM_GLBL_DIAG_CSR_BASE_ADDR_OFFSET +
+ QM_CFG_MEM_RAM_SHUTDOWN_ADDR, 0);
+ do {
+ /* Wait for Memory to come out of shutdown */
+ usleep_range(1000, 2000);
+ xgene_qmtm_rd32(qmtm, QM_GLBL_DIAG_CSR_BASE_ADDR_OFFSET +
+ QM_CFG_MEM_RAM_SHUTDOWN_ADDR, &val);
+
+ if (mwait++ >= 1000) {
+ rc = -EIO;
+ dev_err(dev, "RAM not out of shutdown %d\n", rc);
+ clk_disable_unprepare(qmtm->clk);
+ return rc;
+ }
+ } while (val == QM_CFG_MEM_RAM_SHUTDOWN_DEFAULT);
+
+ rc = qmtm->ops.init(qmtm);
+ if (rc < 0) {
+ dev_err(dev, "not supported on your system\n");
+ return rc;
+ }
+
+ for (inum = qmtm->irq_start; inum < (qmtm->irq_start +
+ qmtm->irq_count); inum++) {
+ int irq = platform_get_irq(qmtm->pdev,
+ inum - qmtm->irq_start + 1);
+ if (irq < 0) {
+ dev_err(dev, "Failed to map QMTM%d PBN %d IRQ\n",
+ qmtm->qmtm_ip, inum);
+ continue;
+ }
+ qmtm->dequeue_irq[inum] = irq;
+ }
+
+ switch (qmtm->qmtm_ip) {
+ case QMTM0:
+ case QMTM2:
+ xgene_qmtm_rd32(qmtm, CSR_RECOMB_CTRL_0_ADDR, &val);
+ val = RECOMB_EN0_SET(val, 1);
+ xgene_qmtm_wr32(qmtm, CSR_RECOMB_CTRL_0_ADDR, val);
+ break;
+ case QMTM3:
+ xgene_qmtm_wr32(qmtm, CSR_QMLITE_PBN_MAP_0_ADDR, 0x00000000);
+ }
+
+ /* program threshold set 1 and all hysteresis */
+ xgene_qmtm_wr32(qmtm, CSR_THRESHOLD0_SET1_ADDR, 100);
+ xgene_qmtm_wr32(qmtm, CSR_THRESHOLD1_SET1_ADDR, 200);
+ xgene_qmtm_wr32(qmtm, CSR_HYSTERESIS_ADDR, 0xFFFFFFFF);
+
+ /* Enable QPcore */
+ xgene_qmtm_wr32(qmtm, CSR_QM_CONFIG_ADDR, QM_ENABLE_WR(1));
+
+ /* Clear all HW queue state in case they were not de-activated */
+ memset(&mbox, 0, sizeof(mbox));
+ mbox.qmtm = qmtm;
+
+ for (qid = 0; qid < QMTM_MAX_QUEUES; qid++) {
+ mbox.qid = qid;
+ qmtm->ops.clr_qstate(&mbox);
+ }
+
+ return rc;
+}
+
+static int xgene_qmtm_disable(struct xgene_qmtm *qmtm)
+{
+ u32 qid;
+
+ for (qid = 0; qid < QMTM_MAX_QUEUES; qid++) {
+ if (qmtm->mbox[qid]) {
+ dev_err(&qmtm->pdev->dev,
+ "QMTM %d Queue ID %d Resource in use\n",
+ qmtm->qmtm_ip, qid);
+ return -EAGAIN;
+ }
+ }
+
+ /* Disable QPcore */
+ xgene_qmtm_wr32(qmtm, CSR_QM_CONFIG_ADDR, QM_ENABLE_WR(0));
+ clk_disable_unprepare(qmtm->clk);
+
+ return 0;
+}
+
+static struct xgene_qmtm *xgene_alloc_qmtm(struct platform_device *pdev)
+{
+ struct xgene_qmtm *qmtm;
+
+ qmtm = devm_kzalloc(&pdev->dev, sizeof(struct xgene_qmtm), GFP_KERNEL);
+ if (qmtm == NULL) {
+ dev_err(&pdev->dev, "Unable to allocate QMTM context\n");
+ return NULL;
+ }
+
+ qmtm->pdev = pdev;
+ platform_set_drvdata(pdev, qmtm);
+ qmtm->mbox = devm_kzalloc(&pdev->dev,
+ QMTM_MAX_QUEUES * (sizeof(struct xgene_qmtm_info *)),
+ GFP_KERNEL);
+ if (qmtm->mbox == NULL) {
+ dev_err(&pdev->dev, "Unable to allocate QMTM Queue context\n");
+ return NULL;
+ }
+
+ return qmtm;
+}
+
+static int xgene_get_qmtm(struct xgene_qmtm *qmtm)
+{
+ struct platform_device *pdev = qmtm->pdev;
+ const struct of_device_id *match;
+ struct resource *res;
+
+ /* Get Match Table */
+ match = of_match_device(xgene_qmtm_match, &pdev->dev);
+ if (!match)
+ return -EINVAL;
+ memcpy(&qmtm->ops, match->data, sizeof(struct xgene_qmtm_ops));
+
+ /* Retrieve QM CSR register address and size */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get QMTM CSR region\n");
+ return -ENODEV;
+ }
+
+ qmtm->csr_vaddr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(qmtm->csr_vaddr)) {
+ dev_err(&pdev->dev, "Invalid QMTM CSR region\n");
+ return PTR_ERR(qmtm->csr_vaddr);
+ }
+
+ /* Retrieve Primary Fabric address and size */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(&pdev->dev, "Failed to get QMTM Fabric region\n");
+ return -ENODEV;
+ }
+
+ qmtm->fabric_vaddr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(qmtm->fabric_vaddr)) {
+ dev_err(&pdev->dev, "Invalid QMTM Fabric region\n");
+ return PTR_ERR(qmtm->fabric_vaddr);
+ }
+ qmtm->fabric_paddr = res->start;
+
+ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)))
+ return dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+
+ return 0;
+}
+
+static int xgene_qmtm_probe(struct platform_device *pdev)
+{
+ struct xgene_qmtm *qmtm;
+ int rc;
+
+ qmtm = xgene_alloc_qmtm(pdev);
+ if (qmtm == NULL)
+ return -ENOMEM;
+
+ rc = xgene_get_qmtm(qmtm);
+ if (rc)
+ return rc;
+
+ return xgene_qmtm_enable(qmtm);
+}
+
+static int xgene_qmtm_remove(struct platform_device *pdev)
+{
+ struct xgene_qmtm *qmtm = platform_get_drvdata(pdev);
+ return xgene_qmtm_disable(qmtm);
+}
+
+static struct platform_driver xgene_qmtm_driver = {
+ .driver = {
+ .name = XGENE_QMTM_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = xgene_qmtm_match,
+ },
+ .probe = xgene_qmtm_probe,
+ .remove = xgene_qmtm_remove,
+};
+
+static int __init xgene_qmtm_init(void)
+{
+ return platform_driver_register(&xgene_qmtm_driver);
+}
+subsys_initcall(xgene_qmtm_init);
+
+static void __exit xgene_qmtm_exit(void)
+{
+ platform_driver_unregister(&xgene_qmtm_driver);
+}
+module_exit(xgene_qmtm_exit);
+
+MODULE_VERSION(XGENE_QMTM_DRIVER_VER);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ravi Patel <rapatel@apm.com>");
+MODULE_DESCRIPTION(XGENE_QMTM_DRIVER_DESC);
diff --git a/drivers/mailbox/xgene/xgene_qmtm_main.h b/drivers/mailbox/xgene/xgene_qmtm_main.h
new file mode 100644
index 0000000..1a9de03
--- /dev/null
+++ b/drivers/mailbox/xgene/xgene_qmtm_main.h
@@ -0,0 +1,112 @@
+/*
+ * AppliedMicro X-Gene SoC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __XGENE_QMTM_MAIN_H__
+#define __XGENE_QMTM_MAIN_H__
+
+#include <linux/of_platform.h>
+#include <linux/platform_data/xgene_qmtm.h>
+
+/* QMTM IP Blocks */
+enum xgene_qmtm_ip {
+ QMTM0,
+ QMTM1,
+ QMTM2,
+ QMTM3,
+};
+
+#define QMTM_MAX_QUEUES 1024
+#define QMTM_MAX_PBN 32
+
+/* QMTM Queue types */
+enum xgene_qmtm_qtype {
+ QTYPE_DISABLED, /* Queue Type is un-configured or disabled */
+ QTYPE_PQ, /* Queue Type is Physical Work Queue */
+ QTYPE_FP, /* Queue Type is Free Pool Queue */
+ QTYPE_VQ, /* Queue Type is Virtual Queue */
+};
+
+/* QMTM Queue possible sizes */
+enum xgene_qmtm_qsize {
+ QSIZE_512B,
+ QSIZE_2KB,
+ QSIZE_16KB,
+ QSIZE_64KB,
+ QSIZE_512KB,
+ QSIZE_MAX,
+};
+
+struct xgene_qmtm_ops {
+ int (*init)(struct xgene_qmtm *qmtm);
+ void (*set_qstate)(struct xgene_mbox *mbox);
+ void (*clr_qstate)(struct xgene_mbox *mbox);
+ u32 (*read_level)(void *qfabric);
+};
+
+struct xgene_qmtm {
+ struct xgene_qmtm_ops ops;
+ void *csr_vaddr;
+ void *fabric_vaddr;
+ u64 fabric_paddr;
+ u16 qmtm_ip; /* qmtm_ip, see xgene_qmtm_ip */
+ u16 irq_start;
+ u16 irq_count;
+ u16 error_irq;
+ u16 dequeue_irq[QMTM_MAX_PBN];
+ char error_irq_s[16];
+ char error_queue_irq_s[16];
+ struct xgene_mbox *(*mbox);
+ struct xgene_mbox *error_mbox;
+ struct clk *clk;
+ struct platform_device *pdev;
+};
+
+/* QMTM Slave IDs */
+enum xgene_qmtm_slave_id {
+ QMTM_SLAVE_ID_ETH0,
+ QMTM_SLAVE_ID_ETH1,
+ QMTM_SLAVE_ID_RES2,
+ QMTM_SLAVE_ID_PKTDMA,
+ QMTM_SLAVE_ID_CTX,
+ QMTM_SLAVE_ID_SEC,
+ QMTM_SLAVE_ID_CLASS,
+ QMTM_SLAVE_ID_MSLIM,
+ QMTM_SLAVE_ID_RES8,
+ QMTM_SLAVE_ID_RES9,
+ QMTM_SLAVE_ID_RESA,
+ QMTM_SLAVE_ID_RESB,
+ QMTM_SLAVE_ID_RESC,
+ QMTM_SLAVE_ID_PMPRO,
+ QMTM_SLAVE_ID_SMPRO,
+ QMTM_SLAVE_ID_CPU,
+ QMTM_SLAVE_ID_MAX,
+};
+
+/* QMTM Free Pool Queue modes */
+enum xgene_qmtm_fp_mode {
+ MSG_NO_CHANGE,
+ ROUND_ADDR,
+ REDUCE_LEN,
+ CHANGE_LEN,
+};
+
+extern struct xgene_qmtm_ops storm_qmtm_ops;
+/* QMTM CSR read/write routine */
+void xgene_qmtm_wr32(struct xgene_qmtm *qmtm, u32 offset, u32 data);
+void xgene_qmtm_rd32(struct xgene_qmtm *qmtm, u32 offset, u32 *data);
+
+#endif /* __XGENE_QMTM_MAIN_H__ */
diff --git a/drivers/mailbox/xgene/xgene_qmtm_storm.c b/drivers/mailbox/xgene/xgene_qmtm_storm.c
new file mode 100644
index 0000000..e214d28
--- /dev/null
+++ b/drivers/mailbox/xgene/xgene_qmtm_storm.c
@@ -0,0 +1,358 @@
+/**
+ * AppliedMicro X-Gene SOC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ * Fushen Chen <fchen@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/slab.h>
+#include "xgene_qmtm_main.h"
+
+#define CSR_IPBRR_ADDR 0x00000000
+#define CSR_IPBRR_QMTM0_DEFAULT 0x00000520
+#define CSR_IPBRR_QMTM1_DEFAULT 0x00000521
+#define CSR_IPBRR_QMTM2_DEFAULT 0x00000522
+#define CSR_IPBRR_QMTM3_DEFAULT 0x000005E0
+
+#define CSR_QSTATE_ADDR 0x0000006c
+#define QNUMBER_WR(src) (((u32)(src)) & 0x000003ff)
+
+#define CSR_QSTATE_WR_0_ADDR 0x00000070
+#define CSR_QSTATE_WR_1_ADDR 0x00000074
+#define CSR_QSTATE_WR_2_ADDR 0x00000078
+#define CSR_QSTATE_WR_3_ADDR 0x0000007c
+#define CSR_QSTATE_WR_4_ADDR 0x00000080
+
+/* QMTM Queue State */
+struct storm_qmtm_csr_qstate {
+ u32 w0;
+ u32 w1;
+ u32 w2;
+ u32 w3;
+ u32 w4;
+} __packed;
+
+/*
+ * Physical or free pool queue state (pq or fp)
+ */
+struct storm_qmtm_pq_fp_qstate {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* register word 0 (bit 31:0) */
+ u32 cpu_notify:8; /* 31:24 */
+ u32 cfgsaben:1; /* 23 enable SAB broadcasting */
+ u32 cfgtmvq:10; /* 22:13 parent vq */
+ u32 cfgtmvqen:1; /* 12 enable pq to belong to vq */
+ u32 resize_done:1; /* 11 */
+ u32 resize_start:1; /* 10 */
+ u32 resize_qid:10; /* 9:0 */
+
+ /* register word 1 (bit 63:32) */
+ u32 headptr:15; /* 63:49 */
+ u32 nummsg:16; /* 48:33 */
+ u32 cfgnotifyqne:1; /* 32 enable Q not empty intr */
+
+ /* register word 2 (bit 95:64) */
+ u32 cfgstartaddrL:27; /* 95:69 split 7/27 */
+ u32 qcoherent:1; /* 68 */
+ u32 rid:3; /* 67:65 */
+ u32 cfgcrid:1; /* 64 */
+
+ /* register word 3 (bit 127:96) */
+ u32 cfgRecombBufTimeoutL:4; /* 127:124 split 3/4 */
+ u32 cfgRecombBuf:1; /* 123 */
+ u32 qstatelock:1; /* 122 */
+ u32 cfgqsize:3; /* 121:119 queue size */
+ u32 fp_mode:3; /* 118:116 free pool mode */
+ u32 cfgacceptlerr:1; /* 115 */
+ u32 reserved_0:1; /* 114 */
+ u32 stashing:1; /* 113 */
+ u32 slot_pending:8; /* 112:105 */
+ u32 vc_chanid:2; /* 104:103 */
+ u32 cfgstartaddrH:7; /* 102:96 split 7/27 */
+
+ /* register word 4 (bit 159:128) */
+ u32 resv1:11; /* 159:149 */
+ u32 cfgqtype:2; /* 148:147 queue type */
+ u32 resv2:5; /* 146:142 */
+ u32 half_64B_override:3; /* 141:139 */
+ u32 resv3:4; /* 138:135 */
+ u32 CfgSupressCmpl:1; /* 134 */
+ u32 cfgselthrsh:3; /* 133:131 associated threshold set */
+ u32 cfgRecombBufTimeoutH:3; /* 130:128 split 3/4 */
+#else
+ /* register word 0 (bit 31:0) */
+ u32 resize_qid:10; /* 9:0 */
+ u32 resize_start:1; /* 10 */
+ u32 resize_done:1; /* 11 */
+ u32 cfgtmvqen:1; /* 12 enable pq to belong to vq */
+ u32 cfgtmvq:10; /* 22:13 parent vq */
+ u32 cfgsaben:1; /* 23 enable SAB broadcasting */
+ u32 cpu_notify:8; /* 31:24 */
+
+ /* register word 1 (bit 63:32) */
+ u32 cfgnotifyqne:1; /* 32 enable Q not empty intr */
+ u32 nummsg:16; /* 48:33 */
+ u32 headptr:15; /* 63:49 */
+
+ /* register word 2 (bit 95:64) */
+ u32 cfgcrid:1; /* 64 */
+ u32 rid:3; /* 67:65 */
+ u32 qcoherent:1; /* 68 */
+ u32 cfgstartaddrL:27; /* 95:69 split 7/27 */
+
+ /* register word 3 (bit 127:96) */
+ u32 cfgstartaddrH:7; /* 102:96 split 7/27 */
+ u32 vc_chanid:2; /* 104:103 */
+ u32 slot_pending:8; /* 112:105 */
+ u32 stashing:1; /* 113 */
+ u32 reserved_0:1; /* 114 */
+ u32 cfgacceptlerr:1; /* 115 */
+ u32 fp_mode:3; /* 118:116 free pool mode */
+ u32 cfgqsize:3; /* 121:119 queue size */
+ u32 qstatelock:1; /* 122 */
+ u32 cfgRecombBuf:1; /* 123 */
+ u32 cfgRecombBufTimeoutL:4; /* 127:124 split 3/4 */
+
+ /* register word 4 (bit 159:128) */
+ u32 cfgRecombBufTimeoutH:3; /* 130:128 split 3/4 */
+ u32 cfgselthrsh:3; /* 133:131 associated threshold set */
+ u32 CfgSupressCmpl:1; /* 134 */
+ u32 resv3:4; /* 138:135 */
+ u32 half_64B_override:3; /* 141:139 */
+ u32 resv2:5; /* 146:142 */
+ u32 cfgqtype:2; /* 148:147 queue type */
+ u32 resv1:11; /* 159:149 */
+#endif
+} __packed;
+
+/*
+ * Virtual queue state (vq)
+ */
+struct storm_qmtm_vq_qstate {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* register word 0 (bit 31:0) */
+ u32 rid:3; /* 31:29 */
+ u32 cpu_notify:8; /* 28:21 */
+ u32 cfgcrid:1; /* 20 critical rid config */
+ u32 cfgnotifyqne:1; /* 19 enable Q not empty intr */
+ u32 cfgsaben:1; /* 18 enable SAB broadcasting */
+ u32 nummsg:18; /* 17:0 */
+
+ /* register word 1 (bit 63:32) */
+ u32 q5reqvld:1; /* 63 */
+ u32 q5txallowed:1; /* 62 */
+ u32 q5selarb:2; /* 61:60 */
+ u32 q6_sel:10; /* 59:50 */
+ u32 q6reqvld:1; /* 49 */
+ u32 q6txallowed:1; /* 48 */
+ u32 q6selarb:2; /* 47:46 */
+ u32 q7_sel:10; /* 45:36 */
+ u32 q7reqvld:1; /* 35 */
+ u32 q7txallowed:1; /* 34 */
+ u32 q7selarb:2; /* 33:32 */
+
+ /* register word 2 (bit 95:64) */
+ u32 q3_selL:4; /* 95:92 split 4/6 */
+ u32 q3reqvld:1; /* 91 */
+ u32 q3txallowed:1; /* 90 */
+ u32 q3selarb:2; /* 89:88 */
+ u32 q4_sel:10; /* 87:78 */
+ u32 q4reqvld:1; /* 77 */
+ u32 q4txallowed:1; /* 76 */
+ u32 q4selarb:2; /* 75:74 */
+ u32 q5_sel:10; /* 73:64 */
+
+ /* register word 3 (bit 127:96) */
+ u32 q1_selL:8; /* 127:120 split 2/8 */
+ u32 q1reqvld:1; /* 119 */
+ u32 q1txallowed:1; /* 118 */
+ u32 q1selarb:2; /* 117:116 */
+ u32 q2_sel:10; /* 115:106 */
+ u32 q2reqvld:1; /* 105 */
+ u32 q2txallowed:1; /* 104 */
+ u32 q2selarb:2; /* 103:102 */
+ u32 q3_selH:6; /* 101:96 split 4/6 */
+
+ /* register word 4 (bit 159:128) */
+ u32 resv1:11; /* 159:149 */
+ u32 cfgqtype:2; /* 148:147 queue type */
+ u32 cfgselthrsh:3; /* 146:144 associated threshold set */
+ u32 q0_sel:10; /* 143:134 */
+ u32 q0reqvld:1; /* 133 */
+ u32 q0txallowed:1; /* 132 */
+ u32 q0selarb:2; /* 131:130 */
+ u32 q1_selH:2; /* 129:128 split 2/8 */
+#else
+ /* register word 0 (bit 31:0) */
+ u32 nummsg:18; /* 17:0 */
+ u32 cfgsaben:1; /* 18 enable SAB broadcasting */
+ u32 cfgnotifyqne:1; /* 19 enable Q not empty intr */
+ u32 cfgcrid:1; /* 20 critical rid config */
+ u32 cpu_notify:8; /* 28:21 */
+ u32 rid:3; /* 31:29 */
+
+ /* register word 1 (bit 63:32) */
+ u32 q7selarb:2; /* 33:32 */
+ u32 q7txallowed:1; /* 34 */
+ u32 q7reqvld:1; /* 35 */
+ u32 q7_sel:10; /* 45:36 */
+ u32 q6selarb:2; /* 47:46 */
+ u32 q6txallowed:1; /* 48 */
+ u32 q6reqvld:1; /* 49 */
+ u32 q6_sel:10; /* 59:50 */
+ u32 q5selarb:2; /* 61:60 */
+ u32 q5txallowed:1; /* 62 */
+ u32 q5reqvld:1; /* 63 */
+
+ /* register word 2 (bit 95:64) */
+ u32 q5_sel:10; /* 73:64 */
+ u32 q4selarb:2; /* 75:74 */
+ u32 q4txallowed:1; /* 76 */
+ u32 q4reqvld:1; /* 77 */
+ u32 q4_sel:10; /* 87:78 */
+ u32 q3selarb:2; /* 89:88 */
+ u32 q3txallowed:1; /* 90 */
+ u32 q3reqvld:1; /* 91 */
+ u32 q3_selL:4; /* 95:92 split 4/6 */
+
+ /* register word 3 (bit 127:96) */
+ u32 q3_selH:6; /* 101:96 split 4/6 */
+ u32 q2selarb:2; /* 103:102 */
+ u32 q2txallowed:1; /* 104 */
+ u32 q2reqvld:1; /* 105 */
+ u32 q2_sel:10; /* 115:106 */
+ u32 q1selarb:2; /* 117:116 */
+ u32 q1txallowed:1; /* 118 */
+ u32 q1reqvld:1; /* 119 */
+ u32 q1_selL:8; /* 127:120 split 2/8 */
+
+ /* register word 4 (bit 159:128) */
+ u32 q1_selH:2; /* 129:128 split 2/8 */
+ u32 q0selarb:2; /* 131:130 */
+ u32 q0txallowed:1; /* 132 */
+ u32 q0reqvld:1; /* 133 */
+ u32 q0_sel:10; /* 143:134 */
+ u32 cfgselthrsh:3; /* 146:144 associated threshold set */
+ u32 cfgqtype:2; /* 148:147 queue type */
+ u32 resv1:11; /* 159:149 */
+#endif
+} __packed;
+
+union storm_qmtm_qstate {
+ struct storm_qmtm_csr_qstate csr;
+ struct storm_qmtm_pq_fp_qstate pq;
+ struct storm_qmtm_pq_fp_qstate fp;
+ struct storm_qmtm_vq_qstate vq;
+} __packed;
+
+/* Storm QMTM operations */
+static void storm_qmtm_write_qstate(struct xgene_mbox *mbox)
+{
+ struct xgene_qmtm *qmtm = mbox->qmtm;
+ struct storm_qmtm_csr_qstate *csr_qstate =
+ &((union storm_qmtm_qstate *)mbox->qstate)->csr;
+
+ /* write queue number */
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_ADDR, QNUMBER_WR(mbox->qid));
+
+ /* write queue state */
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_0_ADDR, csr_qstate->w0);
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_1_ADDR, csr_qstate->w1);
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_2_ADDR, csr_qstate->w2);
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_3_ADDR, csr_qstate->w3);
+ xgene_qmtm_wr32(qmtm, CSR_QSTATE_WR_4_ADDR, csr_qstate->w4);
+}
+
+static void storm_qmtm_set_qstate(struct xgene_mbox *mbox)
+{
+ struct storm_qmtm_pq_fp_qstate *pq_fp =
+ &((union storm_qmtm_qstate *)(mbox->qstate))->pq;
+
+ if (QMTM_QTYPE_VQ(mbox))
+ pq_fp->cfgqtype = QTYPE_VQ;
+ else if (QMTM_QTYPE_FP(mbox))
+ pq_fp->cfgqtype = QTYPE_FP;
+ else
+ pq_fp->cfgqtype = QTYPE_PQ;
+
+ /* if its a free queue, ask QMTM to set len to 0 when dealloc */
+ if (pq_fp->cfgqtype == QTYPE_FP)
+ pq_fp->fp_mode = CHANGE_LEN;
+
+ if (QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_ETH0 ||
+ QMTM_SLAVE_ID(mbox) == QMTM_SLAVE_ID_ETH1) {
+ pq_fp->cfgRecombBuf = 1;
+ pq_fp->cfgRecombBufTimeoutL = 0xf;
+ pq_fp->cfgRecombBufTimeoutH = 0x7;
+ }
+
+ pq_fp->cfgselthrsh = 1;
+ /* Allow the queue to accept message with non-zero LErr */
+ pq_fp->cfgacceptlerr = 1;
+ pq_fp->qcoherent = 1;
+ pq_fp->cfgstartaddrL = (u32)((mbox->dma >> 8) & (u32)(BIT(27) - 1));
+ pq_fp->cfgstartaddrH = (u32)(mbox->dma >> 35);
+ pq_fp->cfgqsize = mbox->slots;
+ storm_qmtm_write_qstate(mbox);
+}
+
+static void storm_qmtm_clr_qstate(struct xgene_mbox *mbox)
+{
+ memset(mbox->qstate, 0, sizeof(union storm_qmtm_qstate));
+ storm_qmtm_write_qstate(mbox);
+}
+
+static u32 storm_qmtm_read_level(void *qfabric)
+{
+ return (readl(&(((u32 *)qfabric)[1])) & 0x1fffe) >> 1;
+}
+
+static int storm_qmtm_init(struct xgene_qmtm *qmtm)
+{
+ int ret = 0, val;
+ xgene_qmtm_rd32(qmtm, CSR_IPBRR_ADDR, &val);
+ switch (val) {
+ case CSR_IPBRR_QMTM0_DEFAULT:
+ qmtm->qmtm_ip = QMTM0;
+ qmtm->irq_start = 0;
+ qmtm->irq_count = 16;
+ break;
+ case CSR_IPBRR_QMTM1_DEFAULT:
+ qmtm->qmtm_ip = QMTM1;
+ qmtm->irq_start = 0;
+ qmtm->irq_count = 32;
+ break;
+ case CSR_IPBRR_QMTM2_DEFAULT:
+ qmtm->qmtm_ip = QMTM2;
+ qmtm->irq_start = 16;
+ qmtm->irq_count = 16;
+ break;
+ case CSR_IPBRR_QMTM3_DEFAULT:
+ qmtm->qmtm_ip = QMTM3;
+ qmtm->irq_start = 0;
+ qmtm->irq_count = 1;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+struct xgene_qmtm_ops storm_qmtm_ops = {
+ .init = storm_qmtm_init,
+ .set_qstate = storm_qmtm_set_qstate,
+ .clr_qstate = storm_qmtm_clr_qstate,
+ .read_level = storm_qmtm_read_level,
+};
diff --git a/include/linux/platform_data/xgene_qmtm.h b/include/linux/platform_data/xgene_qmtm.h
new file mode 100644
index 0000000..23e630c
--- /dev/null
+++ b/include/linux/platform_data/xgene_qmtm.h
@@ -0,0 +1,300 @@
+/*
+ * AppliedMicro X-Gene SoC Queue Manager/Traffic Manager driver
+ *
+ * Copyright (c) 2013 Applied Micro Circuits Corporation.
+ * Author: Ravi Patel <rapatel@apm.com>
+ * Keyur Chudgar <kchudgar@apm.com>
+ * Fushen Chen <fchen@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __XGENE_QMTM_H__
+#define __XGENE_QMTM_H__
+
+/* QMTM Data Length encoded as per QM message format */
+enum xgene_mbox_data_len {
+ DATA_LEN_256B = 0x0100,
+ DATA_LEN_1K = 0x0400,
+ DATA_LEN_2K = 0x0800,
+ DATA_LEN_4K = 0x1000,
+ DATA_LEN_16K = 0x4000,
+};
+
+enum xgene_mbox_mask_len {
+ MASK_LEN_256B = (DATA_LEN_256B - 1),
+ MASK_LEN_1K = (DATA_LEN_1K - 1),
+ MASK_LEN_2K = (DATA_LEN_2K - 1),
+ MASK_LEN_4K = (DATA_LEN_4K - 1),
+ MASK_LEN_16K = (DATA_LEN_16K - 1),
+};
+
+/* QMTM Buffer Length encoded as per QM message format */
+enum xgene_mbox_buf_len {
+ BUF_LEN_256B = 0x7000,
+ BUF_LEN_1K = 0x6000,
+ BUF_LEN_2K = 0x5000,
+ BUF_LEN_4K = 0x4000,
+ BUF_LEN_16K = 0x0000,
+};
+
+/* QMTM messaging structures */
+/* 16 byte QMTM message format */
+struct xgene_mbox_msg16 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* memory word 0 (bit 31:0) */
+ u32 UserInfo;
+
+ /* memory word 1 (bit 63:32) */
+ u32 HL:1;
+ u32 LErr:3;
+ u32 RType:4;
+ u32 IN:1;
+ u32 Rv:1;
+ u32 HB:1;
+ u32 PB:1;
+ u32 LL:1;
+ u32 NV:1;
+ u32 LEI:2;
+ u32 ELErr:2;
+ u32 Rv2:2;
+ u32 FPQNum:12;
+
+ /* memory word 2 (bit 95:64) */
+ u32 DataAddrL; /* split 10/32 */
+
+ /* memory word 3 (bit 127:96) */
+ u32 C:1;
+ u32 BufDataLen:15;
+ u32 Rv6:6;
+ u32 DataAddrH:10; /* split 10/32 */
+#else
+ /* memory word 0 (bit 31:0) */
+ u32 UserInfo;
+
+ /* memory word 1 (bit 63:32) */
+ u32 FPQNum:12;
+ u32 Rv2:2;
+ u32 ELErr:2;
+ u32 LEI:2;
+ u32 NV:1;
+ u32 LL:1;
+ u32 PB:1;
+ u32 HB:1;
+ u32 Rv:1;
+ u32 IN:1;
+ u32 RType:4;
+ u32 LErr:3;
+ u32 HL:1;
+
+ /* memory word 2 (bit 95:64) */
+ u32 DataAddrL; /* split 10/32 */
+
+ /* memory word 3 (bit 127:96) */
+ u32 DataAddrH:10; /* split 10/32 */
+ u32 Rv6:6;
+ u32 BufDataLen:15;
+ u32 C:1;
+#endif
+} __packed;
+
+/* Higher 16 byte portion of 32 byte of QMTM message format */
+struct xgene_mbox_msg16H {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ /* memory word 4 (bit 159:128) */
+ u32 H0Info_msbL; /* split 16/32 */
+
+ /* memory word 5 (bit 191:160) */
+ u32 HR:1;
+ u32 Rv0:1;
+ u32 DR:1;
+ u32 Rv1:1;
+ u32 TotDataLengthLinkListLSBs:12;
+ u16 H0Info_msbH; /* split 16/32 */
+
+ /* memory word 6 (bit 223:192) */
+ u32 H0Info_lsbL; /* split 16/32 */
+
+ /* memory word 7 (bit 255:224) */
+ u32 H0FPSel:4;
+ u32 H0Enq_Num:12;
+ u16 H0Info_lsbH; /* split 16/32 */
+#else
+ /* memory word 4 (bit 159:128) */
+ u32 H0Info_msbL; /* split 16/32 */
+
+ /* memory word 5 (bit 191:160) */
+ u16 H0Info_msbH; /* split 16/32 */
+ u32 TotDataLengthLinkListLSBs:12;
+ u32 Rv1:1;
+ u32 DR:1;
+ u32 Rv0:1;
+ u32 HR:1;
+
+ /* memory word 6 (bit 223:192) */
+ u32 H0Info_lsbL; /* split 16/32 */
+
+ /* memory word 7 (bit 255:224) */
+ u16 H0Info_lsbH; /* split 16/32 */
+ u32 H0Enq_Num:12;
+ u32 H0FPSel:4;
+#endif
+} __packed;
+
+/* 8 byte portion of QMTM extended (64B) message format */
+struct xgene_mbox_msg8 {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ u32 NxtDataAddrL;
+ u32 Rv1:1;
+ u32 NxtBufDataLength:15;
+ u32 NxtFPQNum:4;
+ u32 Rv2:2;
+ u32 NxtDataAddrH:10;
+#else
+ u32 NxtDataAddrL;
+ u32 NxtDataAddrH:10;
+ u32 Rv2:2;
+ u32 NxtFPQNum:4;
+ u32 NxtBufDataLength:15;
+ u32 Rv1:1;
+#endif
+} __packed;
+
+/* 8 byte Link list portion of QMTM extended (64B) message format */
+struct xgene_mbox_msg8_list {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ u32 NxtDataPtrL;
+ u8 TotDataLengthLinkListMSBs;
+ u8 NxtLinkListength;
+ u32 NxtFPQNum:4;
+ u32 Rv2:2;
+ u32 NxtDataPtrH:10;
+#else
+ u32 NxtDataPtrL;
+ u32 NxtDataPtrH:10;
+ u32 Rv2:2;
+ u32 NxtFPQNum:4;
+ u8 NxtLinkListength;
+ u8 TotDataLengthLinkListMSBs;
+#endif
+} __packed;
+
+/* This structure represents 32 byte QMTM message format */
+struct xgene_mbox_msg32 {
+ struct xgene_mbox_msg16 msg16;
+ struct xgene_mbox_msg16H msg16H;
+} __packed;
+
+ /* Higher 32 byte of QMTM extended (64B) message format */
+struct xgene_mbox_msg32H {
+ struct xgene_mbox_msg8 msg8_2;
+ struct xgene_mbox_msg8 msg8_1;
+ union {
+ struct xgene_mbox_msg8 msg8_4;
+ struct xgene_mbox_msg8_list msg8_list;
+ };
+ struct xgene_mbox_msg8 msg8_3;
+} __packed;
+
+/* 64 byte QMTM message format */
+struct xgene_mbox_msg64 {
+ struct xgene_mbox_msg32 msg32;
+ struct xgene_mbox_msg32H msg32H;
+} __packed;
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define xgene_mbox_msg_le32(word, words) \
+ do { \
+ int w; \
+ for (w = 0; w < words; w++) \
+ *(word + w) = cpu_to_le32(*(word + w)); \
+ } while (0)
+#else
+#define xgene_mbox_msg_le32(word, words) \
+ do {} while (0)
+#endif
+
+/* Empty Slot Soft Signature */
+#define EMPTY_SLOT_INDEX 7
+#define EMPTY_SLOT 0x22222222
+
+/* Encoding Destination QMTM (2 MSB) and Queue ID */
+#define QMTM_QUEUE_ID(q) (((u16)(q->qstate[6]) << 10) | q->qid)
+
+/* Decoding PBM signal */
+#define QMTM_PBN(q) (q->pbm & 0x003F)
+#define QMTM_SLAVE_ID(q) ((q->pbm & 0x03C0) >> 6)
+#define QMTM_QTYPE_FP(q) (q->pbm & 0x0020)
+#define QMTM_QTYPE_VQ(q) (q->pbm & 0x0400)
+
+/* Per queue state database */
+struct xgene_mbox {
+ u16 pbm;
+ u16 qid;
+ u16 qhead;
+ u16 qtail;
+ u16 slots;
+ u16 irq;
+ u32 qsize;
+ u32 pbm_state;
+ u32 qstate[7];
+ void *qfabric;
+ void *level;
+ dma_addr_t dma;
+ union {
+ void *qaddr;
+ struct xgene_mbox_msg16 *msg16;
+ struct xgene_mbox_msg32 *msg32;
+ };
+ struct xgene_qmtm *qmtm;
+};
+
+static inline u16 xgene_mbox_encode_bufdatalen(u32 len)
+{
+ if (len <= DATA_LEN_256B)
+ return BUF_LEN_256B | (len & MASK_LEN_256B);
+ else if (len <= DATA_LEN_1K)
+ return BUF_LEN_1K | (len & MASK_LEN_1K);
+ else if (len <= DATA_LEN_2K)
+ return BUF_LEN_2K | (len & MASK_LEN_2K);
+ else if (len <= DATA_LEN_4K)
+ return BUF_LEN_4K | (len & MASK_LEN_4K);
+ else if (len < DATA_LEN_16K)
+ return BUF_LEN_16K | (len & MASK_LEN_16K);
+ else
+ return BUF_LEN_16K;
+}
+
+static inline u16 xgene_mbox_encode_datalen(u32 len)
+{
+ return len & MASK_LEN_16K;
+}
+
+static inline u32 xgene_mbox_decode_datalen(u16 bufdatalen)
+{
+ switch (bufdatalen & BUF_LEN_256B) {
+ case BUF_LEN_256B:
+ return bufdatalen & MASK_LEN_256B ? : DATA_LEN_256B;
+ case BUF_LEN_1K:
+ return bufdatalen & MASK_LEN_1K ? : DATA_LEN_1K;
+ case BUF_LEN_2K:
+ return bufdatalen & MASK_LEN_2K ? : DATA_LEN_2K;
+ case BUF_LEN_4K:
+ return bufdatalen & MASK_LEN_4K ? : DATA_LEN_4K;
+ default:
+ return bufdatalen & MASK_LEN_16K ? : DATA_LEN_16K;
+ };
+}
+
+struct xgene_mbox *xgene_mbox_get(struct device *dev, const char *s);
+void xgene_mbox_put(struct xgene_mbox *mbox);
+u32 xgene_mbox_level(struct xgene_mbox *mbox);
+
+#endif /* __XGENE_QMTM_H__ */
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 2/4] Documentation: devicetree: bindings for APM X-Gene SoC QMTM
From: Ravi Patel @ 2014-02-15 2:22 UTC (permalink / raw)
To: arnd, gregkh, davem
Cc: netdev, linux-kernel, devicetree, linux-arm-kernel, jcm, patches,
Ravi Patel, Keyur Chudgar
In-Reply-To: <1392430922-24643-1-git-send-email-rapatel@apm.com>
This patch adds devicetree bindings documentation for APM X-Gene SoC Queue
Manager/Traffic Manager.
Signed-off-by: Ravi Patel <rapatel@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
.../devicetree/bindings/mailbox/apm-xgene-qmtm.txt | 53 ++++++++++++++++++++
1 file changed, 53 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
diff --git a/Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt b/Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
new file mode 100644
index 0000000..cb17d5f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
@@ -0,0 +1,53 @@
+* APM X-Gene SoC Queue Manager/Traffic Manager mailbox nodes
+
+Mailbox nodes are defined to describe on-chip Queue Managers in APM X-Gene SoC.
+APM X-Gene SoC Ethernet, PktDMA (XOR Engine), and Security Engine subsystems
+communicate with a central Queue Manager using messages which include
+information about the work to be performed and the location of the associated
+data buffers. There are multiple instances of QMTM. Each QMTM instance has its
+own node. Its corresponding clock nodes are shown below.
+
+Required properties:
+- compatible : Shall be "apm,xgene-qmtm"
+- reg : First memory resource shall be the QMTM register
+ memory resource.
+ Second memory resource shall be the QMTM IO-Fabric
+ memory resource.
+- #mailbox-cells : Shall be 4 as it expects following arguments
+ First cell for 64-bit mailbox bus address MSB.
+ Second cell for 64-bit mailbox bus address LSB.
+ Third cell for 32-bit mailbox size.
+ Fourth cell for 32-bit mailbox signal/id value.
+- interrupts : First interrupt resource shall be the QMTM Error
+ interrupt.
+ Remaining interrupt resources shall be the Ingress
+ work message interrupt mapping for receiver,
+ receiving work messages for the QMTM.
+- clocks : Reference to the clock entry.
+
+Optional properties:
+- status : Shall be "ok" if enabled or "disabled" if disabled.
+ Default is "ok".
+
+Example:
+ qmlclk: qmlclk {
+ compatible = "apm,xgene-device-clock";
+ #clock-cells = <1>;
+ clock-names = "socplldiv2";
+ status = "ok";
+ csr-offset = <0x0>;
+ csr-mask = <0x3>;
+ enable-offset = <0x8>;
+ enable-mask = <0x3>;
+ };
+
+ qmlite: mailbox@17030000 {
+ compatible = "apm,xgene-qmtm";
+ #mailbox-cells = <4>;
+ status = "ok";
+ reg = <0x0 0x17030000 0x0 0x10000>,
+ <0x0 0x10000000 0x0 0x400000>;
+ interrupts = <0x0 0x40 0x4>,
+ <0x0 0x3c 0x4>;
+ clocks = <&qmlclk 0>;
+ };
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 1/4] Documentation: mailbox: APM X-Gene SoC QMTM
From: Ravi Patel @ 2014-02-15 2:21 UTC (permalink / raw)
To: arnd, gregkh, davem
Cc: netdev, linux-kernel, devicetree, linux-arm-kernel, jcm, patches,
Ravi Patel, Keyur Chudgar
In-Reply-To: <1392430922-24643-1-git-send-email-rapatel@apm.com>
This patch adds documentation for APM X-Gene SoC Queue Manager/Traffic Manager.
Signed-off-by: Ravi Patel <rapatel@apm.com>
Signed-off-by: Keyur Chudgar <kchudgar@apm.com>
---
Documentation/mailbox/apm-xgene-qmtm.txt | 149 ++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
create mode 100644 Documentation/mailbox/apm-xgene-qmtm.txt
diff --git a/Documentation/mailbox/apm-xgene-qmtm.txt b/Documentation/mailbox/apm-xgene-qmtm.txt
new file mode 100644
index 0000000..2b4ff09
--- /dev/null
+++ b/Documentation/mailbox/apm-xgene-qmtm.txt
@@ -0,0 +1,149 @@
+AppliedMicro X-Gene SOC Queue Manager/Traffic Manager Document
+
+Copyright (c) 2013 Applied Micro Circuits Corporation.
+Author: Ravi Patel <rapatel@apm.com>
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 2 as published by
+the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+
+Overview:
+QMTM is a device which interacts with CPU, Ethernet, PktDMA and Security
+subsystems through AXI BUS. Its centralized resource manager/driver exports
+APIs for CPU, Ethernet, PktDMA and Security subsystems to
+1. Initialize & allocate queue & pbn.
+2. Read queue state so that subsystems driver knows how much more work it can
+ offload to its subsystem.
+3. Apply QoS for subsystems on their queues.
+
+Layout:
+The layout represents run-time flow of messages between Ethernet subsystem, CPU
+and QMTM in APM X-Gene SOC. PktDMA and Security subsystems interfaces with QMTM
+in the same way as Ethernet.
+
+
+ CPU
+ o-------------------------o
+ | |
+ +----|[2] {5}|----+
+ | | [1] {4} | |
+Register | o------+-----------+------o | Register
+Write | CPU WR | | CPU RD | Write
+to start v MSG v ^ MSG v to notify
+packet | | DDR | | packet
+transmit | o--------+-----o-----+--------o | received
+ | | Q0 M . M M | M M . M Q1 | |
+ | | for S . S S | S S . S for | |
+ | | ETH G . G G | G G . G ETH | |
+ | | TX n . 2 1 | 1 2 . n RX | |
+ | o----------+---o---+----------o |
+ | | | |
+ v v ^ v
+ | | | |
+o--------|-------------|-------|-------------|--------o
+| | | | | | Coherent
+| v v ^ v | I/O
+| | | | | | BUS
+o--------|-------------|-------|-------------|--------o
+ | [3] | | {3} |
+ v QMTM RD v ^ QMTM WR v
+ | MSG | | MSG |
+ o----+----o--------+---o---+--------o----+----o
+ | Queue 0 | | | Queue 1 |
+ | Command o ETH PBN 0 o CPU PBN 0 o Command | Queue Manager/
+ | Register| | |Register | Traffic Manager
+ o---------o---+--------o--------+---o---------o
+ | |
+ v ^
+Ethernet RD MSG | [4] ETH {2} | Ethernet WR MSG
+from its PBN o---+-----------------+---o to CPU PBN
+ | |
+ | Egress MAC Ingress MAC |
+ | [5] {1} |
+ o------|-----------|------o
+ v ^
+ | |
+ TX Data RX Data
+
+Transmit Flow
+[1] CPU (Ethernet driver) prepares 32 byte Ethernet egress work message and
+ enqueues the message to the queue in DDR.
+[2] CPU (Ethernet driver) notifies QMTM that there is a message enqueued in
+ Ethernet transmit queue (e.g. Q0).
+[3] QMTM prefetches the Ethernet egress work messages into Ethernet PBN
+ (e.g. ETH PBN 0).
+[4] Ethernet reads work messages from its PBN.
+[5] Ethernet DMAs payload from DDR to its egress FIFO and transmits data out.
+
+Receive Flow
+{1} Ethernet receives data and DMAs payload from its ingress FIFO to DDR and
+ prepares a Ethernet ingress work message.
+{2} Ethernet pushes work message to QMTM.
+{3} QMTM prefetches the Ethernet ingress work messages into CPU PBN
+ (e.g. CPU PBN 0) and then interrupts CPU.
+{4} CPU (Ethernet driver) dequeues the 32 bytes Ethernet ingress work message
+ from the queue in DDR.
+{5} CPU (Ethernet driver) notifies QMTM that it dequeued a message from
+ Ethernet receive queue (e.g. Q1).
+
+
+Definition:
+1. QMTM (Queue/Traffic Manager)
+ QMTM manages queues and pbns for CPU, Ethernet, PktDMA and Security
+ Subsystems. It also performs flow control and QoS on queues.
+
+2. Slave/Client/Agent
+ Ethernet, PktDMA (XOR Engine) and Security Engine Subsystems & CPU whose
+ queues and pbn are managed by QMTM are called slave/client/agent.
+
+3. Queue
+ Queue is circular FIFO memory for QMTM hardware in which a 16 bytes,
+ 32 bytes or 64 bytes message is dequeued OR enqueued between CPU and
+ Ethernet, PktDMA and Security Engine Subsystems.
+
+4. PB
+ Each subsystem in the APM X-Gene SoC device has a prefetch buffer for
+ storing messages in order to pipeline the QMTM processing latency with the
+ subsystem processing latency. The number of buffers prefetched depends on
+ the QM/TM processing latency and the subsystem data rate.
+
+ There are multiple PB for a subsystem, each PB is assigned a number which is
+ called PBN. Each subsystem and CPU can have max 32 pbns, however QMTM limits
+ how many pbns it supports for each subsystem.
+
+5. Message
+ The subsystems in the APM X-Gene SoC communicate with a central Queue Manager
+ (QM) that manages all the messages queued to the subsystems. The subsystems
+ communicate with the QM using messages that include information about the
+ work to be performed and the location of the buffers or data on which the
+ work is to be performed.
+
+ A message consists of 16, 32 or 64 bytes which resides in a queue. A message
+ which is
+ a. 16 bytes contains information of data buffer, length, etc. allocated by
+ subsystem driver.
+ b. 32 or 64 bytes contains information about the work to be done for a
+ subsystem. Each subsystem defines its own format of work message.
+
+ Each subsystem defines their own format of work message. A message (or queue
+ descriptor) has attribute fields (QMTM specific) which are common for all
+ subsystem work messages. The remaining fields of a message are specific to
+ subsystem. QMTM device doesn't have any knowledge of these subsystems
+ specific fields and the data operation which subsystem is going to perform
+ using these fields.
+
+ e.g.
+ 1. Ethernet work message includes data address & length which is used by
+ Ethernet DMA engine for copying the data to/from its internal FIFO.
+ 2. PktDMA work message includes multiple data addresses & lengths for
+ doing scatter/gather, XOR operations and result data address/es to give
+ back result to the CPU (driver).
+ 3. Security work message includes data address & length for doing encryption
+ or decryption, the type of encryption or decryption and result data
+ address to give back result to the CPU (driver).
--
1.7.9.5
^ permalink raw reply related
* [PATCH V3 0/4] mailbox: xgene: Add support for APM X-Gene SoC Queue Manager/Traffic Manager
From: Ravi Patel @ 2014-02-15 2:21 UTC (permalink / raw)
To: arnd-r2nGTMty4D4, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
jcm-H+wXaHxf7aLQT0dZR+AlfA, patches-qTEPVZfXA3Y, Ravi Patel,
Keyur Chudgar
This patch adds support for APM X-Gene SoC Queue Manager/Traffic Manager.
QMTM is required by APM X-Gene SoC Ethernet, PktDMA (XOR Engine) and
Security Engine subsystems. All subsystems communicate with QMTM using
messages which include information about the work to be performed and
the location of associated data buffers.
V3:
* Switch to mailbox framework
* Add support for little and big endian kernel
* Change virt_to_phys function call to dma_zalloc_coherent
V2:
* Adding COMPILE_TEST dependency for QMTM in Kconfig
* Updated license banner as per review comments
* Fixed alignment for macros
* Changed EXPORT_SYMBOL to EXPORT_SYMBOL_GPL
V1:
* inital version
Signed-off-by: Ravi Patel <rapatel-qTEPVZfXA3Y@public.gmane.org>
Signed-off-by: Keyur Chudgar <kchudgar-qTEPVZfXA3Y@public.gmane.org>
---
Ravi Patel (4):
Documentation: mailbox: APM X-Gene SoC QMTM
Documentation: devicetree: bindings for APM X-Gene SoC QMTM
mailbox: xgene: base driver for APM X-Gene SoC QMTM
arm64: boot: dts: entries for APM X-Gene SoC QMTM
.../devicetree/bindings/mailbox/apm-xgene-qmtm.txt | 53 ++
Documentation/mailbox/apm-xgene-qmtm.txt | 149 ++++++
MAINTAINERS | 9 +
arch/arm64/boot/dts/apm-storm.dtsi | 18 +-
drivers/mailbox/Kconfig | 2 +
drivers/mailbox/Makefile | 1 +
drivers/mailbox/xgene/Kconfig | 9 +
drivers/mailbox/xgene/Makefile | 7 +
drivers/mailbox/xgene/xgene_qmtm_main.c | 516 ++++++++++++++++++++
drivers/mailbox/xgene/xgene_qmtm_main.h | 112 +++++
drivers/mailbox/xgene/xgene_qmtm_storm.c | 358 ++++++++++++++
include/linux/platform_data/xgene_qmtm.h | 300 ++++++++++++
12 files changed, 1533 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/mailbox/apm-xgene-qmtm.txt
create mode 100644 Documentation/mailbox/apm-xgene-qmtm.txt
create mode 100644 drivers/mailbox/xgene/Kconfig
create mode 100644 drivers/mailbox/xgene/Makefile
create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.c
create mode 100644 drivers/mailbox/xgene/xgene_qmtm_main.h
create mode 100644 drivers/mailbox/xgene/xgene_qmtm_storm.c
create mode 100644 include/linux/platform_data/xgene_qmtm.h
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 2/3] ARM: dts: add dts files for exynos5260 SoC
From: Tomasz Figa @ 2014-02-15 1:36 UTC (permalink / raw)
To: Rahul Sharma, linux-samsung-soc
Cc: devicetree, linux-arm-kernel, kgene.kim, joshi, r.sh.open
In-Reply-To: <1392385032-22015-3-git-send-email-rahul.sharma@samsung.com>
Hi,
On 14.02.2014 14:37, Rahul Sharma wrote:
> The patch adds the dts files for exynos5260.
>
> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com>
> Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
> Signed-off-by: Arun Kumar K <arun.kk@samsung.com>
> ---
> arch/arm/boot/dts/exynos5260-pinctrl.dtsi | 574 +++++++++++++++++++++++++++++
> arch/arm/boot/dts/exynos5260.dtsi | 304 +++++++++++++++
> 2 files changed, 878 insertions(+)
> create mode 100644 arch/arm/boot/dts/exynos5260-pinctrl.dtsi
> create mode 100644 arch/arm/boot/dts/exynos5260.dtsi
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Best regards,
Tomasz
^ permalink raw reply
* Re: [PATCH RFC v3 3/3] Documentation: arm: define DT idle states bindings
From: Sebastian Capella @ 2014-02-15 1:22 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Mark Rutland, Mike Turquette, Tomasz Figa, Mark Hambleton,
Russell King, Nicolas Pitre, Daniel Lezcano,
linux-arm-kernel@lists.infradead.org, grant.likely@linaro.org,
Dave P Martin, Charles Garcia-Tobin, devicetree@vger.kernel.org,
Kevin Hilman, linux-pm@vger.kernel.org, Kumar Gala, Rob Herring,
Vincent Guittot, Antti Miettinen, pveerapa@broadcom.com,
Peter De Schrijver
In-Reply-To: <20140214112756.GA25043@e102568-lin.cambridge.arm.com>
Quoting Lorenzo Pieralisi (2014-02-14 03:27:56)
> On Fri, Feb 14, 2014 at 12:29:26AM +0000, Sebastian Capella wrote:
> > Quoting Lorenzo Pieralisi (2014-02-13 04:47:32)
> >
> > > Such as ? "idle-states" ?
> >
> > That sounds good to me. Our preference is for idle-states to be used
> > for name of the idle-states.txt node.
>
> Ok, so s/cpu-idle-state/idle-state everywhere, inclusive of state nodes
> compatible properties ("arm,cpu-idle-state" becomes "arm,idle-state") ?
No, we were looking to make sure that the cpu-idle-states defined in
cpus.txt:
- cpu node
- cpu-idle-states
And the cpu-idle-states defined in idle-states.txt:
- cpu-idle-states node
Did not use the same name, and instead had different, unique names.
Our preference was to change only the idle-states.txt name.
> I do not like that, but I can remove the naming scheme and let people
> find a naming scheme that complies with DT rules (nodes within a parent
> must have a unique name). Not sure this would make dts more readable, but
> I do not think it is a problem either.
In the current implementation for cpuidle, we have a descriptive c-state
name. As long as we can get this kind of functionality using the node
name this seems fine to me.
> That's exactly what these bindings are meant to describe too and I think they
> do. There is also loads of information that can be used for tuning (what
> caches are affected by an idle state, what CPUs "share" an idle-state
> and so on).
Great :)
> > >
> > > > Definition: It represents an idle state index.
> > > >
> > > > Index 0 and 1 shall not be specified and are reserved for ARM
> > > > states where index 0 is running, and index 1 is idle_standby
> > > > entered by executing a wfi instruction (SBSA,[3])
> > > >
> > > > What mechanism is used to order the power states WRT power consumption?
> > >
> > > I think we should use index for that. The higher the index the lower the
> > > power consumption.
> >
> > Ok, I think I get it now.
> > If we decouple index and SBSA states, do we really need to reserve index
> > 0 and 1 then?
>
> What I will do: move the entry-method to top-level cpu-idle-states node
> (soon to be idle-states node) and add a property there:
>
> "arm,has-idlewfi"
>
> which allows me to prevent people from adding an explicit state that just
> executes the wfi instruction on entry.
>
> This way we can have a *global* entry-method, and we can also detect if the
> platform supports wfi in its bare form.
>
> Yes, index can start from 0, disallowing 0 and 1 was a (odd) way to prevent
> people from adding wfi to DT. If the platform supports simple idlestandby
> (ie wfi) it has to add the boolean property above.
>
> How does that sound ?
In general I'm ok with indexing as you have it, even if only to specify
an ordering of states by power. I even thought maybe you could call it
order or sort-order or something, to help people understand you won't
use it as an array index or name, but I don't think it's a big deal
either way.
Do platforms remove support for WFI? If they do, is this detectible
somehow directly from the ARM without relying on DTS? It seems like
a comment is enough to discourage people from defining a wfi state.
Then eventually implement a common code path for idle. I'm fine not
specifying this flag, but if you feel it can be useful I don't object.
> > Should we not allow more flexibility here to mix methods where some
> > states use one method and some use others? Is this mostly a security
> > concern? What if a vendor wants to introduce a state between wfi and
> > cpu-sleep?
>
> entry-method-param is the way to differentiate. One interface/entry-method
> (PSCI or vendor specific), different state parameters.
>
> We are not installing multiple back-ends to enter different idle states,
> are we ? That would be awkward.
>
> ACK ?
ACK, thanks!
Sebastian
^ permalink raw reply
* Re: [PATCH v3] sh_eth: add device tree support
From: Sergei Shtylyov @ 2014-02-15 1:03 UTC (permalink / raw)
To: Laurent Pinchart
Cc: robh+dt, pawel.moll, mark.rutland, grant.likely, devicetree,
linux-sh, ijc+devicetree, galak, nobuhiro.iwamatsu.yj, rob,
linux-doc
In-Reply-To: <1591086.qftVlE1XBX@avalon>
Hello.
On 02/11/2014 07:08 PM, Laurent Pinchart wrote:
> Thanks a lot for the patch. DT support for sh-eth was number one on my most
> wanted list :-)
It's been available for several months already (though just for BOCK-W).
Since the clock DT support turned to be the requirement, I had to change to
Lager/Koelsch where CCF is already available.
> Please see below for two minor comments.
Thanks.
Sigh, I had to scroll thru quite a lot of uncommented text to find them.
Please trim such text in the future to save the readers' time.
>> Add support of the device tree probing for the Renesas SH-Mobile SoCs
>> documenting the device tree binding as necessary.
>> This work is loosely based on the original patch by Nobuhiro Iwamatsu
>> <nobuhiro.iwamatsu.yj@renesas.com>.
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
[...]
>> Index: net-next/drivers/net/ethernet/renesas/sh_eth.c
>> ===================================================================
>> --- net-next.orig/drivers/net/ethernet/renesas/sh_eth.c
>> +++ net-next/drivers/net/ethernet/renesas/sh_eth.c
[...]
>> @@ -2710,6 +2714,56 @@ static const struct net_device_ops sh_et
>> .ndo_change_mtu = eth_change_mtu,
>> };
>>
>> +#ifdef CONFIG_OF
>> +static struct sh_eth_plat_data *sh_eth_parse_dt(struct device *dev)
>> +{
>> + struct device_node *np = dev->of_node;
>> + struct sh_eth_plat_data *pdata;
>> + struct device_node *phy;
>> + const char *mac_addr;
>> +
>> + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
>> + if (!pdata)
>> + return NULL;
>> +
>> + pdata->phy_interface = of_get_phy_mode(np);
>> +
>> + phy = of_parse_phandle(np, "phy-handle", 0);
>> + if (of_property_read_u32(phy, "reg", &pdata->phy)) {
>> + devm_kfree(dev, pdata);
> No need to free memory here, this will be handled by the core after the
> probe() function fails.
OK, we should fail the probe when we return NULL from here.
>> + return NULL;
>> + }
[...]
>> @@ -2778,7 +2834,19 @@ static int sh_eth_drv_probe(struct platf
>> mdp->ether_link_active_low = pd->ether_link_active_low;
>>
>> /* set cpu data */
>> - mdp->cd = (struct sh_eth_cpu_data *)id->driver_data;
>> + if (id) {
>> + mdp->cd = (struct sh_eth_cpu_data *)id->driver_data;
>> + } else {
>> + const struct of_device_id *match;
>> +
>> + match = of_match_device(of_match_ptr(sh_eth_match_table),
>> + &pdev->dev);
>> + if (!match) {
>> + ret = -EINVAL;
>> + goto out_release;
>> + }
> You can probably remove error checking, if no match is found the probe
> function wouldn't have been called in the first place.
Yes, you seem to be correct here as well.
WBR, Sergei
^ permalink raw reply
* [PATCHv2 5/5] Documentation: dt: wireless: Add wl1251
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
John W. Linville
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
netdev, Sebastian Reichel
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>
Add device tree binding documentation for Texas Instrument's wl1251
wireless lan chip. For now only the SPI binding is documented.
Signed-off-by: Sebastian Reichel <sre@debian.org>
---
.../devicetree/bindings/net/wireless/ti,wl1251.txt | 39 ++++++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt b/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
new file mode 100644
index 0000000..189ae5c
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
@@ -0,0 +1,39 @@
+* Texas Instruments wl1251 wireless lan controller
+
+The wl1251 chip can be connected via SPI or via SDIO. This
+document describes the binding for the SPI connected chip.
+
+Required properties:
+- compatible : Should be "ti,wl1251"
+- reg : Chip select address of device
+- spi-max-frequency : Maximum SPI clocking speed of device in Hz
+- interrupts : Should contain interrupt line
+- interrupt-parent : Should be the phandle for the interrupt controller
+ that services interrupts for this device
+- vio-supply : phandle to regulator providing VIO
+- ti,power-gpio : GPIO connected to chip's PMEN pin
+
+Optional properties:
+- ti,wl1251-has-eeprom : boolean, the wl1251 has an eeprom connected, which
+ provides configuration data (calibration, MAC, ...)
+- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
+ for optional SPI connection related properties,
+
+Examples:
+
+&spi1 {
+ wl1251@0 {
+ compatible = "ti,wl1251";
+
+ reg = <0>;
+ spi-max-frequency = <48000000>;
+ spi-cpol;
+ spi-cpha;
+
+ interrupt-parent = <&gpio2>;
+ interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */
+
+ vio-supply = <&vio>;
+ ti,power-gpio = <&gpio3 23 GPIO_ACTIVE_HIGH>; /* 87 */
+ };
+};
--
1.8.5.3
^ permalink raw reply related
* [PATCHv2 4/5] wl1251: spi: add device tree support
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
John W. Linville
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
netdev, Sebastian Reichel
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>
Add device tree support for the spi variant of wl1251.
Signed-off-by: Sebastian Reichel <sre@debian.org>
---
drivers/net/wireless/ti/wl1251/spi.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 0a8aacc..b06d36d 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -27,6 +27,8 @@
#include <linux/spi/spi.h>
#include <linux/wl12xx.h>
#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <linux/regulator/consumer.h>
#include "wl1251.h"
@@ -240,13 +242,13 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
static int wl1251_spi_probe(struct spi_device *spi)
{
- struct wl1251_platform_data *pdata;
+ struct wl1251_platform_data *pdata = dev_get_platdata(&spi->dev);
+ struct device_node *np = spi->dev.of_node;
struct ieee80211_hw *hw;
struct wl1251 *wl;
int ret;
- pdata = dev_get_platdata(&spi->dev);
- if (!pdata) {
+ if (!np && !pdata) {
wl1251_error("no platform data");
return -ENODEV;
}
@@ -273,7 +275,18 @@ static int wl1251_spi_probe(struct spi_device *spi)
goto out_free;
}
- wl->power_gpio = pdata->power_gpio;
+ if (np) {
+ wl->use_eeprom = of_property_read_bool(np, "ti,wl1251-has-eeprom");
+ wl->power_gpio = of_get_named_gpio(np, "ti,power-gpio", 0);
+ } else if (pdata) {
+ wl->power_gpio = pdata->power_gpio;
+ wl->use_eeprom = pdata->use_eeprom;
+ }
+
+ if (wl->power_gpio == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto out_free;
+ }
if (gpio_is_valid(wl->power_gpio)) {
ret = devm_gpio_request_one(&spi->dev, wl->power_gpio,
@@ -295,8 +308,6 @@ static int wl1251_spi_probe(struct spi_device *spi)
goto out_free;
}
- wl->use_eeprom = pdata->use_eeprom;
-
irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0,
DRIVER_NAME, wl);
--
1.8.5.3
^ permalink raw reply related
* [PATCHv2 3/5] wl1251: spi: add vio regulator support
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
John W. Linville
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
netdev, Sebastian Reichel
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>
This patch adds support for requesting the regulator powering
the vio pin.
Signed-off-by: Sebastian Reichel <sre@debian.org>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
---
drivers/net/wireless/ti/wl1251/spi.c | 19 +++++++++++++++++--
drivers/net/wireless/ti/wl1251/wl1251.h | 2 ++
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 6abcbc3..0a8aacc 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -27,6 +27,7 @@
#include <linux/spi/spi.h>
#include <linux/wl12xx.h>
#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
#include "wl1251.h"
#include "reg.h"
@@ -306,13 +307,26 @@ static int wl1251_spi_probe(struct spi_device *spi)
irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
- ret = wl1251_init_ieee80211(wl);
+ wl->vio = devm_regulator_get(&spi->dev, "vio");
+ if (IS_ERR(wl->vio)) {
+ ret = PTR_ERR(wl->vio);
+ wl1251_error("vio regulator missing: %d", ret);
+ goto out_free;
+ }
+
+ ret = regulator_enable(wl->vio);
if (ret)
goto out_free;
+ ret = wl1251_init_ieee80211(wl);
+ if (ret)
+ goto disable_regulator;
+
return 0;
- out_free:
+disable_regulator:
+ regulator_disable(wl->vio);
+out_free:
ieee80211_free_hw(hw);
return ret;
@@ -324,6 +338,7 @@ static int wl1251_spi_remove(struct spi_device *spi)
free_irq(wl->irq, wl);
wl1251_free_hw(wl);
+ regulator_disable(wl->vio);
return 0;
}
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 389fe25..16dae52 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -280,6 +280,8 @@ struct wl1251 {
int irq;
bool use_eeprom;
+ struct regulator *vio;
+
spinlock_t wl_lock;
enum wl1251_state state;
--
1.8.5.3
^ permalink raw reply related
* [PATCHv2 2/5] wl1251: move power GPIO handling into the driver
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
John W. Linville
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
netdev, Sebastian Reichel
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>
Move the power GPIO handling from the board code into
the driver. This is a dependency for device tree support.
Signed-off-by: Sebastian Reichel <sre@debian.org>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Tony Lindgren <tony@atomide.com>
---
arch/arm/mach-omap2/board-omap3pandora.c | 2 ++
arch/arm/mach-omap2/board-rx51-peripherals.c | 11 ++--------
drivers/net/wireless/ti/wl1251/sdio.c | 21 +++++++++++++-----
drivers/net/wireless/ti/wl1251/spi.c | 33 ++++++++++++++++++----------
drivers/net/wireless/ti/wl1251/wl1251.h | 2 +-
include/linux/wl12xx.h | 2 +-
6 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 24f3c1b..cf18340 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -541,6 +541,8 @@ static void __init pandora_wl1251_init(void)
memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
+ pandora_wl1251_pdata.power_gpio = -1;
+
ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq");
if (ret < 0)
goto fail;
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index e05e740..ddfc8df 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -1173,13 +1173,7 @@ static inline void board_smc91x_init(void)
#endif
-static void rx51_wl1251_set_power(bool enable)
-{
- gpio_set_value(RX51_WL1251_POWER_GPIO, enable);
-}
-
static struct gpio rx51_wl1251_gpios[] __initdata = {
- { RX51_WL1251_POWER_GPIO, GPIOF_OUT_INIT_LOW, "wl1251 power" },
{ RX51_WL1251_IRQ_GPIO, GPIOF_IN, "wl1251 irq" },
};
@@ -1196,17 +1190,16 @@ static void __init rx51_init_wl1251(void)
if (irq < 0)
goto err_irq;
- wl1251_pdata.set_power = rx51_wl1251_set_power;
+ wl1251_pdata.power_gpio = RX51_WL1251_POWER_GPIO;
rx51_peripherals_spi_board_info[RX51_SPI_WL1251].irq = irq;
return;
err_irq:
gpio_free(RX51_WL1251_IRQ_GPIO);
- gpio_free(RX51_WL1251_POWER_GPIO);
error:
printk(KERN_ERR "wl1251 board initialisation failed\n");
- wl1251_pdata.set_power = NULL;
+ wl1251_pdata.power_gpio = -1;
/*
* Now rx51_peripherals_spi_board_info[1].irq is zero and
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index b75a37a..b661f89 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -28,6 +28,7 @@
#include <linux/wl12xx.h>
#include <linux/irq.h>
#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
#include "wl1251.h"
@@ -182,8 +183,9 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
* callback in case it wants to do any additional setup,
* for example enabling clock buffer for the module.
*/
- if (wl->set_power)
- wl->set_power(true);
+ if (gpio_is_valid(wl->power_gpio))
+ gpio_set_value(wl->power_gpio, true);
+
ret = pm_runtime_get_sync(&func->dev);
if (ret < 0) {
@@ -203,8 +205,8 @@ static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
if (ret < 0)
goto out;
- if (wl->set_power)
- wl->set_power(false);
+ if (gpio_is_valid(wl->power_gpio))
+ gpio_set_value(wl->power_gpio, false);
}
out:
@@ -256,11 +258,20 @@ static int wl1251_sdio_probe(struct sdio_func *func,
wl1251_board_data = wl1251_get_platform_data();
if (!IS_ERR(wl1251_board_data)) {
- wl->set_power = wl1251_board_data->set_power;
+ wl->power_gpio = wl1251_board_data->power_gpio;
wl->irq = wl1251_board_data->irq;
wl->use_eeprom = wl1251_board_data->use_eeprom;
}
+ if (gpio_is_valid(wl->power_gpio)) {
+ ret = devm_gpio_request(&func->dev, wl->power_gpio,
+ "wl1251 power");
+ if (ret) {
+ wl1251_error("Failed to request gpio: %d\n", ret);
+ goto disable;
+ }
+ }
+
if (wl->irq) {
irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 62403a1..6abcbc3 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -26,6 +26,7 @@
#include <linux/crc7.h>
#include <linux/spi/spi.h>
#include <linux/wl12xx.h>
+#include <linux/gpio.h>
#include "wl1251.h"
#include "reg.h"
@@ -221,8 +222,8 @@ static void wl1251_spi_disable_irq(struct wl1251 *wl)
static int wl1251_spi_set_power(struct wl1251 *wl, bool enable)
{
- if (wl->set_power)
- wl->set_power(enable);
+ if (gpio_is_valid(wl->power_gpio))
+ gpio_set_value(wl->power_gpio, enable);
return 0;
}
@@ -271,22 +272,33 @@ static int wl1251_spi_probe(struct spi_device *spi)
goto out_free;
}
- wl->set_power = pdata->set_power;
- if (!wl->set_power) {
- wl1251_error("set power function missing in platform data");
- return -ENODEV;
+ wl->power_gpio = pdata->power_gpio;
+
+ if (gpio_is_valid(wl->power_gpio)) {
+ ret = devm_gpio_request_one(&spi->dev, wl->power_gpio,
+ GPIOF_OUT_INIT_LOW, "wl1251 power");
+ if (ret) {
+ wl1251_error("Failed to request gpio: %d\n", ret);
+ goto out_free;
+ }
+ } else {
+ wl1251_error("set power gpio missing in platform data");
+ ret = -ENODEV;
+ goto out_free;
}
wl->irq = spi->irq;
if (wl->irq < 0) {
wl1251_error("irq missing in platform data");
- return -ENODEV;
+ ret = -ENODEV;
+ goto out_free;
}
wl->use_eeprom = pdata->use_eeprom;
irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
- ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
+ ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0,
+ DRIVER_NAME, wl);
if (ret < 0) {
wl1251_error("request_irq() failed: %d", ret);
goto out_free;
@@ -296,13 +308,10 @@ static int wl1251_spi_probe(struct spi_device *spi)
ret = wl1251_init_ieee80211(wl);
if (ret)
- goto out_irq;
+ goto out_free;
return 0;
- out_irq:
- free_irq(wl->irq, wl);
-
out_free:
ieee80211_free_hw(hw);
diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h
index 235617a..389fe25 100644
--- a/drivers/net/wireless/ti/wl1251/wl1251.h
+++ b/drivers/net/wireless/ti/wl1251/wl1251.h
@@ -276,7 +276,7 @@ struct wl1251 {
void *if_priv;
const struct wl1251_if_operations *if_ops;
- void (*set_power)(bool enable);
+ int power_gpio;
int irq;
bool use_eeprom;
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index b516b4f..a9c723b 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -49,7 +49,7 @@ enum {
};
struct wl1251_platform_data {
- void (*set_power)(bool enable);
+ int power_gpio;
/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
int irq;
bool use_eeprom;
--
1.8.5.3
^ permalink raw reply related
* [PATCHv2 1/5] wl1251: split wl251 platform data to a separate structure
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
John W. Linville
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
netdev, Luciano Coelho
In-Reply-To: <1392419156-14394-1-git-send-email-sre@debian.org>
From: Luciano Coelho <coelho@ti.com>
Move the wl1251 part of the wl12xx platform data structure into a new
structure specifically for wl1251. Change the platform data built-in
block and board files accordingly.
Signed-off-by: Luciano Coelho <coelho@ti.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Reviewed-by: Felipe Balbi <balbi@ti.com>
Reviewed-by: Sebastian Reichel <sre@debian.org>
Reviewed-by: Pavel Machek <pavel@ucw.cz>
---
arch/arm/mach-omap2/board-omap3pandora.c | 4 +--
arch/arm/mach-omap2/board-rx51-peripherals.c | 2 +-
drivers/net/wireless/ti/wilink_platform_data.c | 37 +++++++++++++++++++++-----
drivers/net/wireless/ti/wl1251/sdio.c | 12 ++++-----
drivers/net/wireless/ti/wl1251/spi.c | 2 +-
include/linux/wl12xx.h | 22 ++++++++++++++-
6 files changed, 62 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index de1bc6b..24f3c1b 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -536,7 +536,7 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
static void __init pandora_wl1251_init(void)
{
- struct wl12xx_platform_data pandora_wl1251_pdata;
+ struct wl1251_platform_data pandora_wl1251_pdata;
int ret;
memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
@@ -550,7 +550,7 @@ static void __init pandora_wl1251_init(void)
goto fail_irq;
pandora_wl1251_pdata.use_eeprom = true;
- ret = wl12xx_set_platform_data(&pandora_wl1251_pdata);
+ ret = wl1251_set_platform_data(&pandora_wl1251_pdata);
if (ret < 0)
goto fail_irq;
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index 8760bbe..e05e740 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -84,7 +84,7 @@ enum {
RX51_SPI_MIPID, /* LCD panel */
};
-static struct wl12xx_platform_data wl1251_pdata;
+static struct wl1251_platform_data wl1251_pdata;
static struct tsc2005_platform_data tsc2005_pdata;
#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
diff --git a/drivers/net/wireless/ti/wilink_platform_data.c b/drivers/net/wireless/ti/wilink_platform_data.c
index 998e958..a92bd3e 100644
--- a/drivers/net/wireless/ti/wilink_platform_data.c
+++ b/drivers/net/wireless/ti/wilink_platform_data.c
@@ -23,17 +23,17 @@
#include <linux/err.h>
#include <linux/wl12xx.h>
-static struct wl12xx_platform_data *platform_data;
+static struct wl12xx_platform_data *wl12xx_platform_data;
int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
{
- if (platform_data)
+ if (wl12xx_platform_data)
return -EBUSY;
if (!data)
return -EINVAL;
- platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
- if (!platform_data)
+ wl12xx_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+ if (!wl12xx_platform_data)
return -ENOMEM;
return 0;
@@ -41,9 +41,34 @@ int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data)
struct wl12xx_platform_data *wl12xx_get_platform_data(void)
{
- if (!platform_data)
+ if (!wl12xx_platform_data)
return ERR_PTR(-ENODEV);
- return platform_data;
+ return wl12xx_platform_data;
}
EXPORT_SYMBOL(wl12xx_get_platform_data);
+
+static struct wl1251_platform_data *wl1251_platform_data;
+
+int __init wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+ if (wl1251_platform_data)
+ return -EBUSY;
+ if (!data)
+ return -EINVAL;
+
+ wl1251_platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+ if (!wl1251_platform_data)
+ return -ENOMEM;
+
+ return 0;
+}
+
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+ if (!wl1251_platform_data)
+ return ERR_PTR(-ENODEV);
+
+ return wl1251_platform_data;
+}
+EXPORT_SYMBOL(wl1251_get_platform_data);
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e2b3d9c..b75a37a 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -227,7 +227,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
struct wl1251 *wl;
struct ieee80211_hw *hw;
struct wl1251_sdio *wl_sdio;
- const struct wl12xx_platform_data *wl12xx_board_data;
+ const struct wl1251_platform_data *wl1251_board_data;
hw = wl1251_alloc_hw();
if (IS_ERR(hw))
@@ -254,11 +254,11 @@ static int wl1251_sdio_probe(struct sdio_func *func,
wl->if_priv = wl_sdio;
wl->if_ops = &wl1251_sdio_ops;
- wl12xx_board_data = wl12xx_get_platform_data();
- if (!IS_ERR(wl12xx_board_data)) {
- wl->set_power = wl12xx_board_data->set_power;
- wl->irq = wl12xx_board_data->irq;
- wl->use_eeprom = wl12xx_board_data->use_eeprom;
+ wl1251_board_data = wl1251_get_platform_data();
+ if (!IS_ERR(wl1251_board_data)) {
+ wl->set_power = wl1251_board_data->set_power;
+ wl->irq = wl1251_board_data->irq;
+ wl->use_eeprom = wl1251_board_data->use_eeprom;
}
if (wl->irq) {
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 1342f81..62403a1 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -238,7 +238,7 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
static int wl1251_spi_probe(struct spi_device *spi)
{
- struct wl12xx_platform_data *pdata;
+ struct wl1251_platform_data *pdata;
struct ieee80211_hw *hw;
struct wl1251 *wl;
int ret;
diff --git a/include/linux/wl12xx.h b/include/linux/wl12xx.h
index a54fe82..b516b4f 100644
--- a/include/linux/wl12xx.h
+++ b/include/linux/wl12xx.h
@@ -48,11 +48,15 @@ enum {
WL12XX_TCXOCLOCK_33_6 = 7, /* 33.6 MHz */
};
-struct wl12xx_platform_data {
+struct wl1251_platform_data {
void (*set_power)(bool enable);
/* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */
int irq;
bool use_eeprom;
+};
+
+struct wl12xx_platform_data {
+ int irq;
int board_ref_clock;
int board_tcxo_clock;
unsigned long platform_quirks;
@@ -68,6 +72,10 @@ int wl12xx_set_platform_data(const struct wl12xx_platform_data *data);
struct wl12xx_platform_data *wl12xx_get_platform_data(void);
+int wl1251_set_platform_data(const struct wl1251_platform_data *data);
+
+struct wl1251_platform_data *wl1251_get_platform_data(void);
+
#else
static inline
@@ -82,6 +90,18 @@ struct wl12xx_platform_data *wl12xx_get_platform_data(void)
return ERR_PTR(-ENODATA);
}
+static inline
+int wl1251_set_platform_data(const struct wl1251_platform_data *data)
+{
+ return -ENOSYS;
+}
+
+static inline
+struct wl1251_platform_data *wl1251_get_platform_data(void)
+{
+ return ERR_PTR(-ENODATA);
+}
+
#endif
#endif
--
1.8.5.3
^ permalink raw reply related
* [RESEND] [PATCHv2 0/5] wl1251 device tree support
From: Sebastian Reichel @ 2014-02-14 23:05 UTC (permalink / raw)
To: Sebastian Reichel, Luciano Coelho, Tony Lindgren,
John W. Linville
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Rob Landley,
Kumar Gala, devicetree, linux-kernel, linux-wireless, linux-omap,
netdev, Sebastian Reichel
In-Reply-To: <20140125000929.GD25488@atomide.com>
Hi John,
The following patchset adds device tree support to the spi variant of the
wl1251 driver, which is used in the Nokia N900. Tony requested, that you
take the whole series even if that may introduce merge conflicts:
> Sebastian, please resend the whole series to John and feel free to add my
> acks. It's best that John picks them all up, otherwise we'll have the same
> issue for v3.15. It seems that we should have just taken the merge conflict
> rather than going back and forth with this.
-- Sebastian
Luciano Coelho (1):
wl1251: split wl251 platform data to a separate structure
Sebastian Reichel (4):
wl1251: move power GPIO handling into the driver
wl1251: spi: add vio regulator support
wl1251: spi: add device tree support
Documentation: dt: wireless: Add wl1251
.../devicetree/bindings/net/wireless/ti,wl1251.txt | 39 ++++++++++++
arch/arm/mach-omap2/board-omap3pandora.c | 6 +-
arch/arm/mach-omap2/board-rx51-peripherals.c | 13 +---
drivers/net/wireless/ti/wilink_platform_data.c | 37 +++++++++--
drivers/net/wireless/ti/wl1251/sdio.c | 31 +++++++---
drivers/net/wireless/ti/wl1251/spi.c | 71 ++++++++++++++++------
drivers/net/wireless/ti/wl1251/wl1251.h | 4 +-
include/linux/wl12xx.h | 24 +++++++-
8 files changed, 176 insertions(+), 49 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/wireless/ti,wl1251.txt
--
1.8.5.3
^ permalink raw reply
* Re: [PATCH] DT: net: document Ethernet bindings in one place
From: Sergei Shtylyov @ 2014-02-14 23:05 UTC (permalink / raw)
To: Grant Likely, Florian Fainelli, Rob Herring, David Miller
Cc: netdev, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Rob Landley, linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20140210220541.C7A56C408F7-WNowdnHR2B42iJbIjFUEsiwD8/FfD2ys@public.gmane.org>
Hello.
On 02/11/2014 01:05 AM, Grant Likely wrote:
>>>>>>>>>>>>> I'm afraid that's too late, it has spread very far, so that
>>>>>>>>>>>>> of_get_phy_mode() handles that property, not "phy-connection-type".
>>>>>>>>>>>> Uggg, I guess this is a case of a defacto standard then if the kernel
>>>>>>>>>>>> doesn't even support it.
>>>>>>>>>>> Maybe I forgot to CC you on patch sent to Grant only, I sent a patch a
>>>>>>>>>>> while ago for of_get_phy_mode() to look for both "phy-mode" and
>>>>>>>>>>> "phy-connection-type" since the former has been a Linux invention, but
>>>>>>>>>>> the latter is ePAPR specified.
>>>>>>>>>> Here is a link to the actual patch in question, not sure which tree
>>>>>>>>>> Grant applied it to though:
>>>>>>>>>> http://lkml.indiana.edu/hypermail/linux/kernel/1311.2/00048.html
>>>>>>>>> It's not the patch mail, it's Grant's "applied" reply, patch is mangled in
>>>>>>>>> this reply, and I couldn't follow the thread. Here's the actual patch mail:
>>>>>>>>> http://marc.info/?l=devicetree&m=138449662807254
>>>>>>>> Florian, I didn't find this patch in Grant's official tree, so maybe you
>>>>>>>> should ask him where is the patch already?
>>>>>>> Sorry, I accidentally dropped it. It will be in the next merge window.
>>>>>> Already saw it, thanks. Would that it was in 3.14 instead of course, so
>>>>>> that I could use "phy-connection-type" in my binding...
>>>>> Is 3.14 broken because of missing the patch? If so I'll get it merged as
>>>>> a bug fix.
>>>> No, it's not. I could have used "phy-connection-type" in my binding
>>>> destined for 3.15 and document it as a preferred property as well.
>>> You still can. We just need to make sure that your patch is applied on
>> Patches.
>>> top of the phy-connection-type patch.
>> I'm not sure this trick is possible if the patches are merged via the
>> different trees...
> There are two ways to do it. A) by having a common merge commit
> containing that patch and merged into both branches, or B) just merging
> the patch in the same tree.
> Normally I'd suggest B), but I've already picked up the patch and I try
> very hard not to rebase my commit tree. However, since the branch is
> stable, you can ask for my branch to be merged into the net branch
> before applying the dependant patches. The relevant commit id is
> cf4c9eb5a4, and it is in my devicetree/next branch on
> git://git.secretlab.ca/git/linux
David, would it be possible for you to merge this into net-next?
> g.
WBR, Sergei
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v10 0/4] ata: Add APM X-Gene SoC SATA host controller support
From: Tejun Heo @ 2014-02-14 22:05 UTC (permalink / raw)
To: Loc Ho
Cc: Olof Johansson, Arnd Bergmann, Linux SCSI List,
linux-ide@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, David Milburn, Jon Masters,
patches@apm.com, Tuan Phan, Suman Tripathi
In-Reply-To: <CAPw-ZT=DGKfshpKb2K7+=gXyzbi8r51MeURJDv9d5YgHfE8prw@mail.gmail.com>
On Fri, Feb 14, 2014 at 01:44:08PM -0800, Loc Ho wrote:
> Ok... I will look into Hans' patch again. To be sure that I am looking
> at the correct patch, are you referring to this one:
>
> http://www.spinics.net/lists/linux-ide/msg47628.html
Yeah, v5 is the latest.
Thanks!
--
tejun
^ permalink raw reply
* [PATCH 2/2] ARM: tegra: fix Dalmore PMIC IRQ polarity
From: Stephen Warren @ 2014-02-14 21:58 UTC (permalink / raw)
To: Samuel Ortiz, Lee Jones
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, J Keerthy, Ian Lartey,
Stefan Agner, josephl-DDmLM1+adcrQT0dZR+AlfA,
ldewangan-DDmLM1+adcrQT0dZR+AlfA, Stephen Warren
In-Reply-To: <1392415108-4365-1-git-send-email-swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
From: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
The Tegra PMC's resume-from-sleep logic wants an active-low IRQ input
from the PMIC. However, the PMIC IRQ is also routed to the GIC, which
only supports active high IRQs (or rising edge). Hence, the signal must
be inverted in the PMC before being routed to the GIC. This implies that
the PMC DT property nvidia,invert-interrupt must be set, and it is.
The PMIC's DT interrupts property must represent the IRQ level at the
GIC, since that is the PMIC's parent IRQ controller. Fix the PMIC's
interrupts property to correctly describe the GIC input polarity.
However, the PMIC IRQ output's polarity is programmable in HW, and by
default follows the parent IRQ controller's input polarity. We need to
have an active-low output due to the inversion inside the Tegra PMC.
Hence, add the ti,irq-externally-inverted property to the PMIC.
Reported-by: Stefan Agner <stefan-XLVq0VzYD2Y@public.gmane.org>
Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
arch/arm/boot/dts/tegra114-dalmore.dts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/tegra114-dalmore.dts b/arch/arm/boot/dts/tegra114-dalmore.dts
index 8de543777882..2977206cafc9 100644
--- a/arch/arm/boot/dts/tegra114-dalmore.dts
+++ b/arch/arm/boot/dts/tegra114-dalmore.dts
@@ -893,7 +893,8 @@
palmas: tps65913@58 {
compatible = "ti,palmas";
reg = <0x58>;
- interrupts = <0 86 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
+ ti,irq-externally-inverted;
#interrupt-cells = <2>;
interrupt-controller;
--
1.8.1.5
^ permalink raw reply related
* [PATCH 1/2] mfd: palmas: support IRQ inversion at the board level
From: Stephen Warren @ 2014-02-14 21:58 UTC (permalink / raw)
To: Samuel Ortiz, Lee Jones
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Pawel Moll,
Mark Rutland, Ian Campbell, Kumar Gala,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, J Keerthy, Ian Lartey,
Stefan Agner, josephl-DDmLM1+adcrQT0dZR+AlfA,
ldewangan-DDmLM1+adcrQT0dZR+AlfA, Stephen Warren
From: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Some boards or SoCs have an inverter between the PMIC IRQ output pin and
the IRQ controller input signal.
The IRQ specifier in DT is meant to represent the IRQ flags at the input
to the IRQ controller.
The Palmas HW's IRQ output has configurable polarity. The driver
currently selects the output polarity by querying the input polarity at
the IRQ controller. This works fine if the IRQ signal is routed directly
from the PMIC to the IRQ controller with no intervening logic. However,
if the signal is inverted between the two, this automatic polarity
selection gets the wrong answer.
Add an additional optional DT and platform data parameter which indicates
that such an inversion occurs. If this option is enabled, the Palmas
driver will configure its IRQ output to the opposite polarity of the IRQ
controller's input.
An alternative would have been to add a new non-optional DT parameter to
indicate the exact desired output polarity. However, this would have been
an incompatible change to the DT binding.
Signed-off-by: Stephen Warren <swarren-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
If this patch could be applied to its own branch (w/ signed tag) in the
MFD tree, that would great; then I can pull patch 1/2 into the Tegra tree
so that I can apply patch 2/2 to the Tegra tree. Thanks.
---
Documentation/devicetree/bindings/mfd/palmas.txt | 6 ++++++
drivers/mfd/palmas.c | 4 ++++
include/linux/mfd/palmas.h | 1 +
3 files changed, 11 insertions(+)
diff --git a/Documentation/devicetree/bindings/mfd/palmas.txt b/Documentation/devicetree/bindings/mfd/palmas.txt
index e5f0f8303461..76ec509d5f87 100644
--- a/Documentation/devicetree/bindings/mfd/palmas.txt
+++ b/Documentation/devicetree/bindings/mfd/palmas.txt
@@ -18,6 +18,12 @@ Required properties:
ti,tps659038
and also the generic series names
ti,palmas
+- interrupts : Should contain a single entry for the IRQ output.
+- ti,irq-externally-inverted : If missing, the polarity of the Palmas IRQ
+ output should be set to the opposite of the polarity indicated by the IRQ
+ specifier in the interrupts property. If absent, the polarity should be
+ configured to match. This allows the representation of an inverter between
+ the Palmas IRQ output and the interrupt parent's IRQ input.
- interrupt-controller : palmas has its own internal IRQs
- #interrupt-cells : should be set to 2 for IRQ number and flags
The first cell is the IRQ number.
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index d280d789e55a..f4ea932adf8d 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -293,6 +293,8 @@ static int palmas_set_pdata_irq_flag(struct i2c_client *i2c,
}
pdata->irq_flags = irqd_get_trigger_type(irq_data);
+ pdata->irq_external_inversion = of_property_read_bool(i2c->dev.of_node,
+ "ti,irq-externally-inverted");
dev_info(&i2c->dev, "Irq flag is 0x%08x\n", pdata->irq_flags);
return 0;
}
@@ -447,6 +449,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c,
reg = PALMAS_POLARITY_CTRL_INT_POLARITY;
else
reg = 0;
+ if (pdata->irq_external_inversion)
+ reg ^= PALMAS_POLARITY_CTRL_INT_POLARITY;
ret = palmas_update_bits(palmas, PALMAS_PU_PD_OD_BASE,
PALMAS_POLARITY_CTRL, PALMAS_POLARITY_CTRL_INT_POLARITY,
reg);
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index 9974e387e483..2fdf08c50a48 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -292,6 +292,7 @@ struct palmas_clk_platform_data {
struct palmas_platform_data {
int irq_flags;
+ bool irq_external_inversion;
int gpio_base;
/* bit value to be loaded to the POWER_CTRL register */
--
1.8.1.5
^ permalink raw reply related
* Re: [PATCH v10 0/4] ata: Add APM X-Gene SoC SATA host controller support
From: Loc Ho @ 2014-02-14 21:44 UTC (permalink / raw)
To: Tejun Heo
Cc: Olof Johansson, Arnd Bergmann, Linux SCSI List,
linux-ide@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, David Milburn, Jon Masters,
patches@apm.com, Tuan Phan, Suman Tripathi
In-Reply-To: <20140214150322.GB29516@htj.dyndns.org>
Hi Tejun,
>
> On Thu, Feb 13, 2014 at 03:28:01PM -0800, Loc Ho wrote:
>> 1. There are a number of errata that require workaround. Some can be
>> fixed by adding broken flags while others are better to just wrap
>> around the existent libahci library routines and not overly polluting
>> the libahci routines.
>> 2. There are additional controller programming sequences to configure.
>> 2a. By default, RAM are powered down and require brought out of shutdown.
>> 2b. The controller has an additional corresponding PHY part that needs
>> to be programmed after PHY configuration.
>
> Have you looked at the latest patchset Hans posted? He added multiple
> PHY support and split up init to three steps so that each platform
> driver can mix and match as they see fit. Looking at xgene driver,
> sure there are things specific to the driver but there also are
> non-insignificant amount of boilerplate code and that's what I'm
> primarily concerned about. It may be okay when you have two or three
> drivers duplicating some code but it looks like we could have many
> more and I *really* want to avoid the situation where the same piece
> of code is copied over N times. In addition, frankly, not many people
> except yourself would care about these drivers once they're merged and
> many of these are gonna be painful to test making later refactoring a
> lot harder.
>
Ok... I will look into Hans' patch again. To be sure that I am looking
at the correct patch, are you referring to this one:
http://www.spinics.net/lists/linux-ide/msg47628.html
-Loc
^ permalink raw reply
* Re: [PATCH net-next v5 10/10] MAINTAINERS: add entry for the Broadcom GENET driver
From: Sergei Shtylyov @ 2014-02-14 21:37 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: davem, devicetree, cernekee, mark.rutland, romieu
In-Reply-To: <1392336531-28875-11-git-send-email-f.fainelli@gmail.com>
Hello.
On 02/14/2014 03:08 AM, Florian Fainelli wrote:
> Add myself as a maintainer of the Broadcom GENET driver.
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
[...]
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 091b50e..5a7b3ec 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1845,6 +1845,12 @@ L: netdev@vger.kernel.org
> S: Supported
> F: drivers/net/ethernet/broadcom/b44.*
>
> +BROADCOM GENET ETHERNET DRIVER
> +M: Florian Fainelli <f.fainelli@gmail.com>
> +L: netdev@vger.kernel.org
> +S: Supported
> +F: drivers/net/ethernet/broadcom/genet/
> +
Aren't these entries supposed to be sorted alphabetically? If so, in my
alphabet BNX2 comes before GENET...
> BROADCOM BNX2 GIGABIT ETHERNET DRIVER
> M: Michael Chan <mchan@broadcom.com>
> L: netdev@vger.kernel.org
PS: I'm probably wrong, the entries don't appear to be sorted on the 2nd word...
WBR, Sergei
^ permalink raw reply
* Re: [PATCH 09/10] regulator: Add LM3631 driver
From: Mark Brown @ 2014-02-14 20:55 UTC (permalink / raw)
To: Milo Kim
Cc: Lee Jones, Jingoo Han, Bryan Wu, linux-kernel, devicetree,
Samuel Ortiz
In-Reply-To: <1392359551-7170-1-git-send-email-milo.kim@ti.com>
[-- Attachment #1: Type: text/plain, Size: 1416 bytes --]
On Fri, Feb 14, 2014 at 03:32:31PM +0900, Milo Kim wrote:
> LM3631 regulator driver has 5 regulators.
> One boost output and four LDOs are used for the display module.
> Boost voltage is configurable but always on.
> Supported operations for LDOs are enabled/disabled and voltage change.
This looks basically good, a couple of minor nits below but nothing
substantial.
> +static const int lm3631_boost_vtbl[] = {
> + 4500000, 4550000, 4600000, 4650000, 4700000, 4750000, 4800000, 4850000,
> + 4900000, 4950000, 5000000, 5050000, 5100000, 5150000, 5200000, 5250000,
> + 5300000, 5350000, 5400000, 5450000, 5500000, 5550000, 5600000, 5650000,
> + 5700000, 5750000, 5800000, 5850000, 5900000, 5950000, 6000000, 6050000,
> + 6100000, 6150000, 6200000, 6250000, 6300000, 6350000,
> +};
This looks like a linear range so could use the linear range helpers
(4.5-6.35V in steps of 0.05V)? Similarly for the LDO.
> +static struct of_regulator_match lm3631_regulator_matches[] = {
> + { .name = "vboost", .driver_data = (void *)LM3631_BOOST, },
> + { .name = "vcont", .driver_data = (void *)LM3631_LDO_CONT, },
> + { .name = "voref", .driver_data = (void *)LM3631_LDO_OREF, },
> + { .name = "vpos", .driver_data = (void *)LM3631_LDO_POS, },
> + { .name = "vneg", .driver_data = (void *)LM3631_LDO_NEG, },
> +};
These names don't correspond to what was in the binding document and
there's a couple of extra LDOs.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 10/10] Documentation: Add device tree bindings for TI LMU devices
From: Mark Brown @ 2014-02-14 20:50 UTC (permalink / raw)
To: Milo Kim
Cc: Lee Jones, Jingoo Han, Bryan Wu, linux-kernel, devicetree,
Samuel Ortiz
In-Reply-To: <1392359564-7205-1-git-send-email-milo.kim@ti.com>
[-- Attachment #1: Type: text/plain, Size: 1069 bytes --]
On Fri, Feb 14, 2014 at 03:32:44PM +0900, Milo Kim wrote:
> Bindings for TI LMU, backlight, LM3631 regulator and LM3633 LED are added.
Ah, sorry - I didn't notice that there were several different binding
documents in the patch.
> @@ -0,0 +1,49 @@
> +TI LMU LM3631 regulator device tree bindings
> +
> +Required properties:
> + - compatible: "ti,lm3631-regulator"
> +
> +Optional properties:
> + - regulator-name
> + - regulator-min-microvolt
> + - regulator-max-microvolt
> + - regulator-always-on
> + - regulator-boot-on
> +
> + For those properties, please refer to:
> + Documentation/devicetree/bindings/regulator/regulator.txt
This doesn't correspond to the example which says that there is an
optional property "regulators" which can contain regualators lcd_boost,
lcd_vpos and lcd_vneg. It's also better to not enumerate all the
standard properties but just refer to the generic document (as you do).
That avoids confusion if new properties are added to the generic
regulator bindings.
The actual binding is fine, it's just the way it's documented.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 10/10] Documentation: Add device tree bindings for TI LMU devices
From: Mark Brown @ 2014-02-14 20:44 UTC (permalink / raw)
To: Milo Kim
Cc: Lee Jones, Jingoo Han, Bryan Wu, linux-kernel, devicetree,
Samuel Ortiz
In-Reply-To: <1392359564-7205-1-git-send-email-milo.kim@ti.com>
[-- Attachment #1: Type: text/plain, Size: 257 bytes --]
On Fri, Feb 14, 2014 at 03:32:44PM +0900, Milo Kim wrote:
> Bindings for TI LMU, backlight, LM3631 regulator and LM3633 LED are added.
I don't see actual documentation for the regulators here? They're there
in the examples but not in the binding section.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v2 2/2] ARM: sunxi: dt: Convert to the new i2c compatibles
From: Maxime Ripard @ 2014-02-14 20:36 UTC (permalink / raw)
To: Wolfram Sang
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20140214074407.GA2569@katana>
[-- Attachment #1: Type: text/plain, Size: 1127 bytes --]
On Fri, Feb 14, 2014 at 08:44:07AM +0100, Wolfram Sang wrote:
>
> > > For non-a10, That should be at least
> > >
> > > compatible = "allwinner,sun4i-a13-i2c", "allwinner,sun4i-a10-i2c";
> > >
> > > or
> > >
> > > compatible = "allwinner,sun4i-a13-i2c", "allwinner,sun4i-i2c";
> > >
> > > depending on the outcome above.
> > >
> > > Or is my knowledge outdated already?
> > >
> >
> > Since they are strictly compatible, we don't need to introduce any
> > different compatible string here.
>
> You never know all errata in advance. From what I know, one should
> always use the specfic naming first, and then the generic fallback. So,
> in case a distinction is needed later (think errata), then one doesn't
> need to change the devicetrees.
>
And adding a A13-specific compatible wouldn't change anything, because
it does work on at least one revision of them, so if you'd have to
deal with an errata, you'd have to introduce a new compatible for this
revision only anyway.
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v2 3/4] Regulators: TPS65218: Add Regulator driver for TPS65218 PMIC
From: Mark Brown @ 2014-02-14 20:21 UTC (permalink / raw)
To: Keerthy
Cc: rob.herring, pawel.moll, mark.rutland, swarren, ijc+devicetree,
rob, sameo, lee.jones, grant.likely, lgirdwood, devicetree,
linux-doc, linux-kernel, linux-omap
In-Reply-To: <1391665814-18814-4-git-send-email-j-keerthy@ti.com>
[-- Attachment #1: Type: text/plain, Size: 367 bytes --]
On Thu, Feb 06, 2014 at 11:20:13AM +0530, Keerthy wrote:
> This patch adds support for TPS65218 PMIC regulators.
>
> The regulators set consists of 6 DCDCs and 1 LDO. The output
> voltages are configurable and are meant to supply power to the
> main processor and other components.
Applied, thanks. Please use subject lines consistent with the
subsystem.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox