[parent not found: <1420824103-24169-1-git-send-email-wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>]
* [RFC 01/11] i2c: add quirk structure to describe adapter flaws
[not found] ` <1420824103-24169-1-git-send-email-wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
@ 2015-01-09 17:21 ` Wolfram Sang
2015-01-16 5:50 ` Eddie Huang
2015-01-16 8:18 ` Yingjoe Chen
0 siblings, 2 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c-u79uwXL29TY76Z2rM5mHXA
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-mips-6z/3iImG2C8G8FEW9MqTrA, Benjamin Herrenschmidt,
Ludovic Desroches, Yingjoe Chen, Wolfram Sang,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
The number of I2C adapters which are not fully I2C compatible is rising,
sadly. Drivers usually do handle the flaws, still the user receives only
some errno for a transfer which normally can be expected to work. This
patch introduces a formal description of flaws. One advantage is that
the core can check before the actual transfer if the messages could be
transferred at all. This is done in the next patch. Another advantage is
that we can pass this information to the user so the restrictions are
exactly known and further actions can be based on that. This will be
done later after some stabilization period for this description.
Signed-off-by: Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
---
include/linux/i2c.h | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index e3a1721c8354..f8a642713706 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -447,6 +447,40 @@ int i2c_recover_bus(struct i2c_adapter *adap);
int i2c_generic_gpio_recovery(struct i2c_adapter *adap);
int i2c_generic_scl_recovery(struct i2c_adapter *adap);
+/**
+ * struct i2c_adapter_quirks - describe flaws of an i2c adapter
+ * @flags: see I2C_ADAPTER_QUIRK_* for possible flags
+ * @max_num_msgs: maximum number of messages per transfer
+ * @max_write_len: maximum length of a write message
+ * @max_read_len: maximum length of a read message
+ * @max_comb_write_len: maximum length of a write in a combined message
+ * @max_comb_read_len: maximum length of a read in a combined message
+ *
+ * Note about combined messages: Some I2C controllers can only send one
+ * message per transfer, plus something called combined message or
+ * write-then-read. This is a (usually) small write message followed by
+ * a read message and barely enough to access register based slaves like
+ * EEPROMs. There is a flag to support this mode. It implies max_num_msg = 2
+ * and does the length checks with max_comb_*_len because combined message mode
+ * usually has its own limitations. Read/write flags of the messages are also
+ * checked to be proper. Because of HW implementation, some controllers can
+ * actually do write-then-anything. To support that, write-then-read has been
+ * broken out into write-first and read-second.
+ */
+struct i2c_adapter_quirks {
+ u64 flags;
+ int max_num_msgs;
+ u16 max_write_len;
+ u16 max_read_len;
+ u16 max_comb_write_len;
+ u16 max_comb_read_len;
+};
+
+#define I2C_ADAPTER_QUIRK_COMB_WRITE_FIRST BIT(0)
+#define I2C_ADAPTER_QUIRK_COMB_READ_SECOND BIT(1)
+#define I2C_ADAPTER_QUIRK_COMB_WRITE_THEN_READ (I2C_ADAPTER_QUIRK_COMB_WRITE_FIRST | \
+ I2C_ADAPTER_QUIRK_COMB_READ_SECOND)
+
/*
* i2c_adapter is the structure used to identify a physical i2c bus along
* with the access algorithms necessary to access it.
@@ -472,6 +506,7 @@ struct i2c_adapter {
struct list_head userspace_clients;
struct i2c_bus_recovery_info *bus_recovery_info;
+ struct i2c_adapter_quirks *quirks;
};
#define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [RFC 01/11] i2c: add quirk structure to describe adapter flaws
2015-01-09 17:21 ` [RFC 01/11] i2c: add quirk structure to describe adapter flaws Wolfram Sang
@ 2015-01-16 5:50 ` Eddie Huang
2015-01-19 15:05 ` Wolfram Sang
2015-01-16 8:18 ` Yingjoe Chen
1 sibling, 1 reply; 26+ messages in thread
From: Eddie Huang @ 2015-01-16 5:50 UTC (permalink / raw)
To: Wolfram Sang
Cc: linux-i2c, linux-mips, Benjamin Herrenschmidt, linux-kernel,
Ludovic Desroches, Yingjoe Chen, linuxppc-dev, linux-arm-kernel
Hi Wolfram,
On Fri, 2015-01-09 at 18:21 +0100, Wolfram Sang wrote:
>
> + */
> +struct i2c_adapter_quirks {
> + u64 flags;
> + int max_num_msgs;
> + u16 max_write_len;
> + u16 max_read_len;
> + u16 max_comb_write_len;
> + u16 max_comb_read_len;
> +};
> +
> +#define I2C_ADAPTER_QUIRK_COMB_WRITE_FIRST BIT(0)
> +#define I2C_ADAPTER_QUIRK_COMB_READ_SECOND BIT(1)
> +#define I2C_ADAPTER_QUIRK_COMB_WRITE_THEN_READ (I2C_ADAPTER_QUIRK_COMB_WRITE_FIRST | \
> + I2C_ADAPTER_QUIRK_COMB_READ_SECOND)
> +
> /*
> * i2c_adapter is the structure used to identify a physical i2c bus along
> * with the access algorithms necessary to access it.
> @@ -472,6 +506,7 @@ struct i2c_adapter {
> struct list_head userspace_clients;
>
> struct i2c_bus_recovery_info *bus_recovery_info;
> + struct i2c_adapter_quirks *quirks;
> };
> #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
>
I suggest to add const.
const struct i2c_adapter_quirks *quirks;
also, in i2c-core.c, should modify:
const struct i2c_adapter_quirks *q = adap->quirks;
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [RFC 01/11] i2c: add quirk structure to describe adapter flaws
2015-01-16 5:50 ` Eddie Huang
@ 2015-01-19 15:05 ` Wolfram Sang
2015-02-24 16:04 ` Wolfram Sang
0 siblings, 1 reply; 26+ messages in thread
From: Wolfram Sang @ 2015-01-19 15:05 UTC (permalink / raw)
To: Eddie Huang
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-mips-6z/3iImG2C8G8FEW9MqTrA, Benjamin Herrenschmidt,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Ludovic Desroches,
Yingjoe Chen, linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
[-- Attachment #1: Type: text/plain, Size: 341 bytes --]
> > + struct i2c_adapter_quirks *quirks;
> > };
> > #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
> >
>
> I suggest to add const.
> const struct i2c_adapter_quirks *quirks;
>
> also, in i2c-core.c, should modify:
> const struct i2c_adapter_quirks *q = adap->quirks;
Thanks, I'll think about it.
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [RFC 01/11] i2c: add quirk structure to describe adapter flaws
2015-01-19 15:05 ` Wolfram Sang
@ 2015-02-24 16:04 ` Wolfram Sang
0 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-02-24 16:04 UTC (permalink / raw)
To: Eddie Huang
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-mips-6z/3iImG2C8G8FEW9MqTrA, Benjamin Herrenschmidt,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Ludovic Desroches,
Yingjoe Chen, linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
[-- Attachment #1: Type: text/plain, Size: 449 bytes --]
On Mon, Jan 19, 2015 at 04:05:15PM +0100, Wolfram Sang wrote:
>
> > > + struct i2c_adapter_quirks *quirks;
> > > };
> > > #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)
> > >
> >
> > I suggest to add const.
> > const struct i2c_adapter_quirks *quirks;
> >
> > also, in i2c-core.c, should modify:
> > const struct i2c_adapter_quirks *q = adap->quirks;
>
> Thanks, I'll think about it.
And added it...
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [RFC 01/11] i2c: add quirk structure to describe adapter flaws
2015-01-09 17:21 ` [RFC 01/11] i2c: add quirk structure to describe adapter flaws Wolfram Sang
2015-01-16 5:50 ` Eddie Huang
@ 2015-01-16 8:18 ` Yingjoe Chen
2015-01-19 15:00 ` Wolfram Sang
1 sibling, 1 reply; 26+ messages in thread
From: Yingjoe Chen @ 2015-01-16 8:18 UTC (permalink / raw)
To: Wolfram Sang
Cc: linux-i2c, linux-mips, Benjamin Herrenschmidt, linux-kernel,
Ludovic Desroches, linuxppc-dev, linux-arm-kernel, Eddie Huang,
Xudong Chen, Liguo Zhang
On Fri, 2015-01-09 at 18:21 +0100, Wolfram Sang wrote:
> The number of I2C adapters which are not fully I2C compatible is rising,
> sadly. Drivers usually do handle the flaws, still the user receives only
> some errno for a transfer which normally can be expected to work. This
> patch introduces a formal description of flaws. One advantage is that
> the core can check before the actual transfer if the messages could be
> transferred at all. This is done in the next patch. Another advantage is
> that we can pass this information to the user so the restrictions are
> exactly known and further actions can be based on that. This will be
> done later after some stabilization period for this description.
Hi Wolfram,
This can describe the behavior of our current upstream driver[1], which
only support combine write-then-read.
After checking with Xudong & HW guys, it seems our HW can do more.
On MT8135, it can support at most 2 messages, no matter read or write,
with the limitation that the length of the second message must <=
31bytes.
So this RFC is enough for our driver, but it would be better if we could
also support other case.
Joe.C
[1]:
http://lists.infradead.org/pipermail/linux-arm-kernel/2014-November/305468.html
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [RFC 01/11] i2c: add quirk structure to describe adapter flaws
2015-01-16 8:18 ` Yingjoe Chen
@ 2015-01-19 15:00 ` Wolfram Sang
0 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-19 15:00 UTC (permalink / raw)
To: Yingjoe Chen
Cc: linux-i2c, linux-mips, Benjamin Herrenschmidt, linux-kernel,
Ludovic Desroches, linuxppc-dev, linux-arm-kernel, Eddie Huang,
Xudong Chen, Liguo Zhang
[-- Attachment #1: Type: text/plain, Size: 645 bytes --]
Hi,
> This can describe the behavior of our current upstream driver[1], which
> only support combine write-then-read.
>
> After checking with Xudong & HW guys, it seems our HW can do more.
> On MT8135, it can support at most 2 messages, no matter read or write,
> with the limitation that the length of the second message must <=
> 31bytes.
>
> So this RFC is enough for our driver, but it would be better if we could
> also support other case.
Hmm, I think we can convert max_comb_{read|write}_len to
max_comb_{1st|2nd}_msg_len or similar.
I'll check but it will probably not before next week.
Thanks for the input!
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 26+ messages in thread
* [RFC 02/11] i2c: add quirk checks to core
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
[not found] ` <1420824103-24169-1-git-send-email-wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
@ 2015-01-09 17:21 ` Wolfram Sang
[not found] ` <1420824103-24169-3-git-send-email-wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
2015-01-09 17:21 ` [RFC 03/11] i2c: at91: make use of the new infrastructure for quirks Wolfram Sang
` (8 subsequent siblings)
10 siblings, 1 reply; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-mips, Wolfram Sang, Benjamin Herrenschmidt, linux-kernel,
Ludovic Desroches, Yingjoe Chen, linuxppc-dev, linux-arm-kernel
Let the core do the checks if HW quirks prevent a transfer. Saves code
from drivers and adds consistency.
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/i2c-core.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 39d25a8cb1ad..7b10a19abf5b 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -2063,6 +2063,56 @@ module_exit(i2c_exit);
* ----------------------------------------------------
*/
+/* Check if val is exceeding the quirk IFF quirk is non 0 */
+#define i2c_quirk_exceeded(val, quirk) ((quirk) && ((val) > (quirk)))
+
+static int i2c_quirk_error(struct i2c_adapter *adap, struct i2c_msg *msg, char *err_msg)
+{
+ dev_err(&adap->dev, "quirk: %s (addr 0x%04x, size %u)\n", err_msg, msg->addr, msg->len);
+ return -EOPNOTSUPP;
+}
+
+static int i2c_check_for_quirks(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+ struct i2c_adapter_quirks *q = adap->quirks;
+ u16 max_read = q->max_read_len, max_write = q->max_write_len;
+ int max_num = q->max_num_msgs, i;
+
+ if (q->flags & I2C_ADAPTER_QUIRK_COMB_WRITE_THEN_READ)
+ max_num = 2;
+
+ if (i2c_quirk_exceeded(num, max_num))
+ return i2c_quirk_error(adap, &msgs[0], "too many messages");
+
+ if (num == 2 && q->flags & I2C_ADAPTER_QUIRK_COMB_WRITE_FIRST) {
+ if (msgs[0].flags & I2C_M_RD)
+ return i2c_quirk_error(adap, &msgs[0], "invalid first write msg");
+
+ max_write = q->max_comb_write_len;
+ }
+
+ if (num == 2 && q->flags & I2C_ADAPTER_QUIRK_COMB_READ_SECOND) {
+ if (!(msgs[1].flags & I2C_M_RD) || msgs[0].addr != msgs[1].addr)
+ return i2c_quirk_error(adap, &msgs[1], "invalid second read msg");
+
+ max_read = q->max_comb_read_len;
+ }
+
+ for (i = 0; i < num; i++) {
+ u16 len = msgs[i].len;
+
+ if (msgs[i].flags & I2C_M_RD) {
+ if (i2c_quirk_exceeded(len, max_read))
+ return i2c_quirk_error(adap, &msgs[i], "msg too long");
+ } else {
+ if (i2c_quirk_exceeded(len, max_write))
+ return i2c_quirk_error(adap, &msgs[i], "msg too long");
+ }
+ }
+
+ return 0;
+}
+
/**
* __i2c_transfer - unlocked flavor of i2c_transfer
* @adap: Handle to I2C bus
@@ -2080,6 +2130,9 @@ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
unsigned long orig_jiffies;
int ret, try;
+ if (adap->quirks && i2c_check_for_quirks(adap, msgs, num))
+ return -EOPNOTSUPP;
+
/* i2c_trace_msg gets enabled when tracepoint i2c_transfer gets
* enabled. This is an efficient way of keeping the for-loop from
* being executed when not needed.
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [RFC 03/11] i2c: at91: make use of the new infrastructure for quirks
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
[not found] ` <1420824103-24169-1-git-send-email-wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>
2015-01-09 17:21 ` [RFC 02/11] i2c: add quirk checks to core Wolfram Sang
@ 2015-01-09 17:21 ` Wolfram Sang
2015-01-09 17:21 ` [RFC 04/11] i2c: opal: " Wolfram Sang
` (7 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-mips, Wolfram Sang, Benjamin Herrenschmidt, linux-kernel,
Ludovic Desroches, Yingjoe Chen, linuxppc-dev, linux-arm-kernel
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/busses/i2c-at91.c | 32 +++++++++++---------------------
1 file changed, 11 insertions(+), 21 deletions(-)
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 636fd2efad88..8be7cf6e2747 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -487,30 +487,10 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
if (ret < 0)
goto out;
- /*
- * The hardware can handle at most two messages concatenated by a
- * repeated start via it's internal address feature.
- */
- if (num > 2) {
- dev_err(dev->dev,
- "cannot handle more than two concatenated messages.\n");
- ret = 0;
- goto out;
- } else if (num == 2) {
+ if (num == 2) {
int internal_address = 0;
int i;
- if (msg->flags & I2C_M_RD) {
- dev_err(dev->dev, "first transfer must be write.\n");
- ret = -EINVAL;
- goto out;
- }
- if (msg->len > 3) {
- dev_err(dev->dev, "first message size must be <= 3.\n");
- ret = -EINVAL;
- goto out;
- }
-
/* 1st msg is put into the internal address, start with 2nd */
m_start = &msg[1];
for (i = 0; i < msg->len; ++i) {
@@ -540,6 +520,15 @@ out:
return ret;
}
+/*
+ * The hardware can handle at most two messages concatenated by a
+ * repeated start via it's internal address feature.
+ */
+static struct i2c_adapter_quirks at91_twi_quirks = {
+ .flags = I2C_ADAPTER_QUIRK_COMB_WRITE_FIRST,
+ .max_comb_write_len = 3,
+};
+
static u32 at91_twi_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
@@ -777,6 +766,7 @@ static int at91_twi_probe(struct platform_device *pdev)
dev->adapter.owner = THIS_MODULE;
dev->adapter.class = I2C_CLASS_DEPRECATED;
dev->adapter.algo = &at91_twi_algorithm;
+ dev->adapter.quirks = &at91_twi_quirks;
dev->adapter.dev.parent = dev->dev;
dev->adapter.nr = pdev->id;
dev->adapter.timeout = AT91_I2C_TIMEOUT;
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [RFC 04/11] i2c: opal: make use of the new infrastructure for quirks
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
` (2 preceding siblings ...)
2015-01-09 17:21 ` [RFC 03/11] i2c: at91: make use of the new infrastructure for quirks Wolfram Sang
@ 2015-01-09 17:21 ` Wolfram Sang
2015-01-09 17:21 ` [RFC 05/11] i2c: qup: " Wolfram Sang
` (6 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-arm-kernel, linuxppc-dev, linux-mips,
Benjamin Herrenschmidt, Ludovic Desroches, Yingjoe Chen,
Wolfram Sang, linux-kernel
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/busses/i2c-opal.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/busses/i2c-opal.c b/drivers/i2c/busses/i2c-opal.c
index 16f90b1a7508..f463eae44bf2 100644
--- a/drivers/i2c/busses/i2c-opal.c
+++ b/drivers/i2c/busses/i2c-opal.c
@@ -104,17 +104,6 @@ static int i2c_opal_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
req.buffer_ra = cpu_to_be64(__pa(msgs[0].buf));
break;
case 2:
- /* For two messages, we basically support only simple
- * smbus transactions of a write plus a read. We might
- * want to allow also two writes but we'd have to bounce
- * the data into a single buffer.
- */
- if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD))
- return -EOPNOTSUPP;
- if (msgs[0].len > 4)
- return -EOPNOTSUPP;
- if (msgs[0].addr != msgs[1].addr)
- return -EOPNOTSUPP;
req.type = OPAL_I2C_SM_READ;
req.addr = cpu_to_be16(msgs[0].addr);
req.subaddr_sz = msgs[0].len;
@@ -210,6 +199,16 @@ static const struct i2c_algorithm i2c_opal_algo = {
.functionality = i2c_opal_func,
};
+/* For two messages, we basically support only simple
+ * smbus transactions of a write plus a read. We might
+ * want to allow also two writes but we'd have to bounce
+ * the data into a single buffer.
+ */
+static struct i2c_adapter_quirks i2c_opal_quirks = {
+ .flags = I2C_ADAPTER_QUIRK_COMB_WRITE_THEN_READ,
+ .max_comb_write_len = 4,
+};
+
static int i2c_opal_probe(struct platform_device *pdev)
{
struct i2c_adapter *adapter;
@@ -232,6 +231,7 @@ static int i2c_opal_probe(struct platform_device *pdev)
adapter->algo = &i2c_opal_algo;
adapter->algo_data = (void *)(unsigned long)opal_id;
+ adapter->quirks = &i2c_opal_quirks;
adapter->dev.parent = &pdev->dev;
adapter->dev.of_node = of_node_get(pdev->dev.of_node);
pname = of_get_property(pdev->dev.of_node, "ibm,port-name", NULL);
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [RFC 05/11] i2c: qup: make use of the new infrastructure for quirks
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
` (3 preceding siblings ...)
2015-01-09 17:21 ` [RFC 04/11] i2c: opal: " Wolfram Sang
@ 2015-01-09 17:21 ` Wolfram Sang
2015-01-09 17:21 ` [RFC 06/11] i2c: cpm: " Wolfram Sang
` (5 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-mips, Wolfram Sang, linux-kernel, Ludovic Desroches,
Yingjoe Chen, linuxppc-dev, linux-arm-kernel
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/busses/i2c-qup.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index 4dad23bdffbe..fdcbdab808e9 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -412,17 +412,6 @@ static int qup_i2c_read_one(struct qup_i2c_dev *qup, struct i2c_msg *msg)
unsigned long left;
int ret;
- /*
- * The QUP block will issue a NACK and STOP on the bus when reaching
- * the end of the read, the length of the read is specified as one byte
- * which limits the possible read to 256 (QUP_READ_LIMIT) bytes.
- */
- if (msg->len > QUP_READ_LIMIT) {
- dev_err(qup->dev, "HW not capable of reads over %d bytes\n",
- QUP_READ_LIMIT);
- return -EINVAL;
- }
-
qup->msg = msg;
qup->pos = 0;
@@ -534,6 +523,15 @@ static const struct i2c_algorithm qup_i2c_algo = {
.functionality = qup_i2c_func,
};
+/*
+ * The QUP block will issue a NACK and STOP on the bus when reaching
+ * the end of the read, the length of the read is specified as one byte
+ * which limits the possible read to 256 (QUP_READ_LIMIT) bytes.
+ */
+static struct i2c_adapter_quirks qup_i2c_quirks = {
+ .max_read_len = QUP_READ_LIMIT,
+};
+
static void qup_i2c_enable_clocks(struct qup_i2c_dev *qup)
{
clk_prepare_enable(qup->clk);
@@ -670,6 +668,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
i2c_set_adapdata(&qup->adap, qup);
qup->adap.algo = &qup_i2c_algo;
+ qup->adap.quirks = &qup_i2c_quirks;
qup->adap.dev.parent = qup->dev;
qup->adap.dev.of_node = pdev->dev.of_node;
strlcpy(qup->adap.name, "QUP I2C adapter", sizeof(qup->adap.name));
--
2.1.3
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [RFC 06/11] i2c: cpm: make use of the new infrastructure for quirks
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
` (4 preceding siblings ...)
2015-01-09 17:21 ` [RFC 05/11] i2c: qup: " Wolfram Sang
@ 2015-01-09 17:21 ` Wolfram Sang
2015-01-09 17:21 ` [RFC 07/11] i2c: axxia: " Wolfram Sang
` (4 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-arm-kernel, linuxppc-dev, linux-mips,
Benjamin Herrenschmidt, Ludovic Desroches, Yingjoe Chen,
Wolfram Sang, Jochen Friedrich, linux-kernel
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/busses/i2c-cpm.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
index 2d466538b2e2..714bdc837769 100644
--- a/drivers/i2c/busses/i2c-cpm.c
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -308,22 +308,12 @@ static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
struct i2c_msg *pmsg;
- int ret, i;
+ int ret;
int tptr;
int rptr;
cbd_t __iomem *tbdf;
cbd_t __iomem *rbdf;
- if (num > CPM_MAXBD)
- return -EINVAL;
-
- /* Check if we have any oversized READ requests */
- for (i = 0; i < num; i++) {
- pmsg = &msgs[i];
- if (pmsg->len >= CPM_MAX_READ)
- return -EINVAL;
- }
-
/* Reset to use first buffer */
out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
@@ -424,10 +414,18 @@ static const struct i2c_algorithm cpm_i2c_algo = {
.functionality = cpm_i2c_func,
};
+/* CPM_MAX_READ is also limiting writes according to the code! */
+static struct i2c_adapter_quirks cpm_i2c_quirks = {
+ .max_num_msgs = CPM_MAXBD,
+ .max_read_len = CPM_MAX_READ,
+ .max_write_len = CPM_MAX_READ,
+};
+
static const struct i2c_adapter cpm_ops = {
.owner = THIS_MODULE,
.name = "i2c-cpm",
.algo = &cpm_i2c_algo,
+ .quirks = &cpm_i2c_quirks,
};
static int cpm_i2c_setup(struct cpm_i2c *cpm)
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [RFC 07/11] i2c: axxia: make use of the new infrastructure for quirks
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
` (5 preceding siblings ...)
2015-01-09 17:21 ` [RFC 06/11] i2c: cpm: " Wolfram Sang
@ 2015-01-09 17:21 ` Wolfram Sang
2015-01-09 17:21 ` [RFC 08/11] i2c: dln2: " Wolfram Sang
` (3 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-arm-kernel, linuxppc-dev, linux-mips,
Benjamin Herrenschmidt, Ludovic Desroches, Yingjoe Chen,
Wolfram Sang, linux-kernel
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/busses/i2c-axxia.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/i2c/busses/i2c-axxia.c b/drivers/i2c/busses/i2c-axxia.c
index 768a598d8d03..488c5d3bf9db 100644
--- a/drivers/i2c/busses/i2c-axxia.c
+++ b/drivers/i2c/busses/i2c-axxia.c
@@ -336,11 +336,6 @@ static int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg)
u32 addr_1, addr_2;
int ret;
- if (msg->len > 255) {
- dev_warn(idev->dev, "unsupported length %u\n", msg->len);
- return -EINVAL;
- }
-
idev->msg = msg;
idev->msg_xfrd = 0;
idev->msg_err = 0;
@@ -454,6 +449,11 @@ static const struct i2c_algorithm axxia_i2c_algo = {
.functionality = axxia_i2c_func,
};
+static struct i2c_adapter_quirks axxia_i2c_quirks = {
+ .max_read_len = 255,
+ .max_write_len = 255,
+};
+
static int axxia_i2c_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
@@ -511,6 +511,7 @@ static int axxia_i2c_probe(struct platform_device *pdev)
strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name));
idev->adapter.owner = THIS_MODULE;
idev->adapter.algo = &axxia_i2c_algo;
+ idev->adapter.quirks = &axxia_i2c_quirks;
idev->adapter.dev.parent = &pdev->dev;
idev->adapter.dev.of_node = pdev->dev.of_node;
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [RFC 08/11] i2c: dln2: make use of the new infrastructure for quirks
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
` (6 preceding siblings ...)
2015-01-09 17:21 ` [RFC 07/11] i2c: axxia: " Wolfram Sang
@ 2015-01-09 17:21 ` Wolfram Sang
2015-01-09 17:21 ` [RFC 09/11] i2c: powermac: " Wolfram Sang
` (2 subsequent siblings)
10 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-arm-kernel, linuxppc-dev, linux-mips,
Benjamin Herrenschmidt, Ludovic Desroches, Yingjoe Chen,
Wolfram Sang, linux-kernel
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/busses/i2c-dln2.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-dln2.c b/drivers/i2c/busses/i2c-dln2.c
index b3fb86af4cbb..b6f9ba7eb175 100644
--- a/drivers/i2c/busses/i2c-dln2.c
+++ b/drivers/i2c/busses/i2c-dln2.c
@@ -144,7 +144,6 @@ static int dln2_i2c_xfer(struct i2c_adapter *adapter,
{
struct dln2_i2c *dln2 = i2c_get_adapdata(adapter);
struct i2c_msg *pmsg;
- struct device *dev = &dln2->adapter.dev;
int i;
for (i = 0; i < num; i++) {
@@ -152,11 +151,6 @@ static int dln2_i2c_xfer(struct i2c_adapter *adapter,
pmsg = &msgs[i];
- if (pmsg->len > DLN2_I2C_MAX_XFER_SIZE) {
- dev_warn(dev, "maximum transfer size exceeded\n");
- return -EOPNOTSUPP;
- }
-
if (pmsg->flags & I2C_M_RD) {
ret = dln2_i2c_read(dln2, pmsg->addr, pmsg->buf,
pmsg->len);
@@ -187,6 +181,11 @@ static const struct i2c_algorithm dln2_i2c_usb_algorithm = {
.functionality = dln2_i2c_func,
};
+static struct i2c_adapter_quirks dln2_i2c_quirks = {
+ .max_read_len = DLN2_I2C_MAX_XFER_SIZE,
+ .max_write_len = DLN2_I2C_MAX_XFER_SIZE,
+};
+
static int dln2_i2c_probe(struct platform_device *pdev)
{
int ret;
@@ -209,6 +208,7 @@ static int dln2_i2c_probe(struct platform_device *pdev)
dln2->adapter.owner = THIS_MODULE;
dln2->adapter.class = I2C_CLASS_HWMON;
dln2->adapter.algo = &dln2_i2c_usb_algorithm;
+ dln2->adapter.quirks = &dln2_i2c_quirks;
dln2->adapter.dev.parent = dev;
i2c_set_adapdata(&dln2->adapter, dln2);
snprintf(dln2->adapter.name, sizeof(dln2->adapter.name), "%s-%s-%d",
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [RFC 09/11] i2c: powermac: make use of the new infrastructure for quirks
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
` (7 preceding siblings ...)
2015-01-09 17:21 ` [RFC 08/11] i2c: dln2: " Wolfram Sang
@ 2015-01-09 17:21 ` Wolfram Sang
2015-01-09 17:21 ` [RFC 10/11] i2c: viperboard: " Wolfram Sang
2015-01-09 17:21 ` [RFC 11/11] i2c: pmcmsp: " Wolfram Sang
10 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-arm-kernel, linuxppc-dev, linux-mips,
Benjamin Herrenschmidt, Ludovic Desroches, Yingjoe Chen,
Wolfram Sang, linux-kernel
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/busses/i2c-powermac.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 60a53c169ed2..6abcf696e359 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -153,12 +153,6 @@ static int i2c_powermac_master_xfer( struct i2c_adapter *adap,
int read;
int addrdir;
- if (num != 1) {
- dev_err(&adap->dev,
- "Multi-message I2C transactions not supported\n");
- return -EOPNOTSUPP;
- }
-
if (msgs->flags & I2C_M_TEN)
return -EINVAL;
read = (msgs->flags & I2C_M_RD) != 0;
@@ -205,6 +199,9 @@ static const struct i2c_algorithm i2c_powermac_algorithm = {
.functionality = i2c_powermac_func,
};
+static struct i2c_adapter_quirks i2c_powermac_quirks = {
+ .max_num_msgs = 1,
+};
static int i2c_powermac_remove(struct platform_device *dev)
{
@@ -434,6 +431,7 @@ static int i2c_powermac_probe(struct platform_device *dev)
platform_set_drvdata(dev, adapter);
adapter->algo = &i2c_powermac_algorithm;
+ adapter->quirks = &i2c_powermac_quirks;
i2c_set_adapdata(adapter, bus);
adapter->dev.parent = &dev->dev;
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [RFC 10/11] i2c: viperboard: make use of the new infrastructure for quirks
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
` (8 preceding siblings ...)
2015-01-09 17:21 ` [RFC 09/11] i2c: powermac: " Wolfram Sang
@ 2015-01-09 17:21 ` Wolfram Sang
2015-01-09 17:21 ` [RFC 11/11] i2c: pmcmsp: " Wolfram Sang
10 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-arm-kernel, linuxppc-dev, linux-mips,
Benjamin Herrenschmidt, Ludovic Desroches, Yingjoe Chen,
Wolfram Sang, linux-kernel
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/busses/i2c-viperboard.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/i2c/busses/i2c-viperboard.c b/drivers/i2c/busses/i2c-viperboard.c
index 7533fa34d737..47e88adf2011 100644
--- a/drivers/i2c/busses/i2c-viperboard.c
+++ b/drivers/i2c/busses/i2c-viperboard.c
@@ -288,10 +288,6 @@ static int vprbrd_i2c_xfer(struct i2c_adapter *i2c, struct i2c_msg *msgs,
i, pmsg->flags & I2C_M_RD ? "read" : "write",
pmsg->flags, pmsg->len, pmsg->addr);
- /* msgs longer than 2048 bytes are not supported by adapter */
- if (pmsg->len > 2048)
- return -EINVAL;
-
mutex_lock(&vb->lock);
/* directly send the message */
if (pmsg->flags & I2C_M_RD) {
@@ -358,6 +354,11 @@ static const struct i2c_algorithm vprbrd_algorithm = {
.functionality = vprbrd_i2c_func,
};
+static struct i2c_adapter_quirks vprbrd_quirks = {
+ .max_read_len = 2048,
+ .max_write_len = 2048,
+};
+
static int vprbrd_i2c_probe(struct platform_device *pdev)
{
struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent);
@@ -373,6 +374,7 @@ static int vprbrd_i2c_probe(struct platform_device *pdev)
vb_i2c->i2c.owner = THIS_MODULE;
vb_i2c->i2c.class = I2C_CLASS_HWMON;
vb_i2c->i2c.algo = &vprbrd_algorithm;
+ vb_i2c->i2c.quirks = &vprbrd_quirks;
vb_i2c->i2c.algo_data = vb;
/* save the param in usb capabable memory */
vb_i2c->bus_freq_param = i2c_bus_param;
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [RFC 11/11] i2c: pmcmsp: make use of the new infrastructure for quirks
2015-01-09 17:21 [RFC 00/11] i2c: add generic quirk infrastructure Wolfram Sang
` (9 preceding siblings ...)
2015-01-09 17:21 ` [RFC 10/11] i2c: viperboard: " Wolfram Sang
@ 2015-01-09 17:21 ` Wolfram Sang
10 siblings, 0 replies; 26+ messages in thread
From: Wolfram Sang @ 2015-01-09 17:21 UTC (permalink / raw)
To: linux-i2c
Cc: linux-arm-kernel, linuxppc-dev, linux-mips,
Benjamin Herrenschmidt, Ludovic Desroches, Yingjoe Chen,
Wolfram Sang, linux-kernel
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
drivers/i2c/busses/i2c-pmcmsp.c | 42 ++++++++++++++++-------------------------
1 file changed, 16 insertions(+), 26 deletions(-)
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c
index 44f03eed00dd..e06efee9fa70 100644
--- a/drivers/i2c/busses/i2c-pmcmsp.c
+++ b/drivers/i2c/busses/i2c-pmcmsp.c
@@ -463,14 +463,6 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd(
return -EINVAL;
}
- if (cmd->read_len > MSP_MAX_BYTES_PER_RW ||
- cmd->write_len > MSP_MAX_BYTES_PER_RW) {
- dev_err(&pmcmsptwi_adapter.dev,
- "%s: Cannot transfer more than %d bytes\n",
- __func__, MSP_MAX_BYTES_PER_RW);
- return -EINVAL;
- }
-
mutex_lock(&data->lock);
dev_dbg(&pmcmsptwi_adapter.dev,
"Setting address to 0x%04x\n", cmd->addr);
@@ -527,25 +519,14 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap,
struct pmcmsptwi_cfg oldcfg, newcfg;
int ret;
- if (num > 2) {
- dev_dbg(&adap->dev, "%d messages unsupported\n", num);
- return -EINVAL;
- } else if (num == 2) {
- /* Check for a dual write-then-read command */
+ if (num == 2) {
struct i2c_msg *nextmsg = msg + 1;
- if (!(msg->flags & I2C_M_RD) &&
- (nextmsg->flags & I2C_M_RD) &&
- msg->addr == nextmsg->addr) {
- cmd.type = MSP_TWI_CMD_WRITE_READ;
- cmd.write_len = msg->len;
- cmd.write_data = msg->buf;
- cmd.read_len = nextmsg->len;
- cmd.read_data = nextmsg->buf;
- } else {
- dev_dbg(&adap->dev,
- "Non write-read dual messages unsupported\n");
- return -EINVAL;
- }
+
+ cmd.type = MSP_TWI_CMD_WRITE_READ;
+ cmd.write_len = msg->len;
+ cmd.write_data = msg->buf;
+ cmd.read_len = nextmsg->len;
+ cmd.read_data = nextmsg->buf;
} else if (msg->flags & I2C_M_RD) {
cmd.type = MSP_TWI_CMD_READ;
cmd.read_len = msg->len;
@@ -605,6 +586,14 @@ static u32 pmcmsptwi_i2c_func(struct i2c_adapter *adapter)
I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_PROC_CALL;
}
+static struct i2c_adapter_quirks pmcmsptwi_i2c_quirks = {
+ .flags = I2C_ADAPTER_QUIRK_COMB_WRITE_THEN_READ,
+ .max_write_len = MSP_MAX_BYTES_PER_RW,
+ .max_read_len = MSP_MAX_BYTES_PER_RW,
+ .max_comb_write_len = MSP_MAX_BYTES_PER_RW,
+ .max_comb_read_len = MSP_MAX_BYTES_PER_RW,
+};
+
/* -- Initialization -- */
static struct i2c_algorithm pmcmsptwi_algo = {
@@ -616,6 +605,7 @@ static struct i2c_adapter pmcmsptwi_adapter = {
.owner = THIS_MODULE,
.class = I2C_CLASS_HWMON | I2C_CLASS_SPD,
.algo = &pmcmsptwi_algo,
+ .quirks = &pmcmsptwi_i2c_quirks,
.name = DRV_NAME,
};
--
2.1.3
^ permalink raw reply related [flat|nested] 26+ messages in thread