aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/usb251xb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/misc/usb251xb.c')
-rw-r--r--drivers/usb/misc/usb251xb.c135
1 files changed, 90 insertions, 45 deletions
diff --git a/drivers/usb/misc/usb251xb.c b/drivers/usb/misc/usb251xb.c
index 04684849d683..4d6ae3795a88 100644
--- a/drivers/usb/misc/usb251xb.c
+++ b/drivers/usb/misc/usb251xb.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/gpio/consumer.h> 14#include <linux/gpio/consumer.h>
15#include <linux/gpio/driver.h>
15#include <linux/i2c.h> 16#include <linux/i2c.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/nls.h> 18#include <linux/nls.h>
@@ -222,11 +223,51 @@ static const struct usb251xb_data usb2517i_data = {
222 .product_str = "USB2517i", 223 .product_str = "USB2517i",
223}; 224};
224 225
226#ifdef CONFIG_GPIOLIB
227static int usb251xb_check_dev_children(struct device *dev, void *child)
228{
229 if (dev->type == &i2c_adapter_type) {
230 return device_for_each_child(dev, child,
231 usb251xb_check_dev_children);
232 }
233
234 return (dev == child);
235}
236
237static int usb251x_check_gpio_chip(struct usb251xb *hub)
238{
239 struct gpio_chip *gc = gpiod_to_chip(hub->gpio_reset);
240 struct i2c_adapter *adap = hub->i2c->adapter;
241 int ret;
242
243 if (!hub->gpio_reset)
244 return 0;
245
246 if (!gc)
247 return -EINVAL;
248
249 ret = usb251xb_check_dev_children(&adap->dev, gc->parent);
250 if (ret) {
251 dev_err(hub->dev, "Reset GPIO chip is at the same i2c-bus\n");
252 return -EINVAL;
253 }
254
255 return 0;
256}
257#else
258static int usb251x_check_gpio_chip(struct usb251xb *hub)
259{
260 return 0;
261}
262#endif
263
225static void usb251xb_reset(struct usb251xb *hub, int state) 264static void usb251xb_reset(struct usb251xb *hub, int state)
226{ 265{
227 if (!hub->gpio_reset) 266 if (!hub->gpio_reset)
228 return; 267 return;
229 268
269 i2c_lock_bus(hub->i2c->adapter, I2C_LOCK_SEGMENT);
270
230 gpiod_set_value_cansleep(hub->gpio_reset, state); 271 gpiod_set_value_cansleep(hub->gpio_reset, state);
231 272
232 /* wait for hub recovery/stabilization */ 273 /* wait for hub recovery/stabilization */
@@ -234,6 +275,8 @@ static void usb251xb_reset(struct usb251xb *hub, int state)
234 usleep_range(500, 750); /* >=500us at power on */ 275 usleep_range(500, 750); /* >=500us at power on */
235 else 276 else
236 usleep_range(1, 10); /* >=1us at power down */ 277 usleep_range(1, 10); /* >=1us at power down */
278
279 i2c_unlock_bus(hub->i2c->adapter, I2C_LOCK_SEGMENT);
237} 280}
238 281
239static int usb251xb_connect(struct usb251xb *hub) 282static int usb251xb_connect(struct usb251xb *hub)
@@ -331,18 +374,31 @@ out_err:
331} 374}
332 375
333#ifdef CONFIG_OF 376#ifdef CONFIG_OF
377static void usb251xb_get_ports_field(struct usb251xb *hub,
378 const char *prop_name, u8 port_cnt, u8 *fld)
379{
380 struct device *dev = hub->dev;
381 struct property *prop;
382 const __be32 *p;
383 u32 port;
384
385 of_property_for_each_u32(dev->of_node, prop_name, prop, p, port) {
386 if ((port >= 1) && (port <= port_cnt))
387 *fld |= BIT(port);
388 else
389 dev_warn(dev, "port %u doesn't exist\n", port);
390 }
391}
392
334static int usb251xb_get_ofdata(struct usb251xb *hub, 393static int usb251xb_get_ofdata(struct usb251xb *hub,
335 struct usb251xb_data *data) 394 struct usb251xb_data *data)
336{ 395{
337 struct device *dev = hub->dev; 396 struct device *dev = hub->dev;
338 struct device_node *np = dev->of_node; 397 struct device_node *np = dev->of_node;
339 int len, err, i; 398 int len, err;
340 u32 port, property_u32 = 0; 399 u32 property_u32 = 0;
341 const u32 *cproperty_u32;
342 const char *cproperty_char; 400 const char *cproperty_char;
343 char str[USB251XB_STRING_BUFSIZE / 2]; 401 char str[USB251XB_STRING_BUFSIZE / 2];
344 struct property *prop;
345 const __be32 *p;
346 402
347 if (!np) { 403 if (!np) {
348 dev_err(dev, "failed to get ofdata\n"); 404 dev_err(dev, "failed to get ofdata\n");
@@ -444,46 +500,16 @@ static int usb251xb_get_ofdata(struct usb251xb *hub,
444 hub->conf_data3 |= BIT(0); 500 hub->conf_data3 |= BIT(0);
445 501
446 hub->non_rem_dev = USB251XB_DEF_NON_REMOVABLE_DEVICES; 502 hub->non_rem_dev = USB251XB_DEF_NON_REMOVABLE_DEVICES;
447 cproperty_u32 = of_get_property(np, "non-removable-ports", &len); 503 usb251xb_get_ports_field(hub, "non-removable-ports", data->port_cnt,
448 if (cproperty_u32 && (len / sizeof(u32)) > 0) { 504 &hub->non_rem_dev);
449 for (i = 0; i < len / sizeof(u32); i++) {
450 u32 port = be32_to_cpu(cproperty_u32[i]);
451
452 if ((port >= 1) && (port <= data->port_cnt))
453 hub->non_rem_dev |= BIT(port);
454 else
455 dev_warn(dev, "NRD port %u doesn't exist\n",
456 port);
457 }
458 }
459 505
460 hub->port_disable_sp = USB251XB_DEF_PORT_DISABLE_SELF; 506 hub->port_disable_sp = USB251XB_DEF_PORT_DISABLE_SELF;
461 cproperty_u32 = of_get_property(np, "sp-disabled-ports", &len); 507 usb251xb_get_ports_field(hub, "sp-disabled-ports", data->port_cnt,
462 if (cproperty_u32 && (len / sizeof(u32)) > 0) { 508 &hub->port_disable_sp);
463 for (i = 0; i < len / sizeof(u32); i++) {
464 u32 port = be32_to_cpu(cproperty_u32[i]);
465
466 if ((port >= 1) && (port <= data->port_cnt))
467 hub->port_disable_sp |= BIT(port);
468 else
469 dev_warn(dev, "PDS port %u doesn't exist\n",
470 port);
471 }
472 }
473 509
474 hub->port_disable_bp = USB251XB_DEF_PORT_DISABLE_BUS; 510 hub->port_disable_bp = USB251XB_DEF_PORT_DISABLE_BUS;
475 cproperty_u32 = of_get_property(np, "bp-disabled-ports", &len); 511 usb251xb_get_ports_field(hub, "bp-disabled-ports", data->port_cnt,
476 if (cproperty_u32 && (len / sizeof(u32)) > 0) { 512 &hub->port_disable_bp);
477 for (i = 0; i < len / sizeof(u32); i++) {
478 u32 port = be32_to_cpu(cproperty_u32[i]);
479
480 if ((port >= 1) && (port <= data->port_cnt))
481 hub->port_disable_bp |= BIT(port);
482 else
483 dev_warn(dev, "PDB port %u doesn't exist\n",
484 port);
485 }
486 }
487 513
488 hub->max_power_sp = USB251XB_DEF_MAX_POWER_SELF; 514 hub->max_power_sp = USB251XB_DEF_MAX_POWER_SELF;
489 if (!of_property_read_u32(np, "sp-max-total-current-microamp", 515 if (!of_property_read_u32(np, "sp-max-total-current-microamp",
@@ -546,10 +572,10 @@ static int usb251xb_get_ofdata(struct usb251xb *hub,
546 * register controls the USB DP/DM signal swapping for each port. 572 * register controls the USB DP/DM signal swapping for each port.
547 */ 573 */
548 hub->port_swap = USB251XB_DEF_PORT_SWAP; 574 hub->port_swap = USB251XB_DEF_PORT_SWAP;
549 of_property_for_each_u32(np, "swap-dx-lanes", prop, p, port) { 575 usb251xb_get_ports_field(hub, "swap-dx-lanes", data->port_cnt,
550 if (port <= data->port_cnt) 576 &hub->port_swap);
551 hub->port_swap |= BIT(port); 577 if (of_get_property(np, "swap-us-lanes", NULL))
552 } 578 hub->port_swap |= BIT(0);
553 579
554 /* The following parameters are currently not exposed to devicetree, but 580 /* The following parameters are currently not exposed to devicetree, but
555 * may be as soon as needed. 581 * may be as soon as needed.
@@ -621,6 +647,25 @@ static int usb251xb_probe(struct usb251xb *hub)
621 } 647 }
622 } 648 }
623 649
650 /*
651 * usb251x SMBus-slave SCL lane is muxed with CFG_SEL0 pin. So if anyone
652 * tries to work with the bus at the moment the hub reset is released,
653 * it may cause an invalid config being latched by usb251x. Particularly
654 * one of the config modes makes the hub loading a default registers
655 * value without SMBus-slave interface activation. If the hub
656 * accidentally gets this mode, this will cause the driver SMBus-
657 * functions failure. Normally we could just lock the SMBus-segment the
658 * hub i2c-interface resides for the device-specific reset timing. But
659 * the GPIO controller, which is used to handle the hub reset, might be
660 * placed at the same i2c-bus segment. In this case an error should be
661 * returned since we can't safely use the GPIO controller to clear the
662 * reset state (it may affect the hub configuration) and we can't lock
663 * the i2c-bus segment (it will cause a deadlock).
664 */
665 err = usb251x_check_gpio_chip(hub);
666 if (err)
667 return err;
668
624 err = usb251xb_connect(hub); 669 err = usb251xb_connect(hub);
625 if (err) { 670 if (err) {
626 dev_err(dev, "Failed to connect hub (%d)\n", err); 671 dev_err(dev, "Failed to connect hub (%d)\n", err);