summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0042-Add-bus-timeout-ms-and-retries-device-tree-propertie.patch
blob: 3588d62d97328efbe3c9d5cb27fd61c500c9cb63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
From 6515a2134f90f33dbbea8ede5de598d17bb00c12 Mon Sep 17 00:00:00 2001
From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
Date: Thu, 7 Mar 2019 15:17:40 -0800
Subject: [PATCH] Add bus-timeout-ms and #retries device tree properties

BMC uses I2C bus 7 as a PMBus channel to communicate with PSUs,
also ME uses this bus as SMLink to control PSUs so this bus is
managed by multi-masters. In this use case, some arbitration errors
are expected so we need to add retry logic. And PMBus subsystem
uses I2C bus in kernel internally so retry logic should be
supported in kernel level.

To support the use case, this commit adds 'bus-timeout-ms' and
'#retries' device tree properties to set the bus specific
parameters at kernel boot time without using any additional ioctls
from user space.

This patch would not be accepted by I2C maintainer in linux
upstream because he doesn't like adding these legacy properties
into device tree, so keep it only in downstream.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
---
 Documentation/devicetree/bindings/i2c/i2c-aspeed.txt |  3 +++
 Documentation/devicetree/bindings/i2c/i2c.txt        |  6 ++++++
 drivers/i2c/busses/i2c-aspeed.c                      |  1 -
 drivers/i2c/i2c-core-base.c                          | 12 ++++++++++--
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
index 8fbd8633a387..7da7e813b2b0 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-aspeed.txt
@@ -16,6 +16,9 @@ Optional Properties:
 - bus-frequency	: frequency of the bus clock in Hz defaults to 100 kHz when not
 		  specified
 - multi-master	: states that there is another master active on this bus.
+- bus-timeout-ms: bus timeout in milliseconds defaults to 1 second when not
+		  specified.
+- #retries	: Number of retries for master transfer.
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/i2c/i2c.txt b/Documentation/devicetree/bindings/i2c/i2c.txt
index 44efafdfd7f5..e382931cf3d6 100644
--- a/Documentation/devicetree/bindings/i2c/i2c.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c.txt
@@ -80,6 +80,12 @@ wants to support one of the below features, it should adapt the bindings below.
 	Names of map programmable addresses.
 	It can contain any map needing another address than default one.
 
+- bus-timeout-ms
+	Bus timeout in milliseconds.
+
+- #retries
+	Number of retries for master transfer.
+
 Binding may contain optional "interrupts" property, describing interrupts
 used by the device. I2C core will assign "irq" interrupt (or the very first
 interrupt if not using interrupt names) as primary interrupt for the slave.
diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 506d867b43d9..84237c5d0aca 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -1012,7 +1012,6 @@ static int aspeed_i2c_probe_bus(struct platform_device *pdev)
 	spin_lock_init(&bus->lock);
 	init_completion(&bus->cmd_complete);
 	bus->adap.owner = THIS_MODULE;
-	bus->adap.retries = 0;
 	bus->adap.algo = &aspeed_i2c_algo;
 	bus->adap.dev.parent = &pdev->dev;
 	bus->adap.dev.of_node = pdev->dev.of_node;
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 009b0507768e..386aa2dad908 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1231,6 +1231,7 @@ static void i2c_adapter_hold_timer_callback(struct timer_list *t)
 
 static int i2c_register_adapter(struct i2c_adapter *adap)
 {
+	u32 bus_timeout_ms = 0;
 	int res = -EINVAL;
 
 	/* Can't register until after driver model init */
@@ -1257,8 +1258,15 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 	INIT_LIST_HEAD(&adap->userspace_clients);
 
 	/* Set default timeout to 1 second if not already set */
-	if (adap->timeout == 0)
-		adap->timeout = HZ;
+	if (adap->timeout == 0) {
+		device_property_read_u32(&adap->dev, "bus-timeout-ms",
+					 &bus_timeout_ms);
+		adap->timeout = bus_timeout_ms ?
+					msecs_to_jiffies(bus_timeout_ms) : HZ;
+	}
+
+	/* Set retries count if it has the property setting */
+	device_property_read_u32(&adap->dev, "#retries", &adap->retries);
 
 	/* register soft irqs for Host Notify */
 	res = i2c_setup_host_notify_irq_domain(adap);
-- 
2.7.4