linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Josh Cartwright <joshc@codeaurora.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Alessandro Zummo <a.zummo@towertech.it>,
	David Brown <davidb@codeaurora.org>,
	Daniel Walker <dwalker@fifo99.com>,
	Bryan Huntsman <bryanh@codeaurora.org>
Cc: linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-arm-msm@vger.kernel.org, rtc-linux@googlegroups.com,
	Sagar Dharia <sdharia@codeaurora.org>,
	Gilad Avidov <gavidov@codeaurora.org>,
	Michael Bohan <mbohan@codeaurora.org>
Subject: [PATCH v3 10/10] rtc: pm8xxx: add support for pm8941
Date: Mon, 28 Oct 2013 13:12:35 -0500	[thread overview]
Message-ID: <1392ea90487793f9cbbdfb7f8d148f45122a52c2.1382985169.git.joshc@codeaurora.org> (raw)
In-Reply-To: <cover.1382985169.git.joshc@codeaurora.org>

Adapt the existing pm8xxx driver to work with the RTC available on
Qualcomm's 8941 PMIC.  In order to do this, rework the register access
functions to use a regmap provided by the parent driver.  Account for
slight differences in the RTC address space by parameterizing addresses
and providing a chip-specific initialization function.

Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
---
 drivers/rtc/Kconfig      |   1 -
 drivers/rtc/rtc-pm8xxx.c | 229 +++++++++++++++++++++++++++++------------------
 2 files changed, 143 insertions(+), 87 deletions(-)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 9654aa3..19b89ee 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1177,7 +1177,6 @@ config RTC_DRV_LPC32XX
 
 config RTC_DRV_PM8XXX
 	tristate "Qualcomm PMIC8XXX RTC"
-	depends on MFD_PM8XXX
 	help
 	  If you say yes here you get support for the
 	  Qualcomm PMIC8XXX RTC.
diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c
index 03f8f75..a9044d4 100644
--- a/drivers/rtc/rtc-pm8xxx.c
+++ b/drivers/rtc/rtc-pm8xxx.c
@@ -1,4 +1,5 @@
 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 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
@@ -13,35 +14,33 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/rtc.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/pm.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
 #include <linux/mfd/pm8xxx/core.h>
 #include <linux/mfd/pm8xxx/rtc.h>
 
-
-/* RTC Register offsets from RTC CTRL REG */
-#define PM8XXX_ALARM_CTRL_OFFSET	0x01
-#define PM8XXX_RTC_WRITE_OFFSET		0x02
-#define PM8XXX_RTC_READ_OFFSET		0x06
-#define PM8XXX_ALARM_RW_OFFSET		0x0A
-
 /* RTC_CTRL register bit fields */
 #define PM8xxx_RTC_ENABLE		BIT(7)
 #define PM8xxx_RTC_ALARM_ENABLE		BIT(1)
 #define PM8xxx_RTC_ALARM_CLEAR		BIT(0)
 
 #define NUM_8_BIT_RTC_REGS		0x4
-
 /**
  * struct pm8xxx_rtc -  rtc driver internal structure
  * @rtc:		rtc device for this driver.
  * @rtc_alarm_irq:	rtc alarm irq number.
- * @rtc_base:		address of rtc control register.
+ * @rtc_control_reg:	address of control register.
  * @rtc_read_base:	base address of read registers.
  * @rtc_write_base:	base address of write registers.
  * @alarm_rw_base:	base address of alarm registers.
+ * @alarm_ctrl1:	address of alarm ctrl1 register.
+ * @alarm_ctrl2:	address of alarm ctrl2 register (only used on pm8941).
+ * @alarm_clear:	RTC-specific callback to clear alarm interrupt.
  * @ctrl_reg:		rtc control register.
  * @rtc_dev:		device structure.
  * @ctrl_reg_lock:	spinlock protecting access to ctrl_reg.
@@ -49,51 +48,34 @@
 struct pm8xxx_rtc {
 	struct rtc_device *rtc;
 	int rtc_alarm_irq;
-	int rtc_base;
+	int rtc_control_reg;
 	int rtc_read_base;
 	int rtc_write_base;
 	int alarm_rw_base;
-	u8  ctrl_reg;
+	int alarm_ctrl1;
+	int alarm_ctrl2;
+	int (*alarm_clear)(struct pm8xxx_rtc *);
+	u8 ctrl_reg;
 	struct device *rtc_dev;
 	spinlock_t ctrl_reg_lock;
+	struct regmap *regmap;
 };
 
 /*
  * The RTC registers need to be read/written one byte at a time. This is a
  * hardware limitation.
  */
-static int pm8xxx_read_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val,
-		int base, int count)
+static inline int pm8xxx_read_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val,
+				      int base, int count)
 {
-	int i, rc;
-	struct device *parent = rtc_dd->rtc_dev->parent;
-
-	for (i = 0; i < count; i++) {
-		rc = pm8xxx_readb(parent, base + i, &rtc_val[i]);
-		if (rc < 0) {
-			dev_err(rtc_dd->rtc_dev, "PMIC read failed\n");
-			return rc;
-		}
-	}
-
-	return 0;
+	return regmap_bulk_read(rtc_dd->regmap, base, rtc_val, count);
 }
 
-static int pm8xxx_write_wrapper(struct pm8xxx_rtc *rtc_dd, u8 *rtc_val,
-		int base, int count)
+static inline int pm8xxx_write_wrapper(struct pm8xxx_rtc *rtc_dd,
+				       const u8 *rtc_val,
+				       int base, int count)
 {
-	int i, rc;
-	struct device *parent = rtc_dd->rtc_dev->parent;
-
-	for (i = 0; i < count; i++) {
-		rc = pm8xxx_writeb(parent, base + i, rtc_val[i]);
-		if (rc < 0) {
-			dev_err(rtc_dd->rtc_dev, "PMIC write failed\n");
-			return rc;
-		}
-	}
-
-	return 0;
+	return regmap_bulk_write(rtc_dd->regmap, base, rtc_val, count);
 }
 
 /*
@@ -125,8 +107,8 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
 	if (ctrl_reg & PM8xxx_RTC_ALARM_ENABLE) {
 		alarm_enabled = 1;
 		ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE;
-		rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base,
-				1);
+		rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg,
+					  rtc_dd->rtc_control_reg, 1);
 		if (rc < 0) {
 			dev_err(dev, "Write to RTC control register "
 								"failed\n");
@@ -161,8 +143,8 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm)
 
 	if (alarm_enabled) {
 		ctrl_reg |= PM8xxx_RTC_ALARM_ENABLE;
-		rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base,
-									1);
+		rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg,
+					  rtc_dd->rtc_control_reg, 1);
 		if (rc < 0) {
 			dev_err(dev, "Write to RTC control register "
 								"failed\n");
@@ -255,7 +237,8 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	ctrl_reg = alarm->enabled ? (ctrl_reg | PM8xxx_RTC_ALARM_ENABLE) :
 					(ctrl_reg & ~PM8xxx_RTC_ALARM_ENABLE);
 
-	rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
+	rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg,
+				  rtc_dd->rtc_control_reg, 1);
 	if (rc < 0) {
 		dev_err(dev, "Write to RTC control register failed\n");
 		goto rtc_rw_fail;
@@ -316,7 +299,8 @@ static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
 	ctrl_reg = (enable) ? (ctrl_reg | PM8xxx_RTC_ALARM_ENABLE) :
 				(ctrl_reg & ~PM8xxx_RTC_ALARM_ENABLE);
 
-	rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
+	rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg,
+				  rtc_dd->rtc_control_reg, 1);
 	if (rc < 0) {
 		dev_err(dev, "Write to RTC control register failed\n");
 		goto rtc_rw_fail;
@@ -351,7 +335,8 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id)
 	ctrl_reg = rtc_dd->ctrl_reg;
 	ctrl_reg &= ~PM8xxx_RTC_ALARM_ENABLE;
 
-	rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
+	rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg,
+				  rtc_dd->rtc_control_reg, 1);
 	if (rc < 0) {
 		spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
 		dev_err(rtc_dd->rtc_dev, "Write to RTC control register "
@@ -363,37 +348,105 @@ static irqreturn_t pm8xxx_alarm_trigger(int irq, void *dev_id)
 	spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags);
 
 	/* Clear RTC alarm register */
-	rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base +
-						PM8XXX_ALARM_CTRL_OFFSET, 1);
+	rc = rtc_dd->alarm_clear(rtc_dd);
+	if (rc < 0)
+		dev_err(rtc_dd->rtc_dev, "failed to clear RTC alarm\n");
+
+rtc_alarm_handled:
+	return IRQ_HANDLED;
+}
+
+static int pm8941_alarm_clear(struct pm8xxx_rtc *rtc_dd)
+{
+	u8 ctrl = PM8xxx_RTC_ALARM_CLEAR;
+	return pm8xxx_write_wrapper(rtc_dd, &ctrl, rtc_dd->alarm_ctrl2, 1);
+}
+
+static int pm8941_chip_init(struct platform_device *pdev,
+			    struct pm8xxx_rtc *rtc)
+{
+	u32 addr[2];
+	int err;
+
+	err = of_property_read_u32_array(pdev->dev.of_node,
+					 "reg", addr, 2);
+	if (err || addr[0] > 0xFFFF || addr[1] > 0xFFFF) {
+		dev_err(&pdev->dev, "RTC IO resources absent or invalid\n");
+		return err;
+	}
+
+	rtc->alarm_clear = pm8941_alarm_clear;
+
+	rtc->rtc_control_reg = addr[0] + 0x46;
+	rtc->rtc_write_base  = addr[0] + 0x40;
+	rtc->rtc_read_base   = addr[0] + 0x48;
+	rtc->alarm_rw_base   = addr[1] + 0x40;
+	rtc->alarm_ctrl1     = addr[1] + 0x46;
+	rtc->alarm_ctrl2     = addr[1] + 0x48;
+	return 0;
+}
+
+static int pm8xxx_alarm_clear(struct pm8xxx_rtc *rtc_dd)
+{
+	u8 ctrl_reg;
+	int rc;
+
+	rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->alarm_ctrl1, 1);
 	if (rc < 0) {
 		dev_err(rtc_dd->rtc_dev, "RTC Alarm control register read "
 								"failed\n");
-		goto rtc_alarm_handled;
+		return rc;
 	}
 
 	ctrl_reg &= ~PM8xxx_RTC_ALARM_CLEAR;
-	rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base +
-						PM8XXX_ALARM_CTRL_OFFSET, 1);
-	if (rc < 0)
-		dev_err(rtc_dd->rtc_dev, "Write to RTC Alarm control register"
-								" failed\n");
+	return pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->alarm_ctrl1, 1);
+}
 
-rtc_alarm_handled:
-	return IRQ_HANDLED;
+static int pm8xxx_chip_init(struct platform_device *pdev,
+			    struct pm8xxx_rtc *rtc)
+{
+	const struct pm8xxx_rtc_platform_data *pdata =
+				dev_get_platdata(&pdev->dev);
+	struct resource *res;
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "Platform data not initialized.\n");
+		return -ENXIO;
+	}
+
+	if (pdata->rtc_write_enable)
+		pm8xxx_rtc_ops.set_time = pm8xxx_rtc_set_time;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_IO,
+					   "pmic_rtc_base");
+	if (!res) {
+		dev_err(&pdev->dev, "RTC IO resource absent\n");
+		return -ENXIO;
+	}
+
+	rtc->rtc_control_reg = res->start;
+	rtc->rtc_write_base  = res->start + 0x02;
+	rtc->rtc_read_base   = res->start + 0x06;
+	rtc->alarm_rw_base   = res->start + 0x0A;
+	rtc->alarm_ctrl1     = res->start + 0x01;
+
+	rtc->alarm_clear = pm8xxx_alarm_clear;
+	return 0;
 }
 
+static const struct of_device_id pm8xxx_rtc_idtable[] = {
+	{ .compatible = "qcom,pm8941-rtc", pm8941_chip_init },
+	{},
+};
+MODULE_DEVICE_TABLE(of, pm8xxx_rtc_idtable);
+
 static int pm8xxx_rtc_probe(struct platform_device *pdev)
 {
-	int rc;
-	u8 ctrl_reg;
-	bool rtc_write_enable = false;
+	int (*chip_init)(struct platform_device *pdev, struct pm8xxx_rtc *rtc);
+	const struct device_node *node = pdev->dev.of_node;
 	struct pm8xxx_rtc *rtc_dd;
-	struct resource *rtc_resource;
-	const struct pm8xxx_rtc_platform_data *pdata =
-						dev_get_platdata(&pdev->dev);
-
-	if (pdata != NULL)
-		rtc_write_enable = pdata->rtc_write_enable;
+	u8 ctrl_reg;
+	int rc;
 
 	rtc_dd = devm_kzalloc(&pdev->dev, sizeof(*rtc_dd), GFP_KERNEL);
 	if (rtc_dd == NULL) {
@@ -401,33 +454,40 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	/* Initialise spinlock to protect RTC control register */
-	spin_lock_init(&rtc_dd->ctrl_reg_lock);
+	chip_init = pm8xxx_chip_init;
+	if (node) {
+		const
+		struct of_device_id *id = of_match_node(pm8xxx_rtc_idtable,
+							pdev->dev.of_node);
+		if (id && id->data)
+			chip_init = id->data;
+	}
 
-	rtc_dd->rtc_alarm_irq = platform_get_irq(pdev, 0);
-	if (rtc_dd->rtc_alarm_irq < 0) {
-		dev_err(&pdev->dev, "Alarm IRQ resource absent!\n");
+	rc = chip_init(pdev, rtc_dd);
+	if (rc) {
+		dev_err(&pdev->dev, "Failed to initialize chip.\n");
 		return -ENXIO;
 	}
 
-	rtc_resource = platform_get_resource_byname(pdev, IORESOURCE_IO,
-							"pmic_rtc_base");
-	if (!(rtc_resource && rtc_resource->start)) {
-		dev_err(&pdev->dev, "RTC IO resource absent!\n");
+	rtc_dd->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!rtc_dd->regmap) {
+		dev_err(&pdev->dev, "Unable to get regmap.\n");
 		return -ENXIO;
 	}
 
-	rtc_dd->rtc_base = rtc_resource->start;
+	/* Initialise spinlock to protect RTC control register */
+	spin_lock_init(&rtc_dd->ctrl_reg_lock);
 
-	/* Setup RTC register addresses */
-	rtc_dd->rtc_write_base = rtc_dd->rtc_base + PM8XXX_RTC_WRITE_OFFSET;
-	rtc_dd->rtc_read_base = rtc_dd->rtc_base + PM8XXX_RTC_READ_OFFSET;
-	rtc_dd->alarm_rw_base = rtc_dd->rtc_base + PM8XXX_ALARM_RW_OFFSET;
+	rtc_dd->rtc_alarm_irq = platform_get_irq(pdev, 0);
+	if (rtc_dd->rtc_alarm_irq < 0) {
+		dev_err(&pdev->dev, "Alarm IRQ resource absent!\n");
+		return -ENXIO;
+	}
 
 	rtc_dd->rtc_dev = &pdev->dev;
 
 	/* Check if the RTC is on, else turn it on */
-	rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base, 1);
+	rc = pm8xxx_read_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_control_reg, 1);
 	if (rc < 0) {
 		dev_err(&pdev->dev, "RTC control register read failed!\n");
 		return rc;
@@ -435,8 +495,8 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
 
 	if (!(ctrl_reg & PM8xxx_RTC_ENABLE)) {
 		ctrl_reg |= PM8xxx_RTC_ENABLE;
-		rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg, rtc_dd->rtc_base,
-									1);
+		rc = pm8xxx_write_wrapper(rtc_dd, &ctrl_reg,
+					  rtc_dd->rtc_control_reg, 1);
 		if (rc < 0) {
 			dev_err(&pdev->dev, "Write to RTC control register "
 								"failed\n");
@@ -444,10 +504,6 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev)
 		}
 	}
 
-	rtc_dd->ctrl_reg = ctrl_reg;
-	if (rtc_write_enable == true)
-		pm8xxx_rtc_ops.set_time = pm8xxx_rtc_set_time;
-
 	platform_set_drvdata(pdev, rtc_dd);
 
 	/* Register the RTC device */
@@ -516,6 +572,7 @@ static struct platform_driver pm8xxx_rtc_driver = {
 		.name	= PM8XXX_RTC_DEV_NAME,
 		.owner	= THIS_MODULE,
 		.pm	= &pm8xxx_rtc_pm_ops,
+		.of_match_table	= pm8xxx_rtc_idtable,
 	},
 };
 
-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

  parent reply	other threads:[~2013-10-28 18:12 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-28 18:32 [PATCH v3 00/10] Add support for the System Power Management Interface (SPMI) Josh Cartwright
2013-10-28 18:12 ` [PATCH v3 04/10] spmi: Add MSM PMIC Arbiter SPMI controller Josh Cartwright
2013-10-30 18:05   ` Stephen Boyd
2013-10-30 19:17     ` Josh Cartwright
2013-10-28 18:12 ` Josh Cartwright [this message]
2013-10-29 20:09   ` [PATCH v3 10/10] rtc: pm8xxx: add support for pm8941 Stephen Boyd
2013-10-29 20:15     ` Greg Kroah-Hartman
2013-10-29 20:20       ` Stephen Boyd
2013-10-29 20:32         ` Greg Kroah-Hartman
2013-10-28 18:12 ` [PATCH v3 07/10] regmap: add SPMI support Josh Cartwright
2013-10-28 20:01   ` Mark Brown
2013-10-28 18:12 ` [PATCH v3 05/10] spmi: pmic_arb: add support for interrupt handling Josh Cartwright
2013-10-30 18:17   ` Stephen Boyd
2013-10-30 19:10     ` Josh Cartwright
2013-10-28 18:12 ` [PATCH v3 02/10] spmi: Linux driver framework for SPMI Josh Cartwright
2013-10-29 15:02   ` Ivan T. Ivanov
2013-10-29 16:26     ` Josh Cartwright
2013-10-29 18:00       ` Ivan T. Ivanov
2013-10-29 15:21   ` Lars-Peter Clausen
2013-10-29 15:56     ` Josh Cartwright
2013-10-29 16:30       ` Stephen Boyd
2013-10-29 19:18         ` Lars-Peter Clausen
2013-10-29 19:26       ` Lars-Peter Clausen
2013-10-29 16:52   ` Stephen Boyd
2013-10-30 19:37     ` Josh Cartwright
2013-10-30 19:45       ` Stephen Boyd
2013-10-30  0:11   ` Russell King - ARM Linux
2013-10-28 18:12 ` [PATCH v3 01/10] of: Add empty for_each_available_child_of_node() macro definition Josh Cartwright
2013-10-29  5:50   ` Rob Herring
2013-10-28 18:12 ` [PATCH v3 03/10] spmi: add generic SPMI controller binding documentation Josh Cartwright
2013-10-28 18:12 ` [PATCH v3 06/10] spmi: document the PMIC arbiter SPMI bindings Josh Cartwright
2013-10-29 14:08   ` Ivan T. Ivanov
2013-10-29 15:12     ` Josh Cartwright
2013-10-28 18:12 ` [PATCH v3 08/10] mfd: pm8x41: add support for Qualcomm 8x41 PMICs Josh Cartwright
2013-10-29  0:40   ` Stephen Boyd
2013-10-29 15:56   ` Lee Jones
2013-10-29 16:03     ` Josh Cartwright
2013-10-28 18:12 ` [PATCH v3 09/10] mfd: pm8x41: document device tree bindings Josh Cartwright
2013-10-29 14:18   ` Ivan T. Ivanov
2013-10-29 15:05     ` Josh Cartwright
2013-10-29 15:31       ` Ivan T. Ivanov

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=1392ea90487793f9cbbdfb7f8d148f45122a52c2.1382985169.git.joshc@codeaurora.org \
    --to=joshc@codeaurora.org \
    --cc=a.zummo@towertech.it \
    --cc=bryanh@codeaurora.org \
    --cc=davidb@codeaurora.org \
    --cc=dwalker@fifo99.com \
    --cc=gavidov@codeaurora.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mbohan@codeaurora.org \
    --cc=rtc-linux@googlegroups.com \
    --cc=sdharia@codeaurora.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).