Skip to content

Commit d308dfb

Browse files
Linus Walleijpeda-r
authored andcommitted
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>
1 parent 90af273 commit d308dfb

File tree

3 files changed

+60
-100
lines changed

3 files changed

+60
-100
lines changed

drivers/i2c/busses/i2c-i801.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
#include <linux/pm_runtime.h>
108108

109109
#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
110-
#include <linux/gpio.h>
110+
#include <linux/gpio/machine.h>
111111
#include <linux/platform_data/i2c-mux-gpio.h>
112112
#endif
113113

@@ -274,6 +274,7 @@ struct i801_priv {
274274
#if IS_ENABLED(CONFIG_I2C_MUX_GPIO) && defined CONFIG_DMI
275275
const struct i801_mux_config *mux_drvdata;
276276
struct platform_device *mux_pdev;
277+
struct gpiod_lookup_table *lookup;
277278
#endif
278279
struct platform_device *tco_pdev;
279280

@@ -1258,7 +1259,8 @@ static int i801_add_mux(struct i801_priv *priv)
12581259
struct device *dev = &priv->adapter.dev;
12591260
const struct i801_mux_config *mux_config;
12601261
struct i2c_mux_gpio_platform_data gpio_data;
1261-
int err;
1262+
struct gpiod_lookup_table *lookup;
1263+
int err, i;
12621264

12631265
if (!priv->mux_drvdata)
12641266
return 0;
@@ -1270,17 +1272,36 @@ static int i801_add_mux(struct i801_priv *priv)
12701272
gpio_data.values = mux_config->values;
12711273
gpio_data.n_values = mux_config->n_values;
12721274
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;
12761275
gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
12771276

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+
*/
12791299
priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio",
1280-
PLATFORM_DEVID_AUTO, &gpio_data,
1300+
PLATFORM_DEVID_NONE, &gpio_data,
12811301
sizeof(struct i2c_mux_gpio_platform_data));
12821302
if (IS_ERR(priv->mux_pdev)) {
12831303
err = PTR_ERR(priv->mux_pdev);
1304+
gpiod_remove_lookup_table(lookup);
12841305
priv->mux_pdev = NULL;
12851306
dev_err(dev, "Failed to register i2c-mux-gpio device\n");
12861307
return err;
@@ -1293,6 +1314,8 @@ static void i801_del_mux(struct i801_priv *priv)
12931314
{
12941315
if (priv->mux_pdev)
12951316
platform_device_unregister(priv->mux_pdev);
1317+
if (priv->lookup)
1318+
gpiod_remove_lookup_table(priv->lookup);
12961319
}
12971320

12981321
static unsigned int i801_get_adapter_class(struct i801_priv *priv)

drivers/i2c/muxes/i2c-mux-gpio.c

Lines changed: 30 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414
#include <linux/platform_device.h>
1515
#include <linux/module.h>
1616
#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 */
1820
#include "../../gpio/gpiolib.h"
19-
#include <linux/of_gpio.h>
2021

2122
struct gpiomux {
2223
struct i2c_mux_gpio_platform_data data;
23-
unsigned gpio_base;
24+
int ngpios;
2425
struct gpio_desc **gpios;
2526
};
2627

@@ -30,8 +31,7 @@ static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
3031

3132
values[0] = val;
3233

33-
gpiod_set_array_value_cansleep(mux->data.n_gpios, mux->gpios, NULL,
34-
values);
34+
gpiod_set_array_value_cansleep(mux->ngpios, mux->gpios, NULL, values);
3535
}
3636

3737
static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan)
@@ -52,21 +52,15 @@ static int i2c_mux_gpio_deselect(struct i2c_mux_core *muxc, u32 chan)
5252
return 0;
5353
}
5454

55-
static int match_gpio_chip_by_label(struct gpio_chip *chip,
56-
void *data)
57-
{
58-
return !strcmp(chip->label, data);
59-
}
60-
6155
#ifdef CONFIG_OF
6256
static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
6357
struct platform_device *pdev)
6458
{
6559
struct device_node *np = pdev->dev.of_node;
6660
struct device_node *adapter_np, *child;
6761
struct i2c_adapter *adapter;
68-
unsigned *values, *gpios;
69-
int i = 0, ret;
62+
unsigned *values;
63+
int i = 0;
7064

7165
if (!np)
7266
return -ENODEV;
@@ -103,29 +97,6 @@ static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
10397
if (of_property_read_u32(np, "idle-state", &mux->data.idle))
10498
mux->data.idle = I2C_MUX_GPIO_NO_IDLE;
10599

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-
129100
return 0;
130101
}
131102
#else
@@ -142,8 +113,8 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
142113
struct gpiomux *mux;
143114
struct i2c_adapter *parent;
144115
struct i2c_adapter *root;
145-
unsigned initial_state, gpio_base;
146-
int i, ret;
116+
unsigned initial_state;
117+
int i, ngpios, ret;
147118

148119
mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
149120
if (!mux)
@@ -158,29 +129,19 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
158129
sizeof(mux->data));
159130
}
160131

161-
/*
162-
* If a GPIO chip name is provided, the GPIO pin numbers provided are
163-
* relative to its base GPIO number. Otherwise they are absolute.
164-
*/
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;
132+
ngpios = gpiod_count(&pdev->dev, "mux");
133+
if (ngpios <= 0) {
134+
dev_err(&pdev->dev, "no valid gpios provided\n");
135+
return ngpios ?: -EINVAL;
176136
}
137+
mux->ngpios = ngpios;
177138

178139
parent = i2c_get_adapter(mux->data.parent);
179140
if (!parent)
180141
return -EPROBE_DEFER;
181142

182143
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,
184145
i2c_mux_gpio_select, NULL);
185146
if (!muxc) {
186147
ret = -ENOMEM;
@@ -194,7 +155,6 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
194155
root = i2c_root_adapter(&parent->dev);
195156

196157
muxc->mux_locked = true;
197-
mux->gpio_base = gpio_base;
198158

199159
if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) {
200160
initial_state = mux->data.idle;
@@ -203,34 +163,28 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
203163
initial_state = mux->data.values[0];
204164
}
205165

206-
for (i = 0; i < mux->data.n_gpios; i++) {
166+
for (i = 0; i < ngpios; i++) {
207167
struct device *gpio_dev;
208-
struct gpio_desc *gpio_desc;
209-
210-
ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio");
211-
if (ret) {
212-
dev_err(&pdev->dev, "Failed to request GPIO %d\n",
213-
mux->data.gpios[i]);
214-
goto err_request_gpio;
168+
struct gpio_desc *gpiod;
169+
enum gpiod_flags flag;
170+
171+
if (initial_state & BIT(i))
172+
flag = GPIOD_OUT_HIGH;
173+
else
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;
215179
}
216180

217-
ret = gpio_direction_output(gpio_base + mux->data.gpios[i],
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;
181+
mux->gpios[i] = gpiod;
229182

230183
if (!muxc->mux_locked)
231184
continue;
232185

233-
gpio_dev = &gpio_desc->gdev->dev;
186+
/* FIXME: find a proper way to access the GPIO device */
187+
gpio_dev = &gpiod->gdev->dev;
234188
muxc->mux_locked = i2c_root_adapter(gpio_dev) == root;
235189
}
236190

@@ -253,10 +207,6 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
253207

254208
add_adapter_failed:
255209
i2c_mux_del_adapters(muxc);
256-
i = mux->data.n_gpios;
257-
err_request_gpio:
258-
for (; i > 0; i--)
259-
gpio_free(gpio_base + mux->data.gpios[i - 1]);
260210
alloc_failed:
261211
i2c_put_adapter(parent);
262212

@@ -266,14 +216,8 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
266216
static int i2c_mux_gpio_remove(struct platform_device *pdev)
267217
{
268218
struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
269-
struct gpiomux *mux = i2c_mux_priv(muxc);
270-
int i;
271219

272220
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-
277221
i2c_put_adapter(muxc->parent);
278222

279223
return 0;

include/linux/platform_data/i2c-mux-gpio.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@
2222
* position
2323
* @n_values: Number of multiplexer positions (busses to instantiate)
2424
* @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
2925
* @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used
3026
*/
3127
struct i2c_mux_gpio_platform_data {
@@ -34,9 +30,6 @@ struct i2c_mux_gpio_platform_data {
3430
const unsigned *values;
3531
int n_values;
3632
const unsigned *classes;
37-
char *gpio_chip;
38-
const unsigned *gpios;
39-
int n_gpios;
4033
unsigned idle;
4134
};
4235

0 commit comments

Comments
 (0)