From: Lee Jones <lee.jones@linaro.org>
To: bjorn@kryo.se
Cc: Andy Gross <agross@codeaurora.org>,
Samuel Ortiz <sameo@linux.intel.com>,
Mark Brown <broonie@kernel.org>,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org
Subject: Re: [PATCH v2 06/11] mfd: qcom-smd-rpm: Driver for the Qualcomm RPM over SMD
Date: Tue, 7 Jul 2015 13:37:16 +0100 [thread overview]
Message-ID: <20150707123716.GA3182@x1> (raw)
In-Reply-To: <1435355419-23602-7-git-send-email-bjorn.andersson@sonymobile.com>
On Fri, 26 Jun 2015, bjorn@kryo.se wrote:
> From: Bjorn Andersson <bjorn.andersson@sonymobile.com>
>
> Driver for the Resource Power Manager (RPM) found in Qualcomm 8974 based
> devices.
> The driver exposes resources that child drivers can operate on; to
> implementing regulator, clock and bus frequency drivers.
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
> ---
> drivers/mfd/Kconfig | 14 +++
> drivers/mfd/Makefile | 1 +
> drivers/mfd/qcom-smd-rpm.c | 236 +++++++++++++++++++++++++++++++++++++++
> include/linux/mfd/qcom-smd-rpm.h | 35 ++++++
> 4 files changed, 286 insertions(+)
> create mode 100644 drivers/mfd/qcom-smd-rpm.c
> create mode 100644 include/linux/mfd/qcom-smd-rpm.h
>
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 6538159..666c812 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -656,6 +656,20 @@ config MFD_QCOM_RPM
> Say M here if you want to include support for the Qualcomm RPM as a
> module. This will build a module called "qcom_rpm".
>
> +config MFD_QCOM_SMD_RPM
> + tristate "Qualcomm Resource Power Manager (RPM) over SMD"
> + depends on QCOM_SMD && OF
> + help
> + If you say yes to this option, support will be included for the
> + Resource Power Manager system found in the Qualcomm 8974 based
> + devices.
> +
> + This is required to access many regulators, clocks and bus
> + frequencies controlled by the RPM on these devices.
> +
> + Say M here if you want to include support for the Qualcomm RPM as a
> + module. This will build a module called "qcom-smd-rpm".
I'm not exactly sure what makes this an MFD device.
> config MFD_SPMI_PMIC
> tristate "Qualcomm SPMI PMICs"
> depends on ARCH_QCOM || COMPILE_TEST
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index ea40e07..289bd24 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -156,6 +156,7 @@ obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
> obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
> obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o
> obj-$(CONFIG_MFD_QCOM_RPM) += qcom_rpm.o
> +obj-$(CONFIG_MFD_QCOM_SMD_RPM) += qcom-smd-rpm.o
> obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o
> obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
> obj-$(CONFIG_MFD_TPS65090) += tps65090.o
> diff --git a/drivers/mfd/qcom-smd-rpm.c b/drivers/mfd/qcom-smd-rpm.c
> new file mode 100644
> index 0000000..d6faf85
> --- /dev/null
> +++ b/drivers/mfd/qcom-smd-rpm.c
> @@ -0,0 +1,236 @@
> +/*
> + * Copyright (c) 2015, Sony Mobile Communications AB.
> + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/of_platform.h>
> +#include <linux/io.h>
> +#include <linux/interrupt.h>
> +
> +#include <linux/soc/qcom/smd.h>
> +#include <linux/mfd/qcom-smd-rpm.h>
> +
> +#include <dt-bindings/mfd/qcom-smd-rpm.h>
> +
> +#define RPM_REQUEST_TIMEOUT (5 * HZ)
> +
> +/**
> + * struct qcom_smd_rpm - state of the rpm device driver
> + * @rpm_channel: reference to the smd channel
> + * @ack: completion for acks
> + * @lock: mutual exclusion around the send/complete pair
> + * @ack_status: result of the rpm request
> + */
> +struct qcom_smd_rpm {
> + struct qcom_smd_channel *rpm_channel;
> +
> + struct completion ack;
> + struct mutex lock;
> + int ack_status;
> +};
> +
> +/**
> + * struct qcom_rpm_header - header for all rpm requests and responses
> + * @service_type: identifier of the service
> + * @length: length of the payload
> + */
> +struct qcom_rpm_header {
> + u32 service_type;
> + u32 length;
> +};
> +
> +/**
> + * struct qcom_rpm_request - request message to the rpm
> + * @msg_id: identifier of the outgoing message
> + * @flags: active/sleep state flags
> + * @type: resource type
> + * @id: resource id
> + * @data_len: length of the payload following this header
> + */
> +struct qcom_rpm_request {
> + u32 msg_id;
> + u32 flags;
> + u32 type;
> + u32 id;
> + u32 data_len;
> +};
> +
> +/**
> + * struct qcom_rpm_message - response message from the rpm
> + * @msg_type: indicator of the type of message
> + * @length: the size of this message, including the message header
> + * @msg_id: message id
> + * @message: textual message from the rpm
> + *
> + * Multiple of these messages can be stacked in an rpm message.
> + */
> +struct qcom_rpm_message {
> + u32 msg_type;
> + u32 length;
> + union {
> + u32 msg_id;
> + u8 message[0];
> + };
> +};
> +
> +#define RPM_SERVICE_TYPE_REQUEST 0x00716572 /* "req\0" */
> +
> +#define RPM_MSG_TYPE_ERR 0x00727265 /* "err\0" */
> +#define RPM_MSG_TYPE_MSG_ID 0x2367736d /* "msg#" */
> +
> +/**
> + * qcom_rpm_smd_write - write @buf to @type:@id
> + * @rpm: rpm handle
> + * @type: resource type
> + * @id: resource identifier
> + * @buf: the data to be written
> + * @count: number of bytes in @buf
> + */
> +int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
> + int state,
> + u32 type, u32 id,
> + void *buf,
> + size_t count)
> +{
> + static unsigned msg_id = 1;
> + int left;
> + int ret;
> +
> + struct {
> + struct qcom_rpm_header hdr;
> + struct qcom_rpm_request req;
> + u8 payload[count];
> + } pkt;
> +
> + /* SMD packets to the RPM may not exceed 256 bytes */
> + if (WARN_ON(sizeof(pkt) >= 256))
> + return -EINVAL;
> +
> + mutex_lock(&rpm->lock);
> +
> + pkt.hdr.service_type = RPM_SERVICE_TYPE_REQUEST;
> + pkt.hdr.length = sizeof(struct qcom_rpm_request) + count;
> +
> + pkt.req.msg_id = msg_id++;
> + pkt.req.flags = BIT(state);
> + pkt.req.type = type;
> + pkt.req.id = id;
> + pkt.req.data_len = count;
> + memcpy(pkt.payload, buf, count);
> +
> + ret = qcom_smd_send(rpm->rpm_channel, &pkt, sizeof(pkt));
> + if (ret)
> + goto out;
> +
> + left = wait_for_completion_timeout(&rpm->ack, RPM_REQUEST_TIMEOUT);
> + if (!left)
> + ret = -ETIMEDOUT;
> + else
> + ret = rpm->ack_status;
> +
> +out:
> + mutex_unlock(&rpm->lock);
> + return ret;
> +}
> +EXPORT_SYMBOL(qcom_rpm_smd_write);
> +
> +#define RPM_ERR_INVALID_RESOURCE "resource does not exist"
I don't like this at all.
> +static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev,
> + const void *data,
> + size_t count)
> +{
> + const struct qcom_rpm_header *hdr = data;
> + const struct qcom_rpm_message *msg;
> + const size_t inv_res_len = sizeof(RPM_ERR_INVALID_RESOURCE) - 1;
> + struct qcom_smd_rpm *rpm = dev_get_drvdata(&qsdev->dev);
> + const u8 *buf = data + sizeof(struct qcom_rpm_header);
> + const u8 *end = buf + hdr->length;
> + int status = 0;
> +
> + if (hdr->service_type != RPM_SERVICE_TYPE_REQUEST ||
> + hdr->length < sizeof(struct qcom_rpm_message)) {
> + dev_err(&qsdev->dev, "invalid request\n");
> + return 0;
> + }
> +
> + while (buf < end) {
> + msg = (struct qcom_rpm_message *)buf;
> + switch (msg->msg_type) {
> + case RPM_MSG_TYPE_MSG_ID:
> + break;
> + case RPM_MSG_TYPE_ERR:
> + if (msg->length == inv_res_len &&
> + !memcmp(msg->message,
> + RPM_ERR_INVALID_RESOURCE,
> + inv_res_len))
strncpy(msg->message, "resource does not exist", 23);
> + status = -ENXIO;
> + else
> + status = -EIO;
> + break;
> + }
> +
> + buf = PTR_ALIGN(buf + 2 * sizeof(u32) + msg->length, 4);
> + }
> +
> + rpm->ack_status = status;
> + complete(&rpm->ack);
> + return 0;
> +}
> +
> +static int qcom_smd_rpm_probe(struct qcom_smd_device *sdev)
> +{
> + struct qcom_smd_rpm *rpm;
> +
> + rpm = devm_kzalloc(&sdev->dev, sizeof(*rpm), GFP_KERNEL);
> + if (!rpm)
> + return -ENOMEM;
> +
> + mutex_init(&rpm->lock);
> + init_completion(&rpm->ack);
> +
> + rpm->rpm_channel = sdev->channel;
> +
> + dev_set_drvdata(&sdev->dev, rpm);
> +
> + return of_platform_populate(sdev->dev.of_node, NULL, NULL, &sdev->dev);
> +}
> +
> +static void qcom_smd_rpm_remove(struct qcom_smd_device *sdev)
> +{
> + of_platform_depopulate(&sdev->dev);
> +}
> +
> +static const struct of_device_id qcom_smd_rpm_of_match[] = {
> + { .compatible = "qcom,rpm-msm8974" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, qcom_smd_rpm_of_match);
> +
> +static struct qcom_smd_driver qcom_smd_rpm_driver = {
> + .probe = qcom_smd_rpm_probe,
> + .remove = qcom_smd_rpm_remove,
> + .callback = qcom_smd_rpm_callback,
> + .driver = {
> + .name = "qcom_smd_rpm",
> + .owner = THIS_MODULE,
Remove this line.
> + .of_match_table = qcom_smd_rpm_of_match,
> + },
> +};
> +
> +module_qcom_smd_driver(qcom_smd_rpm_driver);
> +
> +MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");
> +MODULE_DESCRIPTION("Qualcomm SMD backed RPM driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/mfd/qcom-smd-rpm.h b/include/linux/mfd/qcom-smd-rpm.h
> new file mode 100644
> index 0000000..2a53dca
> --- /dev/null
> +++ b/include/linux/mfd/qcom-smd-rpm.h
> @@ -0,0 +1,35 @@
> +#ifndef __QCOM_SMD_RPM_H__
> +#define __QCOM_SMD_RPM_H__
> +
> +struct qcom_smd_rpm;
> +
> +#define QCOM_SMD_RPM_ACTIVE_STATE 0
> +#define QCOM_SMD_RPM_SLEEP_STATE 1
> +
> +/*
> + * Constants used for addressing resources in the RPM.
> + */
> +#define QCOM_SMD_RPM_BOOST 0x61747362
> +#define QCOM_SMD_RPM_BUS_CLK 0x316b6c63
> +#define QCOM_SMD_RPM_BUS_MASTER 0x73616d62
> +#define QCOM_SMD_RPM_BUS_SLAVE 0x766c7362
> +#define QCOM_SMD_RPM_CLK_BUF_A 0x616B6C63
> +#define QCOM_SMD_RPM_LDOA 0x616f646c
> +#define QCOM_SMD_RPM_LDOB 0x626F646C
> +#define QCOM_SMD_RPM_MEM_CLK 0x326b6c63
> +#define QCOM_SMD_RPM_MISC_CLK 0x306b6c63
> +#define QCOM_SMD_RPM_NCPA 0x6170636E
> +#define QCOM_SMD_RPM_NCPB 0x6270636E
> +#define QCOM_SMD_RPM_OCMEM_PWR 0x706d636f
> +#define QCOM_SMD_RPM_QPIC_CLK 0x63697071
> +#define QCOM_SMD_RPM_SMPA 0x61706d73
> +#define QCOM_SMD_RPM_SMPB 0x62706d73
> +#define QCOM_SMD_RPM_SPDM 0x63707362
> +#define QCOM_SMD_RPM_VSA 0x00617376
> +
> +int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
> + int state,
> + u32 resource_type, u32 resource_id,
> + void *buf, size_t count);
> +
> +#endif
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
next prev parent reply other threads:[~2015-07-07 12:37 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-26 21:50 [PATCH v2 00/11] Qualcomm Shared Memory & RPM drivers bjorn
2015-06-26 21:50 ` bjorn at kryo.se
[not found] ` <1435355419-23602-1-git-send-email-bjorn.andersson-/MT0OVThwyLZJqsBc5GL+g@public.gmane.org>
2015-06-26 21:50 ` [PATCH v2 01/11] soc: qcom: Add device tree binding for SMEM bjorn-UYDU3/A3LUY
2015-06-26 21:50 ` bjorn
2015-07-08 23:56 ` Stephen Boyd
2015-07-09 3:50 ` Andy Gross
[not found] ` <559DB8B2.2090202-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2015-07-13 22:30 ` Bjorn Andersson
2015-07-13 22:30 ` Bjorn Andersson
2015-07-23 20:49 ` Andy Gross
2015-06-26 21:50 ` [PATCH v2 02/11] soc: qcom: Add Shared Memory Manager driver bjorn
2015-07-17 21:15 ` Andy Gross
2015-07-23 20:47 ` Andy Gross
2015-06-26 21:50 ` [PATCH v2 03/11] soc: qcom: Add device tree binding for Shared Memory Device bjorn
2015-06-26 21:50 ` [PATCH v2 04/11] soc: qcom: Add Shared Memory Driver bjorn
2015-07-07 13:45 ` Georgi Djakov
2015-07-13 22:27 ` Bjorn Andersson
2015-07-13 22:27 ` Bjorn Andersson
2015-07-21 11:46 ` Georgi Djakov
2015-06-26 21:50 ` [PATCH v2 05/11] mfd: devicetree: bindings: Add Qualcomm SMD based RPM DT binding bjorn
2015-07-07 12:16 ` Lee Jones
2015-07-13 21:48 ` Bjorn Andersson
2015-07-13 21:48 ` Bjorn Andersson
2015-07-23 13:31 ` Lee Jones
2015-07-23 16:41 ` Bjorn Andersson
2015-07-23 16:41 ` Bjorn Andersson
[not found] ` <20150723164128.GD4753-P9SbAA3LsXe39TS3lRcy0mP6iJigPa5YXqFh9Ls21Oc@public.gmane.org>
2015-07-23 17:16 ` Mark Brown
2015-07-23 17:16 ` Mark Brown
2015-07-24 9:58 ` Lee Jones
2015-07-24 10:24 ` Mark Brown
2015-07-24 10:24 ` Mark Brown
[not found] ` <20150724102434.GF11162-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2015-07-24 17:23 ` Mark Brown
2015-07-24 17:23 ` Mark Brown
2015-07-27 7:29 ` Lee Jones
2015-07-27 7:29 ` Lee Jones
2015-07-27 9:53 ` Mark Brown
2015-07-27 10:58 ` Lee Jones
2015-06-26 21:50 ` [PATCH v2 06/11] mfd: qcom-smd-rpm: Driver for the Qualcomm RPM over SMD bjorn
2015-07-07 12:37 ` Lee Jones [this message]
2015-07-13 21:58 ` Bjorn Andersson
2015-07-13 21:58 ` Bjorn Andersson
2015-07-23 13:22 ` Lee Jones
2015-07-23 16:55 ` Bjorn Andersson
2015-07-24 10:06 ` Lee Jones
2015-06-26 21:50 ` [PATCH v2 07/11] regulator: qcom: smd: Regulator driver for the Qualcomm RPM bjorn
2015-06-26 21:50 ` [PATCH v2 08/11] ARM: dts: msm8974: Add tcsr mutex node bjorn
2015-06-26 21:50 ` bjorn
2015-06-26 21:50 ` bjorn at kryo.se
[not found] ` <1435355419-23602-9-git-send-email-bjorn.andersson-/MT0OVThwyLZJqsBc5GL+g@public.gmane.org>
2015-07-23 20:42 ` Andy Gross
2015-07-23 20:42 ` Andy Gross
2015-07-23 20:42 ` Andy Gross
2015-06-26 21:50 ` [PATCH v2 09/11] ARM: dts: msm8974: Add smem reservation and node bjorn
2015-06-26 21:50 ` bjorn
2015-06-26 21:50 ` bjorn at kryo.se
2015-07-23 20:51 ` Andy Gross
2015-07-23 20:51 ` Andy Gross
2015-06-26 21:50 ` [PATCH v2 10/11] ARM: dts: msm8974: Add smd, rpm and regulator nodes bjorn
2015-06-26 21:50 ` bjorn
2015-06-26 21:50 ` bjorn at kryo.se
2015-06-26 21:50 ` [PATCH v2 11/11] ARM: dts: xperia-honami: Add regulator nodes for Honami bjorn
2015-06-26 21:50 ` bjorn at kryo.se
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150707123716.GA3182@x1 \
--to=lee.jones@linaro.org \
--cc=agross@codeaurora.org \
--cc=bjorn@kryo.se \
--cc=broonie@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=sameo@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.