From: Vaibhav Hiremath <vaibhav.hiremath-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
To: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [RFC]: Supporting PIO mode of operation in i2c_msg->flags
Date: Tue, 16 Jun 2015 17:41:30 +0530 [thread overview]
Message-ID: <55801272.1040006@linaro.org> (raw)
In-Reply-To: <20150616091815.GA1595@katana>
On Tuesday 16 June 2015 02:48 PM, Wolfram Sang wrote:
>
>> Any update on this?
>
> Not yet.
>
> a) there was no code to look at
>
Actually its simple question, whether we can call i2c_transfer in
pm_power_off fn, where interupts are disabled and i2c_transfer fn may
sleep.
Just to illustrate my point,
I just quickly created something for you. Correct me if I am wrong here.
pm_power_off Usecase:
=====
File: arch/arm64/kernel/process.c
void machine_power_off(void)
{
local_irq_disable();
smp_send_stop();
if (pm_power_off)
pm_power_off();
}
Dummy pm_power_off Implementation:
=====
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 03b70f8..e364a2a 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -1170,7 +1170,10 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap,
struct i2c_msg msgs[], int num
i2c_pxa_enable(i2c, true);
for (i = adap->retries; i >= 0; i--) {
- ret = i2c_pxa_do_xfer(i2c, msgs, num);
+ if (msgs[0].flags & I2C_M_PIO)
+ ret = i2c_pxa_do_pio_xfer(i2c, msgs, num);
+ else
+ ret = i2c_pxa_do_xfer(i2c, msgs, num);
if (ret != I2C_RETRY)
goto out;
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index 0464e2d..2d7b11b 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -488,6 +488,52 @@ static void pm800_pages_exit(struct pm80x_chip *chip)
i2c_unregister_device(subchip->gpadc_page);
}
+static struct pm80x_chip *pm80x_chip_g;
+
+#define PM800_SW_PDOWN (1 << 5)
+
+static void pm800_power_off(void)
+{
+ u8 data, buf[2];
+ struct i2c_msg msgs[2];
+ struct i2c_client *client = pm80x_chip_g->client;
+
+ pr_info("turning off power....\n");
+
+ /*
+ * pm_power_off fn get called at the end of machine_power_off(),
+ * so at this stage the irqs are disabled, so we have to use
+ * PIO mode of I2C transaction for both read and write.
+ */
+ /* Read register first */
+ msgs[0].addr = client->addr;
+ msgs[0].flags = I2C_M_PIO;
+ msgs[0].len = 1;
+ msgs[0].buf = buf;
+
+ msgs[1].addr = client->addr;
+ msgs[1].flags = I2C_M_RD | I2C_M_PIO;
+ msgs[1].len = 1;
+ msgs[1].buf = &data;
+
+ buf[0] = PM800_WAKEUP1;
+ if ( __i2c_transfer(client->adapter, msgs, 2) < 0) {
+ pr_err("%s read register fails...\n", __func__);
+ WARN_ON(1);
+ }
+
+ /* issue SW power down */
+ msgs[0].addr = client->addr;
+ msgs[0].flags = I2C_M_PIO;
+ msgs[0].len = 2;
+ msgs[0].buf[0] = PM800_WAKEUP1;
+ msgs[0].buf[1] = data | PM800_SW_PDOWN;
+ if (__i2c_transfer(client->adapter, msgs, 1) < 0) {
+ pr_err("%s write data fails...\n", __func__);
+ WARN_ON(1);
+ }
+}
+
static int device_800_init(struct pm80x_chip *chip,
struct pm80x_platform_data *pdata)
{
@@ -612,6 +658,10 @@ static int pm800_probe(struct i2c_client *client,
if (pdata && pdata->plat_config)
pdata->plat_config(chip, pdata);
+ /* keep global copy, required in power_off fn */
+ pm80x_chip_g = chip;
+ pm_power_off = pm800_power_off;
+
return 0;
err_device_init:
diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h
index 0e949cb..22fda83 100644
--- a/include/uapi/linux/i2c.h
+++ b/include/uapi/linux/i2c.h
@@ -76,6 +76,7 @@ struct i2c_msg {
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK 0x0800 /* if
I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN 0x0400 /* length will be first
received byte */
+#define I2C_M_PIO 0x0200 /* pio mode of transaction */
__u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */
};
prev parent reply other threads:[~2015-06-16 12:11 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-25 9:47 [RFC]: Supporting PIO mode of operation in i2c_msg->flags Vaibhav Hiremath
[not found] ` <5562EF9D.1090403-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-05-28 13:55 ` Vaibhav Hiremath
2015-05-28 13:55 ` Vaibhav Hiremath
[not found] ` <55671E44.5000704-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-06-11 19:50 ` Vaibhav Hiremath
2015-06-11 19:50 ` Vaibhav Hiremath
2015-06-11 23:41 ` Wolfram Sang
2015-06-14 12:12 ` Vaibhav Hiremath
[not found] ` <557D6FAF.1050408-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-06-16 8:56 ` Vaibhav Hiremath
[not found] ` <557FE4A9.5030004-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-06-16 9:18 ` Wolfram Sang
2015-06-16 12:11 ` Vaibhav Hiremath [this message]
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=55801272.1040006@linaro.org \
--to=vaibhav.hiremath-qsej5fyqhm4dnm+yrofe0a@public.gmane.org \
--cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.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 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.