aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/chipidea/core.c')
-rw-r--r--drivers/usb/chipidea/core.c70
1 files changed, 64 insertions, 6 deletions
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
index 15e03b308f8a..1083585fad00 100644
--- a/drivers/usb/chipidea/core.c
+++ b/drivers/usb/chipidea/core.c
@@ -56,6 +56,7 @@
56#include <linux/init.h> 56#include <linux/init.h>
57#include <linux/platform_device.h> 57#include <linux/platform_device.h>
58#include <linux/module.h> 58#include <linux/module.h>
59#include <linux/idr.h>
59#include <linux/interrupt.h> 60#include <linux/interrupt.h>
60#include <linux/io.h> 61#include <linux/io.h>
61#include <linux/irq.h> 62#include <linux/irq.h>
@@ -179,7 +180,7 @@ static int hw_device_init(struct ci13xxx *ci, void __iomem *base)
179 ci->hw_bank.abs = base; 180 ci->hw_bank.abs = base;
180 181
181 ci->hw_bank.cap = ci->hw_bank.abs; 182 ci->hw_bank.cap = ci->hw_bank.abs;
182 ci->hw_bank.cap += ci->udc_driver->capoffset; 183 ci->hw_bank.cap += ci->platdata->capoffset;
183 ci->hw_bank.op = ci->hw_bank.cap + ioread8(ci->hw_bank.cap); 184 ci->hw_bank.op = ci->hw_bank.cap + ioread8(ci->hw_bank.cap);
184 185
185 hw_alloc_regmap(ci, false); 186 hw_alloc_regmap(ci, false);
@@ -227,11 +228,11 @@ int hw_device_reset(struct ci13xxx *ci, u32 mode)
227 udelay(10); /* not RTOS friendly */ 228 udelay(10); /* not RTOS friendly */
228 229
229 230
230 if (ci->udc_driver->notify_event) 231 if (ci->platdata->notify_event)
231 ci->udc_driver->notify_event(ci, 232 ci->platdata->notify_event(ci,
232 CI13XXX_CONTROLLER_RESET_EVENT); 233 CI13XXX_CONTROLLER_RESET_EVENT);
233 234
234 if (ci->udc_driver->flags & CI13XXX_DISABLE_STREAMING) 235 if (ci->platdata->flags & CI13XXX_DISABLE_STREAMING)
235 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS); 236 hw_write(ci, OP_USBMODE, USBMODE_CI_SDIS, USBMODE_CI_SDIS);
236 237
237 /* USBMODE should be configured step by step */ 238 /* USBMODE should be configured step by step */
@@ -332,6 +333,59 @@ static irqreturn_t ci_irq(int irq, void *data)
332 return ci->role == CI_ROLE_END ? ret : ci_role(ci)->irq(ci); 333 return ci->role == CI_ROLE_END ? ret : ci_role(ci)->irq(ci);
333} 334}
334 335
336static DEFINE_IDA(ci_ida);
337
338struct platform_device *ci13xxx_add_device(struct device *dev,
339 struct resource *res, int nres,
340 struct ci13xxx_platform_data *platdata)
341{
342 struct platform_device *pdev;
343 int id, ret;
344
345 id = ida_simple_get(&ci_ida, 0, 0, GFP_KERNEL);
346 if (id < 0)
347 return ERR_PTR(id);
348
349 pdev = platform_device_alloc("ci_hdrc", id);
350 if (!pdev) {
351 ret = -ENOMEM;
352 goto put_id;
353 }
354
355 pdev->dev.parent = dev;
356 pdev->dev.dma_mask = dev->dma_mask;
357 pdev->dev.dma_parms = dev->dma_parms;
358 dma_set_coherent_mask(&pdev->dev, dev->coherent_dma_mask);
359
360 ret = platform_device_add_resources(pdev, res, nres);
361 if (ret)
362 goto err;
363
364 ret = platform_device_add_data(pdev, platdata, sizeof(*platdata));
365 if (ret)
366 goto err;
367
368 ret = platform_device_add(pdev);
369 if (ret)
370 goto err;
371
372 return pdev;
373
374err:
375 platform_device_put(pdev);
376put_id:
377 ida_simple_remove(&ci_ida, id);
378 return ERR_PTR(ret);
379}
380EXPORT_SYMBOL_GPL(ci13xxx_add_device);
381
382void ci13xxx_remove_device(struct platform_device *pdev)
383{
384 platform_device_unregister(pdev);
385 ida_simple_remove(&ci_ida, pdev->id);
386}
387EXPORT_SYMBOL_GPL(ci13xxx_remove_device);
388
335static int __devinit ci_hdrc_probe(struct platform_device *pdev) 389static int __devinit ci_hdrc_probe(struct platform_device *pdev)
336{ 390{
337 struct device *dev = &pdev->dev; 391 struct device *dev = &pdev->dev;
@@ -364,7 +418,11 @@ static int __devinit ci_hdrc_probe(struct platform_device *pdev)
364 } 418 }
365 419
366 ci->dev = dev; 420 ci->dev = dev;
367 ci->udc_driver = dev->platform_data; 421 ci->platdata = dev->platform_data;
422 if (ci->platdata->phy)
423 ci->transceiver = ci->platdata->phy;
424 else
425 ci->global_phy = true;
368 426
369 ret = hw_device_init(ci, base); 427 ret = hw_device_init(ci, base);
370 if (ret < 0) { 428 if (ret < 0) {
@@ -419,7 +477,7 @@ static int __devinit ci_hdrc_probe(struct platform_device *pdev)
419 } 477 }
420 478
421 platform_set_drvdata(pdev, ci); 479 platform_set_drvdata(pdev, ci);
422 ret = request_irq(ci->irq, ci_irq, IRQF_SHARED, ci->udc_driver->name, 480 ret = request_irq(ci->irq, ci_irq, IRQF_SHARED, ci->platdata->name,
423 ci); 481 ci);
424 if (ret) 482 if (ret)
425 goto stop; 483 goto stop;