aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/muxes/i2c-arb-gpio-challenge.c79
1 files changed, 27 insertions, 52 deletions
diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
index 812b8cff265f..a664f637bc3d 100644
--- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
+++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
@@ -15,12 +15,11 @@
15 */ 15 */
16 16
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/gpio.h> 18#include <linux/gpio/consumer.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/i2c-mux.h> 21#include <linux/i2c-mux.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/of_gpio.h>
24#include <linux/platform_device.h> 23#include <linux/platform_device.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26 25
@@ -28,22 +27,16 @@
28/** 27/**
29 * struct i2c_arbitrator_data - Driver data for I2C arbitrator 28 * struct i2c_arbitrator_data - Driver data for I2C arbitrator
30 * 29 *
31 * @our_gpio: GPIO we'll use to claim. 30 * @our_gpio: GPIO descriptor we'll use to claim.
32 * @our_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO == 31 * @their_gpio: GPIO descriptor that the other side will use to claim.
33 * this then consider it released.
34 * @their_gpio: GPIO that the other side will use to claim.
35 * @their_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO ==
36 * this then consider it released.
37 * @slew_delay_us: microseconds to wait for a GPIO to go high. 32 * @slew_delay_us: microseconds to wait for a GPIO to go high.
38 * @wait_retry_us: we'll attempt another claim after this many microseconds. 33 * @wait_retry_us: we'll attempt another claim after this many microseconds.
39 * @wait_free_us: we'll give up after this many microseconds. 34 * @wait_free_us: we'll give up after this many microseconds.
40 */ 35 */
41 36
42struct i2c_arbitrator_data { 37struct i2c_arbitrator_data {
43 int our_gpio; 38 struct gpio_desc *our_gpio;
44 int our_gpio_release; 39 struct gpio_desc *their_gpio;
45 int their_gpio;
46 int their_gpio_release;
47 unsigned int slew_delay_us; 40 unsigned int slew_delay_us;
48 unsigned int wait_retry_us; 41 unsigned int wait_retry_us;
49 unsigned int wait_free_us; 42 unsigned int wait_free_us;
@@ -64,15 +57,15 @@ static int i2c_arbitrator_select(struct i2c_mux_core *muxc, u32 chan)
64 stop_time = jiffies + usecs_to_jiffies(arb->wait_free_us) + 1; 57 stop_time = jiffies + usecs_to_jiffies(arb->wait_free_us) + 1;
65 do { 58 do {
66 /* Indicate that we want to claim the bus */ 59 /* Indicate that we want to claim the bus */
67 gpio_set_value(arb->our_gpio, !arb->our_gpio_release); 60 gpiod_set_value(arb->our_gpio, 1);
68 udelay(arb->slew_delay_us); 61 udelay(arb->slew_delay_us);
69 62
70 /* Wait for the other master to release it */ 63 /* Wait for the other master to release it */
71 stop_retry = jiffies + usecs_to_jiffies(arb->wait_retry_us) + 1; 64 stop_retry = jiffies + usecs_to_jiffies(arb->wait_retry_us) + 1;
72 while (time_before(jiffies, stop_retry)) { 65 while (time_before(jiffies, stop_retry)) {
73 int gpio_val = !!gpio_get_value(arb->their_gpio); 66 int gpio_val = gpiod_get_value(arb->their_gpio);
74 67
75 if (gpio_val == arb->their_gpio_release) { 68 if (!gpio_val) {
76 /* We got it, so return */ 69 /* We got it, so return */
77 return 0; 70 return 0;
78 } 71 }
@@ -81,13 +74,13 @@ static int i2c_arbitrator_select(struct i2c_mux_core *muxc, u32 chan)
81 } 74 }
82 75
83 /* It didn't release, so give up, wait, and try again */ 76 /* It didn't release, so give up, wait, and try again */
84 gpio_set_value(arb->our_gpio, arb->our_gpio_release); 77 gpiod_set_value(arb->our_gpio, 0);
85 78
86 usleep_range(arb->wait_retry_us, arb->wait_retry_us * 2); 79 usleep_range(arb->wait_retry_us, arb->wait_retry_us * 2);
87 } while (time_before(jiffies, stop_time)); 80 } while (time_before(jiffies, stop_time));
88 81
89 /* Give up, release our claim */ 82 /* Give up, release our claim */
90 gpio_set_value(arb->our_gpio, arb->our_gpio_release); 83 gpiod_set_value(arb->our_gpio, 0);
91 udelay(arb->slew_delay_us); 84 udelay(arb->slew_delay_us);
92 dev_err(muxc->dev, "Could not claim bus, timeout\n"); 85 dev_err(muxc->dev, "Could not claim bus, timeout\n");
93 return -EBUSY; 86 return -EBUSY;
@@ -103,7 +96,7 @@ static int i2c_arbitrator_deselect(struct i2c_mux_core *muxc, u32 chan)
103 const struct i2c_arbitrator_data *arb = i2c_mux_priv(muxc); 96 const struct i2c_arbitrator_data *arb = i2c_mux_priv(muxc);
104 97
105 /* Release the bus and wait for the other master to notice */ 98 /* Release the bus and wait for the other master to notice */
106 gpio_set_value(arb->our_gpio, arb->our_gpio_release); 99 gpiod_set_value(arb->our_gpio, 0);
107 udelay(arb->slew_delay_us); 100 udelay(arb->slew_delay_us);
108 101
109 return 0; 102 return 0;
@@ -116,8 +109,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
116 struct device_node *parent_np; 109 struct device_node *parent_np;
117 struct i2c_mux_core *muxc; 110 struct i2c_mux_core *muxc;
118 struct i2c_arbitrator_data *arb; 111 struct i2c_arbitrator_data *arb;
119 enum of_gpio_flags gpio_flags; 112 struct gpio_desc *dummy;
120 unsigned long out_init;
121 int ret; 113 int ret;
122 114
123 /* We only support probing from device tree; no platform_data */ 115 /* We only support probing from device tree; no platform_data */
@@ -138,45 +130,28 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
138 130
139 platform_set_drvdata(pdev, muxc); 131 platform_set_drvdata(pdev, muxc);
140 132
141 /* Request GPIOs */ 133 /* Request GPIOs, our GPIO as unclaimed to begin with */
142 ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags); 134 arb->our_gpio = devm_gpiod_get(dev, "our-claim", GPIOD_OUT_LOW);
143 if (!gpio_is_valid(ret)) { 135 if (IS_ERR(arb->our_gpio)) {
144 if (ret != -EPROBE_DEFER) 136 dev_err(dev, "could not get \"our-claim\" GPIO (%ld)\n",
145 dev_err(dev, "Error getting our-claim-gpio\n"); 137 PTR_ERR(arb->our_gpio));
146 return ret; 138 return PTR_ERR(arb->our_gpio);
147 }
148 arb->our_gpio = ret;
149 arb->our_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW);
150 out_init = (gpio_flags & OF_GPIO_ACTIVE_LOW) ?
151 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
152 ret = devm_gpio_request_one(dev, arb->our_gpio, out_init,
153 "our-claim-gpio");
154 if (ret) {
155 if (ret != -EPROBE_DEFER)
156 dev_err(dev, "Error requesting our-claim-gpio\n");
157 return ret;
158 } 139 }
159 140
160 ret = of_get_named_gpio_flags(np, "their-claim-gpios", 0, &gpio_flags); 141 arb->their_gpio = devm_gpiod_get(dev, "their-claim", GPIOD_IN);
161 if (!gpio_is_valid(ret)) { 142 if (IS_ERR(arb->their_gpio)) {
162 if (ret != -EPROBE_DEFER) 143 dev_err(dev, "could not get \"their-claim\" GPIO (%ld)\n",
163 dev_err(dev, "Error getting their-claim-gpio\n"); 144 PTR_ERR(arb->their_gpio));
164 return ret; 145 return PTR_ERR(arb->their_gpio);
165 }
166 arb->their_gpio = ret;
167 arb->their_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW);
168 ret = devm_gpio_request_one(dev, arb->their_gpio, GPIOF_IN,
169 "their-claim-gpio");
170 if (ret) {
171 if (ret != -EPROBE_DEFER)
172 dev_err(dev, "Error requesting their-claim-gpio\n");
173 return ret;
174 } 146 }
175 147
176 /* At the moment we only support a single two master (us + 1 other) */ 148 /* At the moment we only support a single two master (us + 1 other) */
177 if (gpio_is_valid(of_get_named_gpio(np, "their-claim-gpios", 1))) { 149 dummy = devm_gpiod_get_index(dev, "their-claim", 1, GPIOD_IN);
150 if (!IS_ERR(dummy)) {
178 dev_err(dev, "Only one other master is supported\n"); 151 dev_err(dev, "Only one other master is supported\n");
179 return -EINVAL; 152 return -EINVAL;
153 } else if (PTR_ERR(dummy) == -EPROBE_DEFER) {
154 return -EPROBE_DEFER;
180 } 155 }
181 156
182 /* Arbitration parameters */ 157 /* Arbitration parameters */