Skip to content

Commit 8e0285a

Browse files
author
Linus Walleij
committed
ARM/musb: omap2: Remove global GPIO numbers from TUSB6010
The TUSB6010 (MUSB) device is picking up some GPIO lines hardcoded by number and passing on to the TUSB6010 device when registering it. Instead of nasty workarounds, provide a GPIO descriptor table and then make the TUSB6010 MUSB glue driver pick up the GPIO lines directly, convert it to an IRQ and pass down to the MUSB driver. OMAP2 is the only system using the TUSB6010. Stash the GPIO descriptors in the glue layer and use then to power up and down the TUSB6010 on-demand, instead of using boardfile callbacks. Since the OMAP2 boards are the only boards using the .set_power() and .board_set_power() callbacks, we can just delete them as the power is now handled directly in the TUSB6010 glue code. Cc: Bin Liu <b-liu@ti.com> Cc: linux-usb@vger.kernel.org Fixes: 92bf78b ("gpio: omap: use dynamic allocation of base") Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 078dc51 commit 8e0285a

7 files changed

Lines changed: 73 additions & 99 deletions

File tree

arch/arm/mach-omap2/board-n8x0.c

Lines changed: 18 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
#include <linux/clk.h>
1212
#include <linux/delay.h>
13-
#include <linux/gpio.h>
1413
#include <linux/gpio/machine.h>
14+
#include <linux/gpio/consumer.h>
1515
#include <linux/init.h>
1616
#include <linux/io.h>
1717
#include <linux/irq.h>
@@ -29,13 +29,12 @@
2929

3030
#include "common.h"
3131
#include "mmc.h"
32+
#include "usb-tusb6010.h"
3233
#include "soc.h"
3334
#include "common-board-devices.h"
3435

3536
#define TUSB6010_ASYNC_CS 1
3637
#define TUSB6010_SYNC_CS 4
37-
#define TUSB6010_GPIO_INT 58
38-
#define TUSB6010_GPIO_ENABLE 0
3938
#define TUSB6010_DMACHAN 0x3f
4039

4140
#define NOKIA_N810_WIMAX (1 << 2)
@@ -62,37 +61,6 @@ static void board_check_revision(void)
6261
}
6362

6463
#if IS_ENABLED(CONFIG_USB_MUSB_TUSB6010)
65-
/*
66-
* Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
67-
* 1.5 V voltage regulators of PM companion chip. Companion chip will then
68-
* provide then PGOOD signal to TUSB6010 which will release it from reset.
69-
*/
70-
static int tusb_set_power(int state)
71-
{
72-
int i, retval = 0;
73-
74-
if (state) {
75-
gpio_set_value(TUSB6010_GPIO_ENABLE, 1);
76-
msleep(1);
77-
78-
/* Wait until TUSB6010 pulls INT pin down */
79-
i = 100;
80-
while (i && gpio_get_value(TUSB6010_GPIO_INT)) {
81-
msleep(1);
82-
i--;
83-
}
84-
85-
if (!i) {
86-
printk(KERN_ERR "tusb: powerup failed\n");
87-
retval = -ENODEV;
88-
}
89-
} else {
90-
gpio_set_value(TUSB6010_GPIO_ENABLE, 0);
91-
msleep(10);
92-
}
93-
94-
return retval;
95-
}
9664

9765
static struct musb_hdrc_config musb_config = {
9866
.multipoint = 1,
@@ -103,39 +71,36 @@ static struct musb_hdrc_config musb_config = {
10371

10472
static struct musb_hdrc_platform_data tusb_data = {
10573
.mode = MUSB_OTG,
106-
.set_power = tusb_set_power,
10774
.min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */
10875
.power = 100, /* Max 100 mA VBUS for host mode */
10976
.config = &musb_config,
11077
};
11178

79+
static struct gpiod_lookup_table tusb_gpio_table = {
80+
.dev_id = "musb-tusb",
81+
.table = {
82+
GPIO_LOOKUP("gpio-0-15", 0, "enable",
83+
GPIO_ACTIVE_HIGH),
84+
GPIO_LOOKUP("gpio-48-63", 10, "int",
85+
GPIO_ACTIVE_HIGH),
86+
{ }
87+
},
88+
};
89+
11290
static void __init n8x0_usb_init(void)
11391
{
11492
int ret = 0;
115-
static const char announce[] __initconst = KERN_INFO "TUSB 6010\n";
116-
117-
/* PM companion chip power control pin */
118-
ret = gpio_request_one(TUSB6010_GPIO_ENABLE, GPIOF_OUT_INIT_LOW,
119-
"TUSB6010 enable");
120-
if (ret != 0) {
121-
printk(KERN_ERR "Could not get TUSB power GPIO%i\n",
122-
TUSB6010_GPIO_ENABLE);
123-
return;
124-
}
125-
tusb_set_power(0);
12693

94+
gpiod_add_lookup_table(&tusb_gpio_table);
12795
ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2,
128-
TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
129-
TUSB6010_GPIO_INT, TUSB6010_DMACHAN);
96+
TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS,
97+
TUSB6010_DMACHAN);
13098
if (ret != 0)
131-
goto err;
99+
return;
132100

133-
printk(announce);
101+
pr_info("TUSB 6010\n");
134102

135103
return;
136-
137-
err:
138-
gpio_free(TUSB6010_GPIO_ENABLE);
139104
}
140105
#else
141106

arch/arm/mach-omap2/usb-tusb6010.c

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
#include <linux/errno.h>
1212
#include <linux/delay.h>
1313
#include <linux/platform_device.h>
14-
#include <linux/gpio.h>
1514
#include <linux/export.h>
1615
#include <linux/platform_data/usb-omap.h>
1716

1817
#include <linux/usb/musb.h>
1918

19+
#include "usb-tusb6010.h"
2020
#include "gpmc.h"
2121

2222
static u8 async_cs, sync_cs;
@@ -132,10 +132,6 @@ static struct resource tusb_resources[] = {
132132
{ /* Synchronous access */
133133
.flags = IORESOURCE_MEM,
134134
},
135-
{ /* IRQ */
136-
.name = "mc",
137-
.flags = IORESOURCE_IRQ,
138-
},
139135
};
140136

141137
static u64 tusb_dmamask = ~(u32)0;
@@ -154,9 +150,9 @@ static struct platform_device tusb_device = {
154150

155151
/* this may be called only from board-*.c setup code */
156152
int __init tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
157-
unsigned ps_refclk, unsigned waitpin,
158-
unsigned async, unsigned sync,
159-
unsigned irq, unsigned dmachan)
153+
unsigned int ps_refclk, unsigned int waitpin,
154+
unsigned int async, unsigned int sync,
155+
unsigned int dmachan)
160156
{
161157
int status;
162158
static char error[] __initdata =
@@ -192,14 +188,6 @@ int __init tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
192188
if (status < 0)
193189
return status;
194190

195-
/* IRQ */
196-
status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
197-
if (status < 0) {
198-
printk(error, 3, status);
199-
return status;
200-
}
201-
tusb_resources[2].start = gpio_to_irq(irq);
202-
203191
/* set up memory timings ... can speed them up later */
204192
if (!ps_refclk) {
205193
printk(error, 4, status);

arch/arm/mach-omap2/usb-tusb6010.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
3+
#ifndef __USB_TUSB6010_H
4+
#define __USB_TUSB6010_H
5+
6+
extern int __init tusb6010_setup_interface(
7+
struct musb_hdrc_platform_data *data,
8+
unsigned int ps_refclk, unsigned int waitpin,
9+
unsigned int async_cs, unsigned int sync_cs,
10+
unsigned int dmachan);
11+
12+
#endif /* __USB_TUSB6010_H */

drivers/usb/musb/musb_core.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2330,7 +2330,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
23302330

23312331
spin_lock_init(&musb->lock);
23322332
spin_lock_init(&musb->list_lock);
2333-
musb->board_set_power = plat->set_power;
23342333
musb->min_power = plat->min_power;
23352334
musb->ops = plat->platform_ops;
23362335
musb->port_mode = plat->mode;

drivers/usb/musb/musb_core.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,6 @@ struct musb {
352352
u16 epmask;
353353
u8 nr_endpoints;
354354

355-
int (*board_set_power)(int state);
356-
357355
u8 min_power; /* vbus for periph, in mA/2 */
358356

359357
enum musb_mode port_mode;

drivers/usb/musb/tusb6010.c

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
* interface.
1212
*/
1313

14+
#include <linux/gpio/consumer.h>
15+
#include <linux/delay.h>
1416
#include <linux/module.h>
1517
#include <linux/kernel.h>
1618
#include <linux/errno.h>
@@ -30,6 +32,8 @@ struct tusb6010_glue {
3032
struct device *dev;
3133
struct platform_device *musb;
3234
struct platform_device *phy;
35+
struct gpio_desc *enable;
36+
struct gpio_desc *intpin;
3337
};
3438

3539
static void tusb_musb_set_vbus(struct musb *musb, int is_on);
@@ -1021,16 +1025,29 @@ static void tusb_setup_cpu_interface(struct musb *musb)
10211025

10221026
static int tusb_musb_start(struct musb *musb)
10231027
{
1028+
struct tusb6010_glue *glue = dev_get_drvdata(musb->controller->parent);
10241029
void __iomem *tbase = musb->ctrl_base;
1025-
int ret = 0;
10261030
unsigned long flags;
10271031
u32 reg;
1032+
int i;
10281033

1029-
if (musb->board_set_power)
1030-
ret = musb->board_set_power(1);
1031-
if (ret != 0) {
1032-
printk(KERN_ERR "tusb: Cannot enable TUSB6010\n");
1033-
return ret;
1034+
/*
1035+
* Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and
1036+
* 1.5 V voltage regulators of PM companion chip. Companion chip will then
1037+
* provide then PGOOD signal to TUSB6010 which will release it from reset.
1038+
*/
1039+
gpiod_set_value(glue->enable, 1);
1040+
msleep(1);
1041+
1042+
/* Wait for 100ms until TUSB6010 pulls INT pin down */
1043+
i = 100;
1044+
while (i && gpiod_get_value(glue->intpin)) {
1045+
msleep(1);
1046+
i--;
1047+
}
1048+
if (!i) {
1049+
pr_err("tusb: Powerup respones failed\n");
1050+
return -ENODEV;
10341051
}
10351052

10361053
spin_lock_irqsave(&musb->lock, flags);
@@ -1083,8 +1100,8 @@ static int tusb_musb_start(struct musb *musb)
10831100
err:
10841101
spin_unlock_irqrestore(&musb->lock, flags);
10851102

1086-
if (musb->board_set_power)
1087-
musb->board_set_power(0);
1103+
gpiod_set_value(glue->enable, 0);
1104+
msleep(10);
10881105

10891106
return -ENODEV;
10901107
}
@@ -1158,11 +1175,13 @@ static int tusb_musb_init(struct musb *musb)
11581175

11591176
static int tusb_musb_exit(struct musb *musb)
11601177
{
1178+
struct tusb6010_glue *glue = dev_get_drvdata(musb->controller->parent);
1179+
11611180
del_timer_sync(&musb->dev_timer);
11621181
the_musb = NULL;
11631182

1164-
if (musb->board_set_power)
1165-
musb->board_set_power(0);
1183+
gpiod_set_value(glue->enable, 0);
1184+
msleep(10);
11661185

11671186
iounmap(musb->sync_va);
11681187

@@ -1218,6 +1237,15 @@ static int tusb_probe(struct platform_device *pdev)
12181237

12191238
glue->dev = &pdev->dev;
12201239

1240+
glue->enable = devm_gpiod_get(glue->dev, "enable", GPIOD_OUT_LOW);
1241+
if (IS_ERR(glue->enable))
1242+
return dev_err_probe(glue->dev, PTR_ERR(glue->enable),
1243+
"could not obtain power on/off GPIO\n");
1244+
glue->intpin = devm_gpiod_get(glue->dev, "int", GPIOD_IN);
1245+
if (IS_ERR(glue->intpin))
1246+
return dev_err_probe(glue->dev, PTR_ERR(glue->intpin),
1247+
"could not obtain INT GPIO\n");
1248+
12211249
pdata->platform_ops = &tusb_ops;
12221250

12231251
usb_phy_generic_register();
@@ -1236,10 +1264,7 @@ static int tusb_probe(struct platform_device *pdev)
12361264
musb_resources[1].end = pdev->resource[1].end;
12371265
musb_resources[1].flags = pdev->resource[1].flags;
12381266

1239-
musb_resources[2].name = pdev->resource[2].name;
1240-
musb_resources[2].start = pdev->resource[2].start;
1241-
musb_resources[2].end = pdev->resource[2].end;
1242-
musb_resources[2].flags = pdev->resource[2].flags;
1267+
musb_resources[2] = DEFINE_RES_IRQ_NAMED(gpiod_to_irq(glue->intpin), "mc");
12431268

12441269
pinfo = tusb_dev_info;
12451270
pinfo.parent = &pdev->dev;

include/linux/usb/musb.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,6 @@ struct musb_hdrc_platform_data {
9999
/* (HOST or OTG) program PHY for external Vbus */
100100
unsigned extvbus:1;
101101

102-
/* Power the device on or off */
103-
int (*set_power)(int state);
104-
105102
/* MUSB configuration-specific details */
106103
const struct musb_hdrc_config *config;
107104

@@ -135,14 +132,4 @@ static inline int musb_mailbox(enum musb_vbus_id_status status)
135132
#define TUSB6010_REFCLK_24 41667 /* psec/clk @ 24.0 MHz XI */
136133
#define TUSB6010_REFCLK_19 52083 /* psec/clk @ 19.2 MHz CLKIN */
137134

138-
#ifdef CONFIG_ARCH_OMAP2
139-
140-
extern int __init tusb6010_setup_interface(
141-
struct musb_hdrc_platform_data *data,
142-
unsigned ps_refclk, unsigned waitpin,
143-
unsigned async_cs, unsigned sync_cs,
144-
unsigned irq, unsigned dmachan);
145-
146-
#endif /* OMAP2 */
147-
148135
#endif /* __LINUX_USB_MUSB_H */

0 commit comments

Comments
 (0)