* [PATCH v5 1/7] ARM: Add platform support for Fujitsu MB86S7X SoCs
2015-02-03 9:21 ` Vincent Yang
@ 2015-02-03 9:27 ` Vincent Yang
-1 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:27 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
arm-DgEjT+Ai2ygdnm+yROfE0A, linux-lFZ/pmaqli7XmaaqVzeoHQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
patches-QSEj5FYQhm4dnm+yROfE0A,
jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
Tetsuya Nuriya
From: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
The MB86S7X is a bigLITTLE configuration of 2xCA7 & 2xCA15 under Linux.
And the remote master firmware (called SCB) running on CM3. Linux asks
for things to be done over Mailbox API, to SCB which controls most of
the important things. variations S70 & S73 are supported.
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
Documentation/devicetree/bindings/arm/mb86s7x.txt | 8 +
.../devicetree/bindings/soc/mb86s7x/scb_mhu.txt | 35 ++
MAINTAINERS | 7 +
arch/arm/Kconfig | 2 +
arch/arm/Makefile | 1 +
arch/arm/mach-mb86s7x/Kconfig | 19 +
arch/arm/mach-mb86s7x/Makefile | 1 +
arch/arm/mach-mb86s7x/board.c | 23 +
drivers/soc/Makefile | 1 +
drivers/soc/mb86s7x/Makefile | 4 +
drivers/soc/mb86s7x/scb_mhu.c | 514 +++++++++++++++++++++
include/soc/mb86s7x/scb_mhu.h | 97 ++++
12 files changed, 712 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/mb86s7x.txt
create mode 100644 Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
create mode 100644 arch/arm/mach-mb86s7x/Kconfig
create mode 100644 arch/arm/mach-mb86s7x/Makefile
create mode 100644 arch/arm/mach-mb86s7x/board.c
create mode 100644 drivers/soc/mb86s7x/Makefile
create mode 100644 drivers/soc/mb86s7x/scb_mhu.c
create mode 100644 include/soc/mb86s7x/scb_mhu.h
diff --git a/Documentation/devicetree/bindings/arm/mb86s7x.txt b/Documentation/devicetree/bindings/arm/mb86s7x.txt
new file mode 100644
index 0000000..fbaad20
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mb86s7x.txt
@@ -0,0 +1,8 @@
+Fujitsu MB86S7X Device Tree Bindings
+
+Fujitsu has a few closely related platforms that are basically different
+configurations of each others. Like MB86S7{0,1,2,3}.
+
+The EVB boards with S70/S73 have the following property:
+Required root node property:
+ compatible: must contain "fujitsu,mb86s70-evb" or "fujitsu,mb86s73-evb"
diff --git a/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt b/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
new file mode 100644
index 0000000..f466a05
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
@@ -0,0 +1,35 @@
+Fujitsu SCB (Mailbox's Remote Firmware) bindings
+------------------------------------------------
+
+The firmware (running of a remote Cortex-M3 master) on Fujitsu's MB86S7X
+platforms is named SCB. The SCB owns most of core h/w IPs like Clock,
+CPUFreq/DVFS, CPUIdle/SMP, Thermal, a recovery block device and even an
+I2C controller. Linux has to map all of these functionalities on to
+the Mailbox API and get things done by the remote master.
+ Let the current state of SCB firmware be versioned 1.0.
+
+Required properties :
+- compatible : Shall contain "fujitsu,mb86s70-scb-1.0"
+- reg : Point to SharedMemory used for Mailbox protocol.
+- mboxes : phandle to the mailbox controller:channel node.
+
+The consumer specifies the desired clock pointing to its phandle.
+
+Example:
+
+ mhu: mhu0@2b1f0000 {
+ #mbox-cells = <1>;
+ compatible = "arm,mhu";
+ reg = <0 0x2b1f0000 0x1000>;
+ interrupts = <0 36 4>, /* LP Non-Sec */
+ <0 35 4>, /* HP Non-Sec */
+ <0 37 4>; /* Secure */
+ clocks = <&clk 0 2 1>;
+ clock-names = "apb_pclk";
+ };
+
+ mhu_client: scb@2e000000 {
+ compatible = "fujitsu,mb86s70-scb-1.0";
+ reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
+ mboxes = <&mhu 1>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index aaa039d..1436e34 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1111,6 +1111,13 @@ M: Lennert Buytenhek <kernel-OLH4Qvv75CYX/NnBR394Jw@public.gmane.org>
L: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
S: Maintained
+ARM/MB86S7X SOC SUPPORT
+M: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
+M: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
+L: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
+S: Supported
+F: arch/arm/mach-mb86s7x/
+
ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
M: Santosh Shilimkar <ssantosh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
L: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed..3c80a9b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -884,6 +884,8 @@ source "arch/arm/mach-keystone/Kconfig"
source "arch/arm/mach-ks8695/Kconfig"
+source "arch/arm/mach-mb86s7x/Kconfig"
+
source "arch/arm/mach-meson/Kconfig"
source "arch/arm/mach-msm/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c1785ee..c65aff2 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx
machine-$(CONFIG_ARCH_KEYSTONE) += keystone
machine-$(CONFIG_ARCH_KS8695) += ks8695
machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx
+machine-$(CONFIG_ARCH_MB86S7X) += mb86s7x
machine-$(CONFIG_ARCH_MESON) += meson
machine-$(CONFIG_ARCH_MMP) += mmp
machine-$(CONFIG_ARCH_MOXART) += moxart
diff --git a/arch/arm/mach-mb86s7x/Kconfig b/arch/arm/mach-mb86s7x/Kconfig
new file mode 100644
index 0000000..f58b104
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/Kconfig
@@ -0,0 +1,19 @@
+config ARCH_MB86S7X
+ bool "Fujitsu MB86S7x platforms" if ARCH_MULTI_V7
+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
+ select ARCH_HAS_CPUFREQ
+ select ARCH_HAS_OPP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_CCI
+ select ARM_GIC
+ select ARM_TIMER_SP804
+ select BIG_LITTLE
+ select HAVE_ARM_ARCH_TIMER
+ select MAILBOX
+ select PINCTRL
+ select PINCTRL_MB86S7X
+ select PM_OPP
+ select ZONE_DMA if ARM_LPAE
+ help
+ Support for Fujitsu MB86S7x based platforms
diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
new file mode 100644
index 0000000..97640b6
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_MB86S7X) += board.o
diff --git a/arch/arm/mach-mb86s7x/board.c b/arch/arm/mach-mb86s7x/board.c
new file mode 100644
index 0000000..222b63f
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/board.c
@@ -0,0 +1,23 @@
+/*
+ * Support for the Fujitsu's MB86S7x based devices.
+ *
+ * Copyright (C) 2015 Linaro, LTD
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ */
+
+#include <linux/of.h>
+#include <asm/mach/arch.h>
+
+static const char *mb86s7x_dt_match[] __initconst = {
+ "fujitsu,mb86s70-evb",
+ "fujitsu,mb86s73-evb",
+ NULL,
+};
+
+DT_MACHINE_START(MB86S7X_DT, "Fujitsu MB86S7X-based board")
+ .dt_compat = mb86s7x_dt_match,
+MACHINE_END
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 063113d..fb64bf2 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
# Makefile for the Linux Kernel SOC specific device drivers.
#
+obj-$(CONFIG_ARCH_MB86S7X) += mb86s7x/
obj-$(CONFIG_ARCH_QCOM) += qcom/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_SOC_TI) += ti/
diff --git a/drivers/soc/mb86s7x/Makefile b/drivers/soc/mb86s7x/Makefile
new file mode 100644
index 0000000..f6b96cf
--- /dev/null
+++ b/drivers/soc/mb86s7x/Makefile
@@ -0,0 +1,4 @@
+#
+# Fujitsu's MB86S7X drivers
+#
+obj-$(CONFIG_ARCH_MB86S7X) += scb_mhu.o
diff --git a/drivers/soc/mb86s7x/scb_mhu.c b/drivers/soc/mb86s7x/scb_mhu.c
new file mode 100644
index 0000000..2fe59c2
--- /dev/null
+++ b/drivers/soc/mb86s7x/scb_mhu.c
@@ -0,0 +1,514 @@
+/*
+ * arch/arm/mach-mb86s7x/scb_mhu.c Shim 'server' for Mailbox clients
+ *
+ * Created by: Jassi Brar <jassisinghbrar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * Copyright: (C) 2013-2015 Linaro Limited
+ *
+ * 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.
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/of_address.h>
+#include <linux/mailbox_client.h>
+#include <linux/platform_device.h>
+
+#include <soc/mb86s7x/scb_mhu.h>
+
+#include <asm/system_misc.h>
+
+#define INTR_STAT_OFS 0x0
+#define INTR_SET_OFS 0x8
+#define INTR_CLR_OFS 0x10
+
+static LIST_HEAD(free_xfers);
+static LIST_HEAD(pending_xfers);
+static DEFINE_SPINLOCK(fsm_lock);
+static struct completion fsm_rsp;
+static struct mbox_client mhu_cl;
+static struct mbox_chan *mhu_chan;
+static mb86s7x_mhu_handler_t handler[MHU_NUM_CMDS];
+
+static void __iomem *mhu_base, *mb86s7x_shm_base;
+static void __iomem *cmd_to_scb, *rsp_to_scb;
+static void __iomem *cmd_from_scb, *rsp_from_scb;
+
+static enum {
+ MHU_PARK = 0,
+ MHU_WRR, /* Waiting to get Remote's Reply */
+ MHU_WRL, /* Waiting to send Reply */
+ MHU_WRRL, /* WAIT_Ra && WAIT_Rb */
+ MHU_INVLD,
+} fsm_state;
+
+enum fsm_event {
+ EV_LC = 0, /* Local sent a command */
+ EV_RC, /* Remote sent a command */
+ EV_RR, /* Remote sent a reply */
+ EV_LR, /* Local sent a reply */
+};
+
+static int mhu_fsm[4][4] = {
+ [MHU_PARK] = {
+ [EV_LC] = MHU_WRR,
+ [EV_RC] = MHU_WRL,
+ [EV_RR] = MHU_INVLD,
+ [EV_LR] = MHU_INVLD,
+ },
+ [MHU_WRR] = {
+ [EV_LC] = MHU_INVLD,
+ [EV_RC] = MHU_WRRL,
+ [EV_RR] = MHU_PARK,
+ [EV_LR] = MHU_INVLD,
+ },
+ [MHU_WRL] = {
+ [EV_LC] = MHU_WRRL,
+ [EV_RC] = MHU_INVLD,
+ [EV_RR] = MHU_INVLD,
+ [EV_LR] = MHU_PARK,
+ },
+ [MHU_WRRL] = {
+ [EV_LC] = MHU_INVLD,
+ [EV_RC] = MHU_INVLD,
+ [EV_RR] = MHU_WRL,
+ [EV_LR] = MHU_WRR,
+ },
+};
+
+static struct mhu_xfer {
+ int code;
+ int len;
+ void *buf;
+ struct completion *c;
+ struct list_head node;
+} *ax; /* stages of xfer */
+
+static int mhu_alloc_xfers(int n, struct list_head *list)
+{
+ struct mhu_xfer *x = kcalloc(n, sizeof(struct mhu_xfer), GFP_ATOMIC);
+ int i;
+
+ if (!x)
+ return -ENOMEM;
+
+ for (i = 0; i < n; i++)
+ list_add(&x[i].node, &free_xfers);
+
+ return 0;
+}
+
+static void got_data(u32 code)
+{
+ mb86s7x_mhu_handler_t hndlr = NULL;
+ unsigned long flags;
+ int ev;
+
+ if (code & RESP_BIT)
+ ev = EV_RR;
+ else
+ ev = EV_RC;
+
+ spin_lock_irqsave(&fsm_lock, flags);
+
+ if (mhu_fsm[fsm_state][ev] == MHU_INVLD) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ pr_err("State-%d EV-%d FSM Broken!\n", fsm_state, ev);
+ return;
+ }
+ fsm_state = mhu_fsm[fsm_state][ev];
+
+ if (code & RESP_BIT) {
+ memcpy_fromio(ax->buf, rsp_from_scb, ax->len);
+ if (ax->c)
+ complete(ax->c);
+ list_move(&ax->node, &free_xfers);
+ ax = NULL;
+ } else {
+ /* Find and dispatch relevant registered handler */
+ if (code < MHU_NUM_CMDS)
+ hndlr = handler[code];
+ if (hndlr)
+ hndlr(code, cmd_from_scb);
+ else
+ pr_err("No handler for CMD_%u\n", code);
+ }
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+}
+
+static int do_xfer(void)
+{
+ unsigned long flags;
+ struct mhu_xfer *x;
+ int ev, code;
+
+ spin_lock_irqsave(&fsm_lock, flags);
+
+ if (list_empty(&pending_xfers)) {
+ struct mbox_chan *_ch = NULL;
+ int cmd;
+
+ for (cmd = 0; cmd < MHU_NUM_CMDS && !handler[cmd]; cmd++)
+ ;
+ /* Don't free channel if any user is listening */
+ if (cmd != MHU_NUM_CMDS) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ return 0;
+ }
+
+ if (fsm_state == MHU_PARK) {
+ _ch = mhu_chan;
+ mhu_chan = NULL;
+ }
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ if (_ch)
+ mbox_free_channel(_ch);
+
+ return 0;
+ }
+
+ x = list_first_entry(&pending_xfers, struct mhu_xfer, node);
+ code = x->code;
+
+ ev = code & RESP_BIT ? EV_LR : EV_LC;
+ if (mhu_fsm[fsm_state][ev] == MHU_INVLD) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ return 1;
+ }
+ list_del_init(&x->node);
+
+ /* Layout the SHM */
+ if (code & RESP_BIT)
+ memcpy_toio(rsp_to_scb, x->buf, x->len);
+ else
+ memcpy_toio(cmd_to_scb, x->buf, x->len);
+
+ if (ev == EV_LC)
+ ax = x;
+ else
+ list_move(&x->node, &free_xfers);
+ fsm_state = mhu_fsm[fsm_state][ev];
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ /* Prefer mailbox API */
+ if (!mhu_chan) {
+ struct mbox_chan *_ch;
+
+ _ch = mbox_request_channel(&mhu_cl, 0);
+ if (!IS_ERR(_ch))
+ mhu_chan = _ch;
+ }
+
+ if (mhu_chan) {
+ int ret;
+
+ init_completion(&fsm_rsp);
+
+ /* Send via generic api */
+ ret = mbox_send_message(mhu_chan, (void *)code);
+ if (ret < 0) {
+ pr_err("%s:%d CMD_%d Send Failed\n",
+ __func__, __LINE__, code);
+ BUG();
+ }
+ if (!(code & RESP_BIT)) {
+ ret = wait_for_completion_timeout(&fsm_rsp,
+ msecs_to_jiffies(1000));
+ if (!ret) {
+ pr_err("%s:%d CMD_%d Got No Reply\n",
+ __func__, __LINE__, code);
+ BUG();
+ }
+ got_data(ax->code);
+ }
+ } else {
+ void __iomem *tx_reg = mhu_base + 0x120; /* HP-NonSec */
+ void __iomem *rx_reg = mhu_base + 0x20; /* HP-NonSec */
+ u32 val, count;
+
+ /* Send via early-boot api */
+ val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+ if (val) {
+ pr_err("Last CMD not yet read by SCB\n");
+ writel_relaxed(val, tx_reg + INTR_CLR_OFS);
+ }
+
+ writel_relaxed(x->code, tx_reg + INTR_SET_OFS);
+
+ /* Wait until this message is read */
+ count = 0x1000000;
+ do {
+ cpu_relax();
+ val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+ } while (--count && val);
+ if (val)
+ pr_err("%s:%d SCB not listening!\n",
+ __func__, __LINE__);
+
+ if (!ax) {
+ /* A quick poll for pending remote cmd */
+ val = readl_relaxed(rx_reg + INTR_STAT_OFS);
+ if (val) {
+ got_data(val);
+ writel_relaxed(val, rx_reg + INTR_CLR_OFS);
+ }
+ } else {
+ do {
+ /* Wait until we get reply */
+ count = 0x1000000;
+ do {
+ cpu_relax();
+ val = readl_relaxed(
+ rx_reg + INTR_STAT_OFS);
+ } while (--count && !val);
+
+ if (val) {
+ got_data(val);
+ writel_relaxed(val,
+ rx_reg + INTR_CLR_OFS);
+ } else {
+ pr_err("%s:%d SCB didn't reply\n",
+ __func__, __LINE__);
+ return 1;
+ }
+ } while (!(val & RESP_BIT));
+ }
+ if (list_empty(&pending_xfers))
+ return 0;
+ }
+
+ return do_xfer();
+}
+
+static void mhu_recv(struct mbox_client *cl, void *data)
+{
+ if ((u32)data & RESP_BIT) {
+ /* Now that we got a reply to last TX, that
+ * must mean the last TX was successful */
+ mbox_client_txdone(mhu_chan, 0);
+
+ ax->code = (u32)data; /* Save response */
+ complete(&fsm_rsp);
+ return;
+ }
+
+ got_data((u32)data);
+}
+
+int mb86s7x_hndlr_set(u32 cmd, mb86s7x_mhu_handler_t hndlr)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ spin_lock_irqsave(&fsm_lock, flags);
+ if (cmd < MHU_NUM_CMDS && !handler[cmd]) {
+ ret = 0;
+ handler[cmd] = hndlr;
+ }
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ if (!mhu_chan) {
+ struct mbox_chan *_ch;
+
+ _ch = mbox_request_channel(&mhu_cl, 0);
+ if (!IS_ERR(_ch))
+ mhu_chan = _ch;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mb86s7x_hndlr_set);
+
+void mb86s7x_hndlr_clr(u32 cmd, mb86s7x_mhu_handler_t hndlr)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsm_lock, flags);
+
+ if (cmd < MHU_NUM_CMDS && handler[cmd] == hndlr)
+ handler[cmd] = NULL;
+
+ if (list_empty(&pending_xfers)) {
+ struct mbox_chan *_ch = NULL;
+
+ for (cmd = 0; cmd < MHU_NUM_CMDS && !handler[cmd]; cmd++)
+ ;
+ /* Don't free channel if any user is listening */
+ if (cmd != MHU_NUM_CMDS) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ return;
+ }
+
+ if (fsm_state == MHU_PARK) {
+ _ch = mhu_chan;
+ mhu_chan = NULL;
+ }
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ if (_ch)
+ mbox_free_channel(_ch);
+
+ return;
+ }
+ spin_unlock_irqrestore(&fsm_lock, flags);
+}
+EXPORT_SYMBOL_GPL(mb86s7x_hndlr_clr);
+
+static int setup_mhu(void)
+{
+ struct device_node *node;
+
+ node = of_find_compatible_node(NULL, NULL, "arm,mhu");
+ mhu_base = of_iomap(node, 0);
+ if (mhu_base == NULL) {
+ pr_err("Can't work without MHU\n");
+ return -ENODEV;
+ }
+
+ node = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
+ mb86s7x_shm_base = of_iomap(node, 0);
+ if (mb86s7x_shm_base == NULL) {
+ pr_err("Can't work without SHM SRAM\n");
+ return -ENODEV;
+ }
+
+ cmd_from_scb = mb86s7x_shm_base + 0x3800;
+ rsp_from_scb = mb86s7x_shm_base + 0x3900;
+ cmd_to_scb = mb86s7x_shm_base + 0x3a00;
+ rsp_to_scb = mb86s7x_shm_base + 0x3b00;
+
+ return 0;
+}
+
+int mb86s7x_send_packet(int code, void *buf, int len)
+{
+ struct completion got_rsp;
+ unsigned long flags;
+ struct mhu_xfer *x;
+ int ret;
+
+ /*
+ * The first caller could be as early as system clocksource,
+ * when the platform devices are not populated yet.
+ */
+ if (unlikely(!mb86s7x_shm_base) && setup_mhu())
+ return -ENODEV;
+
+ if ((code & ~0xff) || ((code & RESP_BIT)
+ && fsm_state != MHU_WRRL
+ && fsm_state != MHU_WRL)) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ init_completion(&got_rsp);
+
+ spin_lock_irqsave(&fsm_lock, flags);
+
+ if (list_empty(&free_xfers) && mhu_alloc_xfers(5, &free_xfers)) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ pr_err("%s:%d OOM\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ x = list_first_entry(&free_xfers, struct mhu_xfer, node);
+ x->code = code;
+ x->buf = buf;
+ x->len = len;
+ x->c = &got_rsp;
+
+ if (code & RESP_BIT)
+ list_move(&x->node, &pending_xfers);
+ else
+ list_move_tail(&x->node, &pending_xfers);
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ ret = do_xfer();
+ if (ret > 0) {
+ ret = wait_for_completion_timeout(&got_rsp,
+ msecs_to_jiffies(1000));
+ return ret ? 0 : -EIO;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mb86s7x_send_packet);
+
+struct mb86s7x_hard_reset {
+ u32 payload_size;
+ u32 delay;
+};
+
+static void mb86s7x_reboot(u32 delay)
+{
+ void __iomem *tx_reg = mhu_base + 0x120; /* HP-NonSec */
+ struct mb86s7x_hard_reset cmd;
+ u32 val;
+
+ cmd.payload_size = sizeof(cmd);
+ cmd.delay = delay;
+
+ val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+ if (val) /* Flush anything pending */
+ writel_relaxed(val, tx_reg + INTR_CLR_OFS);
+
+ memcpy_toio(cmd_to_scb, &cmd, sizeof(cmd));
+ writel_relaxed(CMD_HARD_RESET_REQ, tx_reg + INTR_SET_OFS);
+}
+
+static void
+mb86s7x_restart(enum reboot_mode reboot_mode, const char *unused)
+{
+ /* Reboot immediately (after 50ms) */
+ mb86s7x_reboot(50);
+}
+
+static void mb86s7x_poweroff(void)
+{
+ /* Reboot never, remain dead */
+ mb86s7x_reboot(~0);
+}
+
+static int f_scb_probe(struct platform_device *pdev)
+{
+ mhu_cl.tx_block = true;
+ mhu_cl.knows_txdone = true;
+ mhu_cl.rx_callback = mhu_recv;
+ mhu_cl.dev = &pdev->dev;
+
+ arm_pm_restart = mb86s7x_restart;
+ pm_power_off = mb86s7x_poweroff;
+
+ return 0;
+}
+
+static const struct of_device_id scb_dt_ids[] = {
+ { .compatible = "fujitsu,mb86s70-scb-1.0" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, scb_dt_ids);
+
+static struct platform_driver f_scb_driver = {
+ .driver = {
+ .name = "f_scb",
+ .of_match_table = scb_dt_ids,
+ },
+ .probe = f_scb_probe,
+};
+
+static int __init f_scb_init(void)
+{
+ return platform_driver_register(&f_scb_driver);
+}
+module_init(f_scb_init);
diff --git a/include/soc/mb86s7x/scb_mhu.h b/include/soc/mb86s7x/scb_mhu.h
new file mode 100644
index 0000000..334fa9f
--- /dev/null
+++ b/include/soc/mb86s7x/scb_mhu.h
@@ -0,0 +1,97 @@
+/*
+ * include/soc/mb86s7x/scb_mhu.h
+ *
+ * Created by: Jassi Brar <jassisinghbrar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ * Copyright: (C) 2013-2015 Linaro Limited
+ *
+ * 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.
+ */
+
+#ifndef __MB86S7X_SCB_MHU_H
+#define __MB86S7X_SCB_MHU_H
+
+#define CMD_MASK 0x7f /* 128 possible commands */
+#define RESP_BIT (1 << 7) /* If it's a response */
+
+#define ENC_CMD(c) ((c) & CMD_MASK)
+#define DEC_CMD(v) (((v) & ~CMD_MASK) ? CMD_INVALID : ((v) & CMD_MASK))
+
+#define ENC_REP(r) (((r) & CMD_MASK) | RESP_BIT)
+
+/* If v is the reply to command c */
+#define IS_A_REP(v, c) (((v) & RESP_BIT) && (((v) & CMD_MASK) == (c)))
+
+enum {
+ CMD_INVALID = 0,
+ CMD_I2C_XFER_REQ = 1,
+ CMD_PERI_POWER_SET_REQ = 2,
+ CMD_PERI_CLOCK_GATE_SET_REQ = 3,
+ CMD_PERI_CLOCK_GATE_GET_REQ = 4,
+ CMD_PERI_CLOCK_RATE_SET_REQ = 5,
+ CMD_PERI_CLOCK_RATE_GET_REQ = 6,
+ CMD_CPU_CLOCK_GATE_SET_REQ = 7,
+ CMD_CPU_CLOCK_GATE_GET_REQ = 8,
+ CMD_CPU_CLOCK_RATE_SET_REQ = 9,
+ CMD_CPU_CLOCK_RATE_GET_REQ = 0xa,
+ CMD_CLUSTER_OPP_GET_REQ = 0xb,
+ CMD_CLOCK_DSI_PIXEL_REQ = 0xc,
+ CMD_SCB_CAPABILITY_GET_REQ = 0xd,
+ CMD_SYS_RESET_CAUSE_GET_REQ = 0xe,
+ CMD_SYS_SPECIFIC_INFO_GET_REQ = 0xf,
+ CMD_REBOOT_AP_AFTER_REQ = 0x10,
+ CMD_TAIKI_REQ = 0x11,
+ CMD_TAIKI_ASYNC_MSG_REQ = 0x12,
+ CMD_GET_WORD_REQ = 0x13,
+ CMD_HARD_RESET_REQ = 0x14,
+ CMD_MAINTENANCE_MODE_REQ = 0x15,
+ CMD_STG_GET_SIZE_REQ = 0x16,
+ CMD_STG_BLOCK_READ_REQ = 0x17,
+ CMD_STG_BLOCK_WRITE_REQ = 0x18,
+ CMD_MEMORY_LAYOUT_GET_REQ = 0x19,
+ CMD_POWERDOMAIN_GET_REQ = 0x1a,
+ CMD_POWERDOMAIN_SET_REQ = 0x1b,
+ CMD_STG_BLOCK_ERASE_REQ = 0x1c,
+
+ /* Do NOT add new commands below this line */
+ MHU_NUM_CMDS,
+};
+
+#define CMD_I2C_XFER_REP ENC_REP(CMD_I2C_XFER_REQ)
+#define CMD_PERI_POWER_SET_REP ENC_REP(CMD_PERI_POWER_SET_REQ)
+#define CMD_PERI_CLOCK_GATE_SET_REP ENC_REP(CMD_PERI_CLOCK_GATE_SET_REQ)
+#define CMD_PERI_CLOCK_GATE_GET_REP ENC_REP(CMD_PERI_CLOCK_GATE_GET_REQ)
+#define CMD_PERI_CLOCK_RATE_SET_REP ENC_REP(CMD_PERI_CLOCK_RATE_SET_REQ)
+#define CMD_PERI_CLOCK_RATE_GET_REP ENC_REP(CMD_PERI_CLOCK_RATE_GET_REQ)
+#define CMD_CPU_CLOCK_GATE_SET_REP ENC_REP(CMD_CPU_CLOCK_GATE_SET_REQ)
+#define CMD_CPU_CLOCK_GATE_GET_REP ENC_REP(CMD_CPU_CLOCK_GATE_GET_REQ)
+#define CMD_CPU_CLOCK_RATE_SET_REP ENC_REP(CMD_CPU_CLOCK_RATE_SET_REQ)
+#define CMD_CPU_CLOCK_RATE_GET_REP ENC_REP(CMD_CPU_CLOCK_RATE_GET_REQ)
+#define CMD_CLUSTER_OPP_GET_REP ENC_REP(CMD_CLUSTER_OPP_GET_REQ)
+#define CMD_CLOCK_DSI_PIXEL_REP ENC_REP(CMD_CLOCK_DSI_PIXEL_REQ)
+#define CMD_SCB_CAPABILITY_GET_REP ENC_REP(CMD_SCB_CAPABILITY_GET_REQ)
+#define CMD_SYS_RESET_CAUSE_GET_REP ENC_REP(CMD_SYS_RESET_CAUSE_GET_REQ)
+#define CMD_SYS_SPECIFIC_INFO_GET_REP ENC_REP(CMD_SYS_SPECIFIC_INFO_GET_REQ)
+#define CMD_GET_WORD_REP ENC_REP(CMD_GET_WORD_REQ)
+#define CMD_REBOOT_AP_AFTER_REP ENC_REP(CMD_REBOOT_AP_AFTER_REQ)
+#define CMD_TAIKI_REP ENC_REP(CMD_TAIKI_REQ)
+#define CMD_TAIKI_ASYNC_MSG_REP ENC_REP(CMD_TAIKI_ASYNC_MSG_REQ)
+#define CMD_HARD_RESET_REP ENC_REP(CMD_HARD_RESET_REQ)
+#define CMD_MAINTENANCE_MODE_REP ENC_RSP(CMD_MAINTENANCE_MODE_REQ)
+#define CMD_STG_GET_SIZE_REP ENC_REP(CMD_STG_GET_SIZE_REQ)
+#define CMD_STG_BLOCK_READ_REP ENC_REP(CMD_STG_BLOCK_READ_REQ)
+#define CMD_STG_BLOCK_WRITE_REP ENC_REP(CMD_STG_BLOCK_WRITE_REQ)
+#define CMD_MEMORY_LAYOUT_GET_REP ENC_REP(CMD_MEMORY_LAYOUT_GET_REQ)
+#define CMD_POWERDOMAIN_GET_REP ENC_REP(CMD_POWERDOMAIN_GET_REQ)
+#define CMD_POWERDOMAIN_SET_REP ENC_REP(CMD_POWERDOMAIN_SET_REQ)
+#define CMD_STG_BLOCK_ERASE_REP ENC_REP(CMD_STG_BLOCK_ERASE_REQ)
+
+/* Helper functions to talk to remote */
+int mb86s7x_send_packet(int cmd, void *buf, int len);
+
+typedef void (*mb86s7x_mhu_handler_t)(u32 cmd, u8 rcbuf[]);
+int mb86s7x_hndlr_set(u32 cmd, mb86s7x_mhu_handler_t);
+void mb86s7x_hndlr_clr(u32 cmd, mb86s7x_mhu_handler_t);
+
+#endif /* __MB86S7X_SCB_MHU_H */
--
1.9.0
--
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 related [flat|nested] 47+ messages in thread
* [PATCH v5 1/7] ARM: Add platform support for Fujitsu MB86S7X SoCs
@ 2015-02-03 9:27 ` Vincent Yang
0 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:27 UTC (permalink / raw)
To: linux-arm-kernel
From: Jassi Brar <jaswinder.singh@linaro.org>
The MB86S7X is a bigLITTLE configuration of 2xCA7 & 2xCA15 under Linux.
And the remote master firmware (called SCB) running on CM3. Linux asks
for things to be done over Mailbox API, to SCB which controls most of
the important things. variations S70 & S73 are supported.
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
Documentation/devicetree/bindings/arm/mb86s7x.txt | 8 +
.../devicetree/bindings/soc/mb86s7x/scb_mhu.txt | 35 ++
MAINTAINERS | 7 +
arch/arm/Kconfig | 2 +
arch/arm/Makefile | 1 +
arch/arm/mach-mb86s7x/Kconfig | 19 +
arch/arm/mach-mb86s7x/Makefile | 1 +
arch/arm/mach-mb86s7x/board.c | 23 +
drivers/soc/Makefile | 1 +
drivers/soc/mb86s7x/Makefile | 4 +
drivers/soc/mb86s7x/scb_mhu.c | 514 +++++++++++++++++++++
include/soc/mb86s7x/scb_mhu.h | 97 ++++
12 files changed, 712 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/mb86s7x.txt
create mode 100644 Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
create mode 100644 arch/arm/mach-mb86s7x/Kconfig
create mode 100644 arch/arm/mach-mb86s7x/Makefile
create mode 100644 arch/arm/mach-mb86s7x/board.c
create mode 100644 drivers/soc/mb86s7x/Makefile
create mode 100644 drivers/soc/mb86s7x/scb_mhu.c
create mode 100644 include/soc/mb86s7x/scb_mhu.h
diff --git a/Documentation/devicetree/bindings/arm/mb86s7x.txt b/Documentation/devicetree/bindings/arm/mb86s7x.txt
new file mode 100644
index 0000000..fbaad20
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mb86s7x.txt
@@ -0,0 +1,8 @@
+Fujitsu MB86S7X Device Tree Bindings
+
+Fujitsu has a few closely related platforms that are basically different
+configurations of each others. Like MB86S7{0,1,2,3}.
+
+The EVB boards with S70/S73 have the following property:
+Required root node property:
+ compatible: must contain "fujitsu,mb86s70-evb" or "fujitsu,mb86s73-evb"
diff --git a/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt b/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
new file mode 100644
index 0000000..f466a05
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mb86s7x/scb_mhu.txt
@@ -0,0 +1,35 @@
+Fujitsu SCB (Mailbox's Remote Firmware) bindings
+------------------------------------------------
+
+The firmware (running of a remote Cortex-M3 master) on Fujitsu's MB86S7X
+platforms is named SCB. The SCB owns most of core h/w IPs like Clock,
+CPUFreq/DVFS, CPUIdle/SMP, Thermal, a recovery block device and even an
+I2C controller. Linux has to map all of these functionalities on to
+the Mailbox API and get things done by the remote master.
+ Let the current state of SCB firmware be versioned 1.0.
+
+Required properties :
+- compatible : Shall contain "fujitsu,mb86s70-scb-1.0"
+- reg : Point to SharedMemory used for Mailbox protocol.
+- mboxes : phandle to the mailbox controller:channel node.
+
+The consumer specifies the desired clock pointing to its phandle.
+
+Example:
+
+ mhu: mhu0 at 2b1f0000 {
+ #mbox-cells = <1>;
+ compatible = "arm,mhu";
+ reg = <0 0x2b1f0000 0x1000>;
+ interrupts = <0 36 4>, /* LP Non-Sec */
+ <0 35 4>, /* HP Non-Sec */
+ <0 37 4>; /* Secure */
+ clocks = <&clk 0 2 1>;
+ clock-names = "apb_pclk";
+ };
+
+ mhu_client: scb at 2e000000 {
+ compatible = "fujitsu,mb86s70-scb-1.0";
+ reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
+ mboxes = <&mhu 1>;
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index aaa039d..1436e34 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1111,6 +1111,13 @@ M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
S: Maintained
+ARM/MB86S7X SOC SUPPORT
+M: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
+M: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
+L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S: Supported
+F: arch/arm/mach-mb86s7x/
+
ARM/TEXAS INSTRUMENT KEYSTONE ARCHITECTURE
M: Santosh Shilimkar <ssantosh@kernel.org>
L: linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed..3c80a9b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -884,6 +884,8 @@ source "arch/arm/mach-keystone/Kconfig"
source "arch/arm/mach-ks8695/Kconfig"
+source "arch/arm/mach-mb86s7x/Kconfig"
+
source "arch/arm/mach-meson/Kconfig"
source "arch/arm/mach-msm/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c1785ee..c65aff2 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx
machine-$(CONFIG_ARCH_KEYSTONE) += keystone
machine-$(CONFIG_ARCH_KS8695) += ks8695
machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx
+machine-$(CONFIG_ARCH_MB86S7X) += mb86s7x
machine-$(CONFIG_ARCH_MESON) += meson
machine-$(CONFIG_ARCH_MMP) += mmp
machine-$(CONFIG_ARCH_MOXART) += moxart
diff --git a/arch/arm/mach-mb86s7x/Kconfig b/arch/arm/mach-mb86s7x/Kconfig
new file mode 100644
index 0000000..f58b104
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/Kconfig
@@ -0,0 +1,19 @@
+config ARCH_MB86S7X
+ bool "Fujitsu MB86S7x platforms" if ARCH_MULTI_V7
+ select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
+ select ARCH_HAS_CPUFREQ
+ select ARCH_HAS_OPP
+ select ARCH_REQUIRE_GPIOLIB
+ select ARM_AMBA
+ select ARM_CCI
+ select ARM_GIC
+ select ARM_TIMER_SP804
+ select BIG_LITTLE
+ select HAVE_ARM_ARCH_TIMER
+ select MAILBOX
+ select PINCTRL
+ select PINCTRL_MB86S7X
+ select PM_OPP
+ select ZONE_DMA if ARM_LPAE
+ help
+ Support for Fujitsu MB86S7x based platforms
diff --git a/arch/arm/mach-mb86s7x/Makefile b/arch/arm/mach-mb86s7x/Makefile
new file mode 100644
index 0000000..97640b6
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_MB86S7X) += board.o
diff --git a/arch/arm/mach-mb86s7x/board.c b/arch/arm/mach-mb86s7x/board.c
new file mode 100644
index 0000000..222b63f
--- /dev/null
+++ b/arch/arm/mach-mb86s7x/board.c
@@ -0,0 +1,23 @@
+/*
+ * Support for the Fujitsu's MB86S7x based devices.
+ *
+ * Copyright (C) 2015 Linaro, LTD
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ */
+
+#include <linux/of.h>
+#include <asm/mach/arch.h>
+
+static const char *mb86s7x_dt_match[] __initconst = {
+ "fujitsu,mb86s70-evb",
+ "fujitsu,mb86s73-evb",
+ NULL,
+};
+
+DT_MACHINE_START(MB86S7X_DT, "Fujitsu MB86S7X-based board")
+ .dt_compat = mb86s7x_dt_match,
+MACHINE_END
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 063113d..fb64bf2 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -2,6 +2,7 @@
# Makefile for the Linux Kernel SOC specific device drivers.
#
+obj-$(CONFIG_ARCH_MB86S7X) += mb86s7x/
obj-$(CONFIG_ARCH_QCOM) += qcom/
obj-$(CONFIG_ARCH_TEGRA) += tegra/
obj-$(CONFIG_SOC_TI) += ti/
diff --git a/drivers/soc/mb86s7x/Makefile b/drivers/soc/mb86s7x/Makefile
new file mode 100644
index 0000000..f6b96cf
--- /dev/null
+++ b/drivers/soc/mb86s7x/Makefile
@@ -0,0 +1,4 @@
+#
+# Fujitsu's MB86S7X drivers
+#
+obj-$(CONFIG_ARCH_MB86S7X) += scb_mhu.o
diff --git a/drivers/soc/mb86s7x/scb_mhu.c b/drivers/soc/mb86s7x/scb_mhu.c
new file mode 100644
index 0000000..2fe59c2
--- /dev/null
+++ b/drivers/soc/mb86s7x/scb_mhu.c
@@ -0,0 +1,514 @@
+/*
+ * arch/arm/mach-mb86s7x/scb_mhu.c Shim 'server' for Mailbox clients
+ *
+ * Created by: Jassi Brar <jassisinghbrar@gmail.com>
+ * Copyright: (C) 2013-2015 Linaro Limited
+ *
+ * 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.
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/of_address.h>
+#include <linux/mailbox_client.h>
+#include <linux/platform_device.h>
+
+#include <soc/mb86s7x/scb_mhu.h>
+
+#include <asm/system_misc.h>
+
+#define INTR_STAT_OFS 0x0
+#define INTR_SET_OFS 0x8
+#define INTR_CLR_OFS 0x10
+
+static LIST_HEAD(free_xfers);
+static LIST_HEAD(pending_xfers);
+static DEFINE_SPINLOCK(fsm_lock);
+static struct completion fsm_rsp;
+static struct mbox_client mhu_cl;
+static struct mbox_chan *mhu_chan;
+static mb86s7x_mhu_handler_t handler[MHU_NUM_CMDS];
+
+static void __iomem *mhu_base, *mb86s7x_shm_base;
+static void __iomem *cmd_to_scb, *rsp_to_scb;
+static void __iomem *cmd_from_scb, *rsp_from_scb;
+
+static enum {
+ MHU_PARK = 0,
+ MHU_WRR, /* Waiting to get Remote's Reply */
+ MHU_WRL, /* Waiting to send Reply */
+ MHU_WRRL, /* WAIT_Ra && WAIT_Rb */
+ MHU_INVLD,
+} fsm_state;
+
+enum fsm_event {
+ EV_LC = 0, /* Local sent a command */
+ EV_RC, /* Remote sent a command */
+ EV_RR, /* Remote sent a reply */
+ EV_LR, /* Local sent a reply */
+};
+
+static int mhu_fsm[4][4] = {
+ [MHU_PARK] = {
+ [EV_LC] = MHU_WRR,
+ [EV_RC] = MHU_WRL,
+ [EV_RR] = MHU_INVLD,
+ [EV_LR] = MHU_INVLD,
+ },
+ [MHU_WRR] = {
+ [EV_LC] = MHU_INVLD,
+ [EV_RC] = MHU_WRRL,
+ [EV_RR] = MHU_PARK,
+ [EV_LR] = MHU_INVLD,
+ },
+ [MHU_WRL] = {
+ [EV_LC] = MHU_WRRL,
+ [EV_RC] = MHU_INVLD,
+ [EV_RR] = MHU_INVLD,
+ [EV_LR] = MHU_PARK,
+ },
+ [MHU_WRRL] = {
+ [EV_LC] = MHU_INVLD,
+ [EV_RC] = MHU_INVLD,
+ [EV_RR] = MHU_WRL,
+ [EV_LR] = MHU_WRR,
+ },
+};
+
+static struct mhu_xfer {
+ int code;
+ int len;
+ void *buf;
+ struct completion *c;
+ struct list_head node;
+} *ax; /* stages of xfer */
+
+static int mhu_alloc_xfers(int n, struct list_head *list)
+{
+ struct mhu_xfer *x = kcalloc(n, sizeof(struct mhu_xfer), GFP_ATOMIC);
+ int i;
+
+ if (!x)
+ return -ENOMEM;
+
+ for (i = 0; i < n; i++)
+ list_add(&x[i].node, &free_xfers);
+
+ return 0;
+}
+
+static void got_data(u32 code)
+{
+ mb86s7x_mhu_handler_t hndlr = NULL;
+ unsigned long flags;
+ int ev;
+
+ if (code & RESP_BIT)
+ ev = EV_RR;
+ else
+ ev = EV_RC;
+
+ spin_lock_irqsave(&fsm_lock, flags);
+
+ if (mhu_fsm[fsm_state][ev] == MHU_INVLD) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ pr_err("State-%d EV-%d FSM Broken!\n", fsm_state, ev);
+ return;
+ }
+ fsm_state = mhu_fsm[fsm_state][ev];
+
+ if (code & RESP_BIT) {
+ memcpy_fromio(ax->buf, rsp_from_scb, ax->len);
+ if (ax->c)
+ complete(ax->c);
+ list_move(&ax->node, &free_xfers);
+ ax = NULL;
+ } else {
+ /* Find and dispatch relevant registered handler */
+ if (code < MHU_NUM_CMDS)
+ hndlr = handler[code];
+ if (hndlr)
+ hndlr(code, cmd_from_scb);
+ else
+ pr_err("No handler for CMD_%u\n", code);
+ }
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+}
+
+static int do_xfer(void)
+{
+ unsigned long flags;
+ struct mhu_xfer *x;
+ int ev, code;
+
+ spin_lock_irqsave(&fsm_lock, flags);
+
+ if (list_empty(&pending_xfers)) {
+ struct mbox_chan *_ch = NULL;
+ int cmd;
+
+ for (cmd = 0; cmd < MHU_NUM_CMDS && !handler[cmd]; cmd++)
+ ;
+ /* Don't free channel if any user is listening */
+ if (cmd != MHU_NUM_CMDS) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ return 0;
+ }
+
+ if (fsm_state == MHU_PARK) {
+ _ch = mhu_chan;
+ mhu_chan = NULL;
+ }
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ if (_ch)
+ mbox_free_channel(_ch);
+
+ return 0;
+ }
+
+ x = list_first_entry(&pending_xfers, struct mhu_xfer, node);
+ code = x->code;
+
+ ev = code & RESP_BIT ? EV_LR : EV_LC;
+ if (mhu_fsm[fsm_state][ev] == MHU_INVLD) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ return 1;
+ }
+ list_del_init(&x->node);
+
+ /* Layout the SHM */
+ if (code & RESP_BIT)
+ memcpy_toio(rsp_to_scb, x->buf, x->len);
+ else
+ memcpy_toio(cmd_to_scb, x->buf, x->len);
+
+ if (ev == EV_LC)
+ ax = x;
+ else
+ list_move(&x->node, &free_xfers);
+ fsm_state = mhu_fsm[fsm_state][ev];
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ /* Prefer mailbox API */
+ if (!mhu_chan) {
+ struct mbox_chan *_ch;
+
+ _ch = mbox_request_channel(&mhu_cl, 0);
+ if (!IS_ERR(_ch))
+ mhu_chan = _ch;
+ }
+
+ if (mhu_chan) {
+ int ret;
+
+ init_completion(&fsm_rsp);
+
+ /* Send via generic api */
+ ret = mbox_send_message(mhu_chan, (void *)code);
+ if (ret < 0) {
+ pr_err("%s:%d CMD_%d Send Failed\n",
+ __func__, __LINE__, code);
+ BUG();
+ }
+ if (!(code & RESP_BIT)) {
+ ret = wait_for_completion_timeout(&fsm_rsp,
+ msecs_to_jiffies(1000));
+ if (!ret) {
+ pr_err("%s:%d CMD_%d Got No Reply\n",
+ __func__, __LINE__, code);
+ BUG();
+ }
+ got_data(ax->code);
+ }
+ } else {
+ void __iomem *tx_reg = mhu_base + 0x120; /* HP-NonSec */
+ void __iomem *rx_reg = mhu_base + 0x20; /* HP-NonSec */
+ u32 val, count;
+
+ /* Send via early-boot api */
+ val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+ if (val) {
+ pr_err("Last CMD not yet read by SCB\n");
+ writel_relaxed(val, tx_reg + INTR_CLR_OFS);
+ }
+
+ writel_relaxed(x->code, tx_reg + INTR_SET_OFS);
+
+ /* Wait until this message is read */
+ count = 0x1000000;
+ do {
+ cpu_relax();
+ val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+ } while (--count && val);
+ if (val)
+ pr_err("%s:%d SCB not listening!\n",
+ __func__, __LINE__);
+
+ if (!ax) {
+ /* A quick poll for pending remote cmd */
+ val = readl_relaxed(rx_reg + INTR_STAT_OFS);
+ if (val) {
+ got_data(val);
+ writel_relaxed(val, rx_reg + INTR_CLR_OFS);
+ }
+ } else {
+ do {
+ /* Wait until we get reply */
+ count = 0x1000000;
+ do {
+ cpu_relax();
+ val = readl_relaxed(
+ rx_reg + INTR_STAT_OFS);
+ } while (--count && !val);
+
+ if (val) {
+ got_data(val);
+ writel_relaxed(val,
+ rx_reg + INTR_CLR_OFS);
+ } else {
+ pr_err("%s:%d SCB didn't reply\n",
+ __func__, __LINE__);
+ return 1;
+ }
+ } while (!(val & RESP_BIT));
+ }
+ if (list_empty(&pending_xfers))
+ return 0;
+ }
+
+ return do_xfer();
+}
+
+static void mhu_recv(struct mbox_client *cl, void *data)
+{
+ if ((u32)data & RESP_BIT) {
+ /* Now that we got a reply to last TX, that
+ * must mean the last TX was successful */
+ mbox_client_txdone(mhu_chan, 0);
+
+ ax->code = (u32)data; /* Save response */
+ complete(&fsm_rsp);
+ return;
+ }
+
+ got_data((u32)data);
+}
+
+int mb86s7x_hndlr_set(u32 cmd, mb86s7x_mhu_handler_t hndlr)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ spin_lock_irqsave(&fsm_lock, flags);
+ if (cmd < MHU_NUM_CMDS && !handler[cmd]) {
+ ret = 0;
+ handler[cmd] = hndlr;
+ }
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ if (!mhu_chan) {
+ struct mbox_chan *_ch;
+
+ _ch = mbox_request_channel(&mhu_cl, 0);
+ if (!IS_ERR(_ch))
+ mhu_chan = _ch;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mb86s7x_hndlr_set);
+
+void mb86s7x_hndlr_clr(u32 cmd, mb86s7x_mhu_handler_t hndlr)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&fsm_lock, flags);
+
+ if (cmd < MHU_NUM_CMDS && handler[cmd] == hndlr)
+ handler[cmd] = NULL;
+
+ if (list_empty(&pending_xfers)) {
+ struct mbox_chan *_ch = NULL;
+
+ for (cmd = 0; cmd < MHU_NUM_CMDS && !handler[cmd]; cmd++)
+ ;
+ /* Don't free channel if any user is listening */
+ if (cmd != MHU_NUM_CMDS) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ return;
+ }
+
+ if (fsm_state == MHU_PARK) {
+ _ch = mhu_chan;
+ mhu_chan = NULL;
+ }
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ if (_ch)
+ mbox_free_channel(_ch);
+
+ return;
+ }
+ spin_unlock_irqrestore(&fsm_lock, flags);
+}
+EXPORT_SYMBOL_GPL(mb86s7x_hndlr_clr);
+
+static int setup_mhu(void)
+{
+ struct device_node *node;
+
+ node = of_find_compatible_node(NULL, NULL, "arm,mhu");
+ mhu_base = of_iomap(node, 0);
+ if (mhu_base == NULL) {
+ pr_err("Can't work without MHU\n");
+ return -ENODEV;
+ }
+
+ node = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
+ mb86s7x_shm_base = of_iomap(node, 0);
+ if (mb86s7x_shm_base == NULL) {
+ pr_err("Can't work without SHM SRAM\n");
+ return -ENODEV;
+ }
+
+ cmd_from_scb = mb86s7x_shm_base + 0x3800;
+ rsp_from_scb = mb86s7x_shm_base + 0x3900;
+ cmd_to_scb = mb86s7x_shm_base + 0x3a00;
+ rsp_to_scb = mb86s7x_shm_base + 0x3b00;
+
+ return 0;
+}
+
+int mb86s7x_send_packet(int code, void *buf, int len)
+{
+ struct completion got_rsp;
+ unsigned long flags;
+ struct mhu_xfer *x;
+ int ret;
+
+ /*
+ * The first caller could be as early as system clocksource,
+ * when the platform devices are not populated yet.
+ */
+ if (unlikely(!mb86s7x_shm_base) && setup_mhu())
+ return -ENODEV;
+
+ if ((code & ~0xff) || ((code & RESP_BIT)
+ && fsm_state != MHU_WRRL
+ && fsm_state != MHU_WRL)) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ init_completion(&got_rsp);
+
+ spin_lock_irqsave(&fsm_lock, flags);
+
+ if (list_empty(&free_xfers) && mhu_alloc_xfers(5, &free_xfers)) {
+ spin_unlock_irqrestore(&fsm_lock, flags);
+ pr_err("%s:%d OOM\n", __func__, __LINE__);
+ return -EAGAIN;
+ }
+
+ x = list_first_entry(&free_xfers, struct mhu_xfer, node);
+ x->code = code;
+ x->buf = buf;
+ x->len = len;
+ x->c = &got_rsp;
+
+ if (code & RESP_BIT)
+ list_move(&x->node, &pending_xfers);
+ else
+ list_move_tail(&x->node, &pending_xfers);
+
+ spin_unlock_irqrestore(&fsm_lock, flags);
+
+ ret = do_xfer();
+ if (ret > 0) {
+ ret = wait_for_completion_timeout(&got_rsp,
+ msecs_to_jiffies(1000));
+ return ret ? 0 : -EIO;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mb86s7x_send_packet);
+
+struct mb86s7x_hard_reset {
+ u32 payload_size;
+ u32 delay;
+};
+
+static void mb86s7x_reboot(u32 delay)
+{
+ void __iomem *tx_reg = mhu_base + 0x120; /* HP-NonSec */
+ struct mb86s7x_hard_reset cmd;
+ u32 val;
+
+ cmd.payload_size = sizeof(cmd);
+ cmd.delay = delay;
+
+ val = readl_relaxed(tx_reg + INTR_STAT_OFS);
+ if (val) /* Flush anything pending */
+ writel_relaxed(val, tx_reg + INTR_CLR_OFS);
+
+ memcpy_toio(cmd_to_scb, &cmd, sizeof(cmd));
+ writel_relaxed(CMD_HARD_RESET_REQ, tx_reg + INTR_SET_OFS);
+}
+
+static void
+mb86s7x_restart(enum reboot_mode reboot_mode, const char *unused)
+{
+ /* Reboot immediately (after 50ms) */
+ mb86s7x_reboot(50);
+}
+
+static void mb86s7x_poweroff(void)
+{
+ /* Reboot never, remain dead */
+ mb86s7x_reboot(~0);
+}
+
+static int f_scb_probe(struct platform_device *pdev)
+{
+ mhu_cl.tx_block = true;
+ mhu_cl.knows_txdone = true;
+ mhu_cl.rx_callback = mhu_recv;
+ mhu_cl.dev = &pdev->dev;
+
+ arm_pm_restart = mb86s7x_restart;
+ pm_power_off = mb86s7x_poweroff;
+
+ return 0;
+}
+
+static const struct of_device_id scb_dt_ids[] = {
+ { .compatible = "fujitsu,mb86s70-scb-1.0" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, scb_dt_ids);
+
+static struct platform_driver f_scb_driver = {
+ .driver = {
+ .name = "f_scb",
+ .of_match_table = scb_dt_ids,
+ },
+ .probe = f_scb_probe,
+};
+
+static int __init f_scb_init(void)
+{
+ return platform_driver_register(&f_scb_driver);
+}
+module_init(f_scb_init);
diff --git a/include/soc/mb86s7x/scb_mhu.h b/include/soc/mb86s7x/scb_mhu.h
new file mode 100644
index 0000000..334fa9f
--- /dev/null
+++ b/include/soc/mb86s7x/scb_mhu.h
@@ -0,0 +1,97 @@
+/*
+ * include/soc/mb86s7x/scb_mhu.h
+ *
+ * Created by: Jassi Brar <jassisinghbrar@gmail.com>
+ * Copyright: (C) 2013-2015 Linaro Limited
+ *
+ * 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.
+ */
+
+#ifndef __MB86S7X_SCB_MHU_H
+#define __MB86S7X_SCB_MHU_H
+
+#define CMD_MASK 0x7f /* 128 possible commands */
+#define RESP_BIT (1 << 7) /* If it's a response */
+
+#define ENC_CMD(c) ((c) & CMD_MASK)
+#define DEC_CMD(v) (((v) & ~CMD_MASK) ? CMD_INVALID : ((v) & CMD_MASK))
+
+#define ENC_REP(r) (((r) & CMD_MASK) | RESP_BIT)
+
+/* If v is the reply to command c */
+#define IS_A_REP(v, c) (((v) & RESP_BIT) && (((v) & CMD_MASK) == (c)))
+
+enum {
+ CMD_INVALID = 0,
+ CMD_I2C_XFER_REQ = 1,
+ CMD_PERI_POWER_SET_REQ = 2,
+ CMD_PERI_CLOCK_GATE_SET_REQ = 3,
+ CMD_PERI_CLOCK_GATE_GET_REQ = 4,
+ CMD_PERI_CLOCK_RATE_SET_REQ = 5,
+ CMD_PERI_CLOCK_RATE_GET_REQ = 6,
+ CMD_CPU_CLOCK_GATE_SET_REQ = 7,
+ CMD_CPU_CLOCK_GATE_GET_REQ = 8,
+ CMD_CPU_CLOCK_RATE_SET_REQ = 9,
+ CMD_CPU_CLOCK_RATE_GET_REQ = 0xa,
+ CMD_CLUSTER_OPP_GET_REQ = 0xb,
+ CMD_CLOCK_DSI_PIXEL_REQ = 0xc,
+ CMD_SCB_CAPABILITY_GET_REQ = 0xd,
+ CMD_SYS_RESET_CAUSE_GET_REQ = 0xe,
+ CMD_SYS_SPECIFIC_INFO_GET_REQ = 0xf,
+ CMD_REBOOT_AP_AFTER_REQ = 0x10,
+ CMD_TAIKI_REQ = 0x11,
+ CMD_TAIKI_ASYNC_MSG_REQ = 0x12,
+ CMD_GET_WORD_REQ = 0x13,
+ CMD_HARD_RESET_REQ = 0x14,
+ CMD_MAINTENANCE_MODE_REQ = 0x15,
+ CMD_STG_GET_SIZE_REQ = 0x16,
+ CMD_STG_BLOCK_READ_REQ = 0x17,
+ CMD_STG_BLOCK_WRITE_REQ = 0x18,
+ CMD_MEMORY_LAYOUT_GET_REQ = 0x19,
+ CMD_POWERDOMAIN_GET_REQ = 0x1a,
+ CMD_POWERDOMAIN_SET_REQ = 0x1b,
+ CMD_STG_BLOCK_ERASE_REQ = 0x1c,
+
+ /* Do NOT add new commands below this line */
+ MHU_NUM_CMDS,
+};
+
+#define CMD_I2C_XFER_REP ENC_REP(CMD_I2C_XFER_REQ)
+#define CMD_PERI_POWER_SET_REP ENC_REP(CMD_PERI_POWER_SET_REQ)
+#define CMD_PERI_CLOCK_GATE_SET_REP ENC_REP(CMD_PERI_CLOCK_GATE_SET_REQ)
+#define CMD_PERI_CLOCK_GATE_GET_REP ENC_REP(CMD_PERI_CLOCK_GATE_GET_REQ)
+#define CMD_PERI_CLOCK_RATE_SET_REP ENC_REP(CMD_PERI_CLOCK_RATE_SET_REQ)
+#define CMD_PERI_CLOCK_RATE_GET_REP ENC_REP(CMD_PERI_CLOCK_RATE_GET_REQ)
+#define CMD_CPU_CLOCK_GATE_SET_REP ENC_REP(CMD_CPU_CLOCK_GATE_SET_REQ)
+#define CMD_CPU_CLOCK_GATE_GET_REP ENC_REP(CMD_CPU_CLOCK_GATE_GET_REQ)
+#define CMD_CPU_CLOCK_RATE_SET_REP ENC_REP(CMD_CPU_CLOCK_RATE_SET_REQ)
+#define CMD_CPU_CLOCK_RATE_GET_REP ENC_REP(CMD_CPU_CLOCK_RATE_GET_REQ)
+#define CMD_CLUSTER_OPP_GET_REP ENC_REP(CMD_CLUSTER_OPP_GET_REQ)
+#define CMD_CLOCK_DSI_PIXEL_REP ENC_REP(CMD_CLOCK_DSI_PIXEL_REQ)
+#define CMD_SCB_CAPABILITY_GET_REP ENC_REP(CMD_SCB_CAPABILITY_GET_REQ)
+#define CMD_SYS_RESET_CAUSE_GET_REP ENC_REP(CMD_SYS_RESET_CAUSE_GET_REQ)
+#define CMD_SYS_SPECIFIC_INFO_GET_REP ENC_REP(CMD_SYS_SPECIFIC_INFO_GET_REQ)
+#define CMD_GET_WORD_REP ENC_REP(CMD_GET_WORD_REQ)
+#define CMD_REBOOT_AP_AFTER_REP ENC_REP(CMD_REBOOT_AP_AFTER_REQ)
+#define CMD_TAIKI_REP ENC_REP(CMD_TAIKI_REQ)
+#define CMD_TAIKI_ASYNC_MSG_REP ENC_REP(CMD_TAIKI_ASYNC_MSG_REQ)
+#define CMD_HARD_RESET_REP ENC_REP(CMD_HARD_RESET_REQ)
+#define CMD_MAINTENANCE_MODE_REP ENC_RSP(CMD_MAINTENANCE_MODE_REQ)
+#define CMD_STG_GET_SIZE_REP ENC_REP(CMD_STG_GET_SIZE_REQ)
+#define CMD_STG_BLOCK_READ_REP ENC_REP(CMD_STG_BLOCK_READ_REQ)
+#define CMD_STG_BLOCK_WRITE_REP ENC_REP(CMD_STG_BLOCK_WRITE_REQ)
+#define CMD_MEMORY_LAYOUT_GET_REP ENC_REP(CMD_MEMORY_LAYOUT_GET_REQ)
+#define CMD_POWERDOMAIN_GET_REP ENC_REP(CMD_POWERDOMAIN_GET_REQ)
+#define CMD_POWERDOMAIN_SET_REP ENC_REP(CMD_POWERDOMAIN_SET_REQ)
+#define CMD_STG_BLOCK_ERASE_REP ENC_REP(CMD_STG_BLOCK_ERASE_REQ)
+
+/* Helper functions to talk to remote */
+int mb86s7x_send_packet(int cmd, void *buf, int len);
+
+typedef void (*mb86s7x_mhu_handler_t)(u32 cmd, u8 rcbuf[]);
+int mb86s7x_hndlr_set(u32 cmd, mb86s7x_mhu_handler_t);
+void mb86s7x_hndlr_clr(u32 cmd, mb86s7x_mhu_handler_t);
+
+#endif /* __MB86S7X_SCB_MHU_H */
--
1.9.0
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-03 9:21 ` Vincent Yang
@ 2015-02-03 9:29 ` Vincent Yang
-1 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:29 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
arm-DgEjT+Ai2ygdnm+yROfE0A, linux-lFZ/pmaqli7XmaaqVzeoHQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, sudeep.holla-5wv7dgnIgG8,
andy.green-QSEj5FYQhm4dnm+yROfE0A,
patches-QSEj5FYQhm4dnm+yROfE0A,
jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
Tetsuya Nuriya
From: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Add driver for the ARM Primecell Message-Handling-Unit(MHU) controller.
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
.../devicetree/bindings/mailbox/arm-mhu.txt | 35 ++++
drivers/mailbox/Kconfig | 7 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/arm_mhu.c | 203 +++++++++++++++++++++
4 files changed, 247 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
create mode 100644 drivers/mailbox/arm_mhu.c
diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
new file mode 100644
index 0000000..986a205
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
@@ -0,0 +1,35 @@
+ARM MHU Mailbox Driver
+======================
+
+The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
+3 independent channels/links to communicate with remote processor(s).
+ MHU links are hardwired on a platform. A link raises interrupt for any
+received data. However, there is no specified way of knowing if the sent
+data has been read by the remote. This driver assumes the sender polls
+STAT register and the remote clears it after having read the data.
+
+Mailbox Device Node:
+====================
+
+Required properties:
+--------------------
+- compatible: Shall be "arm,mhu" & "arm,primecell"
+- reg: Contains the mailbox register address range (base
+ address and length)
+- #mbox-cells Shall be 1
+- interrupts: Contains the interrupt information corresponding to
+ each of the 3 links of MHU.
+
+Example:
+--------
+
+ mhu: mailbox@2b1f0000 {
+ #mbox-cells = <1>;
+ compatible = "arm,mhu", "arm,primecell";
+ reg = <0 0x2b1f0000 0x1000>;
+ interrupts = <0 36 4>,
+ <0 35 4>,
+ <0 37 4>;
+ clocks = <&clock 0 2 1>;
+ clock-names = "apb_pclk";
+ };
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index c04fed9..9238440 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -6,6 +6,13 @@ menuconfig MAILBOX
signals. Say Y if your platform supports hardware mailboxes.
if MAILBOX
+
+config ARM_MHU
+ tristate "ARM MHU Mailbox"
+ depends on ARM
+ help
+ Say Y here if you want to build the ARM MHU controller driver
+
config PL320_MBOX
bool "ARM PL320 Mailbox"
depends on ARM_AMBA
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index dd412c2..c83791d 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -2,6 +2,8 @@
obj-$(CONFIG_MAILBOX) += mailbox.o
+obj-$(CONFIG_ARM_MHU) += arm_mhu.o
+
obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o
diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c
new file mode 100644
index 0000000..5768936
--- /dev/null
+++ b/drivers/mailbox/arm_mhu.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2013-2015 Fujitsu Semiconductor Ltd.
+ * Copyright (C) 2015 Linaro Ltd.
+ * Author: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/amba/bus.h>
+#include <linux/mailbox_controller.h>
+
+#define INTR_STAT_OFS 0x0
+#define INTR_SET_OFS 0x8
+#define INTR_CLR_OFS 0x10
+
+struct mhu_link {
+ unsigned irq;
+ void __iomem *tx_reg;
+ void __iomem *rx_reg;
+};
+
+struct arm_mhu {
+ void __iomem *base;
+ struct mhu_link mlink[3];
+ struct mbox_chan chan[3];
+ struct mbox_controller mbox;
+};
+
+static irqreturn_t mhu_rx_interrupt(int irq, void *p)
+{
+ struct mbox_chan *chan = p;
+ struct mhu_link *mlink = chan->con_priv;
+ u32 val;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ val = readl_relaxed(mlink->rx_reg + INTR_STAT_OFS);
+ if (!val)
+ return IRQ_NONE;
+
+ mbox_chan_received_data(chan, (void *)val);
+
+ writel_relaxed(val, mlink->rx_reg + INTR_CLR_OFS);
+
+ return IRQ_HANDLED;
+}
+
+static bool mhu_last_tx_done(struct mbox_chan *chan)
+{
+ struct mhu_link *mlink = chan->con_priv;
+ u32 val;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
+
+ return (val == 0);
+}
+
+static int mhu_send_data(struct mbox_chan *chan, void *data)
+{
+ struct mhu_link *mlink = chan->con_priv;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ if (!mhu_last_tx_done(chan)) {
+ dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
+ return -EBUSY;
+ }
+
+ writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
+
+ return 0;
+}
+
+static int mhu_startup(struct mbox_chan *chan)
+{
+ struct mhu_link *mlink = chan->con_priv;
+ u32 val;
+ int ret;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
+ writel_relaxed(val, mlink->tx_reg + INTR_CLR_OFS);
+
+ ret = request_irq(mlink->irq, mhu_rx_interrupt, 0, "mhu_link", chan);
+ if (ret) {
+ dev_err(chan->mbox->dev,
+ "Unable to aquire IRQ %d\n", mlink->irq);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void mhu_shutdown(struct mbox_chan *chan)
+{
+ struct mhu_link *mlink = chan->con_priv;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ free_irq(mlink->irq, chan);
+}
+
+static struct mbox_chan_ops mhu_ops = {
+ .send_data = mhu_send_data,
+ .startup = mhu_startup,
+ .shutdown = mhu_shutdown,
+ .last_tx_done = mhu_last_tx_done,
+};
+
+static int mhu_probe(struct amba_device *adev, const struct amba_id *id)
+{
+ int i, err;
+ struct arm_mhu *mhu;
+ struct device *dev = &adev->dev;
+ int mhu_reg[3] = {0x0, 0x20, 0x200};
+
+ err = amba_request_regions(adev, NULL);
+ if (err)
+ return err;
+
+ /* Allocate memory for device */
+ mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
+ if (!mhu)
+ return -ENOMEM;
+
+ mhu->base = devm_ioremap(dev, adev->res.start,
+ resource_size(&adev->res));
+ if (!mhu->base) {
+ dev_err(dev, "ioremap failed\n");
+ return -ENXIO;
+ }
+
+ for (i = 0; i < 3; i++) {
+ mhu->chan[i].con_priv = &mhu->mlink[i];
+ mhu->mlink[i].irq = adev->irq[i];
+ mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i];
+ mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + 0x100;
+ }
+
+ mhu->mbox.dev = dev;
+ mhu->mbox.chans = &mhu->chan[0];
+ mhu->mbox.num_chans = 3;
+ mhu->mbox.ops = &mhu_ops;
+ mhu->mbox.txdone_irq = false;
+ mhu->mbox.txdone_poll = true;
+ mhu->mbox.txpoll_period = 10;
+
+ amba_set_drvdata(adev, mhu);
+
+ err = mbox_controller_register(&mhu->mbox);
+ if (err) {
+ dev_err(dev, "Failed to register mailboxes %d\n", err);
+ return err;
+ }
+
+ dev_err(dev, "ARM MHU Mailbox registered\n");
+ return 0;
+}
+
+static int mhu_remove(struct amba_device *adev)
+{
+ struct arm_mhu *mhu = amba_get_drvdata(adev);
+
+ mbox_controller_unregister(&mhu->mbox);
+
+ return 0;
+}
+
+static struct amba_id mhu_ids[] = {
+ {
+ .id = 0x1bb098,
+ .mask = 0xffffff,
+ },
+ { 0, 0 },
+};
+MODULE_DEVICE_TABLE(amba, mhu_ids);
+
+static struct amba_driver arm_mhu_driver = {
+ .drv = {
+ .name = "mhu",
+ },
+ .id_table = mhu_ids,
+ .probe = mhu_probe,
+ .remove = mhu_remove,
+};
+module_amba_driver(arm_mhu_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ARM MHU Driver");
+MODULE_AUTHOR("Jassi Brar <jassisinghbrar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
--
1.9.0
--
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 related [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-03 9:29 ` Vincent Yang
0 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:29 UTC (permalink / raw)
To: linux-arm-kernel
From: Jassi Brar <jaswinder.singh@linaro.org>
Add driver for the ARM Primecell Message-Handling-Unit(MHU) controller.
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
.../devicetree/bindings/mailbox/arm-mhu.txt | 35 ++++
drivers/mailbox/Kconfig | 7 +
drivers/mailbox/Makefile | 2 +
drivers/mailbox/arm_mhu.c | 203 +++++++++++++++++++++
4 files changed, 247 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mailbox/arm-mhu.txt
create mode 100644 drivers/mailbox/arm_mhu.c
diff --git a/Documentation/devicetree/bindings/mailbox/arm-mhu.txt b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
new file mode 100644
index 0000000..986a205
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/arm-mhu.txt
@@ -0,0 +1,35 @@
+ARM MHU Mailbox Driver
+======================
+
+The ARM's Message-Handling-Unit (MHU) is a mailbox controller that has
+3 independent channels/links to communicate with remote processor(s).
+ MHU links are hardwired on a platform. A link raises interrupt for any
+received data. However, there is no specified way of knowing if the sent
+data has been read by the remote. This driver assumes the sender polls
+STAT register and the remote clears it after having read the data.
+
+Mailbox Device Node:
+====================
+
+Required properties:
+--------------------
+- compatible: Shall be "arm,mhu" & "arm,primecell"
+- reg: Contains the mailbox register address range (base
+ address and length)
+- #mbox-cells Shall be 1
+- interrupts: Contains the interrupt information corresponding to
+ each of the 3 links of MHU.
+
+Example:
+--------
+
+ mhu: mailbox at 2b1f0000 {
+ #mbox-cells = <1>;
+ compatible = "arm,mhu", "arm,primecell";
+ reg = <0 0x2b1f0000 0x1000>;
+ interrupts = <0 36 4>,
+ <0 35 4>,
+ <0 37 4>;
+ clocks = <&clock 0 2 1>;
+ clock-names = "apb_pclk";
+ };
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index c04fed9..9238440 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -6,6 +6,13 @@ menuconfig MAILBOX
signals. Say Y if your platform supports hardware mailboxes.
if MAILBOX
+
+config ARM_MHU
+ tristate "ARM MHU Mailbox"
+ depends on ARM
+ help
+ Say Y here if you want to build the ARM MHU controller driver
+
config PL320_MBOX
bool "ARM PL320 Mailbox"
depends on ARM_AMBA
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index dd412c2..c83791d 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -2,6 +2,8 @@
obj-$(CONFIG_MAILBOX) += mailbox.o
+obj-$(CONFIG_ARM_MHU) += arm_mhu.o
+
obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
obj-$(CONFIG_OMAP2PLUS_MBOX) += omap-mailbox.o
diff --git a/drivers/mailbox/arm_mhu.c b/drivers/mailbox/arm_mhu.c
new file mode 100644
index 0000000..5768936
--- /dev/null
+++ b/drivers/mailbox/arm_mhu.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2013-2015 Fujitsu Semiconductor Ltd.
+ * Copyright (C) 2015 Linaro Ltd.
+ * Author: Jassi Brar <jaswinder.singh@linaro.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/amba/bus.h>
+#include <linux/mailbox_controller.h>
+
+#define INTR_STAT_OFS 0x0
+#define INTR_SET_OFS 0x8
+#define INTR_CLR_OFS 0x10
+
+struct mhu_link {
+ unsigned irq;
+ void __iomem *tx_reg;
+ void __iomem *rx_reg;
+};
+
+struct arm_mhu {
+ void __iomem *base;
+ struct mhu_link mlink[3];
+ struct mbox_chan chan[3];
+ struct mbox_controller mbox;
+};
+
+static irqreturn_t mhu_rx_interrupt(int irq, void *p)
+{
+ struct mbox_chan *chan = p;
+ struct mhu_link *mlink = chan->con_priv;
+ u32 val;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ val = readl_relaxed(mlink->rx_reg + INTR_STAT_OFS);
+ if (!val)
+ return IRQ_NONE;
+
+ mbox_chan_received_data(chan, (void *)val);
+
+ writel_relaxed(val, mlink->rx_reg + INTR_CLR_OFS);
+
+ return IRQ_HANDLED;
+}
+
+static bool mhu_last_tx_done(struct mbox_chan *chan)
+{
+ struct mhu_link *mlink = chan->con_priv;
+ u32 val;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
+
+ return (val == 0);
+}
+
+static int mhu_send_data(struct mbox_chan *chan, void *data)
+{
+ struct mhu_link *mlink = chan->con_priv;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ if (!mhu_last_tx_done(chan)) {
+ dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
+ return -EBUSY;
+ }
+
+ writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
+
+ return 0;
+}
+
+static int mhu_startup(struct mbox_chan *chan)
+{
+ struct mhu_link *mlink = chan->con_priv;
+ u32 val;
+ int ret;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ val = readl_relaxed(mlink->tx_reg + INTR_STAT_OFS);
+ writel_relaxed(val, mlink->tx_reg + INTR_CLR_OFS);
+
+ ret = request_irq(mlink->irq, mhu_rx_interrupt, 0, "mhu_link", chan);
+ if (ret) {
+ dev_err(chan->mbox->dev,
+ "Unable to aquire IRQ %d\n", mlink->irq);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void mhu_shutdown(struct mbox_chan *chan)
+{
+ struct mhu_link *mlink = chan->con_priv;
+
+ pr_debug("%s:%d\n", __func__, __LINE__);
+ free_irq(mlink->irq, chan);
+}
+
+static struct mbox_chan_ops mhu_ops = {
+ .send_data = mhu_send_data,
+ .startup = mhu_startup,
+ .shutdown = mhu_shutdown,
+ .last_tx_done = mhu_last_tx_done,
+};
+
+static int mhu_probe(struct amba_device *adev, const struct amba_id *id)
+{
+ int i, err;
+ struct arm_mhu *mhu;
+ struct device *dev = &adev->dev;
+ int mhu_reg[3] = {0x0, 0x20, 0x200};
+
+ err = amba_request_regions(adev, NULL);
+ if (err)
+ return err;
+
+ /* Allocate memory for device */
+ mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
+ if (!mhu)
+ return -ENOMEM;
+
+ mhu->base = devm_ioremap(dev, adev->res.start,
+ resource_size(&adev->res));
+ if (!mhu->base) {
+ dev_err(dev, "ioremap failed\n");
+ return -ENXIO;
+ }
+
+ for (i = 0; i < 3; i++) {
+ mhu->chan[i].con_priv = &mhu->mlink[i];
+ mhu->mlink[i].irq = adev->irq[i];
+ mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i];
+ mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + 0x100;
+ }
+
+ mhu->mbox.dev = dev;
+ mhu->mbox.chans = &mhu->chan[0];
+ mhu->mbox.num_chans = 3;
+ mhu->mbox.ops = &mhu_ops;
+ mhu->mbox.txdone_irq = false;
+ mhu->mbox.txdone_poll = true;
+ mhu->mbox.txpoll_period = 10;
+
+ amba_set_drvdata(adev, mhu);
+
+ err = mbox_controller_register(&mhu->mbox);
+ if (err) {
+ dev_err(dev, "Failed to register mailboxes %d\n", err);
+ return err;
+ }
+
+ dev_err(dev, "ARM MHU Mailbox registered\n");
+ return 0;
+}
+
+static int mhu_remove(struct amba_device *adev)
+{
+ struct arm_mhu *mhu = amba_get_drvdata(adev);
+
+ mbox_controller_unregister(&mhu->mbox);
+
+ return 0;
+}
+
+static struct amba_id mhu_ids[] = {
+ {
+ .id = 0x1bb098,
+ .mask = 0xffffff,
+ },
+ { 0, 0 },
+};
+MODULE_DEVICE_TABLE(amba, mhu_ids);
+
+static struct amba_driver arm_mhu_driver = {
+ .drv = {
+ .name = "mhu",
+ },
+ .id_table = mhu_ids,
+ .probe = mhu_probe,
+ .remove = mhu_remove,
+};
+module_amba_driver(arm_mhu_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("ARM MHU Driver");
+MODULE_AUTHOR("Jassi Brar <jassisinghbrar@gmail.com>");
--
1.9.0
^ permalink raw reply related [flat|nested] 47+ messages in thread
[parent not found: <1422955763-6630-1-git-send-email-Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>]
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-03 9:29 ` Vincent Yang
@ 2015-02-03 12:32 ` Russell King - ARM Linux
-1 siblings, 0 replies; 47+ messages in thread
From: Russell King - ARM Linux @ 2015-02-03 12:32 UTC (permalink / raw)
To: Vincent Yang
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
arm-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, sudeep.holla-5wv7dgnIgG8,
andy.green-QSEj5FYQhm4dnm+yROfE0A,
patches-QSEj5FYQhm4dnm+yROfE0A,
jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
Tetsuya Nuriya
On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
> +static int mhu_send_data(struct mbox_chan *chan, void *data)
> +{
> + struct mhu_link *mlink = chan->con_priv;
> +
> + pr_debug("%s:%d\n", __func__, __LINE__);
> + if (!mhu_last_tx_done(chan)) {
> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
> + return -EBUSY;
> + }
> +
> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
Doesn't that cause a GCC warning?
> +static int mhu_probe(struct amba_device *adev, const struct amba_id *id)
> +{
> + int i, err;
> + struct arm_mhu *mhu;
> + struct device *dev = &adev->dev;
> + int mhu_reg[3] = {0x0, 0x20, 0x200};
> +
> + err = amba_request_regions(adev, NULL);
> + if (err)
> + return err;
> +
> + /* Allocate memory for device */
> + mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
> + if (!mhu)
> + return -ENOMEM;
> +
> + mhu->base = devm_ioremap(dev, adev->res.start,
> + resource_size(&adev->res));
> + if (!mhu->base) {
> + dev_err(dev, "ioremap failed\n");
> + return -ENXIO;
mhu->base = devm_ioremap_resource(dev, &adev->res);
if (IS_ERR(mhu->base)) {
dev_err(dev, "ioremap failed\n");
return PTR_ERR(mhu->base);
> + }
> +
> + for (i = 0; i < 3; i++) {
> + mhu->chan[i].con_priv = &mhu->mlink[i];
> + mhu->mlink[i].irq = adev->irq[i];
> + mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i];
> + mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + 0x100;
> + }
> +
> + mhu->mbox.dev = dev;
> + mhu->mbox.chans = &mhu->chan[0];
> + mhu->mbox.num_chans = 3;
> + mhu->mbox.ops = &mhu_ops;
> + mhu->mbox.txdone_irq = false;
> + mhu->mbox.txdone_poll = true;
> + mhu->mbox.txpoll_period = 10;
> +
> + amba_set_drvdata(adev, mhu);
> +
> + err = mbox_controller_register(&mhu->mbox);
> + if (err) {
> + dev_err(dev, "Failed to register mailboxes %d\n", err);
> + return err;
> + }
> +
> + dev_err(dev, "ARM MHU Mailbox registered\n");
Why is this an error?
--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-03 12:32 ` Russell King - ARM Linux
0 siblings, 0 replies; 47+ messages in thread
From: Russell King - ARM Linux @ 2015-02-03 12:32 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
> +static int mhu_send_data(struct mbox_chan *chan, void *data)
> +{
> + struct mhu_link *mlink = chan->con_priv;
> +
> + pr_debug("%s:%d\n", __func__, __LINE__);
> + if (!mhu_last_tx_done(chan)) {
> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
> + return -EBUSY;
> + }
> +
> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
Doesn't that cause a GCC warning?
> +static int mhu_probe(struct amba_device *adev, const struct amba_id *id)
> +{
> + int i, err;
> + struct arm_mhu *mhu;
> + struct device *dev = &adev->dev;
> + int mhu_reg[3] = {0x0, 0x20, 0x200};
> +
> + err = amba_request_regions(adev, NULL);
> + if (err)
> + return err;
> +
> + /* Allocate memory for device */
> + mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
> + if (!mhu)
> + return -ENOMEM;
> +
> + mhu->base = devm_ioremap(dev, adev->res.start,
> + resource_size(&adev->res));
> + if (!mhu->base) {
> + dev_err(dev, "ioremap failed\n");
> + return -ENXIO;
mhu->base = devm_ioremap_resource(dev, &adev->res);
if (IS_ERR(mhu->base)) {
dev_err(dev, "ioremap failed\n");
return PTR_ERR(mhu->base);
> + }
> +
> + for (i = 0; i < 3; i++) {
> + mhu->chan[i].con_priv = &mhu->mlink[i];
> + mhu->mlink[i].irq = adev->irq[i];
> + mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i];
> + mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + 0x100;
> + }
> +
> + mhu->mbox.dev = dev;
> + mhu->mbox.chans = &mhu->chan[0];
> + mhu->mbox.num_chans = 3;
> + mhu->mbox.ops = &mhu_ops;
> + mhu->mbox.txdone_irq = false;
> + mhu->mbox.txdone_poll = true;
> + mhu->mbox.txpoll_period = 10;
> +
> + amba_set_drvdata(adev, mhu);
> +
> + err = mbox_controller_register(&mhu->mbox);
> + if (err) {
> + dev_err(dev, "Failed to register mailboxes %d\n", err);
> + return err;
> + }
> +
> + dev_err(dev, "ARM MHU Mailbox registered\n");
Why is this an error?
--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply [flat|nested] 47+ messages in thread
[parent not found: <20150203123216.GO8656-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>]
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-03 12:32 ` Russell King - ARM Linux
@ 2015-02-03 14:39 ` Jassi Brar
-1 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-03 14:39 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Vincent Yang, Devicetree List,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann,
Olof Johansson, arm-DgEjT+Ai2ygdnm+yROfE0A, Rob Herring,
Paweł Moll, Mark Rutland,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Kumar Gala, Sudeep Holla,
Andy Green, Patch Tracking, Vincent Yang, Tetsuya Nuriya
On 3 February 2015 at 18:02, Russell King - ARM Linux
<linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org> wrote:
> On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
>> +static int mhu_send_data(struct mbox_chan *chan, void *data)
>> +{
>> + struct mhu_link *mlink = chan->con_priv;
>> +
>> + pr_debug("%s:%d\n", __func__, __LINE__);
>> + if (!mhu_last_tx_done(chan)) {
>> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
>> + return -EBUSY;
>> + }
>> +
>> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
>
> Doesn't that cause a GCC warning?
>
I don't see any, but I'll drop the cast.
>> +static int mhu_probe(struct amba_device *adev, const struct amba_id *id)
>> +{
>> + int i, err;
>> + struct arm_mhu *mhu;
>> + struct device *dev = &adev->dev;
>> + int mhu_reg[3] = {0x0, 0x20, 0x200};
>> +
>> + err = amba_request_regions(adev, NULL);
>> + if (err)
>> + return err;
>> +
>> + /* Allocate memory for device */
>> + mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
>> + if (!mhu)
>> + return -ENOMEM;
>> +
>> + mhu->base = devm_ioremap(dev, adev->res.start,
>> + resource_size(&adev->res));
>> + if (!mhu->base) {
>> + dev_err(dev, "ioremap failed\n");
>> + return -ENXIO;
>
> mhu->base = devm_ioremap_resource(dev, &adev->res);
> if (IS_ERR(mhu->base)) {
> dev_err(dev, "ioremap failed\n");
> return PTR_ERR(mhu->base);
>
OK
>> +
>> + err = mbox_controller_register(&mhu->mbox);
>> + if (err) {
>> + dev_err(dev, "Failed to register mailboxes %d\n", err);
>> + return err;
>> + }
>> +
>> + dev_err(dev, "ARM MHU Mailbox registered\n");
>
> Why is this an error?
>
ouch! this sneaked in from debugging code. Will make it info.
Thanks.
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-03 14:39 ` Jassi Brar
0 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-03 14:39 UTC (permalink / raw)
To: linux-arm-kernel
On 3 February 2015 at 18:02, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
>> +static int mhu_send_data(struct mbox_chan *chan, void *data)
>> +{
>> + struct mhu_link *mlink = chan->con_priv;
>> +
>> + pr_debug("%s:%d\n", __func__, __LINE__);
>> + if (!mhu_last_tx_done(chan)) {
>> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
>> + return -EBUSY;
>> + }
>> +
>> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
>
> Doesn't that cause a GCC warning?
>
I don't see any, but I'll drop the cast.
>> +static int mhu_probe(struct amba_device *adev, const struct amba_id *id)
>> +{
>> + int i, err;
>> + struct arm_mhu *mhu;
>> + struct device *dev = &adev->dev;
>> + int mhu_reg[3] = {0x0, 0x20, 0x200};
>> +
>> + err = amba_request_regions(adev, NULL);
>> + if (err)
>> + return err;
>> +
>> + /* Allocate memory for device */
>> + mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
>> + if (!mhu)
>> + return -ENOMEM;
>> +
>> + mhu->base = devm_ioremap(dev, adev->res.start,
>> + resource_size(&adev->res));
>> + if (!mhu->base) {
>> + dev_err(dev, "ioremap failed\n");
>> + return -ENXIO;
>
> mhu->base = devm_ioremap_resource(dev, &adev->res);
> if (IS_ERR(mhu->base)) {
> dev_err(dev, "ioremap failed\n");
> return PTR_ERR(mhu->base);
>
OK
>> +
>> + err = mbox_controller_register(&mhu->mbox);
>> + if (err) {
>> + dev_err(dev, "Failed to register mailboxes %d\n", err);
>> + return err;
>> + }
>> +
>> + dev_err(dev, "ARM MHU Mailbox registered\n");
>
> Why is this an error?
>
ouch! this sneaked in from debugging code. Will make it info.
Thanks.
^ permalink raw reply [flat|nested] 47+ messages in thread
[parent not found: <CAJe_ZhdL6=4bMPRitFeCqrO2jeYQuDa9071estTBd3PTbmURYA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-03 14:39 ` Jassi Brar
@ 2015-02-03 14:46 ` Russell King - ARM Linux
-1 siblings, 0 replies; 47+ messages in thread
From: Russell King - ARM Linux @ 2015-02-03 14:46 UTC (permalink / raw)
To: Jassi Brar
Cc: Vincent Yang, Devicetree List,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Arnd Bergmann,
Olof Johansson, arm-DgEjT+Ai2ygdnm+yROfE0A, Rob Herring,
Paweł Moll, Mark Rutland,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Kumar Gala, Sudeep Holla,
Andy Green, Patch Tracking, Vincent Yang, Tetsuya Nuriya
On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
> On 3 February 2015 at 18:02, Russell King - ARM Linux
> <linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org> wrote:
> > On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
> >> +static int mhu_send_data(struct mbox_chan *chan, void *data)
> >> +{
> >> + struct mhu_link *mlink = chan->con_priv;
> >> +
> >> + pr_debug("%s:%d\n", __func__, __LINE__);
> >> + if (!mhu_last_tx_done(chan)) {
> >> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
> >> + return -EBUSY;
> >> + }
> >> +
> >> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
> >
> > Doesn't that cause a GCC warning?
> >
> I don't see any, but I'll drop the cast.
A cast is probably needed. You're right that GCC no longer warns about
this - I'm pretty sure it used to complain about casting pointers to
ints, and we used to need to cast to "unsigned long" first.
--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-03 14:46 ` Russell King - ARM Linux
0 siblings, 0 replies; 47+ messages in thread
From: Russell King - ARM Linux @ 2015-02-03 14:46 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
> On 3 February 2015 at 18:02, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
> >> +static int mhu_send_data(struct mbox_chan *chan, void *data)
> >> +{
> >> + struct mhu_link *mlink = chan->con_priv;
> >> +
> >> + pr_debug("%s:%d\n", __func__, __LINE__);
> >> + if (!mhu_last_tx_done(chan)) {
> >> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
> >> + return -EBUSY;
> >> + }
> >> +
> >> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
> >
> > Doesn't that cause a GCC warning?
> >
> I don't see any, but I'll drop the cast.
A cast is probably needed. You're right that GCC no longer warns about
this - I'm pretty sure it used to complain about casting pointers to
ints, and we used to need to cast to "unsigned long" first.
--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply [flat|nested] 47+ messages in thread
[parent not found: <20150203144611.GS8656-l+eeeJia6m9vn6HldHNs0ANdhmdF6hFW@public.gmane.org>]
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-03 14:46 ` Russell King - ARM Linux
@ 2015-02-03 15:25 ` Arnd Bergmann
-1 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-03 15:25 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Jassi Brar, Vincent Yang, Devicetree List,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Olof Johansson, arm-DgEjT+Ai2ygdnm+yROfE0A, Rob Herring,
Paweł Moll, Mark Rutland,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Kumar Gala, Sudeep Holla,
Andy Green, Patch Tracking, Vincent Yang, Tetsuya Nuriya
On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
> > On 3 February 2015 at 18:02, Russell King - ARM Linux
> > <linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org> wrote:
> > > On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
> > >> +static int mhu_send_data(struct mbox_chan *chan, void *data)
> > >> +{
> > >> + struct mhu_link *mlink = chan->con_priv;
> > >> +
> > >> + pr_debug("%s:%d\n", __func__, __LINE__);
> > >> + if (!mhu_last_tx_done(chan)) {
> > >> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
> > >> + return -EBUSY;
> > >> + }
> > >> +
> > >> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
> > >
> > > Doesn't that cause a GCC warning?
> > >
> > I don't see any, but I'll drop the cast.
>
> A cast is probably needed. You're right that GCC no longer warns about
> this - I'm pretty sure it used to complain about casting pointers to
> ints, and we used to need to cast to "unsigned long" first.
It definitely warns about converting an u64 to pointer or back,
and it warns on 64-bit machines about this conversion.
On a related note, I wonder why the driver actually converts a pointer to
int. I believe we have discussed this in the past but don't remember the
outcome. I had expected to see here something like:
static int mhu_send_data(struct mbox_chan *chan, void *data)
{
struct mhu_link *mlink = chan->con_priv;
u32 *arg = data;
writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
}
i.e. dereferencing the pointer instead of using the actual value.
Arnd
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-03 15:25 ` Arnd Bergmann
0 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-03 15:25 UTC (permalink / raw)
To: linux-arm-kernel
On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
> > On 3 February 2015 at 18:02, Russell King - ARM Linux
> > <linux@arm.linux.org.uk> wrote:
> > > On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
> > >> +static int mhu_send_data(struct mbox_chan *chan, void *data)
> > >> +{
> > >> + struct mhu_link *mlink = chan->con_priv;
> > >> +
> > >> + pr_debug("%s:%d\n", __func__, __LINE__);
> > >> + if (!mhu_last_tx_done(chan)) {
> > >> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
> > >> + return -EBUSY;
> > >> + }
> > >> +
> > >> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
> > >
> > > Doesn't that cause a GCC warning?
> > >
> > I don't see any, but I'll drop the cast.
>
> A cast is probably needed. You're right that GCC no longer warns about
> this - I'm pretty sure it used to complain about casting pointers to
> ints, and we used to need to cast to "unsigned long" first.
It definitely warns about converting an u64 to pointer or back,
and it warns on 64-bit machines about this conversion.
On a related note, I wonder why the driver actually converts a pointer to
int. I believe we have discussed this in the past but don't remember the
outcome. I had expected to see here something like:
static int mhu_send_data(struct mbox_chan *chan, void *data)
{
struct mhu_link *mlink = chan->con_priv;
u32 *arg = data;
writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
}
i.e. dereferencing the pointer instead of using the actual value.
Arnd
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-03 15:25 ` Arnd Bergmann
@ 2015-02-04 3:27 ` Jassi Brar
-1 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-04 3:27 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Russell King - ARM Linux, Vincent Yang, Devicetree List,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Olof Johansson, arm-DgEjT+Ai2ygdnm+yROfE0A, Rob Herring,
Paweł Moll, Mark Rutland,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Kumar Gala, Sudeep Holla,
Andy Green, Patch Tracking, Vincent Yang, Tetsuya Nuriya
On 3 February 2015 at 20:55, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
>> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
>> > On 3 February 2015 at 18:02, Russell King - ARM Linux
>> > <linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org> wrote:
>> > > On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
>> > >> +static int mhu_send_data(struct mbox_chan *chan, void *data)
>> > >> +{
>> > >> + struct mhu_link *mlink = chan->con_priv;
>> > >> +
>> > >> + pr_debug("%s:%d\n", __func__, __LINE__);
>> > >> + if (!mhu_last_tx_done(chan)) {
>> > >> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
>> > >> + return -EBUSY;
>> > >> + }
>> > >> +
>> > >> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
>> > >
>> > > Doesn't that cause a GCC warning?
>> > >
>> > I don't see any, but I'll drop the cast.
>>
>> A cast is probably needed. You're right that GCC no longer warns about
>> this - I'm pretty sure it used to complain about casting pointers to
>> ints, and we used to need to cast to "unsigned long" first.
>
> It definitely warns about converting an u64 to pointer or back,
> and it warns on 64-bit machines about this conversion.
>
> On a related note, I wonder why the driver actually converts a pointer to
> int. I believe we have discussed this in the past but don't remember the
> outcome.
We never discussed this (MHU) driver. It was the generic mailbox API
where, IIRC, I did take into account all your comments. The API does
do what you had asked.
> I had expected to see here something like:
>
> static int mhu_send_data(struct mbox_chan *chan, void *data)
> {
> struct mhu_link *mlink = chan->con_priv;
> u32 *arg = data;
>
> writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
> }
>
> i.e. dereferencing the pointer instead of using the actual value.
>
OK, just curious how is this (dereferencing to the u32 variable on
stack of the client driver) better?
Thanks.
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-04 3:27 ` Jassi Brar
0 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-04 3:27 UTC (permalink / raw)
To: linux-arm-kernel
On 3 February 2015 at 20:55, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
>> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
>> > On 3 February 2015 at 18:02, Russell King - ARM Linux
>> > <linux@arm.linux.org.uk> wrote:
>> > > On Tue, Feb 03, 2015 at 05:29:23PM +0800, Vincent Yang wrote:
>> > >> +static int mhu_send_data(struct mbox_chan *chan, void *data)
>> > >> +{
>> > >> + struct mhu_link *mlink = chan->con_priv;
>> > >> +
>> > >> + pr_debug("%s:%d\n", __func__, __LINE__);
>> > >> + if (!mhu_last_tx_done(chan)) {
>> > >> + dev_err(chan->mbox->dev, "Last TX(%d) pending!\n", mlink->irq);
>> > >> + return -EBUSY;
>> > >> + }
>> > >> +
>> > >> + writel_relaxed((u32)data, mlink->tx_reg + INTR_SET_OFS);
>> > >
>> > > Doesn't that cause a GCC warning?
>> > >
>> > I don't see any, but I'll drop the cast.
>>
>> A cast is probably needed. You're right that GCC no longer warns about
>> this - I'm pretty sure it used to complain about casting pointers to
>> ints, and we used to need to cast to "unsigned long" first.
>
> It definitely warns about converting an u64 to pointer or back,
> and it warns on 64-bit machines about this conversion.
>
> On a related note, I wonder why the driver actually converts a pointer to
> int. I believe we have discussed this in the past but don't remember the
> outcome.
We never discussed this (MHU) driver. It was the generic mailbox API
where, IIRC, I did take into account all your comments. The API does
do what you had asked.
> I had expected to see here something like:
>
> static int mhu_send_data(struct mbox_chan *chan, void *data)
> {
> struct mhu_link *mlink = chan->con_priv;
> u32 *arg = data;
>
> writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
> }
>
> i.e. dereferencing the pointer instead of using the actual value.
>
OK, just curious how is this (dereferencing to the u32 variable on
stack of the client driver) better?
Thanks.
^ permalink raw reply [flat|nested] 47+ messages in thread
[parent not found: <CAJe_Zhfyr9ts=k_=kyXqC=aGtQdrq9MtrRXt6LQKR7iofKjqKg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-04 3:27 ` Jassi Brar
@ 2015-02-04 10:29 ` Arnd Bergmann
-1 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-04 10:29 UTC (permalink / raw)
To: Jassi Brar
Cc: Russell King - ARM Linux, Vincent Yang, Devicetree List,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Olof Johansson, arm-DgEjT+Ai2ygdnm+yROfE0A, Rob Herring,
Paweł Moll, Mark Rutland,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Kumar Gala, Sudeep Holla,
Andy Green, Patch Tracking, Vincent Yang, Tetsuya Nuriya
On Wednesday 04 February 2015 08:57:43 Jassi Brar wrote:
> On 3 February 2015 at 20:55, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> > On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
> >> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
> > I had expected to see here something like:
> >
> > static int mhu_send_data(struct mbox_chan *chan, void *data)
> > {
> > struct mhu_link *mlink = chan->con_priv;
> > u32 *arg = data;
> >
> > writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
> > }
> >
> > i.e. dereferencing the pointer instead of using the actual value.
> >
> OK, just curious how is this (dereferencing to the u32 variable on
> stack of the client driver) better?
The API as I understand is defined to use the pointer to point to
a chunk of data of fixed size, with the size being known to both
the client driver and the mailbox driver. This is the reason for
having a pointer in the first place.
Using the bits of the pointer as the message instead of pointing
to the message feels like an abuse of the API.
Maybe it would have been better to pass the size explictly as
a third argument in the API to make that clear.
Arnd
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-04 10:29 ` Arnd Bergmann
0 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-04 10:29 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 04 February 2015 08:57:43 Jassi Brar wrote:
> On 3 February 2015 at 20:55, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
> >> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
> > I had expected to see here something like:
> >
> > static int mhu_send_data(struct mbox_chan *chan, void *data)
> > {
> > struct mhu_link *mlink = chan->con_priv;
> > u32 *arg = data;
> >
> > writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
> > }
> >
> > i.e. dereferencing the pointer instead of using the actual value.
> >
> OK, just curious how is this (dereferencing to the u32 variable on
> stack of the client driver) better?
The API as I understand is defined to use the pointer to point to
a chunk of data of fixed size, with the size being known to both
the client driver and the mailbox driver. This is the reason for
having a pointer in the first place.
Using the bits of the pointer as the message instead of pointing
to the message feels like an abuse of the API.
Maybe it would have been better to pass the size explictly as
a third argument in the API to make that clear.
Arnd
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-04 10:29 ` Arnd Bergmann
@ 2015-02-04 14:34 ` Jassi Brar
-1 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-04 14:34 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Russell King - ARM Linux, Vincent Yang, Devicetree List,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Olof Johansson, arm-DgEjT+Ai2ygdnm+yROfE0A, Rob Herring,
Paweł Moll, Mark Rutland,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Kumar Gala, Sudeep Holla,
Andy Green, Patch Tracking, Vincent Yang, Tetsuya Nuriya
On 4 February 2015 at 15:59, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Wednesday 04 February 2015 08:57:43 Jassi Brar wrote:
>> On 3 February 2015 at 20:55, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>> > On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
>> >> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
>
>> > I had expected to see here something like:
>> >
>> > static int mhu_send_data(struct mbox_chan *chan, void *data)
>> > {
>> > struct mhu_link *mlink = chan->con_priv;
>> > u32 *arg = data;
>> >
>> > writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
>> > }
>> >
>> > i.e. dereferencing the pointer instead of using the actual value.
>> >
>> OK, just curious how is this (dereferencing to the u32 variable on
>> stack of the client driver) better?
>
> The API as I understand is defined to use the pointer to point to
> a chunk of data of fixed size, with the size being known to both
> the client driver and the mailbox driver. This is the reason for
> having a pointer in the first place.
>
Yes, we are on the same page. I just have a slightly more liberal view
about the usage of 'void* data'.
> Using the bits of the pointer as the message instead of pointing
> to the message feels like an abuse of the API.
>
I can see your POV.
Now consider a client, like mine, that sends a u32 value as the data.
But unlike me, the client uses the mailbox api in 'async' mode i.e,
register a callback function, submit a 32bit message and move on. It
is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
seem overkill? Lets say what the client and controller drivers do in
their bedroom is none of the API's business.
> Maybe it would have been better to pass the size explictly as
> a third argument in the API to make that clear.
>
Actually that did come up for consideration. But since the structure
of 'data' packet is already known to the controller driver, having to
also tell the size of that structure seems redundant.
Thanks.
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-04 14:34 ` Jassi Brar
0 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-04 14:34 UTC (permalink / raw)
To: linux-arm-kernel
On 4 February 2015 at 15:59, Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 04 February 2015 08:57:43 Jassi Brar wrote:
>> On 3 February 2015 at 20:55, Arnd Bergmann <arnd@arndb.de> wrote:
>> > On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
>> >> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
>
>> > I had expected to see here something like:
>> >
>> > static int mhu_send_data(struct mbox_chan *chan, void *data)
>> > {
>> > struct mhu_link *mlink = chan->con_priv;
>> > u32 *arg = data;
>> >
>> > writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
>> > }
>> >
>> > i.e. dereferencing the pointer instead of using the actual value.
>> >
>> OK, just curious how is this (dereferencing to the u32 variable on
>> stack of the client driver) better?
>
> The API as I understand is defined to use the pointer to point to
> a chunk of data of fixed size, with the size being known to both
> the client driver and the mailbox driver. This is the reason for
> having a pointer in the first place.
>
Yes, we are on the same page. I just have a slightly more liberal view
about the usage of 'void* data'.
> Using the bits of the pointer as the message instead of pointing
> to the message feels like an abuse of the API.
>
I can see your POV.
Now consider a client, like mine, that sends a u32 value as the data.
But unlike me, the client uses the mailbox api in 'async' mode i.e,
register a callback function, submit a 32bit message and move on. It
is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
seem overkill? Lets say what the client and controller drivers do in
their bedroom is none of the API's business.
> Maybe it would have been better to pass the size explictly as
> a third argument in the API to make that clear.
>
Actually that did come up for consideration. But since the structure
of 'data' packet is already known to the controller driver, having to
also tell the size of that structure seems redundant.
Thanks.
^ permalink raw reply [flat|nested] 47+ messages in thread
[parent not found: <CAJe_Zhe_d-H10J8cH-fxcbusoJV8jMUW-pruXVkEKY7PnLMGFA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-04 14:34 ` Jassi Brar
@ 2015-02-04 14:48 ` Arnd Bergmann
-1 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-04 14:48 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Jassi Brar, Mark Rutland, Devicetree List, Andy Green,
Russell King - ARM Linux, Paweł Moll,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Vincent Yang,
Sudeep Holla, Vincent Yang, Rob Herring,
arm-DgEjT+Ai2ygdnm+yROfE0A, Patch Tracking, Kumar Gala,
Olof Johansson, Tetsuya Nuriya
On Wednesday 04 February 2015 20:04:21 Jassi Brar wrote:
>
> > Using the bits of the pointer as the message instead of pointing
> > to the message feels like an abuse of the API.
> >
> I can see your POV.
> Now consider a client, like mine, that sends a u32 value as the data.
> But unlike me, the client uses the mailbox api in 'async' mode i.e,
> register a callback function, submit a 32bit message and move on. It
> is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
> seem overkill?
That could easily be done by dereferencing the message data in the
function that queues the asynchronous message: instead of queuing
the pointer, you queue the data in the driver.
Arnd
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-04 14:48 ` Arnd Bergmann
0 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-04 14:48 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 04 February 2015 20:04:21 Jassi Brar wrote:
>
> > Using the bits of the pointer as the message instead of pointing
> > to the message feels like an abuse of the API.
> >
> I can see your POV.
> Now consider a client, like mine, that sends a u32 value as the data.
> But unlike me, the client uses the mailbox api in 'async' mode i.e,
> register a callback function, submit a 32bit message and move on. It
> is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
> seem overkill?
That could easily be done by dereferencing the message data in the
function that queues the asynchronous message: instead of queuing
the pointer, you queue the data in the driver.
Arnd
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-04 14:48 ` Arnd Bergmann
@ 2015-02-04 15:33 ` Jassi Brar
-1 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-04 15:33 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Rutland,
Devicetree List, Andy Green, Russell King - ARM Linux,
Paweł Moll, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
Vincent Yang, Sudeep Holla, Vincent Yang, Rob Herring,
arm-DgEjT+Ai2ygdnm+yROfE0A, Patch Tracking, Kumar Gala,
Olof Johansson, Tetsuya Nuriya
On 4 February 2015 at 20:18, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Wednesday 04 February 2015 20:04:21 Jassi Brar wrote:
>>
>> > Using the bits of the pointer as the message instead of pointing
>> > to the message feels like an abuse of the API.
>> >
>> I can see your POV.
>> Now consider a client, like mine, that sends a u32 value as the data.
>> But unlike me, the client uses the mailbox api in 'async' mode i.e,
>> register a callback function, submit a 32bit message and move on. It
>> is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
>> seem overkill?
>
> That could easily be done by dereferencing the message data in the
> function that queues the asynchronous message: instead of queuing
> the pointer, you queue the data in the driver.
>
The 'void *data' is not queued in the driver, but in the API code. Or
do I not get your point?
Thanks.
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-04 15:33 ` Jassi Brar
0 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-04 15:33 UTC (permalink / raw)
To: linux-arm-kernel
On 4 February 2015 at 20:18, Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 04 February 2015 20:04:21 Jassi Brar wrote:
>>
>> > Using the bits of the pointer as the message instead of pointing
>> > to the message feels like an abuse of the API.
>> >
>> I can see your POV.
>> Now consider a client, like mine, that sends a u32 value as the data.
>> But unlike me, the client uses the mailbox api in 'async' mode i.e,
>> register a callback function, submit a 32bit message and move on. It
>> is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
>> seem overkill?
>
> That could easily be done by dereferencing the message data in the
> function that queues the asynchronous message: instead of queuing
> the pointer, you queue the data in the driver.
>
The 'void *data' is not queued in the driver, but in the API code. Or
do I not get your point?
Thanks.
^ permalink raw reply [flat|nested] 47+ messages in thread
[parent not found: <CAJe_ZhceTfWnSWmR+_T+G-BM00hAhTbn5OGwNiOZQFxy6f5QSw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-04 15:33 ` Jassi Brar
@ 2015-02-04 16:42 ` Arnd Bergmann
-1 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-04 16:42 UTC (permalink / raw)
To: Jassi Brar
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Rutland,
Devicetree List, Andy Green, Russell King - ARM Linux,
Paweł Moll, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
Vincent Yang, Sudeep Holla, Vincent Yang, Rob Herring,
arm-DgEjT+Ai2ygdnm+yROfE0A, Patch Tracking, Kumar Gala,
Olof Johansson, Tetsuya Nuriya
On Wednesday 04 February 2015 21:03:50 Jassi Brar wrote:
> On 4 February 2015 at 20:18, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> > On Wednesday 04 February 2015 20:04:21 Jassi Brar wrote:
> >>
> >> > Using the bits of the pointer as the message instead of pointing
> >> > to the message feels like an abuse of the API.
> >> >
> >> I can see your POV.
> >> Now consider a client, like mine, that sends a u32 value as the data.
> >> But unlike me, the client uses the mailbox api in 'async' mode i.e,
> >> register a callback function, submit a 32bit message and move on. It
> >> is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
> >> seem overkill?
> >
> > That could easily be done by dereferencing the message data in the
> > function that queues the asynchronous message: instead of queuing
> > the pointer, you queue the data in the driver.
> >
> The 'void *data' is not queued in the driver, but in the API code. Or
> do I not get your point?
My mistake. If the API keeps that pointer after returning to the caller
here, this is indeed a problem for callers that have the message on the
stack.
The solution of storing the message in a circular buffer (in the API)
would in turn require knowing the length of the data.
Another option would be to require that the asynchronous version of the
interface cannot be used with on-stack data and requires the object
lifetime to be managed by the caller, which seems reasonable to me
since you already need the completion callback.
Arnd
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-04 16:42 ` Arnd Bergmann
0 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-04 16:42 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 04 February 2015 21:03:50 Jassi Brar wrote:
> On 4 February 2015 at 20:18, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Wednesday 04 February 2015 20:04:21 Jassi Brar wrote:
> >>
> >> > Using the bits of the pointer as the message instead of pointing
> >> > to the message feels like an abuse of the API.
> >> >
> >> I can see your POV.
> >> Now consider a client, like mine, that sends a u32 value as the data.
> >> But unlike me, the client uses the mailbox api in 'async' mode i.e,
> >> register a callback function, submit a 32bit message and move on. It
> >> is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
> >> seem overkill?
> >
> > That could easily be done by dereferencing the message data in the
> > function that queues the asynchronous message: instead of queuing
> > the pointer, you queue the data in the driver.
> >
> The 'void *data' is not queued in the driver, but in the API code. Or
> do I not get your point?
My mistake. If the API keeps that pointer after returning to the caller
here, this is indeed a problem for callers that have the message on the
stack.
The solution of storing the message in a circular buffer (in the API)
would in turn require knowing the length of the data.
Another option would be to require that the asynchronous version of the
interface cannot be used with on-stack data and requires the object
lifetime to be managed by the caller, which seems reasonable to me
since you already need the completion callback.
Arnd
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-04 16:42 ` Arnd Bergmann
@ 2015-02-05 5:08 ` Jassi Brar
-1 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-05 5:08 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Rutland,
Devicetree List, Andy Green, Russell King - ARM Linux,
Paweł Moll, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
Vincent Yang, Sudeep Holla, Vincent Yang, Rob Herring,
arm-DgEjT+Ai2ygdnm+yROfE0A, Patch Tracking, Kumar Gala,
Olof Johansson, Tetsuya Nuriya
On 4 February 2015 at 22:12, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> On Wednesday 04 February 2015 21:03:50 Jassi Brar wrote:
>> On 4 February 2015 at 20:18, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
>> > On Wednesday 04 February 2015 20:04:21 Jassi Brar wrote:
>> >>
>> >> > Using the bits of the pointer as the message instead of pointing
>> >> > to the message feels like an abuse of the API.
>> >> >
>> >> I can see your POV.
>> >> Now consider a client, like mine, that sends a u32 value as the data.
>> >> But unlike me, the client uses the mailbox api in 'async' mode i.e,
>> >> register a callback function, submit a 32bit message and move on. It
>> >> is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
>> >> seem overkill?
>> >
>> > That could easily be done by dereferencing the message data in the
>> > function that queues the asynchronous message: instead of queuing
>> > the pointer, you queue the data in the driver.
>> >
>> The 'void *data' is not queued in the driver, but in the API code. Or
>> do I not get your point?
>
> My mistake. If the API keeps that pointer after returning to the caller
> here, this is indeed a problem for callers that have the message on the
> stack.
>
> The solution of storing the message in a circular buffer (in the API)
> would in turn require knowing the length of the data.
>
> Another option would be to require that the asynchronous version of the
> interface cannot be used with on-stack data and requires the object
> lifetime to be managed by the caller, which seems reasonable to me
> since you already need the completion callback.
>
Passing pointer to a structure on stack will be automatically punished
as a random crash/behavior.
We just need to make sure no client passes a value directly in 'void
*data', right?
I know typedef's are frowned upon, but how bad is the following option?
typedef void* mbox_data_info
int mbox_send_message(struct mbox_chan *chan, mbox_data_info data);
Thanks
Jassi
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-05 5:08 ` Jassi Brar
0 siblings, 0 replies; 47+ messages in thread
From: Jassi Brar @ 2015-02-05 5:08 UTC (permalink / raw)
To: linux-arm-kernel
On 4 February 2015 at 22:12, Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 04 February 2015 21:03:50 Jassi Brar wrote:
>> On 4 February 2015 at 20:18, Arnd Bergmann <arnd@arndb.de> wrote:
>> > On Wednesday 04 February 2015 20:04:21 Jassi Brar wrote:
>> >>
>> >> > Using the bits of the pointer as the message instead of pointing
>> >> > to the message feels like an abuse of the API.
>> >> >
>> >> I can see your POV.
>> >> Now consider a client, like mine, that sends a u32 value as the data.
>> >> But unlike me, the client uses the mailbox api in 'async' mode i.e,
>> >> register a callback function, submit a 32bit message and move on. It
>> >> is perfectly doable, but doesn't kalloc'ing a u32 for each submission,
>> >> seem overkill?
>> >
>> > That could easily be done by dereferencing the message data in the
>> > function that queues the asynchronous message: instead of queuing
>> > the pointer, you queue the data in the driver.
>> >
>> The 'void *data' is not queued in the driver, but in the API code. Or
>> do I not get your point?
>
> My mistake. If the API keeps that pointer after returning to the caller
> here, this is indeed a problem for callers that have the message on the
> stack.
>
> The solution of storing the message in a circular buffer (in the API)
> would in turn require knowing the length of the data.
>
> Another option would be to require that the asynchronous version of the
> interface cannot be used with on-stack data and requires the object
> lifetime to be managed by the caller, which seems reasonable to me
> since you already need the completion callback.
>
Passing pointer to a structure on stack will be automatically punished
as a random crash/behavior.
We just need to make sure no client passes a value directly in 'void
*data', right?
I know typedef's are frowned upon, but how bad is the following option?
typedef void* mbox_data_info
int mbox_send_message(struct mbox_chan *chan, mbox_data_info data);
Thanks
Jassi
^ permalink raw reply [flat|nested] 47+ messages in thread
[parent not found: <CAJe_ZhcXR4oaBKZx3n0ckCzXgbREoezUXjizJ09QXQVqEQ3G_g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>]
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-05 5:08 ` Jassi Brar
@ 2015-02-05 11:43 ` Arnd Bergmann
-1 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-05 11:43 UTC (permalink / raw)
To: Jassi Brar
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Rutland,
Devicetree List, Andy Green, Russell King - ARM Linux,
Paweł Moll, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
Vincent Yang, Sudeep Holla, Vincent Yang, Rob Herring,
arm-DgEjT+Ai2ygdnm+yROfE0A, Patch Tracking, Kumar Gala,
Olof Johansson, Tetsuya Nuriya
On Thursday 05 February 2015 10:38:16 Jassi Brar wrote:
> Passing pointer to a structure on stack will be automatically punished
> as a random crash/behavior.
> We just need to make sure no client passes a value directly in 'void
> *data', right?
Yes.
>
> I know typedef's are frowned upon, but how bad is the following option?
> typedef void* mbox_data_info
> int mbox_send_message(struct mbox_chan *chan, mbox_data_info data);
I don't see how that would help. I believe typedefs for pointer types
are particularly bad because they hide what is going on. If we want to
enforce the use of pointers to point to data, having the pointer in
the function prototype should be enough as a hint to driver developers ;-)
Arnd
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-05 11:43 ` Arnd Bergmann
0 siblings, 0 replies; 47+ messages in thread
From: Arnd Bergmann @ 2015-02-05 11:43 UTC (permalink / raw)
To: linux-arm-kernel
On Thursday 05 February 2015 10:38:16 Jassi Brar wrote:
> Passing pointer to a structure on stack will be automatically punished
> as a random crash/behavior.
> We just need to make sure no client passes a value directly in 'void
> *data', right?
Yes.
>
> I know typedef's are frowned upon, but how bad is the following option?
> typedef void* mbox_data_info
> int mbox_send_message(struct mbox_chan *chan, mbox_data_info data);
I don't see how that would help. I believe typedefs for pointer types
are particularly bad because they hide what is going on. If we want to
enforce the use of pointers to point to data, having the pointer in
the function prototype should be enough as a hint to driver developers ;-)
Arnd
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-05 11:43 ` Arnd Bergmann
(?)
@ 2015-02-05 12:02 ` Jassi Brar
[not found] ` <CAJe_Zhf_WuRK2EE0Sj9ksXDDe5VA=DJ+H3eS4YRKpDZLdRRfow-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
-1 siblings, 1 reply; 47+ messages in thread
From: Jassi Brar @ 2015-02-05 12:02 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Vincent Yang, Kumar Gala, Rob Herring, Devicetree List,
Vincent Yang, Russell King - ARM Linux, Andy Green, Sudeep Holla,
linux-arm-kernel, Mark Rutland, Paweł Moll, Olof Johansson,
ijc+devicetree, Patch Tracking, arm, Tetsuya Nuriya
[-- Attachment #1: Type: text/plain, Size: 464 bytes --]
On Feb 5, 2015 5:13 PM, "Arnd Bergmann" <arnd@arndb.de> wrote:
>
> >
> > I know typedef's are frowned upon, but how bad is the following option?
> > typedef void* mbox_data_info
> > int mbox_send_message(struct mbox_chan *chan, mbox_data_info
data);
>
> I don't see how that would help.
>
If it's abuse because the argument is a void*... What if we called it
mbox_data_info? To say platforms are free to pass data as a pointer or a
value :)
Jassi
[-- Attachment #2: Type: text/html, Size: 660 bytes --]
^ permalink raw reply [flat|nested] 47+ messages in thread
* Re: [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
2015-02-04 10:29 ` Arnd Bergmann
@ 2015-02-04 15:09 ` Russell King - ARM Linux
-1 siblings, 0 replies; 47+ messages in thread
From: Russell King - ARM Linux @ 2015-02-04 15:09 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Jassi Brar, Vincent Yang, Devicetree List,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Olof Johansson, arm-DgEjT+Ai2ygdnm+yROfE0A, Rob Herring,
Paweł Moll, Mark Rutland,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg, Kumar Gala, Sudeep Holla,
Andy Green, Patch Tracking, Vincent Yang, Tetsuya Nuriya
On Wed, Feb 04, 2015 at 11:29:55AM +0100, Arnd Bergmann wrote:
> On Wednesday 04 February 2015 08:57:43 Jassi Brar wrote:
> > On 3 February 2015 at 20:55, Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org> wrote:
> > > On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
> > >> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
>
> > > I had expected to see here something like:
> > >
> > > static int mhu_send_data(struct mbox_chan *chan, void *data)
> > > {
> > > struct mhu_link *mlink = chan->con_priv;
> > > u32 *arg = data;
> > >
> > > writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
> > > }
> > >
> > > i.e. dereferencing the pointer instead of using the actual value.
> > >
> > OK, just curious how is this (dereferencing to the u32 variable on
> > stack of the client driver) better?
>
> The API as I understand is defined to use the pointer to point to
> a chunk of data of fixed size, with the size being known to both
> the client driver and the mailbox driver. This is the reason for
> having a pointer in the first place.
>
> Using the bits of the pointer as the message instead of pointing
> to the message feels like an abuse of the API.
I agree on those two points. However, passing the address of something
on the stack to mbox_send_message() is also not particularly on - it
may save the pointer to use later on if its operating on non-blocking
mode.
A possible alternative would be if the user of mbox_send_message()
stored the message in an array, operated as a circular buffer, and
passed the address of the word to send. That would avoid the need
to repeatedly allocate and free memory (which would be expensive for
the sake of a u32.)
--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
--
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 [flat|nested] 47+ messages in thread
* [PATCH v5 2/7] mailbox: arm_mhu: add driver for ARM MHU controller
@ 2015-02-04 15:09 ` Russell King - ARM Linux
0 siblings, 0 replies; 47+ messages in thread
From: Russell King - ARM Linux @ 2015-02-04 15:09 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Feb 04, 2015 at 11:29:55AM +0100, Arnd Bergmann wrote:
> On Wednesday 04 February 2015 08:57:43 Jassi Brar wrote:
> > On 3 February 2015 at 20:55, Arnd Bergmann <arnd@arndb.de> wrote:
> > > On Tuesday 03 February 2015 14:46:11 Russell King - ARM Linux wrote:
> > >> On Tue, Feb 03, 2015 at 08:09:34PM +0530, Jassi Brar wrote:
>
> > > I had expected to see here something like:
> > >
> > > static int mhu_send_data(struct mbox_chan *chan, void *data)
> > > {
> > > struct mhu_link *mlink = chan->con_priv;
> > > u32 *arg = data;
> > >
> > > writel_relaxed(*arg, mlink->tx_reg + INTR_SET_OFS);
> > > }
> > >
> > > i.e. dereferencing the pointer instead of using the actual value.
> > >
> > OK, just curious how is this (dereferencing to the u32 variable on
> > stack of the client driver) better?
>
> The API as I understand is defined to use the pointer to point to
> a chunk of data of fixed size, with the size being known to both
> the client driver and the mailbox driver. This is the reason for
> having a pointer in the first place.
>
> Using the bits of the pointer as the message instead of pointing
> to the message feels like an abuse of the API.
I agree on those two points. However, passing the address of something
on the stack to mbox_send_message() is also not particularly on - it
may save the pointer to use later on if its operating on non-blocking
mode.
A possible alternative would be if the user of mbox_send_message()
stored the message in an array, operated as a circular buffer, and
passed the address of the word to send. That would avoid the need
to repeatedly allocate and free memory (which would be expensive for
the sake of a u32.)
--
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply [flat|nested] 47+ messages in thread
* [PATCH v5 4/7] clk: Add clock driver for mb86s7x
2015-02-03 9:21 ` Vincent Yang
@ 2015-02-03 9:31 ` Vincent Yang
-1 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:31 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
arm-DgEjT+Ai2ygdnm+yROfE0A, linux-lFZ/pmaqli7XmaaqVzeoHQ,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, pawel.moll-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-QSEj5FYQhm4dnm+yROfE0A,
andy.green-QSEj5FYQhm4dnm+yROfE0A,
patches-QSEj5FYQhm4dnm+yROfE0A,
jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
Tetsuya Nuriya
From: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
The CRG11 clock controller is managed by remote f/w.
This driver simply maps Linux CLK ops onto mailbox api.
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
.../bindings/clock/fujitsu,mb86s70-crg11.txt | 26 ++
drivers/clk/Makefile | 1 +
drivers/clk/clk-mb86s7x.c | 386 +++++++++++++++++++++
3 files changed, 413 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/fujitsu,mb86s70-crg11.txt
create mode 100644 drivers/clk/clk-mb86s7x.c
diff --git a/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-crg11.txt b/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-crg11.txt
new file mode 100644
index 0000000..3323962
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-crg11.txt
@@ -0,0 +1,26 @@
+Fujitsu CRG11 clock driver bindings
+-----------------------------------
+
+Required properties :
+- compatible : Shall contain "fujitsu,mb86s70-crg11"
+- #clock-cells : Shall be 3 {cntrlr domain port}
+
+The consumer specifies the desired clock pointing to its phandle.
+
+Example:
+
+ clock: crg11 {
+ compatible = "fujitsu,mb86s70-crg11";
+ #clock-cells = <3>;
+ };
+
+ mhu: mhu0@2b1f0000 {
+ #mbox-cells = <1>;
+ compatible = "arm,mhu";
+ reg = <0 0x2B1F0000 0x1000>;
+ interrupts = <0 36 4>, /* LP Non-Sec */
+ <0 35 4>, /* HP Non-Sec */
+ <0 37 4>; /* Secure */
+ clocks = <&clock 0 2 1>; /* Cntrlr:0 Domain:2 Port:1 */
+ clock-names = "clk";
+ };
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..19d73a1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o
+obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o
obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c
new file mode 100644
index 0000000..51703cb
--- /dev/null
+++ b/drivers/clk/clk-mb86s7x.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/cpu.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+#include <linux/mailbox_client.h>
+#include <linux/platform_device.h>
+
+#include <soc/mb86s7x/scb_mhu.h>
+
+#define to_crg_clk(p) container_of(p, struct crg_clk, hw)
+#define to_clc_clk(p) container_of(p, struct cl_clk, hw)
+
+struct mb86s7x_peri_clk {
+ u32 payload_size;
+ u32 cntrlr;
+ u32 domain;
+ u32 port;
+ u32 en;
+ u64 freqency;
+} __packed __aligned(4);
+
+struct hack_rate {
+ unsigned clk_id;
+ unsigned long rate;
+ int gated;
+};
+
+struct crg_clk {
+ struct clk_hw hw;
+ u8 cntrlr, domain, port;
+};
+
+static int crg_gate_control(struct clk_hw *hw, int en)
+{
+ struct crg_clk *crgclk = to_crg_clk(hw);
+ struct mb86s7x_peri_clk cmd;
+ int ret;
+
+ cmd.payload_size = sizeof(cmd);
+ cmd.cntrlr = crgclk->cntrlr;
+ cmd.domain = crgclk->domain;
+ cmd.port = crgclk->port;
+ cmd.en = en;
+
+ /* Port is UngatedCLK */
+ if (cmd.port == 8)
+ return en ? 0 : -EINVAL;
+
+ pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u En-%u}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.en);
+
+ ret = mb86s7x_send_packet(CMD_PERI_CLOCK_GATE_SET_REQ,
+ &cmd, sizeof(cmd));
+ if (ret < 0) {
+ pr_err("%s:%d failed!\n", __func__, __LINE__);
+ return ret;
+ }
+
+ pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u En-%u}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.en);
+
+ /* If the request was rejected */
+ if (cmd.en != en)
+ ret = -EINVAL;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+static int crg_port_prepare(struct clk_hw *hw)
+{
+ return crg_gate_control(hw, 1);
+}
+
+static void crg_port_unprepare(struct clk_hw *hw)
+{
+ crg_gate_control(hw, 0);
+}
+
+static int
+crg_rate_control(struct clk_hw *hw, int set, unsigned long *rate)
+{
+ struct crg_clk *crgclk = to_crg_clk(hw);
+ struct mb86s7x_peri_clk cmd;
+ int code, ret;
+
+ cmd.payload_size = sizeof(cmd);
+ cmd.cntrlr = crgclk->cntrlr;
+ cmd.domain = crgclk->domain;
+ cmd.port = crgclk->port;
+ cmd.freqency = *rate;
+
+ if (set) {
+ code = CMD_PERI_CLOCK_RATE_SET_REQ;
+ pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.freqency);
+ } else {
+ code = CMD_PERI_CLOCK_RATE_GET_REQ;
+ pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-GET}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port);
+ }
+
+ ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
+ if (ret < 0) {
+ pr_err("%s:%d failed!\n", __func__, __LINE__);
+ return ret;
+ }
+
+ if (set)
+ pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.freqency);
+ else
+ pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-GOT %lluHz}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.freqency);
+
+ *rate = cmd.freqency;
+ return 0;
+}
+
+static unsigned long
+crg_port_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ unsigned long rate;
+
+ crg_rate_control(hw, 0, &rate);
+
+ return rate;
+}
+
+static long
+crg_port_round_rate(struct clk_hw *hw,
+ unsigned long rate, unsigned long *pr)
+{
+ return rate;
+}
+
+static int
+crg_port_set_rate(struct clk_hw *hw,
+ unsigned long rate, unsigned long parent_rate)
+{
+ return crg_rate_control(hw, 1, &rate);
+}
+
+const struct clk_ops crg_port_ops = {
+ .prepare = crg_port_prepare,
+ .unprepare = crg_port_unprepare,
+ .recalc_rate = crg_port_recalc_rate,
+ .round_rate = crg_port_round_rate,
+ .set_rate = crg_port_set_rate,
+};
+
+struct mb86s70_crg11 {
+ struct mutex lock; /* protects CLK populating and searching */
+};
+
+static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data)
+{
+ struct mb86s70_crg11 *crg11 = data;
+ struct clk_init_data init;
+ u32 cntrlr, domain, port;
+ struct crg_clk *crgclk;
+ struct clk *clk;
+ char clkp[20];
+
+ if (clkspec->args_count != 3)
+ return ERR_PTR(-EINVAL);
+
+ cntrlr = clkspec->args[0];
+ domain = clkspec->args[1];
+ port = clkspec->args[2];
+
+ if (port > 7)
+ snprintf(clkp, 20, "UngatedCLK%d_%X", cntrlr, domain);
+ else
+ snprintf(clkp, 20, "CLK%d_%X_%d", cntrlr, domain, port);
+
+ mutex_lock(&crg11->lock);
+
+ clk = __clk_lookup(clkp);
+ if (clk) {
+ mutex_unlock(&crg11->lock);
+ return clk;
+ }
+
+ crgclk = kzalloc(sizeof(*crgclk), GFP_KERNEL);
+ if (!crgclk) {
+ mutex_unlock(&crg11->lock);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = clkp;
+ init.num_parents = 0;
+ init.ops = &crg_port_ops;
+ init.flags = CLK_IS_ROOT;
+ crgclk->hw.init = &init;
+ crgclk->cntrlr = cntrlr;
+ crgclk->domain = domain;
+ crgclk->port = port;
+ clk = clk_register(NULL, &crgclk->hw);
+ if (IS_ERR(clk))
+ pr_err("%s:%d Error!\n", __func__, __LINE__);
+ else
+ pr_debug("Registered %s\n", clkp);
+
+ clk_register_clkdev(clk, clkp, NULL);
+ mutex_unlock(&crg11->lock);
+ return clk;
+}
+
+static void __init crg_port_init(struct device_node *node)
+{
+ struct mb86s70_crg11 *crg11;
+
+ crg11 = kzalloc(sizeof(*crg11), GFP_KERNEL);
+ if (!crg11)
+ return;
+
+ mutex_init(&crg11->lock);
+
+ of_clk_add_provider(node, crg11_get, crg11);
+}
+CLK_OF_DECLARE(crg11_gate, "fujitsu,mb86s70-crg11", crg_port_init);
+
+struct cl_clk {
+ struct clk_hw hw;
+ int cluster;
+};
+
+struct mb86s7x_cpu_freq {
+ u32 payload_size;
+ u32 cluster_class;
+ u32 cluster_id;
+ u32 cpu_id;
+ u64 freqency;
+};
+
+static void mhu_cluster_rate(struct clk_hw *hw, unsigned long *rate, int get)
+{
+ struct cl_clk *clc = to_clc_clk(hw);
+ struct mb86s7x_cpu_freq cmd;
+ int code, ret;
+
+ cmd.payload_size = sizeof(cmd);
+ cmd.cluster_class = 0;
+ cmd.cluster_id = clc->cluster;
+ cmd.cpu_id = 0;
+ cmd.freqency = *rate;
+
+ if (get)
+ code = CMD_CPU_CLOCK_RATE_GET_REQ;
+ else
+ code = CMD_CPU_CLOCK_RATE_SET_REQ;
+
+ pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
+ __func__, __LINE__, cmd.cluster_class,
+ cmd.cluster_id, cmd.cpu_id, cmd.freqency);
+
+ ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
+ if (ret < 0) {
+ pr_err("%s:%d failed!\n", __func__, __LINE__);
+ return;
+ }
+
+ pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
+ __func__, __LINE__, cmd.cluster_class,
+ cmd.cluster_id, cmd.cpu_id, cmd.freqency);
+
+ *rate = cmd.freqency;
+}
+
+static unsigned long
+clc_recalc_rate(struct clk_hw *hw, unsigned long unused)
+{
+ unsigned long rate;
+
+ mhu_cluster_rate(hw, &rate, 1);
+ return rate;
+}
+
+static long
+clc_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *unused)
+{
+ return rate;
+}
+
+static int
+clc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long unused)
+{
+ unsigned long res = rate;
+
+ mhu_cluster_rate(hw, &res, 0);
+
+ return (res == rate) ? 0 : -EINVAL;
+}
+
+static struct clk_ops clk_clc_ops = {
+ .recalc_rate = clc_recalc_rate,
+ .round_rate = clc_round_rate,
+ .set_rate = clc_set_rate,
+};
+
+struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
+{
+ struct clk_init_data init;
+ struct cl_clk *clc;
+
+ clc = kzalloc(sizeof(*clc), GFP_KERNEL);
+ if (!clc)
+ return ERR_PTR(-ENOMEM);
+
+ clc->hw.init = &init;
+ clc->cluster = topology_physical_package_id(cpu_dev->id);
+
+ init.name = dev_name(cpu_dev);
+ init.ops = &clk_clc_ops;
+ init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
+ init.num_parents = 0;
+
+ return devm_clk_register(cpu_dev, &clc->hw);
+}
+
+static int mb86s7x_clclk_of_init(void)
+{
+ int cpu, ret = -ENODEV;
+ struct device_node *np;
+ struct clk *clk;
+
+ np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
+ if (!np || !of_device_is_available(np))
+ goto exit;
+
+ for_each_possible_cpu(cpu) {
+ struct device *cpu_dev = get_cpu_device(cpu);
+
+ if (!cpu_dev) {
+ pr_err("failed to get cpu%d device\n", cpu);
+ continue;
+ }
+
+ clk = mb86s7x_clclk_register(cpu_dev);
+ if (IS_ERR(clk)) {
+ pr_err("failed to register cpu%d clock\n", cpu);
+ continue;
+ }
+ if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
+ pr_err("failed to register cpu%d clock lookup\n", cpu);
+ continue;
+ }
+ pr_debug("registered clk for %s\n", dev_name(cpu_dev));
+ }
+ ret = 0;
+
+ platform_device_register_simple("arm-bL-cpufreq-dt", -1, NULL, 0);
+exit:
+ of_node_put(np);
+ return ret;
+}
+module_init(mb86s7x_clclk_of_init);
--
1.9.0
--
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 related [flat|nested] 47+ messages in thread
* [PATCH v5 4/7] clk: Add clock driver for mb86s7x
@ 2015-02-03 9:31 ` Vincent Yang
0 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:31 UTC (permalink / raw)
To: linux-arm-kernel
From: Jassi Brar <jaswinder.singh@linaro.org>
The CRG11 clock controller is managed by remote f/w.
This driver simply maps Linux CLK ops onto mailbox api.
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
.../bindings/clock/fujitsu,mb86s70-crg11.txt | 26 ++
drivers/clk/Makefile | 1 +
drivers/clk/clk-mb86s7x.c | 386 +++++++++++++++++++++
3 files changed, 413 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/fujitsu,mb86s70-crg11.txt
create mode 100644 drivers/clk/clk-mb86s7x.c
diff --git a/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-crg11.txt b/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-crg11.txt
new file mode 100644
index 0000000..3323962
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fujitsu,mb86s70-crg11.txt
@@ -0,0 +1,26 @@
+Fujitsu CRG11 clock driver bindings
+-----------------------------------
+
+Required properties :
+- compatible : Shall contain "fujitsu,mb86s70-crg11"
+- #clock-cells : Shall be 3 {cntrlr domain port}
+
+The consumer specifies the desired clock pointing to its phandle.
+
+Example:
+
+ clock: crg11 {
+ compatible = "fujitsu,mb86s70-crg11";
+ #clock-cells = <3>;
+ };
+
+ mhu: mhu0 at 2b1f0000 {
+ #mbox-cells = <1>;
+ compatible = "arm,mhu";
+ reg = <0 0x2B1F0000 0x1000>;
+ interrupts = <0 36 4>, /* LP Non-Sec */
+ <0 35 4>, /* HP Non-Sec */
+ <0 37 4>; /* Secure */
+ clocks = <&clock 0 2 1>; /* Cntrlr:0 Domain:2 Port:1 */
+ clock-names = "clk";
+ };
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..19d73a1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o
obj-$(CONFIG_COMMON_CLK_MAX_GEN) += clk-max-gen.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
obj-$(CONFIG_COMMON_CLK_MAX77802) += clk-max77802.o
+obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o
obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o
obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c
new file mode 100644
index 0000000..51703cb
--- /dev/null
+++ b/drivers/clk/clk-mb86s7x.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ *
+ * 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/clkdev.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/cpu.h>
+#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+#include <linux/mailbox_client.h>
+#include <linux/platform_device.h>
+
+#include <soc/mb86s7x/scb_mhu.h>
+
+#define to_crg_clk(p) container_of(p, struct crg_clk, hw)
+#define to_clc_clk(p) container_of(p, struct cl_clk, hw)
+
+struct mb86s7x_peri_clk {
+ u32 payload_size;
+ u32 cntrlr;
+ u32 domain;
+ u32 port;
+ u32 en;
+ u64 freqency;
+} __packed __aligned(4);
+
+struct hack_rate {
+ unsigned clk_id;
+ unsigned long rate;
+ int gated;
+};
+
+struct crg_clk {
+ struct clk_hw hw;
+ u8 cntrlr, domain, port;
+};
+
+static int crg_gate_control(struct clk_hw *hw, int en)
+{
+ struct crg_clk *crgclk = to_crg_clk(hw);
+ struct mb86s7x_peri_clk cmd;
+ int ret;
+
+ cmd.payload_size = sizeof(cmd);
+ cmd.cntrlr = crgclk->cntrlr;
+ cmd.domain = crgclk->domain;
+ cmd.port = crgclk->port;
+ cmd.en = en;
+
+ /* Port is UngatedCLK */
+ if (cmd.port == 8)
+ return en ? 0 : -EINVAL;
+
+ pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u En-%u}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.en);
+
+ ret = mb86s7x_send_packet(CMD_PERI_CLOCK_GATE_SET_REQ,
+ &cmd, sizeof(cmd));
+ if (ret < 0) {
+ pr_err("%s:%d failed!\n", __func__, __LINE__);
+ return ret;
+ }
+
+ pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u En-%u}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.en);
+
+ /* If the request was rejected */
+ if (cmd.en != en)
+ ret = -EINVAL;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+static int crg_port_prepare(struct clk_hw *hw)
+{
+ return crg_gate_control(hw, 1);
+}
+
+static void crg_port_unprepare(struct clk_hw *hw)
+{
+ crg_gate_control(hw, 0);
+}
+
+static int
+crg_rate_control(struct clk_hw *hw, int set, unsigned long *rate)
+{
+ struct crg_clk *crgclk = to_crg_clk(hw);
+ struct mb86s7x_peri_clk cmd;
+ int code, ret;
+
+ cmd.payload_size = sizeof(cmd);
+ cmd.cntrlr = crgclk->cntrlr;
+ cmd.domain = crgclk->domain;
+ cmd.port = crgclk->port;
+ cmd.freqency = *rate;
+
+ if (set) {
+ code = CMD_PERI_CLOCK_RATE_SET_REQ;
+ pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.freqency);
+ } else {
+ code = CMD_PERI_CLOCK_RATE_GET_REQ;
+ pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-GET}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port);
+ }
+
+ ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
+ if (ret < 0) {
+ pr_err("%s:%d failed!\n", __func__, __LINE__);
+ return ret;
+ }
+
+ if (set)
+ pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.freqency);
+ else
+ pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-GOT %lluHz}\n",
+ __func__, __LINE__, cmd.cntrlr,
+ cmd.domain, cmd.port, cmd.freqency);
+
+ *rate = cmd.freqency;
+ return 0;
+}
+
+static unsigned long
+crg_port_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ unsigned long rate;
+
+ crg_rate_control(hw, 0, &rate);
+
+ return rate;
+}
+
+static long
+crg_port_round_rate(struct clk_hw *hw,
+ unsigned long rate, unsigned long *pr)
+{
+ return rate;
+}
+
+static int
+crg_port_set_rate(struct clk_hw *hw,
+ unsigned long rate, unsigned long parent_rate)
+{
+ return crg_rate_control(hw, 1, &rate);
+}
+
+const struct clk_ops crg_port_ops = {
+ .prepare = crg_port_prepare,
+ .unprepare = crg_port_unprepare,
+ .recalc_rate = crg_port_recalc_rate,
+ .round_rate = crg_port_round_rate,
+ .set_rate = crg_port_set_rate,
+};
+
+struct mb86s70_crg11 {
+ struct mutex lock; /* protects CLK populating and searching */
+};
+
+static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data)
+{
+ struct mb86s70_crg11 *crg11 = data;
+ struct clk_init_data init;
+ u32 cntrlr, domain, port;
+ struct crg_clk *crgclk;
+ struct clk *clk;
+ char clkp[20];
+
+ if (clkspec->args_count != 3)
+ return ERR_PTR(-EINVAL);
+
+ cntrlr = clkspec->args[0];
+ domain = clkspec->args[1];
+ port = clkspec->args[2];
+
+ if (port > 7)
+ snprintf(clkp, 20, "UngatedCLK%d_%X", cntrlr, domain);
+ else
+ snprintf(clkp, 20, "CLK%d_%X_%d", cntrlr, domain, port);
+
+ mutex_lock(&crg11->lock);
+
+ clk = __clk_lookup(clkp);
+ if (clk) {
+ mutex_unlock(&crg11->lock);
+ return clk;
+ }
+
+ crgclk = kzalloc(sizeof(*crgclk), GFP_KERNEL);
+ if (!crgclk) {
+ mutex_unlock(&crg11->lock);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ init.name = clkp;
+ init.num_parents = 0;
+ init.ops = &crg_port_ops;
+ init.flags = CLK_IS_ROOT;
+ crgclk->hw.init = &init;
+ crgclk->cntrlr = cntrlr;
+ crgclk->domain = domain;
+ crgclk->port = port;
+ clk = clk_register(NULL, &crgclk->hw);
+ if (IS_ERR(clk))
+ pr_err("%s:%d Error!\n", __func__, __LINE__);
+ else
+ pr_debug("Registered %s\n", clkp);
+
+ clk_register_clkdev(clk, clkp, NULL);
+ mutex_unlock(&crg11->lock);
+ return clk;
+}
+
+static void __init crg_port_init(struct device_node *node)
+{
+ struct mb86s70_crg11 *crg11;
+
+ crg11 = kzalloc(sizeof(*crg11), GFP_KERNEL);
+ if (!crg11)
+ return;
+
+ mutex_init(&crg11->lock);
+
+ of_clk_add_provider(node, crg11_get, crg11);
+}
+CLK_OF_DECLARE(crg11_gate, "fujitsu,mb86s70-crg11", crg_port_init);
+
+struct cl_clk {
+ struct clk_hw hw;
+ int cluster;
+};
+
+struct mb86s7x_cpu_freq {
+ u32 payload_size;
+ u32 cluster_class;
+ u32 cluster_id;
+ u32 cpu_id;
+ u64 freqency;
+};
+
+static void mhu_cluster_rate(struct clk_hw *hw, unsigned long *rate, int get)
+{
+ struct cl_clk *clc = to_clc_clk(hw);
+ struct mb86s7x_cpu_freq cmd;
+ int code, ret;
+
+ cmd.payload_size = sizeof(cmd);
+ cmd.cluster_class = 0;
+ cmd.cluster_id = clc->cluster;
+ cmd.cpu_id = 0;
+ cmd.freqency = *rate;
+
+ if (get)
+ code = CMD_CPU_CLOCK_RATE_GET_REQ;
+ else
+ code = CMD_CPU_CLOCK_RATE_SET_REQ;
+
+ pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
+ __func__, __LINE__, cmd.cluster_class,
+ cmd.cluster_id, cmd.cpu_id, cmd.freqency);
+
+ ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd));
+ if (ret < 0) {
+ pr_err("%s:%d failed!\n", __func__, __LINE__);
+ return;
+ }
+
+ pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n",
+ __func__, __LINE__, cmd.cluster_class,
+ cmd.cluster_id, cmd.cpu_id, cmd.freqency);
+
+ *rate = cmd.freqency;
+}
+
+static unsigned long
+clc_recalc_rate(struct clk_hw *hw, unsigned long unused)
+{
+ unsigned long rate;
+
+ mhu_cluster_rate(hw, &rate, 1);
+ return rate;
+}
+
+static long
+clc_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *unused)
+{
+ return rate;
+}
+
+static int
+clc_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long unused)
+{
+ unsigned long res = rate;
+
+ mhu_cluster_rate(hw, &res, 0);
+
+ return (res == rate) ? 0 : -EINVAL;
+}
+
+static struct clk_ops clk_clc_ops = {
+ .recalc_rate = clc_recalc_rate,
+ .round_rate = clc_round_rate,
+ .set_rate = clc_set_rate,
+};
+
+struct clk *mb86s7x_clclk_register(struct device *cpu_dev)
+{
+ struct clk_init_data init;
+ struct cl_clk *clc;
+
+ clc = kzalloc(sizeof(*clc), GFP_KERNEL);
+ if (!clc)
+ return ERR_PTR(-ENOMEM);
+
+ clc->hw.init = &init;
+ clc->cluster = topology_physical_package_id(cpu_dev->id);
+
+ init.name = dev_name(cpu_dev);
+ init.ops = &clk_clc_ops;
+ init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE;
+ init.num_parents = 0;
+
+ return devm_clk_register(cpu_dev, &clc->hw);
+}
+
+static int mb86s7x_clclk_of_init(void)
+{
+ int cpu, ret = -ENODEV;
+ struct device_node *np;
+ struct clk *clk;
+
+ np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0");
+ if (!np || !of_device_is_available(np))
+ goto exit;
+
+ for_each_possible_cpu(cpu) {
+ struct device *cpu_dev = get_cpu_device(cpu);
+
+ if (!cpu_dev) {
+ pr_err("failed to get cpu%d device\n", cpu);
+ continue;
+ }
+
+ clk = mb86s7x_clclk_register(cpu_dev);
+ if (IS_ERR(clk)) {
+ pr_err("failed to register cpu%d clock\n", cpu);
+ continue;
+ }
+ if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
+ pr_err("failed to register cpu%d clock lookup\n", cpu);
+ continue;
+ }
+ pr_debug("registered clk for %s\n", dev_name(cpu_dev));
+ }
+ ret = 0;
+
+ platform_device_register_simple("arm-bL-cpufreq-dt", -1, NULL, 0);
+exit:
+ of_node_put(np);
+ return ret;
+}
+module_init(mb86s7x_clclk_of_init);
--
1.9.0
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [PATCH v5 5/7] dt: mb86s7x: add dt files for MB86S7x evbs
2015-02-03 9:21 ` Vincent Yang
@ 2015-02-03 9:32 ` Vincent Yang
-1 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:32 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
arm-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
patches-QSEj5FYQhm4dnm+yROfE0A,
jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A,
Sneeker.Yeh-l16TxrwUIHTQFUHtdCDX3A, Vincent Yang, Tetsuya Nuriya
From: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Add dt files for MB86S7x evb.
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/mb86s70.dtsi | 91 +++++++++++++++++++++++++
arch/arm/boot/dts/mb86s70eb.dts | 57 ++++++++++++++++
arch/arm/boot/dts/mb86s73.dtsi | 63 ++++++++++++++++++
arch/arm/boot/dts/mb86s73eb.dts | 44 +++++++++++++
arch/arm/boot/dts/mb86s7x.dtsi | 142 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 398 insertions(+)
create mode 100644 arch/arm/boot/dts/mb86s70.dtsi
create mode 100644 arch/arm/boot/dts/mb86s70eb.dts
create mode 100644 arch/arm/boot/dts/mb86s73.dtsi
create mode 100644 arch/arm/boot/dts/mb86s73eb.dts
create mode 100644 arch/arm/boot/dts/mb86s7x.dtsi
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 91bd5bd..43b091b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -176,6 +176,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
kirkwood-ts419-6282.dtb
dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
+dtb-$(CONFIG_ARCH_MB86S7X) += mb86s70eb.dtb mb86s73eb.dtb
dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb
dtb-$(CONFIG_ARCH_MMP) += pxa168-aspenite.dtb \
pxa910-dkb.dtb \
diff --git a/arch/arm/boot/dts/mb86s70.dtsi b/arch/arm/boot/dts/mb86s70.dtsi
new file mode 100644
index 0000000..057e135
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s70.dtsi
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#include "mb86s7x.dtsi"
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ cci-control-port = <&cci_control4>;
+ clock-frequency = <1200000000>;
+ clock-latency = <100000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x1>;
+ cci-control-port = <&cci_control4>;
+ clock-frequency = <1200000000>;
+ clock-latency = <100000>;
+ };
+
+ cpu2: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ cci-control-port = <&cci_control3>;
+ clock-frequency = <800000000>;
+ clock-latency = <100000>;
+ };
+
+ cpu3: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ cci-control-port = <&cci_control3>;
+ clock-frequency = <800000000>;
+ clock-latency = <100000>;
+ };
+ };
+
+ cci@2c090000 {
+ compatible = "arm,cci-400";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x2c090000 0x1000>;
+ ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+ cci_control3: slave-if@4000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x4000 0x1000>;
+ };
+
+ cci_control4: slave-if@5000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x5000 0x1000>;
+ };
+
+ pmu@9000 {
+ compatible = "arm,cci-400-pmu";
+ reg = <0x9000 0x5000>;
+ interrupts = <0 77 4>,
+ <0 77 4>,
+ <0 77 4>,
+ <0 77 4>,
+ <0 77 4>;
+ };
+ };
+};
+
+&archtimer {
+ status = "disabled";
+};
+
+&pmua7 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/mb86s70eb.dts b/arch/arm/boot/dts/mb86s70eb.dts
new file mode 100644
index 0000000..1e51ce0
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s70eb.dts
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+/dts-v1/;
+
+#include "mb86s70.dtsi"
+
+/ {
+ model = "Fujitsu MB86S70 EVB";
+ compatible = "fujitsu,mb86s70-evb";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>;
+
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
+ linux,initrd-start = <0xc0000000>;
+ linux,initrd-end = <0xc0800000>;
+ };
+
+ vccq_sdhci1: regulator@0 {
+ compatible = "regulator-gpio";
+ regulator-name = "SDHCI1 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio0 7 0>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+};
+
+&sdhci0 {
+ status = "ok";
+ bus-width = <8>;
+};
+
+&sdhci1 {
+ status = "ok";
+ bus-width = <4>;
+ vqmmc-supply = <&vccq_sdhci1>;
+};
diff --git a/arch/arm/boot/dts/mb86s73.dtsi b/arch/arm/boot/dts/mb86s73.dtsi
new file mode 100644
index 0000000..3c9d8d0
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s73.dtsi
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#include "mb86s7x.dtsi"
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ cci-control-port = <&cci_control3>;
+ clock-frequency = <800000000>;
+ clock-latency = <100000>;
+ };
+
+ cpu1: cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ cci-control-port = <&cci_control3>;
+ clock-frequency = <800000000>;
+ clock-latency = <100000>;
+ };
+ };
+
+ cci@2c090000 {
+ compatible = "arm,cci-400";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x2c090000 0x1000>;
+ ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+ cci_control3: slave-if@4000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x4000 0x1000>;
+ };
+ };
+
+ hcd21_ehci: f_usb20ho_echi@34240000 {
+ compatible = "fujitsu,f_usb20ho", "generic-ehci";
+ reg = <0 0x34240000 0x1000>;
+ interrupts = <0 419 0x4>;
+ clocks = <&clock 2 2 4>, <&clock 2 4 5>, <&clock 4 0 0>;
+ };
+
+ hcd21_ohci: f_usb20ho_ochi@34240000 {
+ compatible = "fujitsu,f_usb20ho", "generic-ohci";
+ reg = <0 0x34241000 0x1000>;
+ interrupts = <0 419 0x4>;
+ clocks = <&clock 2 2 4>, <&clock 2 4 5>, <&clock 4 0 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/mb86s73eb.dts b/arch/arm/boot/dts/mb86s73eb.dts
new file mode 100644
index 0000000..43f2fc6
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s73eb.dts
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+/dts-v1/;
+
+#include "mb86s73.dtsi"
+
+/ {
+ model = "Fujitsu MB86S73 EVB";
+ compatible = "fujitsu,mb86s73-evb";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x80000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
+ linux,initrd-start = <0xc0000000>;
+ linux,initrd-end = <0xc0800000>;
+ };
+};
+
+&sdhci0 {
+ status = "ok";
+ bus-width = <8>;
+};
+
+&sdhci1 {
+ status = "ok";
+ bus-width = <4>;
+};
diff --git a/arch/arm/boot/dts/mb86s7x.dtsi b/arch/arm/boot/dts/mb86s7x.dtsi
new file mode 100644
index 0000000..4731af1
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s7x.dtsi
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ pmua7: pmu_a7 {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <0 18 4>,
+ <0 22 4>;
+ };
+
+ clock: crg11 {
+ compatible = "fujitsu,mb86s70-crg11";
+ #clock-cells = <3>;
+ };
+
+ timer0: timer@31080000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0 0x31080000 0x1000>;
+ interrupts = <0 324 4>,
+ <0 325 4>;
+ clocks = <&clock 0 6 8>;
+ clock-names = "apb_pclk";
+ };
+
+ archtimer: archtimer {
+ compatible = "arm,armv7-timer";
+ clock-frequency = <125000000>;
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ };
+
+ gic: interrupt-controller@2c001000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0 0x2c001000 0x1000>,
+ <0 0x2c002000 0x1000>,
+ <0 0x2c004000 0x2000>,
+ <0 0x2c006000 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ mhu: mailbox@2b1f0000 {
+ #mbox-cells = <1>;
+ compatible = "arm,mhu", "arm,primecell";
+ reg = <0 0x2b1f0000 0x1000>;
+ interrupts = <0 36 4>, /* LP Non-Sec */
+ <0 35 4>, /* HP Non-Sec */
+ <0 37 4>; /* Secure */
+ clocks = <&clock 0 6 8>;
+ clock-names = "apb_pclk";
+ };
+
+ mhu_client: scb@2e000000 {
+ compatible = "fujitsu,mb86s70-scb-1.0";
+ reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
+ mboxes = <&mhu 1>;
+ };
+
+ uart0: serial@31040000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0 0x31040000 0x100>;
+ interrupts = <0 320 0x4>;
+ clock-frequency = <62500000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&clock 0 2 1>;
+ clock-names = "sclk";
+ };
+
+ uart1: serial@31050000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0 0x31050000 0x100>;
+ interrupts = <0 321 0x4>;
+ clock-frequency = <62500000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&clock 0 2 1>;
+ clock-names = "sclk";
+ };
+
+ uart2: serial@31060000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0 0x31060000 0x100>;
+ interrupts = <0 322 0x4>;
+ clock-frequency = <62500000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&clock 0 2 1>;
+ clock-names = "sclk";
+ };
+
+ gpio0: gpio@31000000 {
+ compatible = "fujitsu,mb86s70-gpio";
+ reg = <0 0x31000000 0x10000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock 0 2 1>;
+ };
+
+ gpio1: gpio@31010000 {
+ compatible = "fujitsu,mb86s70-gpio";
+ reg = <0 0x31010000 0x10000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock 0 2 1>;
+ };
+
+ sdhci0: mmc@300c0000 {
+ status = "disabled";
+ compatible = "fujitsu,mb86s70-sdhci-3.0";
+ reg = <0 0x300c0000 0x1000>;
+ interrupts = <0 164 0x4>,
+ <0 165 0x4>;
+ clocks = <&clock 0 0xc 0>, <&clock 0 0xb 0>;
+ clock-names = "iface", "core";
+ };
+
+ sdhci1: mmc@36600000 {
+ status = "disabled";
+ compatible = "fujitsu,mb86s70-sdhci-3.0";
+ reg = <0 0x36600000 0x1000>;
+ interrupts = <0 172 0x4>,
+ <0 173 0x4>;
+ clocks = <&clock 2 0xc 0>, <&clock 2 0xd 0>;
+ clock-names = "iface", "core";
+ };
+};
--
1.9.0
--
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 related [flat|nested] 47+ messages in thread
* [PATCH v5 5/7] dt: mb86s7x: add dt files for MB86S7x evbs
@ 2015-02-03 9:32 ` Vincent Yang
0 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:32 UTC (permalink / raw)
To: linux-arm-kernel
From: Jassi Brar <jaswinder.singh@linaro.org>
Add dt files for MB86S7x evb.
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/mb86s70.dtsi | 91 +++++++++++++++++++++++++
arch/arm/boot/dts/mb86s70eb.dts | 57 ++++++++++++++++
arch/arm/boot/dts/mb86s73.dtsi | 63 ++++++++++++++++++
arch/arm/boot/dts/mb86s73eb.dts | 44 +++++++++++++
arch/arm/boot/dts/mb86s7x.dtsi | 142 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 398 insertions(+)
create mode 100644 arch/arm/boot/dts/mb86s70.dtsi
create mode 100644 arch/arm/boot/dts/mb86s70eb.dts
create mode 100644 arch/arm/boot/dts/mb86s73.dtsi
create mode 100644 arch/arm/boot/dts/mb86s73eb.dts
create mode 100644 arch/arm/boot/dts/mb86s7x.dtsi
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 91bd5bd..43b091b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -176,6 +176,7 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += kirkwood-b3.dtb \
kirkwood-ts419-6282.dtb
dtb-$(CONFIG_ARCH_LPC32XX) += ea3250.dtb phy3250.dtb
dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb
+dtb-$(CONFIG_ARCH_MB86S7X) += mb86s70eb.dtb mb86s73eb.dtb
dtb-$(CONFIG_MACH_MESON6) += meson6-atv1200.dtb
dtb-$(CONFIG_ARCH_MMP) += pxa168-aspenite.dtb \
pxa910-dkb.dtb \
diff --git a/arch/arm/boot/dts/mb86s70.dtsi b/arch/arm/boot/dts/mb86s70.dtsi
new file mode 100644
index 0000000..057e135
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s70.dtsi
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#include "mb86s7x.dtsi"
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu at 0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x0>;
+ cci-control-port = <&cci_control4>;
+ clock-frequency = <1200000000>;
+ clock-latency = <100000>;
+ };
+
+ cpu1: cpu at 1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a15";
+ reg = <0x1>;
+ cci-control-port = <&cci_control4>;
+ clock-frequency = <1200000000>;
+ clock-latency = <100000>;
+ };
+
+ cpu2: cpu at 100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ cci-control-port = <&cci_control3>;
+ clock-frequency = <800000000>;
+ clock-latency = <100000>;
+ };
+
+ cpu3: cpu at 101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ cci-control-port = <&cci_control3>;
+ clock-frequency = <800000000>;
+ clock-latency = <100000>;
+ };
+ };
+
+ cci at 2c090000 {
+ compatible = "arm,cci-400";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x2c090000 0x1000>;
+ ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+ cci_control3: slave-if at 4000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x4000 0x1000>;
+ };
+
+ cci_control4: slave-if at 5000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x5000 0x1000>;
+ };
+
+ pmu at 9000 {
+ compatible = "arm,cci-400-pmu";
+ reg = <0x9000 0x5000>;
+ interrupts = <0 77 4>,
+ <0 77 4>,
+ <0 77 4>,
+ <0 77 4>,
+ <0 77 4>;
+ };
+ };
+};
+
+&archtimer {
+ status = "disabled";
+};
+
+&pmua7 {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/mb86s70eb.dts b/arch/arm/boot/dts/mb86s70eb.dts
new file mode 100644
index 0000000..1e51ce0
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s70eb.dts
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+/dts-v1/;
+
+#include "mb86s70.dtsi"
+
+/ {
+ model = "Fujitsu MB86S70 EVB";
+ compatible = "fujitsu,mb86s70-evb";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x80000000 0x80000000>, <0x08 0x80000000 0x80000000>;
+
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
+ linux,initrd-start = <0xc0000000>;
+ linux,initrd-end = <0xc0800000>;
+ };
+
+ vccq_sdhci1: regulator at 0 {
+ compatible = "regulator-gpio";
+ regulator-name = "SDHCI1 VccQ";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ gpios = <&gpio0 7 0>;
+ gpios-states = <1>;
+ states = <3300000 1
+ 1800000 0>;
+ };
+};
+
+&sdhci0 {
+ status = "ok";
+ bus-width = <8>;
+};
+
+&sdhci1 {
+ status = "ok";
+ bus-width = <4>;
+ vqmmc-supply = <&vccq_sdhci1>;
+};
diff --git a/arch/arm/boot/dts/mb86s73.dtsi b/arch/arm/boot/dts/mb86s73.dtsi
new file mode 100644
index 0000000..3c9d8d0
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s73.dtsi
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#include "mb86s7x.dtsi"
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu at 100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x100>;
+ cci-control-port = <&cci_control3>;
+ clock-frequency = <800000000>;
+ clock-latency = <100000>;
+ };
+
+ cpu1: cpu at 101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x101>;
+ cci-control-port = <&cci_control3>;
+ clock-frequency = <800000000>;
+ clock-latency = <100000>;
+ };
+ };
+
+ cci at 2c090000 {
+ compatible = "arm,cci-400";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x2c090000 0x1000>;
+ ranges = <0x0 0x0 0x2c090000 0x10000>;
+
+ cci_control3: slave-if at 4000 {
+ compatible = "arm,cci-400-ctrl-if";
+ interface-type = "ace";
+ reg = <0x4000 0x1000>;
+ };
+ };
+
+ hcd21_ehci: f_usb20ho_echi at 34240000 {
+ compatible = "fujitsu,f_usb20ho", "generic-ehci";
+ reg = <0 0x34240000 0x1000>;
+ interrupts = <0 419 0x4>;
+ clocks = <&clock 2 2 4>, <&clock 2 4 5>, <&clock 4 0 0>;
+ };
+
+ hcd21_ohci: f_usb20ho_ochi at 34240000 {
+ compatible = "fujitsu,f_usb20ho", "generic-ohci";
+ reg = <0 0x34241000 0x1000>;
+ interrupts = <0 419 0x4>;
+ clocks = <&clock 2 2 4>, <&clock 2 4 5>, <&clock 4 0 0>;
+ };
+};
diff --git a/arch/arm/boot/dts/mb86s73eb.dts b/arch/arm/boot/dts/mb86s73eb.dts
new file mode 100644
index 0000000..43f2fc6
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s73eb.dts
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+/dts-v1/;
+
+#include "mb86s73.dtsi"
+
+/ {
+ model = "Fujitsu MB86S73 EVB";
+ compatible = "fujitsu,mb86s73-evb";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x80000000 0x80000000>;
+ };
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/mmcblk1p1 rootfstype=ext4 rootwait rw";
+ linux,initrd-start = <0xc0000000>;
+ linux,initrd-end = <0xc0800000>;
+ };
+};
+
+&sdhci0 {
+ status = "ok";
+ bus-width = <8>;
+};
+
+&sdhci1 {
+ status = "ok";
+ bus-width = <4>;
+};
diff --git a/arch/arm/boot/dts/mb86s7x.dtsi b/arch/arm/boot/dts/mb86s7x.dtsi
new file mode 100644
index 0000000..4731af1
--- /dev/null
+++ b/arch/arm/boot/dts/mb86s7x.dtsi
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED
+ * Copyright (C) 2015 Linaro Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#include "skeleton.dtsi"
+
+/ {
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+
+ pmua7: pmu_a7 {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <0 18 4>,
+ <0 22 4>;
+ };
+
+ clock: crg11 {
+ compatible = "fujitsu,mb86s70-crg11";
+ #clock-cells = <3>;
+ };
+
+ timer0: timer at 31080000 {
+ compatible = "arm,sp804", "arm,primecell";
+ reg = <0 0x31080000 0x1000>;
+ interrupts = <0 324 4>,
+ <0 325 4>;
+ clocks = <&clock 0 6 8>;
+ clock-names = "apb_pclk";
+ };
+
+ archtimer: archtimer {
+ compatible = "arm,armv7-timer";
+ clock-frequency = <125000000>;
+ interrupts = <1 13 0xf08>,
+ <1 14 0xf08>,
+ <1 11 0xf08>,
+ <1 10 0xf08>;
+ };
+
+ gic: interrupt-controller at 2c001000 {
+ compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0 0x2c001000 0x1000>,
+ <0 0x2c002000 0x1000>,
+ <0 0x2c004000 0x2000>,
+ <0 0x2c006000 0x2000>;
+ interrupts = <1 9 0xf04>;
+ };
+
+ mhu: mailbox at 2b1f0000 {
+ #mbox-cells = <1>;
+ compatible = "arm,mhu", "arm,primecell";
+ reg = <0 0x2b1f0000 0x1000>;
+ interrupts = <0 36 4>, /* LP Non-Sec */
+ <0 35 4>, /* HP Non-Sec */
+ <0 37 4>; /* Secure */
+ clocks = <&clock 0 6 8>;
+ clock-names = "apb_pclk";
+ };
+
+ mhu_client: scb at 2e000000 {
+ compatible = "fujitsu,mb86s70-scb-1.0";
+ reg = <0 0x2e000000 0x4000>; /* SHM for IPC */
+ mboxes = <&mhu 1>;
+ };
+
+ uart0: serial at 31040000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0 0x31040000 0x100>;
+ interrupts = <0 320 0x4>;
+ clock-frequency = <62500000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&clock 0 2 1>;
+ clock-names = "sclk";
+ };
+
+ uart1: serial at 31050000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0 0x31050000 0x100>;
+ interrupts = <0 321 0x4>;
+ clock-frequency = <62500000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&clock 0 2 1>;
+ clock-names = "sclk";
+ };
+
+ uart2: serial at 31060000 {
+ compatible = "snps,dw-apb-uart";
+ reg = <0 0x31060000 0x100>;
+ interrupts = <0 322 0x4>;
+ clock-frequency = <62500000>;
+ reg-io-width = <4>;
+ reg-shift = <2>;
+ clocks = <&clock 0 2 1>;
+ clock-names = "sclk";
+ };
+
+ gpio0: gpio at 31000000 {
+ compatible = "fujitsu,mb86s70-gpio";
+ reg = <0 0x31000000 0x10000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock 0 2 1>;
+ };
+
+ gpio1: gpio at 31010000 {
+ compatible = "fujitsu,mb86s70-gpio";
+ reg = <0 0x31010000 0x10000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ clocks = <&clock 0 2 1>;
+ };
+
+ sdhci0: mmc at 300c0000 {
+ status = "disabled";
+ compatible = "fujitsu,mb86s70-sdhci-3.0";
+ reg = <0 0x300c0000 0x1000>;
+ interrupts = <0 164 0x4>,
+ <0 165 0x4>;
+ clocks = <&clock 0 0xc 0>, <&clock 0 0xb 0>;
+ clock-names = "iface", "core";
+ };
+
+ sdhci1: mmc at 36600000 {
+ status = "disabled";
+ compatible = "fujitsu,mb86s70-sdhci-3.0";
+ reg = <0 0x36600000 0x1000>;
+ interrupts = <0 172 0x4>,
+ <0 173 0x4>;
+ clocks = <&clock 2 0xc 0>, <&clock 2 0xd 0>;
+ clock-names = "iface", "core";
+ };
+};
--
1.9.0
^ permalink raw reply related [flat|nested] 47+ messages in thread
* [PATCH v5 6/7] of: add Fujitsu vendor prefix
2015-02-03 9:21 ` Vincent Yang
@ 2015-02-03 9:34 ` Vincent Yang
-1 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:34 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: arnd-r2nGTMty4D4, olof-nZhT3qVonbNeoWH0uzbU5w,
arm-DgEjT+Ai2ygdnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, andy.green-QSEj5FYQhm4dnm+yROfE0A,
patches-QSEj5FYQhm4dnm+yROfE0A,
jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A, Vincent Yang,
Tetsuya Nuriya
From: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Add 'fujitsu' as the vendor prefix for Fujitsu Semiconductor Ltd.
Signed-off-by: Jassi Brar <jaswinder.singh-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Andy Green <andy.green-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Vincent Yang <Vincent.Yang-l16TxrwUIHTQFUHtdCDX3A@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
---
Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index d443279..e0ac020 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -59,6 +59,7 @@ everest Everest Semiconductor Co. Ltd.
excito Excito
fcs Fairchild Semiconductor
fsl Freescale Semiconductor
+fujitsu Fujitsu Semiconductor Ltd.
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
geniatech Geniatech, Inc.
--
1.9.0
--
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 related [flat|nested] 47+ messages in thread
* [PATCH v5 6/7] of: add Fujitsu vendor prefix
@ 2015-02-03 9:34 ` Vincent Yang
0 siblings, 0 replies; 47+ messages in thread
From: Vincent Yang @ 2015-02-03 9:34 UTC (permalink / raw)
To: linux-arm-kernel
From: Jassi Brar <jaswinder.singh@linaro.org>
Add 'fujitsu' as the vendor prefix for Fujitsu Semiconductor Ltd.
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
Signed-off-by: Andy Green <andy.green@linaro.org>
Signed-off-by: Vincent Yang <Vincent.Yang@tw.fujitsu.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Tetsuya Nuriya <nuriya.tetsuya@jp.fujitsu.com>
---
Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index d443279..e0ac020 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -59,6 +59,7 @@ everest Everest Semiconductor Co. Ltd.
excito Excito
fcs Fairchild Semiconductor
fsl Freescale Semiconductor
+fujitsu Fujitsu Semiconductor Ltd.
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
geniatech Geniatech, Inc.
--
1.9.0
^ permalink raw reply related [flat|nested] 47+ messages in thread