aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2019-06-18 06:58:33 -0400
committerPeter Rosin <peda@axentia.se>2019-06-22 01:01:34 -0400
commitd308dfbf62eff897d71968d764f21a78678ee0a5 (patch)
treed70706269e586a3e7450b9890f092dab1a5bc1d5
parent90af27317b63403bce3874566b71883fc1e1f459 (diff)
i2c: mux/i801: Switch to use descriptor passing
This switches the i801 GPIO mux to use GPIO descriptors for handling the GPIO lines. The previous hack which was reaching inside the GPIO chips etc cannot live on. We pass descriptors along with the GPIO mux device at creation instead. The GPIO mux was only used by way of platform data with a platform device from one place in the kernel: the i801 i2c bus driver. Let's just associate the GPIO descriptor table with the actual device like everyone else and dynamically create a descriptor table passed along with the GPIO i2c mux. This enables simplification of the GPIO i2c mux driver to use only the descriptor API and the OF probe path gets simplified in the process. The i801 driver was registering the GPIO i2c mux with PLATFORM_DEVID_AUTO which would make it hard to predict the device name and assign the descriptor table properly, but this seems to be a mistake to begin with: all of the GPIO mux devices are hardcoded to look up GPIO lines from the "gpio_ich" GPIO chip. If there are more than one mux, there is certainly more than one gpio chip as well, and then we have more serious problems. Switch to PLATFORM_DEVID_NONE instead. There can be only one. Cc: Mika Westerberg <mika.westerberg@linux.intel.com> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Peter Rosin <peda@axentia.se> Cc: Jean Delvare <jdelvare@suse.com> Signed-off-by: Serge Semin <fancer.lancer@gmail.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com> [Removed a newline, suggested by Andy. /Peter] Signed-off-by: Peter Rosin <peda@axentia.se>
-rw-r--r--drivers/i2c/busses/i2c-i801.c37
-rw-r--r--drivers/i2c/muxes/i2c-mux-gpio.c116
-rw-r--r--include/linux/platform_data/i2c-mux-gpio.h7
3 files changed, 60 insertions, 100 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 679c6c41f64b..bf484cd775ec 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -107,7 +107,7 @@
107#include <linux/pm_runtime.h> 107#include <linux/pm_runtime.h>
108 108
109#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI 109#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
110#include <linux/gpio.h> 110#include <linux/gpio/machine.h>
111#include <linux/platform_data/i2c-mux-gpio.h> 111#include <linux/platform_data/i2c-mux-gpio.h>
112#endif 112#endif
113 113
@@ -274,6 +274,7 @@ struct i801_priv {
274#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI 274#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
275 const struct i801_mux_config *mux_drvdata; 275 const struct i801_mux_config *mux_drvdata;
276 struct platform_device *mux_pdev; 276 struct platform_device *mux_pdev;
277 struct gpiod_lookup_table *lookup;
277#endif 278#endif
278 struct platform_device *tco_pdev; 279 struct platform_device *tco_pdev;
279 280
@@ -1258,7 +1259,8 @@ static int i801_add_mux(struct i801_priv *priv)
1258 struct device *dev = &priv->adapter.dev; 1259 struct device *dev = &priv->adapter.dev;
1259 const struct i801_mux_config *mux_config; 1260 const struct i801_mux_config *mux_config;
1260 struct i2c_mux_gpio_platform_data gpio_data; 1261 struct i2c_mux_gpio_platform_data gpio_data;
1261 int err; 1262 struct gpiod_lookup_table *lookup;
1263 int err, i;
1262 1264
1263 if (!priv->mux_drvdata) 1265 if (!priv->mux_drvdata)
1264 return 0; 1266 return 0;
@@ -1270,17 +1272,36 @@ static int i801_add_mux(struct i801_priv *priv)
1270 gpio_data.values = mux_config->values; 1272 gpio_data.values = mux_config->values;
1271 gpio_data.n_values = mux_config->n_values; 1273 gpio_data.n_values = mux_config->n_values;
1272 gpio_data.classes = mux_config->classes; 1274 gpio_data.classes = mux_config->classes;
1273 gpio_data.gpio_chip = mux_config->gpio_chip;
1274 gpio_data.gpios = mux_config->gpios;
1275 gpio_data.n_gpios = mux_config->n_gpios;
1276 gpio_data.idle = I2C_MUX_GPIO_NO_IDLE; 1275 gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
1277 1276
1278 /* Register the mux device */ 1277 /* Register GPIO descriptor lookup table */
1278 lookup = devm_kzalloc(dev,
1279 struct_size(lookup, table, mux_config->n_gpios),
1280 GFP_KERNEL);
1281 if (!lookup)
1282 return -ENOMEM;
1283 lookup->dev_id = "i2c-mux-gpio";
1284 for (i = 0; i < mux_config->n_gpios; i++) {
1285 lookup->table[i].chip_label = mux_config->gpio_chip;
1286 lookup->table[i].chip_hwnum = mux_config->gpios[i];
1287 lookup->table[i].con_id = "mux";
1288 }
1289 gpiod_add_lookup_table(lookup);
1290 priv->lookup = lookup;
1291
1292 /*
1293 * Register the mux device, we use PLATFORM_DEVID_NONE here
1294 * because since we are referring to the GPIO chip by name we are
1295 * anyways in deep trouble if there is more than one of these
1296 * devices, and there should likely only be one platform controller
1297 * hub.
1298 */
1279 priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio", 1299 priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio",
1280 PLATFORM_DEVID_AUTO, &gpio_data, 1300 PLATFORM_DEVID_NONE, &gpio_data,
1281 sizeof(struct i2c_mux_gpio_platform_data)); 1301 sizeof(struct i2c_mux_gpio_platform_data));
1282 if (IS_ERR(priv->mux_pdev)) { 1302 if (IS_ERR(priv->mux_pdev)) {
1283 err = PTR_ERR(priv->mux_pdev); 1303 err = PTR_ERR(priv->mux_pdev);
1304 gpiod_remove_lookup_table(lookup);
1284 priv->mux_pdev = NULL; 1305 priv->mux_pdev = NULL;
1285 dev_err(dev, "Failed to register i2c-mux-gpio device\n"); 1306 dev_err(dev, "Failed to register i2c-mux-gpio device\n");
1286 return err; 1307 return err;
@@ -1293,6 +1314,8 @@ static void i801_del_mux(struct i801_priv *priv)
1293{ 1314{
1294 if (priv->mux_pdev) 1315 if (priv->mux_pdev)
1295 platform_device_unregister(priv->mux_pdev); 1316 platform_device_unregister(priv->mux_pdev);
1317 if (priv->lookup)
1318 gpiod_remove_lookup_table(priv->lookup);
1296} 1319}
1297 1320
1298static unsigned int i801_get_adapter_class(struct i801_priv *priv) 1321static unsigned int i801_get_adapter_class(struct i801_priv *priv)
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index 13882a2a4f60..fd482feafb19 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -14,13 +14,14 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/gpio.h> 17#include <linux/bits.h>
18#include <linux/gpio/consumer.h>
19/* FIXME: stop poking around inside gpiolib */
18#include "../../gpio/gpiolib.h" 20#include "../../gpio/gpiolib.h"
19#include <linux/of_gpio.h>
20 21
21struct gpiomux { 22struct gpiomux {
22 struct i2c_mux_gpio_platform_data data; 23 struct i2c_mux_gpio_platform_data data;
23 unsigned gpio_base; 24 int ngpios;
24 struct gpio_desc **gpios; 25 struct gpio_desc **gpios;
25}; 26};
26 27
@@ -30,8 +31,7 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
30 31
31 values[0] = val; 32 values[0] = val;
32 33
33 gpiod_set_array_value_cansleep(mux->data.n_gpios, mux->gpios, NULL, 34 gpiod_set_array_value_cansleep(mux->ngpios, mux->gpios, NULL, values);
34 values);
35} 35}
36 36
37static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan) 37static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
@@ -52,12 +52,6 @@ static int i2c_mux_gpio_deselect(struct i2c_mux_core *muxc, u32 chan)
52 return 0; 52 return 0;
53} 53}
54 54
55static int match_gpio_chip_by_label(struct gpio_chip *chip,
56 void *data)
57{
58 return !strcmp(chip->label, data);
59}
60
61#ifdef CONFIG_OF 55#ifdef CONFIG_OF
62static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, 56static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
63 struct platform_device *pdev) 57 struct platform_device *pdev)
@@ -65,8 +59,8 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
65 struct device_node *np = pdev->dev.of_node; 59 struct device_node *np = pdev->dev.of_node;
66 struct device_node *adapter_np, *child; 60 struct device_node *adapter_np, *child;
67 struct i2c_adapter *adapter; 61 struct i2c_adapter *adapter;
68 unsigned *values, *gpios; 62 unsigned *values;
69 int i = 0, ret; 63 int i = 0;
70 64
71 if (!np) 65 if (!np)
72 return -ENODEV; 66 return -ENODEV;
@@ -103,29 +97,6 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
103 if (of_property_read_u32(np, "idle-state", &mux->data.idle)) 97 if (of_property_read_u32(np, "idle-state", &mux->data.idle))
104 mux->data.idle = I2C_MUX_GPIO_NO_IDLE; 98 mux->data.idle = I2C_MUX_GPIO_NO_IDLE;
105 99
106 mux->data.n_gpios = of_gpio_named_count(np, "mux-gpios");
107 if (mux->data.n_gpios < 0) {
108 dev_err(&pdev->dev, "Missing mux-gpios property in the DT.\n");
109 return -EINVAL;
110 }
111
112 gpios = devm_kcalloc(&pdev->dev,
113 mux->data.n_gpios, sizeof(*mux->data.gpios),
114 GFP_KERNEL);
115 if (!gpios) {
116 dev_err(&pdev->dev, "Cannot allocate gpios array");
117 return -ENOMEM;
118 }
119
120 for (i = 0; i < mux->data.n_gpios; i++) {
121 ret = of_get_named_gpio(np, "mux-gpios", i);
122 if (ret < 0)
123 return ret;
124 gpios[i] = ret;
125 }
126
127 mux->data.gpios = gpios;
128
129 return 0; 100 return 0;
130} 101}
131#else 102#else
@@ -142,8 +113,8 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
142 struct gpiomux *mux; 113 struct gpiomux *mux;
143 struct i2c_adapter *parent; 114 struct i2c_adapter *parent;
144 struct i2c_adapter *root; 115 struct i2c_adapter *root;
145 unsigned initial_state, gpio_base; 116 unsigned initial_state;
146 int i, ret; 117 int i, ngpios, ret;
147 118
148 mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL); 119 mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
149 if (!mux) 120 if (!mux)
@@ -158,29 +129,19 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
158 sizeof(mux->data)); 129 sizeof(mux->data));
159 } 130 }
160 131
161 /* 132 ngpios = gpiod_count(&pdev->dev, "mux");
162 * If a GPIO chip name is provided, the GPIO pin numbers provided are 133 if (ngpios <= 0) {
163 * relative to its base GPIO number. Otherwise they are absolute. 134 dev_err(&pdev->dev, "no valid gpios provided\n");
164 */ 135 return ngpios ?: -EINVAL;
165 if (mux->data.gpio_chip) {
166 struct gpio_chip *gpio;
167
168 gpio = gpiochip_find(mux->data.gpio_chip,
169 match_gpio_chip_by_label);
170 if (!gpio)
171 return -EPROBE_DEFER;
172
173 gpio_base = gpio->base;
174 } else {
175 gpio_base = 0;
176 } 136 }
137 mux->ngpios = ngpios;
177 138
178 parent = i2c_get_adapter(mux->data.parent); 139 parent = i2c_get_adapter(mux->data.parent);
179 if (!parent) 140 if (!parent)
180 return -EPROBE_DEFER; 141 return -EPROBE_DEFER;
181 142
182 muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, 143 muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values,
183 mux->data.n_gpios * sizeof(*mux->gpios), 0, 144 ngpios * sizeof(*mux->gpios), 0,
184 i2c_mux_gpio_select, NULL); 145 i2c_mux_gpio_select, NULL);
185 if (!muxc) { 146 if (!muxc) {
186 ret = -ENOMEM; 147 ret = -ENOMEM;
@@ -194,7 +155,6 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
194 root = i2c_root_adapter(&parent->dev); 155 root = i2c_root_adapter(&parent->dev);
195 156
196 muxc->mux_locked = true; 157 muxc->mux_locked = true;
197 mux->gpio_base = gpio_base;
198 158
199 if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) { 159 if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) {
200 initial_state = mux->data.idle; 160 initial_state = mux->data.idle;
@@ -203,34 +163,28 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
203 initial_state = mux->data.values[0]; 163 initial_state = mux->data.values[0];
204 } 164 }
205 165
206 for (i = 0; i < mux->data.n_gpios; i++) { 166 for (i = 0; i < ngpios; i++) {
207 struct device *gpio_dev; 167 struct device *gpio_dev;
208 struct gpio_desc *gpio_desc; 168 struct gpio_desc *gpiod;
209 169 enum gpiod_flags flag;
210 ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio"); 170
211 if (ret) { 171 if (initial_state & BIT(i))
212 dev_err(&pdev->dev, "Failed to request GPIO %d\n", 172 flag = GPIOD_OUT_HIGH;
213 mux->data.gpios[i]); 173 else
214 goto err_request_gpio; 174 flag = GPIOD_OUT_LOW;
175 gpiod = devm_gpiod_get_index(&pdev->dev, "mux", i, flag);
176 if (IS_ERR(gpiod)) {
177 ret = PTR_ERR(gpiod);
178 goto alloc_failed;
215 } 179 }
216 180
217 ret = gpio_direction_output(gpio_base + mux->data.gpios[i], 181 mux->gpios[i] = gpiod;
218 initial_state & (1 << i));
219 if (ret) {
220 dev_err(&pdev->dev,
221 "Failed to set direction of GPIO %d to output\n",
222 mux->data.gpios[i]);
223 i++; /* gpio_request above succeeded, so must free */
224 goto err_request_gpio;
225 }
226
227 gpio_desc = gpio_to_desc(gpio_base + mux->data.gpios[i]);
228 mux->gpios[i] = gpio_desc;
229 182
230 if (!muxc->mux_locked) 183 if (!muxc->mux_locked)
231 continue; 184 continue;
232 185
233 gpio_dev = &gpio_desc->gdev->dev; 186 /* FIXME: find a proper way to access the GPIO device */
187 gpio_dev = &gpiod->gdev->dev;
234 muxc->mux_locked = i2c_root_adapter(gpio_dev) == root; 188 muxc->mux_locked = i2c_root_adapter(gpio_dev) == root;
235 } 189 }
236 190
@@ -253,10 +207,6 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
253 207
254add_adapter_failed: 208add_adapter_failed:
255 i2c_mux_del_adapters(muxc); 209 i2c_mux_del_adapters(muxc);
256 i = mux->data.n_gpios;
257err_request_gpio:
258 for (; i > 0; i--)
259 gpio_free(gpio_base + mux->data.gpios[i - 1]);
260alloc_failed: 210alloc_failed:
261 i2c_put_adapter(parent); 211 i2c_put_adapter(parent);
262 212
@@ -266,14 +216,8 @@ alloc_failed:
266static int i2c_mux_gpio_remove(struct platform_device *pdev) 216static int i2c_mux_gpio_remove(struct platform_device *pdev)
267{ 217{
268 struct i2c_mux_core *muxc = platform_get_drvdata(pdev); 218 struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
269 struct gpiomux *mux = i2c_mux_priv(muxc);
270 int i;
271 219
272 i2c_mux_del_adapters(muxc); 220 i2c_mux_del_adapters(muxc);
273
274 for (i = 0; i < mux->data.n_gpios; i++)
275 gpio_free(mux->gpio_base + mux->data.gpios[i]);
276
277 i2c_put_adapter(muxc->parent); 221 i2c_put_adapter(muxc->parent);
278 222
279 return 0; 223 return 0;
diff --git a/include/linux/platform_data/i2c-mux-gpio.h b/include/linux/platform_data/i2c-mux-gpio.h
index 4406108201fe..28f288eed652 100644
--- a/include/linux/platform_data/i2c-mux-gpio.h
+++ b/include/linux/platform_data/i2c-mux-gpio.h
@@ -22,10 +22,6 @@
22 * position 22 * position
23 * @n_values: Number of multiplexer positions (busses to instantiate) 23 * @n_values: Number of multiplexer positions (busses to instantiate)
24 * @classes: Optional I2C auto-detection classes 24 * @classes: Optional I2C auto-detection classes
25 * @gpio_chip: Optional GPIO chip name; if set, GPIO pin numbers are given
26 * relative to the base GPIO number of that chip
27 * @gpios: Array of GPIO numbers used to control MUX
28 * @n_gpios: Number of GPIOs used to control MUX
29 * @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used 25 * @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used
30 */ 26 */
31struct i2c_mux_gpio_platform_data { 27struct i2c_mux_gpio_platform_data {
@@ -34,9 +30,6 @@ struct i2c_mux_gpio_platform_data {
34 const unsigned *values; 30 const unsigned *values;
35 int n_values; 31 int n_values;
36 const unsigned *classes; 32 const unsigned *classes;
37 char *gpio_chip;
38 const unsigned *gpios;
39 int n_gpios;
40 unsigned idle; 33 unsigned idle;
41}; 34};
42 35