Skip to content

Commit f40017e

Browse files
agnersgregkh
authored andcommitted
chipidea: usbmisc_imx: Add USB support for VF610 SoCs
This adds Vybrid VF610 SoC support. The IP is very similar to i.MX6, however, the non-core registers are spread in two different register areas. Hence we support multiple instances of the USB misc driver and add the driver instance to the imx_usbmisc_data structure. Signed-off-by: Peter Chen <[email protected]> Signed-off-by: Stefan Agner <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent c0e602d commit f40017e

File tree

4 files changed

+51
-11
lines changed

4 files changed

+51
-11
lines changed

Documentation/devicetree/bindings/usb/usbmisc-imx.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Required properties:
44
- #index-cells: Cells used to descibe usb controller index. Should be <1>
55
- compatible: Should be one of below:
66
"fsl,imx6q-usbmisc" for imx6q
7+
"fsl,vf610-usbmisc" for Vybrid vf610
78
- reg: Should contain registers location and length
89

910
Examples:

drivers/usb/chipidea/ci_hdrc_imx.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ struct ci_hdrc_imx_data {
5454

5555
static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
5656
{
57+
struct platform_device *misc_pdev;
5758
struct device_node *np = dev->of_node;
5859
struct of_phandle_args args;
5960
struct imx_usbmisc_data *data;
@@ -79,8 +80,15 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
7980
}
8081

8182
data->index = args.args[0];
83+
84+
misc_pdev = of_find_device_by_node(args.np);
8285
of_node_put(args.np);
8386

87+
if (!misc_pdev)
88+
return ERR_PTR(-EPROBE_DEFER);
89+
90+
data->dev = &misc_pdev->dev;
91+
8492
if (of_find_property(np, "disable-over-current", NULL))
8593
data->disable_oc = 1;
8694

drivers/usb/chipidea/ci_hdrc_imx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define __DRIVER_USB_CHIPIDEA_CI_HDRC_IMX_H
1414

1515
struct imx_usbmisc_data {
16+
struct device *dev;
1617
int index;
1718

1819
unsigned int disable_oc:1; /* over current detect disabled */

drivers/usb/chipidea/usbmisc_imx.c

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757

5858
#define MX6_BM_OVER_CUR_DIS BIT(7)
5959

60+
#define VF610_OVER_CUR_DIS BIT(7)
61+
6062
struct usbmisc_ops {
6163
/* It's called once when probe a usb device */
6264
int (*init)(struct imx_usbmisc_data *data);
@@ -71,10 +73,9 @@ struct imx_usbmisc {
7173
const struct usbmisc_ops *ops;
7274
};
7375

74-
static struct imx_usbmisc *usbmisc;
75-
7676
static int usbmisc_imx25_init(struct imx_usbmisc_data *data)
7777
{
78+
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
7879
unsigned long flags;
7980
u32 val = 0;
8081

@@ -108,6 +109,7 @@ static int usbmisc_imx25_init(struct imx_usbmisc_data *data)
108109

109110
static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
110111
{
112+
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
111113
void __iomem *reg;
112114
unsigned long flags;
113115
u32 val;
@@ -130,6 +132,7 @@ static int usbmisc_imx25_post(struct imx_usbmisc_data *data)
130132

131133
static int usbmisc_imx27_init(struct imx_usbmisc_data *data)
132134
{
135+
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
133136
unsigned long flags;
134137
u32 val;
135138

@@ -160,6 +163,7 @@ static int usbmisc_imx27_init(struct imx_usbmisc_data *data)
160163

161164
static int usbmisc_imx53_init(struct imx_usbmisc_data *data)
162165
{
166+
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
163167
void __iomem *reg = NULL;
164168
unsigned long flags;
165169
u32 val = 0;
@@ -204,6 +208,7 @@ static int usbmisc_imx53_init(struct imx_usbmisc_data *data)
204208

205209
static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
206210
{
211+
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
207212
unsigned long flags;
208213
u32 reg;
209214

@@ -221,6 +226,26 @@ static int usbmisc_imx6q_init(struct imx_usbmisc_data *data)
221226
return 0;
222227
}
223228

229+
static int usbmisc_vf610_init(struct imx_usbmisc_data *data)
230+
{
231+
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
232+
u32 reg;
233+
234+
/*
235+
* Vybrid only has one misc register set, but in two different
236+
* areas. These is reflected in two instances of this driver.
237+
*/
238+
if (data->index >= 1)
239+
return -EINVAL;
240+
241+
if (data->disable_oc) {
242+
reg = readl(usbmisc->base);
243+
writel(reg | VF610_OVER_CUR_DIS, usbmisc->base);
244+
}
245+
246+
return 0;
247+
}
248+
224249
static const struct usbmisc_ops imx25_usbmisc_ops = {
225250
.init = usbmisc_imx25_init,
226251
.post = usbmisc_imx25_post,
@@ -238,10 +263,14 @@ static const struct usbmisc_ops imx6q_usbmisc_ops = {
238263
.init = usbmisc_imx6q_init,
239264
};
240265

266+
static const struct usbmisc_ops vf610_usbmisc_ops = {
267+
.init = usbmisc_vf610_init,
268+
};
269+
241270
int imx_usbmisc_init(struct imx_usbmisc_data *data)
242271
{
243-
if (!usbmisc)
244-
return -EPROBE_DEFER;
272+
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
273+
245274
if (!usbmisc->ops->init)
246275
return 0;
247276
return usbmisc->ops->init(data);
@@ -250,8 +279,8 @@ EXPORT_SYMBOL_GPL(imx_usbmisc_init);
250279

251280
int imx_usbmisc_init_post(struct imx_usbmisc_data *data)
252281
{
253-
if (!usbmisc)
254-
return -EPROBE_DEFER;
282+
struct imx_usbmisc *usbmisc = dev_get_drvdata(data->dev);
283+
255284
if (!usbmisc->ops->post)
256285
return 0;
257286
return usbmisc->ops->post(data);
@@ -283,6 +312,10 @@ static const struct of_device_id usbmisc_imx_dt_ids[] = {
283312
.compatible = "fsl,imx6q-usbmisc",
284313
.data = &imx6q_usbmisc_ops,
285314
},
315+
{
316+
.compatible = "fsl,vf610-usbmisc",
317+
.data = &vf610_usbmisc_ops,
318+
},
286319
{ /* sentinel */ }
287320
};
288321
MODULE_DEVICE_TABLE(of, usbmisc_imx_dt_ids);
@@ -294,9 +327,6 @@ static int usbmisc_imx_probe(struct platform_device *pdev)
294327
int ret;
295328
struct of_device_id *tmp_dev;
296329

297-
if (usbmisc)
298-
return -EBUSY;
299-
300330
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
301331
if (!data)
302332
return -ENOMEM;
@@ -325,15 +355,15 @@ static int usbmisc_imx_probe(struct platform_device *pdev)
325355
tmp_dev = (struct of_device_id *)
326356
of_match_device(usbmisc_imx_dt_ids, &pdev->dev);
327357
data->ops = (const struct usbmisc_ops *)tmp_dev->data;
328-
usbmisc = data;
358+
platform_set_drvdata(pdev, data);
329359

330360
return 0;
331361
}
332362

333363
static int usbmisc_imx_remove(struct platform_device *pdev)
334364
{
365+
struct imx_usbmisc *usbmisc = dev_get_drvdata(&pdev->dev);
335366
clk_disable_unprepare(usbmisc->clk);
336-
usbmisc = NULL;
337367
return 0;
338368
}
339369

0 commit comments

Comments
 (0)