diff options
-rw-r--r-- | Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt | 18 | ||||
-rw-r--r-- | drivers/mailbox/qcom-apcs-ipc-mailbox.c | 35 | ||||
-rw-r--r-- | drivers/mailbox/ti-msgmgr.c | 14 |
3 files changed, 51 insertions, 16 deletions
diff --git a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt index fb961c310f44..16964f0c1773 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt +++ b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt @@ -15,12 +15,21 @@ platforms. Usage: required Value type: <prop-encoded-array> Definition: must specify the base address and size of the global block +- clocks: + Usage: required if #clocks-cells property is present + Value type: <phandle> + Definition: phandle to the input PLL, which feeds the APCS mux/divider - #mbox-cells: Usage: required Value type: <u32> Definition: as described in mailbox.txt, must be 1 +- #clock-cells: + Usage: optional + Value type: <u32> + Definition: as described in clock.txt, must be 0 + = EXAMPLE The following example describes the APCS HMSS found in MSM8996 and part of the @@ -44,3 +53,12 @@ GLINK RPM referencing the "rpm_hlos" doorbell therein. mbox-names = "rpm_hlos"; }; +Below is another example of the APCS binding on MSM8916 platforms: + + apcs: mailbox@b011000 { + compatible = "qcom,msm8916-apcs-kpss-global"; + reg = <0xb011000 0x1000>; + #mbox-cells = <1>; + clocks = <&a53pll>; + #clock-cells = <0>; + }; diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c index 9924c6d7f05d..57bde0dfd12f 100644 --- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c +++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c @@ -18,6 +18,7 @@ #include <linux/of.h> #include <linux/of_platform.h> #include <linux/platform_device.h> +#include <linux/regmap.h> #include <linux/mailbox_controller.h> #define QCOM_APCS_IPC_BITS 32 @@ -26,8 +27,17 @@ struct qcom_apcs_ipc { struct mbox_controller mbox; struct mbox_chan mbox_chans[QCOM_APCS_IPC_BITS]; - void __iomem *reg; + struct regmap *regmap; unsigned long offset; + struct platform_device *clk; +}; + +static const struct regmap_config apcs_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1000, + .fast_io = true, }; static int qcom_apcs_ipc_send_data(struct mbox_chan *chan, void *data) @@ -36,9 +46,7 @@ static int qcom_apcs_ipc_send_data(struct mbox_chan *chan, void *data) struct qcom_apcs_ipc, mbox); unsigned long idx = (unsigned long)chan->con_priv; - writel(BIT(idx), apcs->reg); - - return 0; + return regmap_write(apcs->regmap, apcs->offset, BIT(idx)); } static const struct mbox_chan_ops qcom_apcs_ipc_ops = { @@ -47,7 +55,9 @@ static const struct mbox_chan_ops qcom_apcs_ipc_ops = { static int qcom_apcs_ipc_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct qcom_apcs_ipc *apcs; + struct regmap *regmap; struct resource *res; unsigned long offset; void __iomem *base; @@ -63,9 +73,14 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); + regmap = devm_regmap_init_mmio(&pdev->dev, base, &apcs_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + offset = (unsigned long)of_device_get_match_data(&pdev->dev); - apcs->reg = base + offset; + apcs->regmap = regmap; + apcs->offset = offset; /* Initialize channel identifiers */ for (i = 0; i < ARRAY_SIZE(apcs->mbox_chans); i++) @@ -82,6 +97,14 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev) return ret; } + if (of_device_is_compatible(np, "qcom,msm8916-apcs-kpss-global")) { + apcs->clk = platform_device_register_data(&pdev->dev, + "qcom-apcs-msm8916-clk", + -1, NULL, 0); + if (IS_ERR(apcs->clk)) + dev_err(&pdev->dev, "failed to register APCS clk\n"); + } + platform_set_drvdata(pdev, apcs); return 0; @@ -90,8 +113,10 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev) static int qcom_apcs_ipc_remove(struct platform_device *pdev) { struct qcom_apcs_ipc *apcs = platform_get_drvdata(pdev); + struct platform_device *clk = apcs->clk; mbox_controller_unregister(&apcs->mbox); + platform_device_unregister(clk); return 0; } diff --git a/drivers/mailbox/ti-msgmgr.c b/drivers/mailbox/ti-msgmgr.c index 54b9e4cb4cfa..78753a87ba4d 100644 --- a/drivers/mailbox/ti-msgmgr.c +++ b/drivers/mailbox/ti-msgmgr.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Texas Instruments' Message Manager Driver * - * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/ * Nishanth Menon - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -291,7 +283,7 @@ static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data) desc = inst->desc; if (desc->max_message_size < message->len) { - dev_err(dev, "Queue %s message length %d > max %d\n", + dev_err(dev, "Queue %s message length %zu > max %d\n", qinst->name, message->len, desc->max_message_size); return -EINVAL; } |