aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/usb251xb.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-08 13:03:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-08 13:03:52 -0400
commit132d68d37d33f1d0b9c1f507c8b4d64c27ecec8a (patch)
treeb3c05972e5579e1574873fe745fb1358c62a269c /drivers/usb/misc/usb251xb.c
parent80f232121b69cc69a31ccb2b38c1665d770b0710 (diff)
parent3515468a87a47781f6af818773650513ff14656a (diff)
Merge tag 'usb-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH: "Here is the big set of USB and PHY driver patches for 5.2-rc1 There is the usual set of: - USB gadget updates - PHY driver updates and additions - USB serial driver updates and fixes - typec updates and new chips supported - mtu3 driver updates - xhci driver updates - other tiny driver updates Nothing really interesting, just constant forward progress. All of these have been in linux-next for a while with no reported issues. The usb-gadget and usb-serial trees were merged a bit "late", but both of them had been in linux-next before they got merged here last Friday" * tag 'usb-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (206 commits) USB: serial: f81232: implement break control USB: serial: f81232: add high baud rate support USB: serial: f81232: clear overrun flag USB: serial: f81232: fix interrupt worker not stop usb: dwc3: Rename DWC3_DCTL_LPM_ERRATA usb: dwc3: Fix default lpm_nyet_threshold value usb: dwc3: debug: Print GET_STATUS(device) tracepoint usb: dwc3: Do core validation early on probe usb: dwc3: gadget: Set lpm_capable usb: gadget: atmel: tie wake lock to running clock usb: gadget: atmel: support USB suspend usb: gadget: atmel_usba_udc: simplify setting of interrupt-enabled mask dwc2: gadget: Fix completed transfer size calculation in DDMA usb: dwc2: Set lpm mode parameters depend on HW configuration usb: dwc2: Fix channel disable flow usb: dwc2: Set actual frame number for completed ISOC transfer usb: gadget: do not use __constant_cpu_to_le16 usb: dwc2: gadget: Increase descriptors count for ISOC's usb: introduce usb_ep_type_string() function usb: dwc3: move synchronize_irq() out of the spinlock protected block ...
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);