Skip to content

Commit 40758e4

Browse files
tq-steinagregkh
authored andcommitted
usb: misc: onboard_usb_hub: Add reset-gpio support
Despite default reset upon probe, release reset line after powering up the hub and assert reset again before powering down. Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com> Link: https://lore.kernel.org/r/20220727141117.909361-1-alexander.stein@ew.tq-group.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e0c6b1f commit 40758e4

2 files changed

Lines changed: 45 additions & 5 deletions

File tree

drivers/usb/misc/onboard_usb_hub.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <linux/device.h>
99
#include <linux/export.h>
10+
#include <linux/gpio/consumer.h>
1011
#include <linux/init.h>
1112
#include <linux/kernel.h>
1213
#include <linux/list.h>
@@ -38,6 +39,8 @@ struct usbdev_node {
3839
struct onboard_hub {
3940
struct regulator *vdd;
4041
struct device *dev;
42+
const struct onboard_hub_pdata *pdata;
43+
struct gpio_desc *reset_gpio;
4144
bool always_powered_in_suspend;
4245
bool is_powered_on;
4346
bool going_away;
@@ -56,6 +59,9 @@ static int onboard_hub_power_on(struct onboard_hub *hub)
5659
return err;
5760
}
5861

62+
fsleep(hub->pdata->reset_us);
63+
gpiod_set_value_cansleep(hub->reset_gpio, 0);
64+
5965
hub->is_powered_on = true;
6066

6167
return 0;
@@ -65,6 +71,11 @@ static int onboard_hub_power_off(struct onboard_hub *hub)
6571
{
6672
int err;
6773

74+
if (hub->reset_gpio) {
75+
gpiod_set_value_cansleep(hub->reset_gpio, 1);
76+
fsleep(hub->pdata->reset_us);
77+
}
78+
6879
err = regulator_disable(hub->vdd);
6980
if (err) {
7081
dev_err(hub->dev, "failed to disable regulator: %d\n", err);
@@ -219,6 +230,7 @@ static void onboard_hub_attach_usb_driver(struct work_struct *work)
219230

220231
static int onboard_hub_probe(struct platform_device *pdev)
221232
{
233+
const struct of_device_id *of_id;
222234
struct device *dev = &pdev->dev;
223235
struct onboard_hub *hub;
224236
int err;
@@ -227,10 +239,26 @@ static int onboard_hub_probe(struct platform_device *pdev)
227239
if (!hub)
228240
return -ENOMEM;
229241

242+
of_id = of_match_device(onboard_hub_match, &pdev->dev);
243+
if (!of_id)
244+
return -ENODEV;
245+
246+
hub->pdata = of_id->data;
247+
if (!hub->pdata)
248+
return -EINVAL;
249+
230250
hub->vdd = devm_regulator_get(dev, "vdd");
231251
if (IS_ERR(hub->vdd))
232252
return PTR_ERR(hub->vdd);
233253

254+
hub->reset_gpio = devm_gpiod_get_optional(dev, "reset",
255+
GPIOD_OUT_HIGH);
256+
if (IS_ERR(hub->reset_gpio))
257+
return dev_err_probe(dev, PTR_ERR(hub->reset_gpio), "failed to get reset GPIO\n");
258+
259+
if (hub->reset_gpio)
260+
fsleep(hub->pdata->reset_us);
261+
234262
hub->dev = dev;
235263
mutex_init(&hub->lock);
236264
INIT_LIST_HEAD(&hub->udev_list);

drivers/usb/misc/onboard_usb_hub.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,24 @@
66
#ifndef _USB_MISC_ONBOARD_USB_HUB_H
77
#define _USB_MISC_ONBOARD_USB_HUB_H
88

9+
struct onboard_hub_pdata {
10+
unsigned long reset_us; /* reset pulse width in us */
11+
};
12+
13+
static const struct onboard_hub_pdata microchip_usb424_data = {
14+
.reset_us = 1,
15+
};
16+
17+
static const struct onboard_hub_pdata realtek_rts5411_data = {
18+
.reset_us = 0,
19+
};
20+
921
static const struct of_device_id onboard_hub_match[] = {
10-
{ .compatible = "usb424,2514" },
11-
{ .compatible = "usbbda,411" },
12-
{ .compatible = "usbbda,5411" },
13-
{ .compatible = "usbbda,414" },
14-
{ .compatible = "usbbda,5414" },
22+
{ .compatible = "usb424,2514", .data = &microchip_usb424_data, },
23+
{ .compatible = "usbbda,411", .data = &realtek_rts5411_data, },
24+
{ .compatible = "usbbda,5411", .data = &realtek_rts5411_data, },
25+
{ .compatible = "usbbda,414", .data = &realtek_rts5411_data, },
26+
{ .compatible = "usbbda,5414", .data = &realtek_rts5411_data, },
1527
{}
1628
};
1729

0 commit comments

Comments
 (0)