diff options
Diffstat (limited to 'drivers')
95 files changed, 14436 insertions, 1840 deletions
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c index c91424c0c135..99c81a9a4f46 100644 --- a/drivers/media/video/tlg2300/pd-main.c +++ b/drivers/media/video/tlg2300/pd-main.c | |||
| @@ -452,7 +452,8 @@ static int poseidon_probe(struct usb_interface *interface, | |||
| 452 | 452 | ||
| 453 | device_init_wakeup(&udev->dev, 1); | 453 | device_init_wakeup(&udev->dev, 1); |
| 454 | #ifdef CONFIG_PM | 454 | #ifdef CONFIG_PM |
| 455 | pd->udev->autosuspend_delay = HZ * PM_SUSPEND_DELAY; | 455 | pm_runtime_set_autosuspend_delay(&pd->udev->dev, |
| 456 | 1000 * PM_SUSPEND_DELAY); | ||
| 456 | usb_enable_autosuspend(pd->udev); | 457 | usb_enable_autosuspend(pd->udev); |
| 457 | 458 | ||
| 458 | if (in_hibernation(pd)) { | 459 | if (in_hibernation(pd)) { |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 35275ba7096f..12abd5b924b3 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
| @@ -95,7 +95,8 @@ | |||
| 95 | #define twl_has_rtc() false | 95 | #define twl_has_rtc() false |
| 96 | #endif | 96 | #endif |
| 97 | 97 | ||
| 98 | #if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) | 98 | #if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) ||\ |
| 99 | defined(CONFIG_TWL6030_USB) || defined(CONFIG_TWL6030_USB_MODULE) | ||
| 99 | #define twl_has_usb() true | 100 | #define twl_has_usb() true |
| 100 | #else | 101 | #else |
| 101 | #define twl_has_usb() false | 102 | #define twl_has_usb() false |
| @@ -682,6 +683,43 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
| 682 | usb3v1.dev = child; | 683 | usb3v1.dev = child; |
| 683 | } | 684 | } |
| 684 | } | 685 | } |
| 686 | if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { | ||
| 687 | |||
| 688 | static struct regulator_consumer_supply usb3v3 = { | ||
| 689 | .supply = "vusb", | ||
| 690 | }; | ||
| 691 | |||
| 692 | if (twl_has_regulator()) { | ||
| 693 | /* this is a template that gets copied */ | ||
| 694 | struct regulator_init_data usb_fixed = { | ||
| 695 | .constraints.valid_modes_mask = | ||
| 696 | REGULATOR_MODE_NORMAL | ||
| 697 | | REGULATOR_MODE_STANDBY, | ||
| 698 | .constraints.valid_ops_mask = | ||
| 699 | REGULATOR_CHANGE_MODE | ||
| 700 | | REGULATOR_CHANGE_STATUS, | ||
| 701 | }; | ||
| 702 | |||
| 703 | child = add_regulator_linked(TWL6030_REG_VUSB, | ||
| 704 | &usb_fixed, &usb3v3, 1); | ||
| 705 | if (IS_ERR(child)) | ||
| 706 | return PTR_ERR(child); | ||
| 707 | } | ||
| 708 | |||
| 709 | child = add_child(0, "twl6030_usb", | ||
| 710 | pdata->usb, sizeof(*pdata->usb), | ||
| 711 | true, | ||
| 712 | /* irq1 = VBUS_PRES, irq0 = USB ID */ | ||
| 713 | pdata->irq_base + USBOTG_INTR_OFFSET, | ||
| 714 | pdata->irq_base + USB_PRES_INTR_OFFSET); | ||
| 715 | |||
| 716 | if (IS_ERR(child)) | ||
| 717 | return PTR_ERR(child); | ||
| 718 | /* we need to connect regulators to this transceiver */ | ||
| 719 | if (twl_has_regulator() && child) | ||
| 720 | usb3v3.dev = child; | ||
| 721 | |||
| 722 | } | ||
| 685 | 723 | ||
| 686 | if (twl_has_watchdog()) { | 724 | if (twl_has_watchdog()) { |
| 687 | child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); | 725 | child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); |
| @@ -815,10 +853,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) | |||
| 815 | if (IS_ERR(child)) | 853 | if (IS_ERR(child)) |
| 816 | return PTR_ERR(child); | 854 | return PTR_ERR(child); |
| 817 | 855 | ||
| 818 | child = add_regulator(TWL6030_REG_VUSB, pdata->vusb); | ||
| 819 | if (IS_ERR(child)) | ||
| 820 | return PTR_ERR(child); | ||
| 821 | |||
| 822 | child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1); | 856 | child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1); |
| 823 | if (IS_ERR(child)) | 857 | if (IS_ERR(child)) |
| 824 | return PTR_ERR(child); | 858 | return PTR_ERR(child); |
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index aaedb11d9d2c..06c8955907e9 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
| @@ -74,7 +74,7 @@ static int twl6030_interrupt_mapping[24] = { | |||
| 74 | USBOTG_INTR_OFFSET, /* Bit 16 ID_WKUP */ | 74 | USBOTG_INTR_OFFSET, /* Bit 16 ID_WKUP */ |
| 75 | USBOTG_INTR_OFFSET, /* Bit 17 VBUS_WKUP */ | 75 | USBOTG_INTR_OFFSET, /* Bit 17 VBUS_WKUP */ |
| 76 | USBOTG_INTR_OFFSET, /* Bit 18 ID */ | 76 | USBOTG_INTR_OFFSET, /* Bit 18 ID */ |
| 77 | USBOTG_INTR_OFFSET, /* Bit 19 VBUS */ | 77 | USB_PRES_INTR_OFFSET, /* Bit 19 VBUS */ |
| 78 | CHARGER_INTR_OFFSET, /* Bit 20 CHRG_CTRL */ | 78 | CHARGER_INTR_OFFSET, /* Bit 20 CHRG_CTRL */ |
| 79 | CHARGER_INTR_OFFSET, /* Bit 21 EXT_CHRG */ | 79 | CHARGER_INTR_OFFSET, /* Bit 21 EXT_CHRG */ |
| 80 | CHARGER_INTR_OFFSET, /* Bit 22 INT_CHRG */ | 80 | CHARGER_INTR_OFFSET, /* Bit 22 INT_CHRG */ |
| @@ -128,6 +128,13 @@ static int twl6030_irq_thread(void *data) | |||
| 128 | 128 | ||
| 129 | sts.bytes[3] = 0; /* Only 24 bits are valid*/ | 129 | sts.bytes[3] = 0; /* Only 24 bits are valid*/ |
| 130 | 130 | ||
| 131 | /* | ||
| 132 | * Since VBUS status bit is not reliable for VBUS disconnect | ||
| 133 | * use CHARGER VBUS detection status bit instead. | ||
| 134 | */ | ||
| 135 | if (sts.bytes[2] & 0x10) | ||
| 136 | sts.bytes[2] |= 0x08; | ||
| 137 | |||
| 131 | for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) { | 138 | for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) { |
| 132 | local_irq_disable(); | 139 | local_irq_disable(); |
| 133 | if (sts.int_sts & 0x1) { | 140 | if (sts.int_sts & 0x1) { |
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c index d3365ac85dde..7cb375515e1e 100644 --- a/drivers/net/wimax/i2400m/usb.c +++ b/drivers/net/wimax/i2400m/usb.c | |||
| @@ -514,7 +514,7 @@ int i2400mu_probe(struct usb_interface *iface, | |||
| 514 | #ifdef CONFIG_PM | 514 | #ifdef CONFIG_PM |
| 515 | iface->needs_remote_wakeup = 1; /* autosuspend (15s delay) */ | 515 | iface->needs_remote_wakeup = 1; /* autosuspend (15s delay) */ |
| 516 | device_init_wakeup(dev, 1); | 516 | device_init_wakeup(dev, 1); |
| 517 | usb_dev->autosuspend_delay = 15 * HZ; | 517 | pm_runtime_set_autosuspend_delay(&usb_dev->dev, 15000); |
| 518 | usb_enable_autosuspend(usb_dev); | 518 | usb_enable_autosuspend(usb_dev); |
| 519 | #endif | 519 | #endif |
| 520 | 520 | ||
diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 824f9a45007a..e97ad99b1bb4 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c | |||
| @@ -277,7 +277,7 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 277 | if(psAdapter->bDoSuspend) | 277 | if(psAdapter->bDoSuspend) |
| 278 | { | 278 | { |
| 279 | #ifdef CONFIG_PM | 279 | #ifdef CONFIG_PM |
| 280 | udev->autosuspend_delay = 0; | 280 | pm_runtime_set_autosuspend_delay(&udev->dev, 0); |
| 281 | intf->needs_remote_wakeup = 1; | 281 | intf->needs_remote_wakeup = 1; |
| 282 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) | 282 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) |
| 283 | udev->autosuspend_disabled = 0; | 283 | udev->autosuspend_disabled = 0; |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 67eb3770868f..b8e70a982fd4 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
| @@ -41,17 +41,13 @@ config USB_ARCH_HAS_OHCI | |||
| 41 | default y if MFD_TC6393XB | 41 | default y if MFD_TC6393XB |
| 42 | default y if ARCH_W90X900 | 42 | default y if ARCH_W90X900 |
| 43 | default y if ARCH_DAVINCI_DA8XX | 43 | default y if ARCH_DAVINCI_DA8XX |
| 44 | default y if PLAT_SPEAR | ||
| 44 | # PPC: | 45 | # PPC: |
| 45 | default y if STB03xxx | 46 | default y if STB03xxx |
| 46 | default y if PPC_MPC52xx | 47 | default y if PPC_MPC52xx |
| 47 | # MIPS: | 48 | # MIPS: |
| 48 | default y if MIPS_ALCHEMY | 49 | default y if MIPS_ALCHEMY |
| 49 | default y if MACH_JZ4740 | 50 | default y if MACH_JZ4740 |
| 50 | # SH: | ||
| 51 | default y if CPU_SUBTYPE_SH7720 | ||
| 52 | default y if CPU_SUBTYPE_SH7721 | ||
| 53 | default y if CPU_SUBTYPE_SH7763 | ||
| 54 | default y if CPU_SUBTYPE_SH7786 | ||
| 55 | # more: | 51 | # more: |
| 56 | default PCI | 52 | default PCI |
| 57 | 53 | ||
| @@ -66,6 +62,9 @@ config USB_ARCH_HAS_EHCI | |||
| 66 | default y if ARCH_AT91SAM9G45 | 62 | default y if ARCH_AT91SAM9G45 |
| 67 | default y if ARCH_MXC | 63 | default y if ARCH_MXC |
| 68 | default y if ARCH_OMAP3 | 64 | default y if ARCH_OMAP3 |
| 65 | default y if ARCH_VT8500 | ||
| 66 | default y if PLAT_SPEAR | ||
| 67 | default y if ARCH_MSM | ||
| 69 | default PCI | 68 | default PCI |
| 70 | 69 | ||
| 71 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. | 70 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c0e60fbcb048..b9278a1fb9e5 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
| 28 | #include <linux/usb/quirks.h> | 28 | #include <linux/usb/quirks.h> |
| 29 | #include <linux/usb/hcd.h> | 29 | #include <linux/usb/hcd.h> |
| 30 | #include <linux/pm_runtime.h> | ||
| 31 | 30 | ||
| 32 | #include "usb.h" | 31 | #include "usb.h" |
| 33 | 32 | ||
| @@ -1262,6 +1261,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) | |||
| 1262 | udev->reset_resume); | 1261 | udev->reset_resume); |
| 1263 | } | 1262 | } |
| 1264 | } | 1263 | } |
| 1264 | usb_mark_last_busy(udev); | ||
| 1265 | 1265 | ||
| 1266 | done: | 1266 | done: |
| 1267 | dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); | 1267 | dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); |
| @@ -1329,7 +1329,6 @@ int usb_resume(struct device *dev, pm_message_t msg) | |||
| 1329 | pm_runtime_disable(dev); | 1329 | pm_runtime_disable(dev); |
| 1330 | pm_runtime_set_active(dev); | 1330 | pm_runtime_set_active(dev); |
| 1331 | pm_runtime_enable(dev); | 1331 | pm_runtime_enable(dev); |
| 1332 | udev->last_busy = jiffies; | ||
| 1333 | do_unbind_rebind(udev, DO_REBIND); | 1332 | do_unbind_rebind(udev, DO_REBIND); |
| 1334 | } | 1333 | } |
| 1335 | } | 1334 | } |
| @@ -1397,33 +1396,8 @@ void usb_autosuspend_device(struct usb_device *udev) | |||
| 1397 | { | 1396 | { |
| 1398 | int status; | 1397 | int status; |
| 1399 | 1398 | ||
| 1400 | udev->last_busy = jiffies; | 1399 | usb_mark_last_busy(udev); |
| 1401 | status = pm_runtime_put_sync(&udev->dev); | 1400 | status = pm_runtime_put_sync_autosuspend(&udev->dev); |
| 1402 | dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", | ||
| 1403 | __func__, atomic_read(&udev->dev.power.usage_count), | ||
| 1404 | status); | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | /** | ||
| 1408 | * usb_try_autosuspend_device - attempt an autosuspend of a USB device and its interfaces | ||
| 1409 | * @udev: the usb_device to autosuspend | ||
| 1410 | * | ||
| 1411 | * This routine should be called when a core subsystem thinks @udev may | ||
| 1412 | * be ready to autosuspend. | ||
| 1413 | * | ||
| 1414 | * @udev's usage counter left unchanged. If it is 0 and all the interfaces | ||
| 1415 | * are inactive then an autosuspend will be attempted. The attempt may | ||
| 1416 | * fail or be delayed. | ||
| 1417 | * | ||
| 1418 | * The caller must hold @udev's device lock. | ||
| 1419 | * | ||
| 1420 | * This routine can run only in process context. | ||
| 1421 | */ | ||
| 1422 | void usb_try_autosuspend_device(struct usb_device *udev) | ||
| 1423 | { | ||
| 1424 | int status; | ||
| 1425 | |||
| 1426 | status = pm_runtime_idle(&udev->dev); | ||
| 1427 | dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", | 1401 | dev_vdbg(&udev->dev, "%s: cnt %d -> %d\n", |
| 1428 | __func__, atomic_read(&udev->dev.power.usage_count), | 1402 | __func__, atomic_read(&udev->dev.power.usage_count), |
| 1429 | status); | 1403 | status); |
| @@ -1482,7 +1456,7 @@ void usb_autopm_put_interface(struct usb_interface *intf) | |||
| 1482 | struct usb_device *udev = interface_to_usbdev(intf); | 1456 | struct usb_device *udev = interface_to_usbdev(intf); |
| 1483 | int status; | 1457 | int status; |
| 1484 | 1458 | ||
| 1485 | udev->last_busy = jiffies; | 1459 | usb_mark_last_busy(udev); |
| 1486 | atomic_dec(&intf->pm_usage_cnt); | 1460 | atomic_dec(&intf->pm_usage_cnt); |
| 1487 | status = pm_runtime_put_sync(&intf->dev); | 1461 | status = pm_runtime_put_sync(&intf->dev); |
| 1488 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", | 1462 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", |
| @@ -1509,32 +1483,11 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interface); | |||
| 1509 | void usb_autopm_put_interface_async(struct usb_interface *intf) | 1483 | void usb_autopm_put_interface_async(struct usb_interface *intf) |
| 1510 | { | 1484 | { |
| 1511 | struct usb_device *udev = interface_to_usbdev(intf); | 1485 | struct usb_device *udev = interface_to_usbdev(intf); |
| 1512 | unsigned long last_busy; | 1486 | int status; |
| 1513 | int status = 0; | ||
| 1514 | 1487 | ||
| 1515 | last_busy = udev->last_busy; | 1488 | usb_mark_last_busy(udev); |
| 1516 | udev->last_busy = jiffies; | ||
| 1517 | atomic_dec(&intf->pm_usage_cnt); | 1489 | atomic_dec(&intf->pm_usage_cnt); |
| 1518 | pm_runtime_put_noidle(&intf->dev); | 1490 | status = pm_runtime_put(&intf->dev); |
| 1519 | |||
| 1520 | if (udev->dev.power.runtime_auto) { | ||
| 1521 | /* Optimization: Don't schedule a delayed autosuspend if | ||
| 1522 | * the timer is already running and the expiration time | ||
| 1523 | * wouldn't change. | ||
| 1524 | * | ||
| 1525 | * We have to use the interface's timer. Attempts to | ||
| 1526 | * schedule a suspend for the device would fail because | ||
| 1527 | * the interface is still active. | ||
| 1528 | */ | ||
| 1529 | if (intf->dev.power.timer_expires == 0 || | ||
| 1530 | round_jiffies_up(last_busy) != | ||
| 1531 | round_jiffies_up(jiffies)) { | ||
| 1532 | status = pm_schedule_suspend(&intf->dev, | ||
| 1533 | jiffies_to_msecs( | ||
| 1534 | round_jiffies_up_relative( | ||
| 1535 | udev->autosuspend_delay))); | ||
| 1536 | } | ||
| 1537 | } | ||
| 1538 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", | 1491 | dev_vdbg(&intf->dev, "%s: cnt %d -> %d\n", |
| 1539 | __func__, atomic_read(&intf->dev.power.usage_count), | 1492 | __func__, atomic_read(&intf->dev.power.usage_count), |
| 1540 | status); | 1493 | status); |
| @@ -1554,7 +1507,7 @@ void usb_autopm_put_interface_no_suspend(struct usb_interface *intf) | |||
| 1554 | { | 1507 | { |
| 1555 | struct usb_device *udev = interface_to_usbdev(intf); | 1508 | struct usb_device *udev = interface_to_usbdev(intf); |
| 1556 | 1509 | ||
| 1557 | udev->last_busy = jiffies; | 1510 | usb_mark_last_busy(udev); |
| 1558 | atomic_dec(&intf->pm_usage_cnt); | 1511 | atomic_dec(&intf->pm_usage_cnt); |
| 1559 | pm_runtime_put_noidle(&intf->dev); | 1512 | pm_runtime_put_noidle(&intf->dev); |
| 1560 | } | 1513 | } |
| @@ -1612,18 +1565,9 @@ EXPORT_SYMBOL_GPL(usb_autopm_get_interface); | |||
| 1612 | */ | 1565 | */ |
| 1613 | int usb_autopm_get_interface_async(struct usb_interface *intf) | 1566 | int usb_autopm_get_interface_async(struct usb_interface *intf) |
| 1614 | { | 1567 | { |
| 1615 | int status = 0; | 1568 | int status; |
| 1616 | enum rpm_status s; | ||
| 1617 | |||
| 1618 | /* Don't request a resume unless the interface is already suspending | ||
| 1619 | * or suspended. Doing so would force a running suspend timer to be | ||
| 1620 | * cancelled. | ||
| 1621 | */ | ||
| 1622 | pm_runtime_get_noresume(&intf->dev); | ||
| 1623 | s = ACCESS_ONCE(intf->dev.power.runtime_status); | ||
| 1624 | if (s == RPM_SUSPENDING || s == RPM_SUSPENDED) | ||
| 1625 | status = pm_request_resume(&intf->dev); | ||
| 1626 | 1569 | ||
| 1570 | status = pm_runtime_get(&intf->dev); | ||
| 1627 | if (status < 0 && status != -EINPROGRESS) | 1571 | if (status < 0 && status != -EINPROGRESS) |
| 1628 | pm_runtime_put_noidle(&intf->dev); | 1572 | pm_runtime_put_noidle(&intf->dev); |
| 1629 | else | 1573 | else |
| @@ -1650,7 +1594,7 @@ void usb_autopm_get_interface_no_resume(struct usb_interface *intf) | |||
| 1650 | { | 1594 | { |
| 1651 | struct usb_device *udev = interface_to_usbdev(intf); | 1595 | struct usb_device *udev = interface_to_usbdev(intf); |
| 1652 | 1596 | ||
| 1653 | udev->last_busy = jiffies; | 1597 | usb_mark_last_busy(udev); |
| 1654 | atomic_inc(&intf->pm_usage_cnt); | 1598 | atomic_inc(&intf->pm_usage_cnt); |
| 1655 | pm_runtime_get_noresume(&intf->dev); | 1599 | pm_runtime_get_noresume(&intf->dev); |
| 1656 | } | 1600 | } |
| @@ -1661,7 +1605,6 @@ static int autosuspend_check(struct usb_device *udev) | |||
| 1661 | { | 1605 | { |
| 1662 | int w, i; | 1606 | int w, i; |
| 1663 | struct usb_interface *intf; | 1607 | struct usb_interface *intf; |
| 1664 | unsigned long suspend_time, j; | ||
| 1665 | 1608 | ||
| 1666 | /* Fail if autosuspend is disabled, or any interfaces are in use, or | 1609 | /* Fail if autosuspend is disabled, or any interfaces are in use, or |
| 1667 | * any interface drivers require remote wakeup but it isn't available. | 1610 | * any interface drivers require remote wakeup but it isn't available. |
| @@ -1701,87 +1644,46 @@ static int autosuspend_check(struct usb_device *udev) | |||
| 1701 | return -EOPNOTSUPP; | 1644 | return -EOPNOTSUPP; |
| 1702 | } | 1645 | } |
| 1703 | udev->do_remote_wakeup = w; | 1646 | udev->do_remote_wakeup = w; |
| 1704 | |||
| 1705 | /* If everything is okay but the device hasn't been idle for long | ||
| 1706 | * enough, queue a delayed autosuspend request. | ||
| 1707 | */ | ||
| 1708 | j = ACCESS_ONCE(jiffies); | ||
| 1709 | suspend_time = udev->last_busy + udev->autosuspend_delay; | ||
| 1710 | if (time_before(j, suspend_time)) { | ||
| 1711 | pm_schedule_suspend(&udev->dev, jiffies_to_msecs( | ||
| 1712 | round_jiffies_up_relative(suspend_time - j))); | ||
| 1713 | return -EAGAIN; | ||
| 1714 | } | ||
| 1715 | return 0; | 1647 | return 0; |
| 1716 | } | 1648 | } |
| 1717 | 1649 | ||
| 1718 | static int usb_runtime_suspend(struct device *dev) | 1650 | static int usb_runtime_suspend(struct device *dev) |
| 1719 | { | 1651 | { |
| 1720 | int status = 0; | 1652 | struct usb_device *udev = to_usb_device(dev); |
| 1653 | int status; | ||
| 1721 | 1654 | ||
| 1722 | /* A USB device can be suspended if it passes the various autosuspend | 1655 | /* A USB device can be suspended if it passes the various autosuspend |
| 1723 | * checks. Runtime suspend for a USB device means suspending all the | 1656 | * checks. Runtime suspend for a USB device means suspending all the |
| 1724 | * interfaces and then the device itself. | 1657 | * interfaces and then the device itself. |
| 1725 | */ | 1658 | */ |
| 1726 | if (is_usb_device(dev)) { | 1659 | if (autosuspend_check(udev) != 0) |
| 1727 | struct usb_device *udev = to_usb_device(dev); | 1660 | return -EAGAIN; |
| 1728 | |||
| 1729 | if (autosuspend_check(udev) != 0) | ||
| 1730 | return -EAGAIN; | ||
| 1731 | |||
| 1732 | status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); | ||
| 1733 | |||
| 1734 | /* If an interface fails the suspend, adjust the last_busy | ||
| 1735 | * time so that we don't get another suspend attempt right | ||
| 1736 | * away. | ||
| 1737 | */ | ||
| 1738 | if (status) { | ||
| 1739 | udev->last_busy = jiffies + | ||
| 1740 | (udev->autosuspend_delay == 0 ? | ||
| 1741 | HZ/2 : 0); | ||
| 1742 | } | ||
| 1743 | |||
| 1744 | /* Prevent the parent from suspending immediately after */ | ||
| 1745 | else if (udev->parent) | ||
| 1746 | udev->parent->last_busy = jiffies; | ||
| 1747 | } | ||
| 1748 | 1661 | ||
| 1749 | /* Runtime suspend for a USB interface doesn't mean anything. */ | 1662 | status = usb_suspend_both(udev, PMSG_AUTO_SUSPEND); |
| 1750 | return status; | 1663 | return status; |
| 1751 | } | 1664 | } |
| 1752 | 1665 | ||
| 1753 | static int usb_runtime_resume(struct device *dev) | 1666 | static int usb_runtime_resume(struct device *dev) |
| 1754 | { | 1667 | { |
| 1668 | struct usb_device *udev = to_usb_device(dev); | ||
| 1669 | int status; | ||
| 1670 | |||
| 1755 | /* Runtime resume for a USB device means resuming both the device | 1671 | /* Runtime resume for a USB device means resuming both the device |
| 1756 | * and all its interfaces. | 1672 | * and all its interfaces. |
| 1757 | */ | 1673 | */ |
| 1758 | if (is_usb_device(dev)) { | 1674 | status = usb_resume_both(udev, PMSG_AUTO_RESUME); |
| 1759 | struct usb_device *udev = to_usb_device(dev); | 1675 | return status; |
| 1760 | int status; | ||
| 1761 | |||
| 1762 | status = usb_resume_both(udev, PMSG_AUTO_RESUME); | ||
| 1763 | udev->last_busy = jiffies; | ||
| 1764 | return status; | ||
| 1765 | } | ||
| 1766 | |||
| 1767 | /* Runtime resume for a USB interface doesn't mean anything. */ | ||
| 1768 | return 0; | ||
| 1769 | } | 1676 | } |
| 1770 | 1677 | ||
| 1771 | static int usb_runtime_idle(struct device *dev) | 1678 | static int usb_runtime_idle(struct device *dev) |
| 1772 | { | 1679 | { |
| 1680 | struct usb_device *udev = to_usb_device(dev); | ||
| 1681 | |||
| 1773 | /* An idle USB device can be suspended if it passes the various | 1682 | /* An idle USB device can be suspended if it passes the various |
| 1774 | * autosuspend checks. An idle interface can be suspended at | 1683 | * autosuspend checks. |
| 1775 | * any time. | ||
| 1776 | */ | 1684 | */ |
| 1777 | if (is_usb_device(dev)) { | 1685 | if (autosuspend_check(udev) == 0) |
| 1778 | struct usb_device *udev = to_usb_device(dev); | 1686 | pm_runtime_autosuspend(dev); |
| 1779 | |||
| 1780 | if (autosuspend_check(udev) != 0) | ||
| 1781 | return 0; | ||
| 1782 | } | ||
| 1783 | |||
| 1784 | pm_runtime_suspend(dev); | ||
| 1785 | return 0; | 1687 | return 0; |
| 1786 | } | 1688 | } |
| 1787 | 1689 | ||
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 3799573bd385..b55d46070a25 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
| 22 | #include <linux/pm_runtime.h> | ||
| 23 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
| 24 | #include <linux/usb/hcd.h> | 23 | #include <linux/usb/hcd.h> |
| 25 | 24 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index ced846ac4141..6a95017fa62b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
| 39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
| 40 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
| 41 | #include <linux/pm_runtime.h> | ||
| 42 | 41 | ||
| 43 | #include <linux/usb.h> | 42 | #include <linux/usb.h> |
| 44 | #include <linux/usb/hcd.h> | 43 | #include <linux/usb/hcd.h> |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 27115b45edc5..b98efae6a1cf 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
| 25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
| 26 | #include <linux/freezer.h> | 26 | #include <linux/freezer.h> |
| 27 | #include <linux/pm_runtime.h> | ||
| 28 | 27 | ||
| 29 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
| 30 | #include <asm/byteorder.h> | 29 | #include <asm/byteorder.h> |
| @@ -1804,8 +1803,15 @@ int usb_new_device(struct usb_device *udev) | |||
| 1804 | 1803 | ||
| 1805 | /* Tell the runtime-PM framework the device is active */ | 1804 | /* Tell the runtime-PM framework the device is active */ |
| 1806 | pm_runtime_set_active(&udev->dev); | 1805 | pm_runtime_set_active(&udev->dev); |
| 1806 | pm_runtime_get_noresume(&udev->dev); | ||
| 1807 | pm_runtime_use_autosuspend(&udev->dev); | ||
| 1807 | pm_runtime_enable(&udev->dev); | 1808 | pm_runtime_enable(&udev->dev); |
| 1808 | 1809 | ||
| 1810 | /* By default, forbid autosuspend for all devices. It will be | ||
| 1811 | * allowed for hubs during binding. | ||
| 1812 | */ | ||
| 1813 | usb_disable_autosuspend(udev); | ||
| 1814 | |||
| 1809 | err = usb_enumerate_device(udev); /* Read descriptors */ | 1815 | err = usb_enumerate_device(udev); /* Read descriptors */ |
| 1810 | if (err < 0) | 1816 | if (err < 0) |
| 1811 | goto fail; | 1817 | goto fail; |
| @@ -1831,6 +1837,8 @@ int usb_new_device(struct usb_device *udev) | |||
| 1831 | } | 1837 | } |
| 1832 | 1838 | ||
| 1833 | (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); | 1839 | (void) usb_create_ep_devs(&udev->dev, &udev->ep0, udev); |
| 1840 | usb_mark_last_busy(udev); | ||
| 1841 | pm_runtime_put_sync_autosuspend(&udev->dev); | ||
| 1834 | return err; | 1842 | return err; |
| 1835 | 1843 | ||
| 1836 | fail: | 1844 | fail: |
| @@ -2221,6 +2229,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
| 2221 | usb_set_device_state(udev, USB_STATE_SUSPENDED); | 2229 | usb_set_device_state(udev, USB_STATE_SUSPENDED); |
| 2222 | msleep(10); | 2230 | msleep(10); |
| 2223 | } | 2231 | } |
| 2232 | usb_mark_last_busy(hub->hdev); | ||
| 2224 | return status; | 2233 | return status; |
| 2225 | } | 2234 | } |
| 2226 | 2235 | ||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index d6e3e410477e..832487423826 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
| @@ -1804,6 +1804,7 @@ free_interfaces: | |||
| 1804 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); | 1804 | INIT_WORK(&intf->reset_ws, __usb_queue_reset_device); |
| 1805 | intf->minor = -1; | 1805 | intf->minor = -1; |
| 1806 | device_initialize(&intf->dev); | 1806 | device_initialize(&intf->dev); |
| 1807 | pm_runtime_no_callbacks(&intf->dev); | ||
| 1807 | dev_set_name(&intf->dev, "%d-%s:%d.%d", | 1808 | dev_set_name(&intf->dev, "%d-%s:%d.%d", |
| 1808 | dev->bus->busnum, dev->devpath, | 1809 | dev->bus->busnum, dev->devpath, |
| 1809 | configuration, alt->desc.bInterfaceNumber); | 1810 | configuration, alt->desc.bInterfaceNumber); |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 25719da45e33..44c595432d6f 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -117,21 +117,6 @@ void usb_detect_quirks(struct usb_device *udev) | |||
| 117 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", | 117 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", |
| 118 | udev->quirks); | 118 | udev->quirks); |
| 119 | 119 | ||
| 120 | #ifdef CONFIG_USB_SUSPEND | ||
| 121 | |||
| 122 | /* By default, disable autosuspend for all devices. The hub driver | ||
| 123 | * will enable it for hubs. | ||
| 124 | */ | ||
| 125 | usb_disable_autosuspend(udev); | ||
| 126 | |||
| 127 | /* Autosuspend can also be disabled if the initial autosuspend_delay | ||
| 128 | * is negative. | ||
| 129 | */ | ||
| 130 | if (udev->autosuspend_delay < 0) | ||
| 131 | usb_autoresume_device(udev); | ||
| 132 | |||
| 133 | #endif | ||
| 134 | |||
| 135 | /* For the present, all devices default to USB-PERSIST enabled */ | 120 | /* For the present, all devices default to USB-PERSIST enabled */ |
| 136 | #if 0 /* was: #ifdef CONFIG_PM */ | 121 | #if 0 /* was: #ifdef CONFIG_PM */ |
| 137 | /* Hubs are automatically enabled for USB-PERSIST */ | 122 | /* Hubs are automatically enabled for USB-PERSIST */ |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 448f5b47fc48..6781c369ce2d 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
| @@ -233,8 +233,6 @@ static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL); | |||
| 233 | 233 | ||
| 234 | #ifdef CONFIG_PM | 234 | #ifdef CONFIG_PM |
| 235 | 235 | ||
| 236 | static const char power_group[] = "power"; | ||
| 237 | |||
| 238 | static ssize_t | 236 | static ssize_t |
| 239 | show_persist(struct device *dev, struct device_attribute *attr, char *buf) | 237 | show_persist(struct device *dev, struct device_attribute *attr, char *buf) |
| 240 | { | 238 | { |
| @@ -278,7 +276,7 @@ static int add_persist_attributes(struct device *dev) | |||
| 278 | if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) | 276 | if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) |
| 279 | rc = sysfs_add_file_to_group(&dev->kobj, | 277 | rc = sysfs_add_file_to_group(&dev->kobj, |
| 280 | &dev_attr_persist.attr, | 278 | &dev_attr_persist.attr, |
| 281 | power_group); | 279 | power_group_name); |
| 282 | } | 280 | } |
| 283 | return rc; | 281 | return rc; |
| 284 | } | 282 | } |
| @@ -287,7 +285,7 @@ static void remove_persist_attributes(struct device *dev) | |||
| 287 | { | 285 | { |
| 288 | sysfs_remove_file_from_group(&dev->kobj, | 286 | sysfs_remove_file_from_group(&dev->kobj, |
| 289 | &dev_attr_persist.attr, | 287 | &dev_attr_persist.attr, |
| 290 | power_group); | 288 | power_group_name); |
| 291 | } | 289 | } |
| 292 | #else | 290 | #else |
| 293 | 291 | ||
| @@ -336,44 +334,20 @@ static DEVICE_ATTR(active_duration, S_IRUGO, show_active_duration, NULL); | |||
| 336 | static ssize_t | 334 | static ssize_t |
| 337 | show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf) | 335 | show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf) |
| 338 | { | 336 | { |
| 339 | struct usb_device *udev = to_usb_device(dev); | 337 | return sprintf(buf, "%d\n", dev->power.autosuspend_delay / 1000); |
| 340 | |||
| 341 | return sprintf(buf, "%d\n", udev->autosuspend_delay / HZ); | ||
| 342 | } | 338 | } |
| 343 | 339 | ||
| 344 | static ssize_t | 340 | static ssize_t |
| 345 | set_autosuspend(struct device *dev, struct device_attribute *attr, | 341 | set_autosuspend(struct device *dev, struct device_attribute *attr, |
| 346 | const char *buf, size_t count) | 342 | const char *buf, size_t count) |
| 347 | { | 343 | { |
| 348 | struct usb_device *udev = to_usb_device(dev); | 344 | int value; |
| 349 | int value, old_delay; | ||
| 350 | int rc; | ||
| 351 | 345 | ||
| 352 | if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || | 346 | if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/1000 || |
| 353 | value <= - INT_MAX/HZ) | 347 | value <= -INT_MAX/1000) |
| 354 | return -EINVAL; | 348 | return -EINVAL; |
| 355 | value *= HZ; | ||
| 356 | |||
| 357 | usb_lock_device(udev); | ||
| 358 | old_delay = udev->autosuspend_delay; | ||
| 359 | udev->autosuspend_delay = value; | ||
| 360 | |||
| 361 | if (old_delay < 0) { /* Autosuspend wasn't allowed */ | ||
| 362 | if (value >= 0) | ||
| 363 | usb_autosuspend_device(udev); | ||
| 364 | } else { /* Autosuspend was allowed */ | ||
| 365 | if (value < 0) { | ||
| 366 | rc = usb_autoresume_device(udev); | ||
| 367 | if (rc < 0) { | ||
| 368 | count = rc; | ||
| 369 | udev->autosuspend_delay = old_delay; | ||
| 370 | } | ||
| 371 | } else { | ||
| 372 | usb_try_autosuspend_device(udev); | ||
| 373 | } | ||
| 374 | } | ||
| 375 | 349 | ||
| 376 | usb_unlock_device(udev); | 350 | pm_runtime_set_autosuspend_delay(dev, value * 1000); |
| 377 | return count; | 351 | return count; |
| 378 | } | 352 | } |
| 379 | 353 | ||
| @@ -438,44 +412,30 @@ set_level(struct device *dev, struct device_attribute *attr, | |||
| 438 | 412 | ||
| 439 | static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); | 413 | static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); |
| 440 | 414 | ||
| 415 | static struct attribute *power_attrs[] = { | ||
| 416 | &dev_attr_autosuspend.attr, | ||
| 417 | &dev_attr_level.attr, | ||
| 418 | &dev_attr_connected_duration.attr, | ||
| 419 | &dev_attr_active_duration.attr, | ||
| 420 | NULL, | ||
| 421 | }; | ||
| 422 | static struct attribute_group power_attr_group = { | ||
| 423 | .name = power_group_name, | ||
| 424 | .attrs = power_attrs, | ||
| 425 | }; | ||
| 426 | |||
| 441 | static int add_power_attributes(struct device *dev) | 427 | static int add_power_attributes(struct device *dev) |
| 442 | { | 428 | { |
| 443 | int rc = 0; | 429 | int rc = 0; |
| 444 | 430 | ||
| 445 | if (is_usb_device(dev)) { | 431 | if (is_usb_device(dev)) |
| 446 | rc = sysfs_add_file_to_group(&dev->kobj, | 432 | rc = sysfs_merge_group(&dev->kobj, &power_attr_group); |
| 447 | &dev_attr_autosuspend.attr, | ||
| 448 | power_group); | ||
| 449 | if (rc == 0) | ||
| 450 | rc = sysfs_add_file_to_group(&dev->kobj, | ||
| 451 | &dev_attr_level.attr, | ||
| 452 | power_group); | ||
| 453 | if (rc == 0) | ||
| 454 | rc = sysfs_add_file_to_group(&dev->kobj, | ||
| 455 | &dev_attr_connected_duration.attr, | ||
| 456 | power_group); | ||
| 457 | if (rc == 0) | ||
| 458 | rc = sysfs_add_file_to_group(&dev->kobj, | ||
| 459 | &dev_attr_active_duration.attr, | ||
| 460 | power_group); | ||
| 461 | } | ||
| 462 | return rc; | 433 | return rc; |
| 463 | } | 434 | } |
| 464 | 435 | ||
| 465 | static void remove_power_attributes(struct device *dev) | 436 | static void remove_power_attributes(struct device *dev) |
| 466 | { | 437 | { |
| 467 | sysfs_remove_file_from_group(&dev->kobj, | 438 | sysfs_unmerge_group(&dev->kobj, &power_attr_group); |
| 468 | &dev_attr_active_duration.attr, | ||
| 469 | power_group); | ||
| 470 | sysfs_remove_file_from_group(&dev->kobj, | ||
| 471 | &dev_attr_connected_duration.attr, | ||
| 472 | power_group); | ||
| 473 | sysfs_remove_file_from_group(&dev->kobj, | ||
| 474 | &dev_attr_level.attr, | ||
| 475 | power_group); | ||
| 476 | sysfs_remove_file_from_group(&dev->kobj, | ||
| 477 | &dev_attr_autosuspend.attr, | ||
| 478 | power_group); | ||
| 479 | } | 439 | } |
| 480 | 440 | ||
| 481 | #else | 441 | #else |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index fdd4130fbb7d..079cb57bab4f 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
| @@ -445,7 +445,8 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, | |||
| 445 | INIT_LIST_HEAD(&dev->filelist); | 445 | INIT_LIST_HEAD(&dev->filelist); |
| 446 | 446 | ||
| 447 | #ifdef CONFIG_PM | 447 | #ifdef CONFIG_PM |
| 448 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; | 448 | pm_runtime_set_autosuspend_delay(&dev->dev, |
| 449 | usb_autosuspend_delay * 1000); | ||
| 449 | dev->connect_time = jiffies; | 450 | dev->connect_time = jiffies; |
| 450 | dev->active_duration = -jiffies; | 451 | dev->active_duration = -jiffies; |
| 451 | #endif | 452 | #endif |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index cd882203ad34..b975450f403e 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
| @@ -75,14 +75,12 @@ static inline int usb_port_resume(struct usb_device *udev, pm_message_t msg) | |||
| 75 | #ifdef CONFIG_USB_SUSPEND | 75 | #ifdef CONFIG_USB_SUSPEND |
| 76 | 76 | ||
| 77 | extern void usb_autosuspend_device(struct usb_device *udev); | 77 | extern void usb_autosuspend_device(struct usb_device *udev); |
| 78 | extern void usb_try_autosuspend_device(struct usb_device *udev); | ||
| 79 | extern int usb_autoresume_device(struct usb_device *udev); | 78 | extern int usb_autoresume_device(struct usb_device *udev); |
| 80 | extern int usb_remote_wakeup(struct usb_device *dev); | 79 | extern int usb_remote_wakeup(struct usb_device *dev); |
| 81 | 80 | ||
| 82 | #else | 81 | #else |
| 83 | 82 | ||
| 84 | #define usb_autosuspend_device(udev) do {} while (0) | 83 | #define usb_autosuspend_device(udev) do {} while (0) |
| 85 | #define usb_try_autosuspend_device(udev) do {} while (0) | ||
| 86 | static inline int usb_autoresume_device(struct usb_device *udev) | 84 | static inline int usb_autoresume_device(struct usb_device *udev) |
| 87 | { | 85 | { |
| 88 | return 0; | 86 | return 0; |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 607d0db4a988..1dc9739277b4 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -338,6 +338,19 @@ config USB_S3C2410_DEBUG | |||
| 338 | boolean "S3C2410 udc debug messages" | 338 | boolean "S3C2410 udc debug messages" |
| 339 | depends on USB_GADGET_S3C2410 | 339 | depends on USB_GADGET_S3C2410 |
| 340 | 340 | ||
| 341 | config USB_GADGET_PXA_U2O | ||
| 342 | boolean "PXA9xx Processor USB2.0 controller" | ||
| 343 | select USB_GADGET_DUALSPEED | ||
| 344 | help | ||
| 345 | PXA9xx Processor series include a high speed USB2.0 device | ||
| 346 | controller, which support high speed and full speed USB peripheral. | ||
| 347 | |||
| 348 | config USB_PXA_U2O | ||
| 349 | tristate | ||
| 350 | depends on USB_GADGET_PXA_U2O | ||
| 351 | default USB_GADGET | ||
| 352 | select USB_GADGET_SELECTED | ||
| 353 | |||
| 341 | # | 354 | # |
| 342 | # Controllers available in both integrated and discrete versions | 355 | # Controllers available in both integrated and discrete versions |
| 343 | # | 356 | # |
| @@ -414,8 +427,8 @@ config USB_FSL_QE | |||
| 414 | default USB_GADGET | 427 | default USB_GADGET |
| 415 | select USB_GADGET_SELECTED | 428 | select USB_GADGET_SELECTED |
| 416 | 429 | ||
| 417 | config USB_GADGET_CI13XXX | 430 | config USB_GADGET_CI13XXX_PCI |
| 418 | boolean "MIPS USB CI13xxx" | 431 | boolean "MIPS USB CI13xxx PCI UDC" |
| 419 | depends on PCI | 432 | depends on PCI |
| 420 | select USB_GADGET_DUALSPEED | 433 | select USB_GADGET_DUALSPEED |
| 421 | help | 434 | help |
| @@ -426,9 +439,9 @@ config USB_GADGET_CI13XXX | |||
| 426 | dynamically linked module called "ci13xxx_udc" and force all | 439 | dynamically linked module called "ci13xxx_udc" and force all |
| 427 | gadget drivers to also be dynamically linked. | 440 | gadget drivers to also be dynamically linked. |
| 428 | 441 | ||
| 429 | config USB_CI13XXX | 442 | config USB_CI13XXX_PCI |
| 430 | tristate | 443 | tristate |
| 431 | depends on USB_GADGET_CI13XXX | 444 | depends on USB_GADGET_CI13XXX_PCI |
| 432 | default USB_GADGET | 445 | default USB_GADGET |
| 433 | select USB_GADGET_SELECTED | 446 | select USB_GADGET_SELECTED |
| 434 | 447 | ||
| @@ -495,6 +508,49 @@ config USB_LANGWELL | |||
| 495 | default USB_GADGET | 508 | default USB_GADGET |
| 496 | select USB_GADGET_SELECTED | 509 | select USB_GADGET_SELECTED |
| 497 | 510 | ||
| 511 | config USB_GADGET_EG20T | ||
| 512 | boolean "Intel EG20T(Topcliff) USB Device controller" | ||
| 513 | depends on PCI | ||
| 514 | select USB_GADGET_DUALSPEED | ||
| 515 | help | ||
| 516 | This is a USB device driver for EG20T PCH. | ||
| 517 | EG20T PCH is the platform controller hub that is used in Intel's | ||
| 518 | general embedded platform. EG20T PCH has USB device interface. | ||
| 519 | Using this interface, it is able to access system devices connected | ||
| 520 | to USB device. | ||
| 521 | This driver enables USB device function. | ||
| 522 | USB device is a USB peripheral controller which | ||
| 523 | supports both full and high speed USB 2.0 data transfers. | ||
| 524 | This driver supports both control transfer and bulk transfer modes. | ||
| 525 | This driver dose not support interrupt transfer or isochronous | ||
| 526 | transfer modes. | ||
| 527 | |||
| 528 | config USB_EG20T | ||
| 529 | tristate | ||
| 530 | depends on USB_GADGET_EG20T | ||
| 531 | default USB_GADGET | ||
| 532 | select USB_GADGET_SELECTED | ||
| 533 | |||
| 534 | config USB_GADGET_CI13XXX_MSM | ||
| 535 | boolean "MIPS USB CI13xxx for MSM" | ||
| 536 | depends on ARCH_MSM | ||
| 537 | select USB_GADGET_DUALSPEED | ||
| 538 | select USB_MSM_OTG_72K | ||
| 539 | help | ||
| 540 | MSM SoC has chipidea USB controller. This driver uses | ||
| 541 | ci13xxx_udc core. | ||
| 542 | This driver depends on OTG driver for PHY initialization, | ||
| 543 | clock management, powering up VBUS, and power management. | ||
| 544 | |||
| 545 | Say "y" to link the driver statically, or "m" to build a | ||
| 546 | dynamically linked module called "ci13xxx_msm" and force all | ||
| 547 | gadget drivers to also be dynamically linked. | ||
| 548 | |||
| 549 | config USB_CI13XXX_MSM | ||
| 550 | tristate | ||
| 551 | depends on USB_GADGET_CI13XXX_MSM | ||
| 552 | default USB_GADGET | ||
| 553 | select USB_GADGET_SELECTED | ||
| 498 | 554 | ||
| 499 | # | 555 | # |
| 500 | # LAST -- dummy/emulated controller | 556 | # LAST -- dummy/emulated controller |
| @@ -685,6 +741,19 @@ config USB_ETH_EEM | |||
| 685 | If you say "y" here, the Ethernet gadget driver will use the EEM | 741 | If you say "y" here, the Ethernet gadget driver will use the EEM |
| 686 | protocol rather than ECM. If unsure, say "n". | 742 | protocol rather than ECM. If unsure, say "n". |
| 687 | 743 | ||
| 744 | config USB_G_NCM | ||
| 745 | tristate "Network Control Model (NCM) support" | ||
| 746 | depends on NET | ||
| 747 | select CRC32 | ||
| 748 | help | ||
| 749 | This driver implements USB CDC NCM subclass standard. NCM is | ||
| 750 | an advanced protocol for Ethernet encapsulation, allows grouping | ||
| 751 | of several ethernet frames into one USB transfer and diffferent | ||
| 752 | alignment possibilities. | ||
| 753 | |||
| 754 | Say "y" to link the driver statically, or "m" to build a | ||
| 755 | dynamically linked module called "g_ncm". | ||
| 756 | |||
| 688 | config USB_GADGETFS | 757 | config USB_GADGETFS |
| 689 | tristate "Gadget Filesystem (EXPERIMENTAL)" | 758 | tristate "Gadget Filesystem (EXPERIMENTAL)" |
| 690 | depends on EXPERIMENTAL | 759 | depends on EXPERIMENTAL |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 5780db42417b..55f5e8ae5924 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
| @@ -21,9 +21,13 @@ fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | |||
| 21 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | 21 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
| 22 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o | 22 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o |
| 23 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o | 23 | obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o |
| 24 | obj-$(CONFIG_USB_CI13XXX) += ci13xxx_udc.o | 24 | obj-$(CONFIG_USB_CI13XXX_PCI) += ci13xxx_pci.o |
| 25 | obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o | 25 | obj-$(CONFIG_USB_S3C_HSOTG) += s3c-hsotg.o |
| 26 | obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o | 26 | obj-$(CONFIG_USB_LANGWELL) += langwell_udc.o |
| 27 | obj-$(CONFIG_USB_EG20T) += pch_udc.o | ||
| 28 | obj-$(CONFIG_USB_PXA_U2O) += mv_udc.o | ||
| 29 | mv_udc-y := mv_udc_core.o mv_udc_phy.o | ||
| 30 | obj-$(CONFIG_USB_CI13XXX_MSM) += ci13xxx_msm.o | ||
| 27 | 31 | ||
| 28 | # | 32 | # |
| 29 | # USB gadget drivers | 33 | # USB gadget drivers |
| @@ -43,6 +47,7 @@ g_hid-y := hid.o | |||
| 43 | g_dbgp-y := dbgp.o | 47 | g_dbgp-y := dbgp.o |
| 44 | g_nokia-y := nokia.o | 48 | g_nokia-y := nokia.o |
| 45 | g_webcam-y := webcam.o | 49 | g_webcam-y := webcam.o |
| 50 | g_ncm-y := ncm.o | ||
| 46 | 51 | ||
| 47 | obj-$(CONFIG_USB_ZERO) += g_zero.o | 52 | obj-$(CONFIG_USB_ZERO) += g_zero.o |
| 48 | obj-$(CONFIG_USB_AUDIO) += g_audio.o | 53 | obj-$(CONFIG_USB_AUDIO) += g_audio.o |
| @@ -60,3 +65,4 @@ obj-$(CONFIG_USB_G_DBGP) += g_dbgp.o | |||
| 60 | obj-$(CONFIG_USB_G_MULTI) += g_multi.o | 65 | obj-$(CONFIG_USB_G_MULTI) += g_multi.o |
| 61 | obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o | 66 | obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o |
| 62 | obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o | 67 | obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o |
| 68 | obj-$(CONFIG_USB_G_NCM) += g_ncm.o | ||
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 9034e0344723..f8dd7269d79c 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
| @@ -3359,7 +3359,6 @@ static int udc_probe(struct udc *dev) | |||
| 3359 | dev_set_name(&dev->gadget.dev, "gadget"); | 3359 | dev_set_name(&dev->gadget.dev, "gadget"); |
| 3360 | dev->gadget.dev.release = gadget_release; | 3360 | dev->gadget.dev.release = gadget_release; |
| 3361 | dev->gadget.name = name; | 3361 | dev->gadget.name = name; |
| 3362 | dev->gadget.name = name; | ||
| 3363 | dev->gadget.is_dualspeed = 1; | 3362 | dev->gadget.is_dualspeed = 1; |
| 3364 | 3363 | ||
| 3365 | /* init registers, interrupts, ... */ | 3364 | /* init registers, interrupts, ... */ |
diff --git a/drivers/usb/gadget/ci13xxx_msm.c b/drivers/usb/gadget/ci13xxx_msm.c new file mode 100644 index 000000000000..139ac9419597 --- /dev/null +++ b/drivers/usb/gadget/ci13xxx_msm.c | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | /* Copyright (c) 2010, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License version 2 and | ||
| 5 | * only version 2 as published by the Free Software Foundation. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 15 | * 02110-1301, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/pm_runtime.h> | ||
| 22 | #include <linux/usb/msm_hsusb_hw.h> | ||
| 23 | #include <linux/usb/ulpi.h> | ||
| 24 | |||
| 25 | #include "ci13xxx_udc.c" | ||
| 26 | |||
| 27 | #define MSM_USB_BASE (udc->regs) | ||
| 28 | |||
| 29 | static irqreturn_t msm_udc_irq(int irq, void *data) | ||
| 30 | { | ||
| 31 | return udc_irq(); | ||
| 32 | } | ||
| 33 | |||
| 34 | static void ci13xxx_msm_notify_event(struct ci13xxx *udc, unsigned event) | ||
| 35 | { | ||
| 36 | struct device *dev = udc->gadget.dev.parent; | ||
| 37 | int val; | ||
| 38 | |||
| 39 | switch (event) { | ||
| 40 | case CI13XXX_CONTROLLER_RESET_EVENT: | ||
| 41 | dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n"); | ||
| 42 | writel(0, USB_AHBBURST); | ||
| 43 | writel(0, USB_AHBMODE); | ||
| 44 | break; | ||
| 45 | case CI13XXX_CONTROLLER_STOPPED_EVENT: | ||
| 46 | dev_dbg(dev, "CI13XXX_CONTROLLER_STOPPED_EVENT received\n"); | ||
| 47 | /* | ||
| 48 | * Put the transceiver in non-driving mode. Otherwise host | ||
| 49 | * may not detect soft-disconnection. | ||
| 50 | */ | ||
| 51 | val = otg_io_read(udc->transceiver, ULPI_FUNC_CTRL); | ||
| 52 | val &= ~ULPI_FUNC_CTRL_OPMODE_MASK; | ||
| 53 | val |= ULPI_FUNC_CTRL_OPMODE_NONDRIVING; | ||
| 54 | otg_io_write(udc->transceiver, val, ULPI_FUNC_CTRL); | ||
| 55 | break; | ||
| 56 | default: | ||
| 57 | dev_dbg(dev, "unknown ci13xxx_udc event\n"); | ||
| 58 | break; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | static struct ci13xxx_udc_driver ci13xxx_msm_udc_driver = { | ||
| 63 | .name = "ci13xxx_msm", | ||
| 64 | .flags = CI13XXX_REGS_SHARED | | ||
| 65 | CI13XXX_REQUIRE_TRANSCEIVER | | ||
| 66 | CI13XXX_PULLUP_ON_VBUS | | ||
| 67 | CI13XXX_DISABLE_STREAMING, | ||
| 68 | |||
| 69 | .notify_event = ci13xxx_msm_notify_event, | ||
| 70 | }; | ||
| 71 | |||
| 72 | static int ci13xxx_msm_probe(struct platform_device *pdev) | ||
| 73 | { | ||
| 74 | struct resource *res; | ||
| 75 | void __iomem *regs; | ||
| 76 | int irq; | ||
| 77 | int ret; | ||
| 78 | |||
| 79 | dev_dbg(&pdev->dev, "ci13xxx_msm_probe\n"); | ||
| 80 | |||
| 81 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 82 | if (!res) { | ||
| 83 | dev_err(&pdev->dev, "failed to get platform resource mem\n"); | ||
| 84 | return -ENXIO; | ||
| 85 | } | ||
| 86 | |||
| 87 | regs = ioremap(res->start, resource_size(res)); | ||
| 88 | if (!regs) { | ||
| 89 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
| 90 | return -ENOMEM; | ||
| 91 | } | ||
| 92 | |||
| 93 | ret = udc_probe(&ci13xxx_msm_udc_driver, &pdev->dev, regs); | ||
| 94 | if (ret < 0) { | ||
| 95 | dev_err(&pdev->dev, "udc_probe failed\n"); | ||
| 96 | goto iounmap; | ||
| 97 | } | ||
| 98 | |||
| 99 | irq = platform_get_irq(pdev, 0); | ||
| 100 | if (irq < 0) { | ||
| 101 | dev_err(&pdev->dev, "IRQ not found\n"); | ||
| 102 | ret = -ENXIO; | ||
| 103 | goto udc_remove; | ||
| 104 | } | ||
| 105 | |||
| 106 | ret = request_irq(irq, msm_udc_irq, IRQF_SHARED, pdev->name, pdev); | ||
| 107 | if (ret < 0) { | ||
| 108 | dev_err(&pdev->dev, "request_irq failed\n"); | ||
| 109 | goto udc_remove; | ||
| 110 | } | ||
| 111 | |||
| 112 | pm_runtime_no_callbacks(&pdev->dev); | ||
| 113 | pm_runtime_enable(&pdev->dev); | ||
| 114 | |||
| 115 | return 0; | ||
| 116 | |||
| 117 | udc_remove: | ||
| 118 | udc_remove(); | ||
| 119 | iounmap: | ||
| 120 | iounmap(regs); | ||
| 121 | |||
| 122 | return ret; | ||
| 123 | } | ||
| 124 | |||
| 125 | static struct platform_driver ci13xxx_msm_driver = { | ||
| 126 | .probe = ci13xxx_msm_probe, | ||
| 127 | .driver = { .name = "msm_hsusb", }, | ||
| 128 | }; | ||
| 129 | |||
| 130 | static int __init ci13xxx_msm_init(void) | ||
| 131 | { | ||
| 132 | return platform_driver_register(&ci13xxx_msm_driver); | ||
| 133 | } | ||
| 134 | module_init(ci13xxx_msm_init); | ||
diff --git a/drivers/usb/gadget/ci13xxx_pci.c b/drivers/usb/gadget/ci13xxx_pci.c new file mode 100644 index 000000000000..883ab5e832d1 --- /dev/null +++ b/drivers/usb/gadget/ci13xxx_pci.c | |||
| @@ -0,0 +1,176 @@ | |||
| 1 | /* | ||
| 2 | * ci13xxx_pci.c - MIPS USB IP core family device controller | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Chipidea - MIPS Technologies, Inc. All rights reserved. | ||
| 5 | * | ||
| 6 | * Author: David Lopo | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/pci.h> | ||
| 15 | |||
| 16 | #include "ci13xxx_udc.c" | ||
| 17 | |||
| 18 | /* driver name */ | ||
| 19 | #define UDC_DRIVER_NAME "ci13xxx_pci" | ||
| 20 | |||
| 21 | /****************************************************************************** | ||
| 22 | * PCI block | ||
| 23 | *****************************************************************************/ | ||
| 24 | /** | ||
| 25 | * ci13xxx_pci_irq: interrut handler | ||
| 26 | * @irq: irq number | ||
| 27 | * @pdev: USB Device Controller interrupt source | ||
| 28 | * | ||
| 29 | * This function returns IRQ_HANDLED if the IRQ has been handled | ||
| 30 | * This is an ISR don't trace, use attribute interface instead | ||
| 31 | */ | ||
| 32 | static irqreturn_t ci13xxx_pci_irq(int irq, void *pdev) | ||
| 33 | { | ||
| 34 | if (irq == 0) { | ||
| 35 | dev_err(&((struct pci_dev *)pdev)->dev, "Invalid IRQ0 usage!"); | ||
| 36 | return IRQ_HANDLED; | ||
| 37 | } | ||
| 38 | return udc_irq(); | ||
| 39 | } | ||
| 40 | |||
| 41 | static struct ci13xxx_udc_driver ci13xxx_pci_udc_driver = { | ||
| 42 | .name = UDC_DRIVER_NAME, | ||
| 43 | }; | ||
| 44 | |||
| 45 | /** | ||
| 46 | * ci13xxx_pci_probe: PCI probe | ||
| 47 | * @pdev: USB device controller being probed | ||
| 48 | * @id: PCI hotplug ID connecting controller to UDC framework | ||
| 49 | * | ||
| 50 | * This function returns an error code | ||
| 51 | * Allocates basic PCI resources for this USB device controller, and then | ||
| 52 | * invokes the udc_probe() method to start the UDC associated with it | ||
| 53 | */ | ||
| 54 | static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev, | ||
| 55 | const struct pci_device_id *id) | ||
| 56 | { | ||
| 57 | void __iomem *regs = NULL; | ||
| 58 | int retval = 0; | ||
| 59 | |||
| 60 | if (id == NULL) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | retval = pci_enable_device(pdev); | ||
| 64 | if (retval) | ||
| 65 | goto done; | ||
| 66 | |||
| 67 | if (!pdev->irq) { | ||
| 68 | dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!"); | ||
| 69 | retval = -ENODEV; | ||
| 70 | goto disable_device; | ||
| 71 | } | ||
| 72 | |||
| 73 | retval = pci_request_regions(pdev, UDC_DRIVER_NAME); | ||
| 74 | if (retval) | ||
| 75 | goto disable_device; | ||
| 76 | |||
| 77 | /* BAR 0 holds all the registers */ | ||
| 78 | regs = pci_iomap(pdev, 0, 0); | ||
| 79 | if (!regs) { | ||
| 80 | dev_err(&pdev->dev, "Error mapping memory!"); | ||
| 81 | retval = -EFAULT; | ||
| 82 | goto release_regions; | ||
| 83 | } | ||
| 84 | pci_set_drvdata(pdev, (__force void *)regs); | ||
| 85 | |||
| 86 | pci_set_master(pdev); | ||
| 87 | pci_try_set_mwi(pdev); | ||
| 88 | |||
| 89 | retval = udc_probe(&ci13xxx_pci_udc_driver, &pdev->dev, regs); | ||
| 90 | if (retval) | ||
| 91 | goto iounmap; | ||
| 92 | |||
| 93 | /* our device does not have MSI capability */ | ||
| 94 | |||
| 95 | retval = request_irq(pdev->irq, ci13xxx_pci_irq, IRQF_SHARED, | ||
| 96 | UDC_DRIVER_NAME, pdev); | ||
| 97 | if (retval) | ||
| 98 | goto gadget_remove; | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | |||
| 102 | gadget_remove: | ||
| 103 | udc_remove(); | ||
| 104 | iounmap: | ||
| 105 | pci_iounmap(pdev, regs); | ||
| 106 | release_regions: | ||
| 107 | pci_release_regions(pdev); | ||
| 108 | disable_device: | ||
| 109 | pci_disable_device(pdev); | ||
| 110 | done: | ||
| 111 | return retval; | ||
| 112 | } | ||
| 113 | |||
| 114 | /** | ||
| 115 | * ci13xxx_pci_remove: PCI remove | ||
| 116 | * @pdev: USB Device Controller being removed | ||
| 117 | * | ||
| 118 | * Reverses the effect of ci13xxx_pci_probe(), | ||
| 119 | * first invoking the udc_remove() and then releases | ||
| 120 | * all PCI resources allocated for this USB device controller | ||
| 121 | */ | ||
| 122 | static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev) | ||
| 123 | { | ||
| 124 | free_irq(pdev->irq, pdev); | ||
| 125 | udc_remove(); | ||
| 126 | pci_iounmap(pdev, (__force void __iomem *)pci_get_drvdata(pdev)); | ||
| 127 | pci_release_regions(pdev); | ||
| 128 | pci_disable_device(pdev); | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * PCI device table | ||
| 133 | * PCI device structure | ||
| 134 | * | ||
| 135 | * Check "pci.h" for details | ||
| 136 | */ | ||
| 137 | static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = { | ||
| 138 | { PCI_DEVICE(0x153F, 0x1004) }, | ||
| 139 | { PCI_DEVICE(0x153F, 0x1006) }, | ||
| 140 | { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ } | ||
| 141 | }; | ||
| 142 | MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table); | ||
| 143 | |||
| 144 | static struct pci_driver ci13xxx_pci_driver = { | ||
| 145 | .name = UDC_DRIVER_NAME, | ||
| 146 | .id_table = ci13xxx_pci_id_table, | ||
| 147 | .probe = ci13xxx_pci_probe, | ||
| 148 | .remove = __devexit_p(ci13xxx_pci_remove), | ||
| 149 | }; | ||
| 150 | |||
| 151 | /** | ||
| 152 | * ci13xxx_pci_init: module init | ||
| 153 | * | ||
| 154 | * Driver load | ||
| 155 | */ | ||
| 156 | static int __init ci13xxx_pci_init(void) | ||
| 157 | { | ||
| 158 | return pci_register_driver(&ci13xxx_pci_driver); | ||
| 159 | } | ||
| 160 | module_init(ci13xxx_pci_init); | ||
| 161 | |||
| 162 | /** | ||
| 163 | * ci13xxx_pci_exit: module exit | ||
| 164 | * | ||
| 165 | * Driver unload | ||
| 166 | */ | ||
| 167 | static void __exit ci13xxx_pci_exit(void) | ||
| 168 | { | ||
| 169 | pci_unregister_driver(&ci13xxx_pci_driver); | ||
| 170 | } | ||
| 171 | module_exit(ci13xxx_pci_exit); | ||
| 172 | |||
| 173 | MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>"); | ||
| 174 | MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller"); | ||
| 175 | MODULE_LICENSE("GPL"); | ||
| 176 | MODULE_VERSION("June 2008"); | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 98b36fc88c77..f200e472e476 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | * - ENDPT: endpoint operations (Gadget API) | 22 | * - ENDPT: endpoint operations (Gadget API) |
| 23 | * - GADGET: gadget operations (Gadget API) | 23 | * - GADGET: gadget operations (Gadget API) |
| 24 | * - BUS: bus glue code, bus abstraction layer | 24 | * - BUS: bus glue code, bus abstraction layer |
| 25 | * - PCI: PCI core interface and PCI resources (interrupts, memory...) | ||
| 26 | * | 25 | * |
| 27 | * Compile Options | 26 | * Compile Options |
| 28 | * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities | 27 | * - CONFIG_USB_GADGET_DEBUG_FILES: enable debug facilities |
| @@ -60,11 +59,11 @@ | |||
| 60 | #include <linux/io.h> | 59 | #include <linux/io.h> |
| 61 | #include <linux/irq.h> | 60 | #include <linux/irq.h> |
| 62 | #include <linux/kernel.h> | 61 | #include <linux/kernel.h> |
| 63 | #include <linux/module.h> | ||
| 64 | #include <linux/pci.h> | ||
| 65 | #include <linux/slab.h> | 62 | #include <linux/slab.h> |
| 63 | #include <linux/pm_runtime.h> | ||
| 66 | #include <linux/usb/ch9.h> | 64 | #include <linux/usb/ch9.h> |
| 67 | #include <linux/usb/gadget.h> | 65 | #include <linux/usb/gadget.h> |
| 66 | #include <linux/usb/otg.h> | ||
| 68 | 67 | ||
| 69 | #include "ci13xxx_udc.h" | 68 | #include "ci13xxx_udc.h" |
| 70 | 69 | ||
| @@ -75,9 +74,6 @@ | |||
| 75 | /* ctrl register bank access */ | 74 | /* ctrl register bank access */ |
| 76 | static DEFINE_SPINLOCK(udc_lock); | 75 | static DEFINE_SPINLOCK(udc_lock); |
| 77 | 76 | ||
| 78 | /* driver name */ | ||
| 79 | #define UDC_DRIVER_NAME "ci13xxx_udc" | ||
| 80 | |||
| 81 | /* control endpoint description */ | 77 | /* control endpoint description */ |
| 82 | static const struct usb_endpoint_descriptor | 78 | static const struct usb_endpoint_descriptor |
| 83 | ctrl_endpt_desc = { | 79 | ctrl_endpt_desc = { |
| @@ -132,6 +128,9 @@ static struct { | |||
| 132 | size_t size; /* bank size */ | 128 | size_t size; /* bank size */ |
| 133 | } hw_bank; | 129 | } hw_bank; |
| 134 | 130 | ||
| 131 | /* MSM specific */ | ||
| 132 | #define ABS_AHBBURST (0x0090UL) | ||
| 133 | #define ABS_AHBMODE (0x0098UL) | ||
| 135 | /* UDC register map */ | 134 | /* UDC register map */ |
| 136 | #define ABS_CAPLENGTH (0x100UL) | 135 | #define ABS_CAPLENGTH (0x100UL) |
| 137 | #define ABS_HCCPARAMS (0x108UL) | 136 | #define ABS_HCCPARAMS (0x108UL) |
| @@ -248,13 +247,7 @@ static u32 hw_ctest_and_write(u32 addr, u32 mask, u32 data) | |||
| 248 | return (reg & mask) >> ffs_nr(mask); | 247 | return (reg & mask) >> ffs_nr(mask); |
| 249 | } | 248 | } |
| 250 | 249 | ||
| 251 | /** | 250 | static int hw_device_init(void __iomem *base) |
| 252 | * hw_device_reset: resets chip (execute without interruption) | ||
| 253 | * @base: register base address | ||
| 254 | * | ||
| 255 | * This function returns an error code | ||
| 256 | */ | ||
| 257 | static int hw_device_reset(void __iomem *base) | ||
| 258 | { | 251 | { |
| 259 | u32 reg; | 252 | u32 reg; |
| 260 | 253 | ||
| @@ -271,6 +264,28 @@ static int hw_device_reset(void __iomem *base) | |||
| 271 | hw_bank.size += CAP_LAST; | 264 | hw_bank.size += CAP_LAST; |
| 272 | hw_bank.size /= sizeof(u32); | 265 | hw_bank.size /= sizeof(u32); |
| 273 | 266 | ||
| 267 | reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN); | ||
| 268 | if (reg == 0 || reg > ENDPT_MAX) | ||
| 269 | return -ENODEV; | ||
| 270 | |||
| 271 | hw_ep_max = reg; /* cache hw ENDPT_MAX */ | ||
| 272 | |||
| 273 | /* setup lock mode ? */ | ||
| 274 | |||
| 275 | /* ENDPTSETUPSTAT is '0' by default */ | ||
| 276 | |||
| 277 | /* HCSPARAMS.bf.ppc SHOULD BE zero for device */ | ||
| 278 | |||
| 279 | return 0; | ||
| 280 | } | ||
| 281 | /** | ||
| 282 | * hw_device_reset: resets chip (execute without interruption) | ||
| 283 | * @base: register base address | ||
| 284 | * | ||
| 285 | * This function returns an error code | ||
| 286 | */ | ||
| 287 | static int hw_device_reset(struct ci13xxx *udc) | ||
| 288 | { | ||
| 274 | /* should flush & stop before reset */ | 289 | /* should flush & stop before reset */ |
| 275 | hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); | 290 | hw_cwrite(CAP_ENDPTFLUSH, ~0, ~0); |
| 276 | hw_cwrite(CAP_USBCMD, USBCMD_RS, 0); | 291 | hw_cwrite(CAP_USBCMD, USBCMD_RS, 0); |
| @@ -279,6 +294,14 @@ static int hw_device_reset(void __iomem *base) | |||
| 279 | while (hw_cread(CAP_USBCMD, USBCMD_RST)) | 294 | while (hw_cread(CAP_USBCMD, USBCMD_RST)) |
| 280 | udelay(10); /* not RTOS friendly */ | 295 | udelay(10); /* not RTOS friendly */ |
| 281 | 296 | ||
| 297 | |||
| 298 | if (udc->udc_driver->notify_event) | ||
| 299 | udc->udc_driver->notify_event(udc, | ||
| 300 | CI13XXX_CONTROLLER_RESET_EVENT); | ||
| 301 | |||
| 302 | if (udc->udc_driver->flags && CI13XXX_DISABLE_STREAMING) | ||
| 303 | hw_cwrite(CAP_USBMODE, USBMODE_SDIS, USBMODE_SDIS); | ||
| 304 | |||
| 282 | /* USBMODE should be configured step by step */ | 305 | /* USBMODE should be configured step by step */ |
| 283 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); | 306 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_IDLE); |
| 284 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE); | 307 | hw_cwrite(CAP_USBMODE, USBMODE_CM, USBMODE_CM_DEVICE); |
| @@ -290,18 +313,6 @@ static int hw_device_reset(void __iomem *base) | |||
| 290 | return -ENODEV; | 313 | return -ENODEV; |
| 291 | } | 314 | } |
| 292 | 315 | ||
| 293 | reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN); | ||
| 294 | if (reg == 0 || reg > ENDPT_MAX) | ||
| 295 | return -ENODEV; | ||
| 296 | |||
| 297 | hw_ep_max = reg; /* cache hw ENDPT_MAX */ | ||
| 298 | |||
| 299 | /* setup lock mode ? */ | ||
| 300 | |||
| 301 | /* ENDPTSETUPSTAT is '0' by default */ | ||
| 302 | |||
| 303 | /* HCSPARAMS.bf.ppc SHOULD BE zero for device */ | ||
| 304 | |||
| 305 | return 0; | 316 | return 0; |
| 306 | } | 317 | } |
| 307 | 318 | ||
| @@ -1557,8 +1568,6 @@ __acquires(mEp->lock) | |||
| 1557 | * Caller must hold lock | 1568 | * Caller must hold lock |
| 1558 | */ | 1569 | */ |
| 1559 | static int _gadget_stop_activity(struct usb_gadget *gadget) | 1570 | static int _gadget_stop_activity(struct usb_gadget *gadget) |
| 1560 | __releases(udc->lock) | ||
| 1561 | __acquires(udc->lock) | ||
| 1562 | { | 1571 | { |
| 1563 | struct usb_ep *ep; | 1572 | struct usb_ep *ep; |
| 1564 | struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); | 1573 | struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); |
| @@ -1570,8 +1579,6 @@ __acquires(udc->lock) | |||
| 1570 | if (gadget == NULL) | 1579 | if (gadget == NULL) |
| 1571 | return -EINVAL; | 1580 | return -EINVAL; |
| 1572 | 1581 | ||
| 1573 | spin_unlock(udc->lock); | ||
| 1574 | |||
| 1575 | /* flush all endpoints */ | 1582 | /* flush all endpoints */ |
| 1576 | gadget_for_each_ep(ep, gadget) { | 1583 | gadget_for_each_ep(ep, gadget) { |
| 1577 | usb_ep_fifo_flush(ep); | 1584 | usb_ep_fifo_flush(ep); |
| @@ -1591,8 +1598,6 @@ __acquires(udc->lock) | |||
| 1591 | mEp->status = NULL; | 1598 | mEp->status = NULL; |
| 1592 | } | 1599 | } |
| 1593 | 1600 | ||
| 1594 | spin_lock(udc->lock); | ||
| 1595 | |||
| 1596 | return 0; | 1601 | return 0; |
| 1597 | } | 1602 | } |
| 1598 | 1603 | ||
| @@ -1621,6 +1626,7 @@ __acquires(udc->lock) | |||
| 1621 | 1626 | ||
| 1622 | dbg_event(0xFF, "BUS RST", 0); | 1627 | dbg_event(0xFF, "BUS RST", 0); |
| 1623 | 1628 | ||
| 1629 | spin_unlock(udc->lock); | ||
| 1624 | retval = _gadget_stop_activity(&udc->gadget); | 1630 | retval = _gadget_stop_activity(&udc->gadget); |
| 1625 | if (retval) | 1631 | if (retval) |
| 1626 | goto done; | 1632 | goto done; |
| @@ -1629,10 +1635,9 @@ __acquires(udc->lock) | |||
| 1629 | if (retval) | 1635 | if (retval) |
| 1630 | goto done; | 1636 | goto done; |
| 1631 | 1637 | ||
| 1632 | spin_unlock(udc->lock); | ||
| 1633 | retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); | 1638 | retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); |
| 1634 | if (!retval) { | 1639 | if (!retval) { |
| 1635 | mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_KERNEL); | 1640 | mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_ATOMIC); |
| 1636 | if (mEp->status == NULL) { | 1641 | if (mEp->status == NULL) { |
| 1637 | usb_ep_disable(&mEp->ep); | 1642 | usb_ep_disable(&mEp->ep); |
| 1638 | retval = -ENOMEM; | 1643 | retval = -ENOMEM; |
| @@ -2061,7 +2066,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) | |||
| 2061 | { | 2066 | { |
| 2062 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); | 2067 | struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); |
| 2063 | struct ci13xxx_req *mReq = NULL; | 2068 | struct ci13xxx_req *mReq = NULL; |
| 2064 | unsigned long flags; | ||
| 2065 | 2069 | ||
| 2066 | trace("%p, %i", ep, gfp_flags); | 2070 | trace("%p, %i", ep, gfp_flags); |
| 2067 | 2071 | ||
| @@ -2070,8 +2074,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) | |||
| 2070 | return NULL; | 2074 | return NULL; |
| 2071 | } | 2075 | } |
| 2072 | 2076 | ||
| 2073 | spin_lock_irqsave(mEp->lock, flags); | ||
| 2074 | |||
| 2075 | mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); | 2077 | mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); |
| 2076 | if (mReq != NULL) { | 2078 | if (mReq != NULL) { |
| 2077 | INIT_LIST_HEAD(&mReq->queue); | 2079 | INIT_LIST_HEAD(&mReq->queue); |
| @@ -2086,8 +2088,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) | |||
| 2086 | 2088 | ||
| 2087 | dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL); | 2089 | dbg_event(_usb_addr(mEp), "ALLOC", mReq == NULL); |
| 2088 | 2090 | ||
| 2089 | spin_unlock_irqrestore(mEp->lock, flags); | ||
| 2090 | |||
| 2091 | return (mReq == NULL) ? NULL : &mReq->req; | 2091 | return (mReq == NULL) ? NULL : &mReq->req; |
| 2092 | } | 2092 | } |
| 2093 | 2093 | ||
| @@ -2332,12 +2332,47 @@ static const struct usb_ep_ops usb_ep_ops = { | |||
| 2332 | /****************************************************************************** | 2332 | /****************************************************************************** |
| 2333 | * GADGET block | 2333 | * GADGET block |
| 2334 | *****************************************************************************/ | 2334 | *****************************************************************************/ |
| 2335 | static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) | ||
| 2336 | { | ||
| 2337 | struct ci13xxx *udc = container_of(_gadget, struct ci13xxx, gadget); | ||
| 2338 | unsigned long flags; | ||
| 2339 | int gadget_ready = 0; | ||
| 2340 | |||
| 2341 | if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS)) | ||
| 2342 | return -EOPNOTSUPP; | ||
| 2343 | |||
| 2344 | spin_lock_irqsave(udc->lock, flags); | ||
| 2345 | udc->vbus_active = is_active; | ||
| 2346 | if (udc->driver) | ||
| 2347 | gadget_ready = 1; | ||
| 2348 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2349 | |||
| 2350 | if (gadget_ready) { | ||
| 2351 | if (is_active) { | ||
| 2352 | pm_runtime_get_sync(&_gadget->dev); | ||
| 2353 | hw_device_reset(udc); | ||
| 2354 | hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma); | ||
| 2355 | } else { | ||
| 2356 | hw_device_state(0); | ||
| 2357 | if (udc->udc_driver->notify_event) | ||
| 2358 | udc->udc_driver->notify_event(udc, | ||
| 2359 | CI13XXX_CONTROLLER_STOPPED_EVENT); | ||
| 2360 | _gadget_stop_activity(&udc->gadget); | ||
| 2361 | pm_runtime_put_sync(&_gadget->dev); | ||
| 2362 | } | ||
| 2363 | } | ||
| 2364 | |||
| 2365 | return 0; | ||
| 2366 | } | ||
| 2367 | |||
| 2335 | /** | 2368 | /** |
| 2336 | * Device operations part of the API to the USB controller hardware, | 2369 | * Device operations part of the API to the USB controller hardware, |
| 2337 | * which don't involve endpoints (or i/o) | 2370 | * which don't involve endpoints (or i/o) |
| 2338 | * Check "usb_gadget.h" for details | 2371 | * Check "usb_gadget.h" for details |
| 2339 | */ | 2372 | */ |
| 2340 | static const struct usb_gadget_ops usb_gadget_ops; | 2373 | static const struct usb_gadget_ops usb_gadget_ops = { |
| 2374 | .vbus_session = ci13xxx_vbus_session, | ||
| 2375 | }; | ||
| 2341 | 2376 | ||
| 2342 | /** | 2377 | /** |
| 2343 | * usb_gadget_probe_driver: register a gadget driver | 2378 | * usb_gadget_probe_driver: register a gadget driver |
| @@ -2390,7 +2425,6 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
| 2390 | info("hw_ep_max = %d", hw_ep_max); | 2425 | info("hw_ep_max = %d", hw_ep_max); |
| 2391 | 2426 | ||
| 2392 | udc->driver = driver; | 2427 | udc->driver = driver; |
| 2393 | udc->gadget.ops = NULL; | ||
| 2394 | udc->gadget.dev.driver = NULL; | 2428 | udc->gadget.dev.driver = NULL; |
| 2395 | 2429 | ||
| 2396 | retval = 0; | 2430 | retval = 0; |
| @@ -2410,9 +2444,11 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
| 2410 | /* this allocation cannot be random */ | 2444 | /* this allocation cannot be random */ |
| 2411 | for (k = RX; k <= TX; k++) { | 2445 | for (k = RX; k <= TX; k++) { |
| 2412 | INIT_LIST_HEAD(&mEp->qh[k].queue); | 2446 | INIT_LIST_HEAD(&mEp->qh[k].queue); |
| 2447 | spin_unlock_irqrestore(udc->lock, flags); | ||
| 2413 | mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool, | 2448 | mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool, |
| 2414 | GFP_KERNEL, | 2449 | GFP_KERNEL, |
| 2415 | &mEp->qh[k].dma); | 2450 | &mEp->qh[k].dma); |
| 2451 | spin_lock_irqsave(udc->lock, flags); | ||
| 2416 | if (mEp->qh[k].ptr == NULL) | 2452 | if (mEp->qh[k].ptr == NULL) |
| 2417 | retval = -ENOMEM; | 2453 | retval = -ENOMEM; |
| 2418 | else | 2454 | else |
| @@ -2429,7 +2465,6 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
| 2429 | 2465 | ||
| 2430 | /* bind gadget */ | 2466 | /* bind gadget */ |
| 2431 | driver->driver.bus = NULL; | 2467 | driver->driver.bus = NULL; |
| 2432 | udc->gadget.ops = &usb_gadget_ops; | ||
| 2433 | udc->gadget.dev.driver = &driver->driver; | 2468 | udc->gadget.dev.driver = &driver->driver; |
| 2434 | 2469 | ||
| 2435 | spin_unlock_irqrestore(udc->lock, flags); | 2470 | spin_unlock_irqrestore(udc->lock, flags); |
| @@ -2437,12 +2472,24 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
| 2437 | spin_lock_irqsave(udc->lock, flags); | 2472 | spin_lock_irqsave(udc->lock, flags); |
| 2438 | 2473 | ||
| 2439 | if (retval) { | 2474 | if (retval) { |
| 2440 | udc->gadget.ops = NULL; | ||
| 2441 | udc->gadget.dev.driver = NULL; | 2475 | udc->gadget.dev.driver = NULL; |
| 2442 | goto done; | 2476 | goto done; |
| 2443 | } | 2477 | } |
| 2444 | 2478 | ||
| 2479 | pm_runtime_get_sync(&udc->gadget.dev); | ||
| 2480 | if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) { | ||
| 2481 | if (udc->vbus_active) { | ||
| 2482 | if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) | ||
| 2483 | hw_device_reset(udc); | ||
| 2484 | } else { | ||
| 2485 | pm_runtime_put_sync(&udc->gadget.dev); | ||
| 2486 | goto done; | ||
| 2487 | } | ||
| 2488 | } | ||
| 2489 | |||
| 2445 | retval = hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma); | 2490 | retval = hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma); |
| 2491 | if (retval) | ||
| 2492 | pm_runtime_put_sync(&udc->gadget.dev); | ||
| 2446 | 2493 | ||
| 2447 | done: | 2494 | done: |
| 2448 | spin_unlock_irqrestore(udc->lock, flags); | 2495 | spin_unlock_irqrestore(udc->lock, flags); |
| @@ -2475,19 +2522,22 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 2475 | 2522 | ||
| 2476 | spin_lock_irqsave(udc->lock, flags); | 2523 | spin_lock_irqsave(udc->lock, flags); |
| 2477 | 2524 | ||
| 2478 | hw_device_state(0); | 2525 | if (!(udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) || |
| 2479 | 2526 | udc->vbus_active) { | |
| 2480 | /* unbind gadget */ | 2527 | hw_device_state(0); |
| 2481 | if (udc->gadget.ops != NULL) { | 2528 | if (udc->udc_driver->notify_event) |
| 2529 | udc->udc_driver->notify_event(udc, | ||
| 2530 | CI13XXX_CONTROLLER_STOPPED_EVENT); | ||
| 2482 | _gadget_stop_activity(&udc->gadget); | 2531 | _gadget_stop_activity(&udc->gadget); |
| 2532 | pm_runtime_put(&udc->gadget.dev); | ||
| 2533 | } | ||
| 2483 | 2534 | ||
| 2484 | spin_unlock_irqrestore(udc->lock, flags); | 2535 | /* unbind gadget */ |
| 2485 | driver->unbind(&udc->gadget); /* MAY SLEEP */ | 2536 | spin_unlock_irqrestore(udc->lock, flags); |
| 2486 | spin_lock_irqsave(udc->lock, flags); | 2537 | driver->unbind(&udc->gadget); /* MAY SLEEP */ |
| 2538 | spin_lock_irqsave(udc->lock, flags); | ||
| 2487 | 2539 | ||
| 2488 | udc->gadget.ops = NULL; | 2540 | udc->gadget.dev.driver = NULL; |
| 2489 | udc->gadget.dev.driver = NULL; | ||
| 2490 | } | ||
| 2491 | 2541 | ||
| 2492 | /* free resources */ | 2542 | /* free resources */ |
| 2493 | for (i = 0; i < hw_ep_max; i++) { | 2543 | for (i = 0; i < hw_ep_max; i++) { |
| @@ -2544,6 +2594,14 @@ static irqreturn_t udc_irq(void) | |||
| 2544 | } | 2594 | } |
| 2545 | 2595 | ||
| 2546 | spin_lock(udc->lock); | 2596 | spin_lock(udc->lock); |
| 2597 | |||
| 2598 | if (udc->udc_driver->flags & CI13XXX_REGS_SHARED) { | ||
| 2599 | if (hw_cread(CAP_USBMODE, USBMODE_CM) != | ||
| 2600 | USBMODE_CM_DEVICE) { | ||
| 2601 | spin_unlock(udc->lock); | ||
| 2602 | return IRQ_NONE; | ||
| 2603 | } | ||
| 2604 | } | ||
| 2547 | intr = hw_test_and_clear_intr_active(); | 2605 | intr = hw_test_and_clear_intr_active(); |
| 2548 | if (intr) { | 2606 | if (intr) { |
| 2549 | isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr; | 2607 | isr_statistics.hndl.buf[isr_statistics.hndl.idx++] = intr; |
| @@ -2602,14 +2660,16 @@ static void udc_release(struct device *dev) | |||
| 2602 | * No interrupts active, the IRQ has not been requested yet | 2660 | * No interrupts active, the IRQ has not been requested yet |
| 2603 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask | 2661 | * Kernel assumes 32-bit DMA operations by default, no need to dma_set_mask |
| 2604 | */ | 2662 | */ |
| 2605 | static int udc_probe(struct device *dev, void __iomem *regs, const char *name) | 2663 | static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, |
| 2664 | void __iomem *regs) | ||
| 2606 | { | 2665 | { |
| 2607 | struct ci13xxx *udc; | 2666 | struct ci13xxx *udc; |
| 2608 | int retval = 0; | 2667 | int retval = 0; |
| 2609 | 2668 | ||
| 2610 | trace("%p, %p, %p", dev, regs, name); | 2669 | trace("%p, %p, %p", dev, regs, name); |
| 2611 | 2670 | ||
| 2612 | if (dev == NULL || regs == NULL || name == NULL) | 2671 | if (dev == NULL || regs == NULL || driver == NULL || |
| 2672 | driver->name == NULL) | ||
| 2613 | return -EINVAL; | 2673 | return -EINVAL; |
| 2614 | 2674 | ||
| 2615 | udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL); | 2675 | udc = kzalloc(sizeof(struct ci13xxx), GFP_KERNEL); |
| @@ -2617,42 +2677,77 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name) | |||
| 2617 | return -ENOMEM; | 2677 | return -ENOMEM; |
| 2618 | 2678 | ||
| 2619 | udc->lock = &udc_lock; | 2679 | udc->lock = &udc_lock; |
| 2680 | udc->regs = regs; | ||
| 2681 | udc->udc_driver = driver; | ||
| 2620 | 2682 | ||
| 2621 | retval = hw_device_reset(regs); | 2683 | udc->gadget.ops = &usb_gadget_ops; |
| 2622 | if (retval) | ||
| 2623 | goto done; | ||
| 2624 | |||
| 2625 | udc->gadget.ops = NULL; | ||
| 2626 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 2684 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
| 2627 | udc->gadget.is_dualspeed = 1; | 2685 | udc->gadget.is_dualspeed = 1; |
| 2628 | udc->gadget.is_otg = 0; | 2686 | udc->gadget.is_otg = 0; |
| 2629 | udc->gadget.name = name; | 2687 | udc->gadget.name = driver->name; |
| 2630 | 2688 | ||
| 2631 | INIT_LIST_HEAD(&udc->gadget.ep_list); | 2689 | INIT_LIST_HEAD(&udc->gadget.ep_list); |
| 2632 | udc->gadget.ep0 = NULL; | 2690 | udc->gadget.ep0 = NULL; |
| 2633 | 2691 | ||
| 2634 | dev_set_name(&udc->gadget.dev, "gadget"); | 2692 | dev_set_name(&udc->gadget.dev, "gadget"); |
| 2635 | udc->gadget.dev.dma_mask = dev->dma_mask; | 2693 | udc->gadget.dev.dma_mask = dev->dma_mask; |
| 2694 | udc->gadget.dev.coherent_dma_mask = dev->coherent_dma_mask; | ||
| 2636 | udc->gadget.dev.parent = dev; | 2695 | udc->gadget.dev.parent = dev; |
| 2637 | udc->gadget.dev.release = udc_release; | 2696 | udc->gadget.dev.release = udc_release; |
| 2638 | 2697 | ||
| 2698 | retval = hw_device_init(regs); | ||
| 2699 | if (retval < 0) | ||
| 2700 | goto free_udc; | ||
| 2701 | |||
| 2702 | udc->transceiver = otg_get_transceiver(); | ||
| 2703 | |||
| 2704 | if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) { | ||
| 2705 | if (udc->transceiver == NULL) { | ||
| 2706 | retval = -ENODEV; | ||
| 2707 | goto free_udc; | ||
| 2708 | } | ||
| 2709 | } | ||
| 2710 | |||
| 2711 | if (!(udc->udc_driver->flags & CI13XXX_REGS_SHARED)) { | ||
| 2712 | retval = hw_device_reset(udc); | ||
| 2713 | if (retval) | ||
| 2714 | goto put_transceiver; | ||
| 2715 | } | ||
| 2716 | |||
| 2639 | retval = device_register(&udc->gadget.dev); | 2717 | retval = device_register(&udc->gadget.dev); |
| 2640 | if (retval) | 2718 | if (retval) { |
| 2641 | goto done; | 2719 | put_device(&udc->gadget.dev); |
| 2720 | goto put_transceiver; | ||
| 2721 | } | ||
| 2642 | 2722 | ||
| 2643 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 2723 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
| 2644 | retval = dbg_create_files(&udc->gadget.dev); | 2724 | retval = dbg_create_files(&udc->gadget.dev); |
| 2645 | #endif | 2725 | #endif |
| 2646 | if (retval) { | 2726 | if (retval) |
| 2647 | device_unregister(&udc->gadget.dev); | 2727 | goto unreg_device; |
| 2648 | goto done; | 2728 | |
| 2729 | if (udc->transceiver) { | ||
| 2730 | retval = otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
| 2731 | if (retval) | ||
| 2732 | goto remove_dbg; | ||
| 2649 | } | 2733 | } |
| 2734 | pm_runtime_no_callbacks(&udc->gadget.dev); | ||
| 2735 | pm_runtime_enable(&udc->gadget.dev); | ||
| 2650 | 2736 | ||
| 2651 | _udc = udc; | 2737 | _udc = udc; |
| 2652 | return retval; | 2738 | return retval; |
| 2653 | 2739 | ||
| 2654 | done: | ||
| 2655 | err("error = %i", retval); | 2740 | err("error = %i", retval); |
| 2741 | remove_dbg: | ||
| 2742 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | ||
| 2743 | dbg_remove_files(&udc->gadget.dev); | ||
| 2744 | #endif | ||
| 2745 | unreg_device: | ||
| 2746 | device_unregister(&udc->gadget.dev); | ||
| 2747 | put_transceiver: | ||
| 2748 | if (udc->transceiver) | ||
| 2749 | otg_put_transceiver(udc->transceiver); | ||
| 2750 | free_udc: | ||
| 2656 | kfree(udc); | 2751 | kfree(udc); |
| 2657 | _udc = NULL; | 2752 | _udc = NULL; |
| 2658 | return retval; | 2753 | return retval; |
| @@ -2672,6 +2767,10 @@ static void udc_remove(void) | |||
| 2672 | return; | 2767 | return; |
| 2673 | } | 2768 | } |
| 2674 | 2769 | ||
| 2770 | if (udc->transceiver) { | ||
| 2771 | otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
| 2772 | otg_put_transceiver(udc->transceiver); | ||
| 2773 | } | ||
| 2675 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 2774 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
| 2676 | dbg_remove_files(&udc->gadget.dev); | 2775 | dbg_remove_files(&udc->gadget.dev); |
| 2677 | #endif | 2776 | #endif |
| @@ -2680,156 +2779,3 @@ static void udc_remove(void) | |||
| 2680 | kfree(udc); | 2779 | kfree(udc); |
| 2681 | _udc = NULL; | 2780 | _udc = NULL; |
| 2682 | } | 2781 | } |
| 2683 | |||
| 2684 | /****************************************************************************** | ||
| 2685 | * PCI block | ||
| 2686 | *****************************************************************************/ | ||
| 2687 | /** | ||
| 2688 | * ci13xxx_pci_irq: interrut handler | ||
| 2689 | * @irq: irq number | ||
| 2690 | * @pdev: USB Device Controller interrupt source | ||
| 2691 | * | ||
| 2692 | * This function returns IRQ_HANDLED if the IRQ has been handled | ||
| 2693 | * This is an ISR don't trace, use attribute interface instead | ||
| 2694 | */ | ||
| 2695 | static irqreturn_t ci13xxx_pci_irq(int irq, void *pdev) | ||
| 2696 | { | ||
| 2697 | if (irq == 0) { | ||
| 2698 | dev_err(&((struct pci_dev *)pdev)->dev, "Invalid IRQ0 usage!"); | ||
| 2699 | return IRQ_HANDLED; | ||
| 2700 | } | ||
| 2701 | return udc_irq(); | ||
| 2702 | } | ||
| 2703 | |||
| 2704 | /** | ||
| 2705 | * ci13xxx_pci_probe: PCI probe | ||
| 2706 | * @pdev: USB device controller being probed | ||
| 2707 | * @id: PCI hotplug ID connecting controller to UDC framework | ||
| 2708 | * | ||
| 2709 | * This function returns an error code | ||
| 2710 | * Allocates basic PCI resources for this USB device controller, and then | ||
| 2711 | * invokes the udc_probe() method to start the UDC associated with it | ||
| 2712 | */ | ||
| 2713 | static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev, | ||
| 2714 | const struct pci_device_id *id) | ||
| 2715 | { | ||
| 2716 | void __iomem *regs = NULL; | ||
| 2717 | int retval = 0; | ||
| 2718 | |||
| 2719 | if (id == NULL) | ||
| 2720 | return -EINVAL; | ||
| 2721 | |||
| 2722 | retval = pci_enable_device(pdev); | ||
| 2723 | if (retval) | ||
| 2724 | goto done; | ||
| 2725 | |||
| 2726 | if (!pdev->irq) { | ||
| 2727 | dev_err(&pdev->dev, "No IRQ, check BIOS/PCI setup!"); | ||
| 2728 | retval = -ENODEV; | ||
| 2729 | goto disable_device; | ||
| 2730 | } | ||
| 2731 | |||
| 2732 | retval = pci_request_regions(pdev, UDC_DRIVER_NAME); | ||
| 2733 | if (retval) | ||
| 2734 | goto disable_device; | ||
| 2735 | |||
| 2736 | /* BAR 0 holds all the registers */ | ||
| 2737 | regs = pci_iomap(pdev, 0, 0); | ||
| 2738 | if (!regs) { | ||
| 2739 | dev_err(&pdev->dev, "Error mapping memory!"); | ||
| 2740 | retval = -EFAULT; | ||
| 2741 | goto release_regions; | ||
| 2742 | } | ||
| 2743 | pci_set_drvdata(pdev, (__force void *)regs); | ||
| 2744 | |||
| 2745 | pci_set_master(pdev); | ||
| 2746 | pci_try_set_mwi(pdev); | ||
| 2747 | |||
| 2748 | retval = udc_probe(&pdev->dev, regs, UDC_DRIVER_NAME); | ||
| 2749 | if (retval) | ||
| 2750 | goto iounmap; | ||
| 2751 | |||
| 2752 | /* our device does not have MSI capability */ | ||
| 2753 | |||
| 2754 | retval = request_irq(pdev->irq, ci13xxx_pci_irq, IRQF_SHARED, | ||
| 2755 | UDC_DRIVER_NAME, pdev); | ||
| 2756 | if (retval) | ||
| 2757 | goto gadget_remove; | ||
| 2758 | |||
| 2759 | return 0; | ||
| 2760 | |||
| 2761 | gadget_remove: | ||
| 2762 | udc_remove(); | ||
| 2763 | iounmap: | ||
| 2764 | pci_iounmap(pdev, regs); | ||
| 2765 | release_regions: | ||
| 2766 | pci_release_regions(pdev); | ||
| 2767 | disable_device: | ||
| 2768 | pci_disable_device(pdev); | ||
| 2769 | done: | ||
| 2770 | return retval; | ||
| 2771 | } | ||
| 2772 | |||
| 2773 | /** | ||
| 2774 | * ci13xxx_pci_remove: PCI remove | ||
| 2775 | * @pdev: USB Device Controller being removed | ||
| 2776 | * | ||
| 2777 | * Reverses the effect of ci13xxx_pci_probe(), | ||
| 2778 | * first invoking the udc_remove() and then releases | ||
| 2779 | * all PCI resources allocated for this USB device controller | ||
| 2780 | */ | ||
| 2781 | static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev) | ||
| 2782 | { | ||
| 2783 | free_irq(pdev->irq, pdev); | ||
| 2784 | udc_remove(); | ||
| 2785 | pci_iounmap(pdev, (__force void __iomem *)pci_get_drvdata(pdev)); | ||
| 2786 | pci_release_regions(pdev); | ||
| 2787 | pci_disable_device(pdev); | ||
| 2788 | } | ||
| 2789 | |||
| 2790 | /** | ||
| 2791 | * PCI device table | ||
| 2792 | * PCI device structure | ||
| 2793 | * | ||
| 2794 | * Check "pci.h" for details | ||
| 2795 | */ | ||
| 2796 | static DEFINE_PCI_DEVICE_TABLE(ci13xxx_pci_id_table) = { | ||
| 2797 | { PCI_DEVICE(0x153F, 0x1004) }, | ||
| 2798 | { PCI_DEVICE(0x153F, 0x1006) }, | ||
| 2799 | { 0, 0, 0, 0, 0, 0, 0 /* end: all zeroes */ } | ||
| 2800 | }; | ||
| 2801 | MODULE_DEVICE_TABLE(pci, ci13xxx_pci_id_table); | ||
| 2802 | |||
| 2803 | static struct pci_driver ci13xxx_pci_driver = { | ||
| 2804 | .name = UDC_DRIVER_NAME, | ||
| 2805 | .id_table = ci13xxx_pci_id_table, | ||
| 2806 | .probe = ci13xxx_pci_probe, | ||
| 2807 | .remove = __devexit_p(ci13xxx_pci_remove), | ||
| 2808 | }; | ||
| 2809 | |||
| 2810 | /** | ||
| 2811 | * ci13xxx_pci_init: module init | ||
| 2812 | * | ||
| 2813 | * Driver load | ||
| 2814 | */ | ||
| 2815 | static int __init ci13xxx_pci_init(void) | ||
| 2816 | { | ||
| 2817 | return pci_register_driver(&ci13xxx_pci_driver); | ||
| 2818 | } | ||
| 2819 | module_init(ci13xxx_pci_init); | ||
| 2820 | |||
| 2821 | /** | ||
| 2822 | * ci13xxx_pci_exit: module exit | ||
| 2823 | * | ||
| 2824 | * Driver unload | ||
| 2825 | */ | ||
| 2826 | static void __exit ci13xxx_pci_exit(void) | ||
| 2827 | { | ||
| 2828 | pci_unregister_driver(&ci13xxx_pci_driver); | ||
| 2829 | } | ||
| 2830 | module_exit(ci13xxx_pci_exit); | ||
| 2831 | |||
| 2832 | MODULE_AUTHOR("MIPS - David Lopo <dlopo@chipidea.mips.com>"); | ||
| 2833 | MODULE_DESCRIPTION("MIPS CI13XXX USB Peripheral Controller"); | ||
| 2834 | MODULE_LICENSE("GPL"); | ||
| 2835 | MODULE_VERSION("June 2008"); | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index 4026e9cede34..4fd19313e238 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h | |||
| @@ -97,9 +97,24 @@ struct ci13xxx_ep { | |||
| 97 | struct dma_pool *td_pool; | 97 | struct dma_pool *td_pool; |
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | struct ci13xxx; | ||
| 101 | struct ci13xxx_udc_driver { | ||
| 102 | const char *name; | ||
| 103 | unsigned long flags; | ||
| 104 | #define CI13XXX_REGS_SHARED BIT(0) | ||
| 105 | #define CI13XXX_REQUIRE_TRANSCEIVER BIT(1) | ||
| 106 | #define CI13XXX_PULLUP_ON_VBUS BIT(2) | ||
| 107 | #define CI13XXX_DISABLE_STREAMING BIT(3) | ||
| 108 | |||
| 109 | #define CI13XXX_CONTROLLER_RESET_EVENT 0 | ||
| 110 | #define CI13XXX_CONTROLLER_STOPPED_EVENT 1 | ||
| 111 | void (*notify_event) (struct ci13xxx *udc, unsigned event); | ||
| 112 | }; | ||
| 113 | |||
| 100 | /* CI13XXX UDC descriptor & global resources */ | 114 | /* CI13XXX UDC descriptor & global resources */ |
| 101 | struct ci13xxx { | 115 | struct ci13xxx { |
| 102 | spinlock_t *lock; /* ctrl register bank access */ | 116 | spinlock_t *lock; /* ctrl register bank access */ |
| 117 | void __iomem *regs; /* registers address space */ | ||
| 103 | 118 | ||
| 104 | struct dma_pool *qh_pool; /* DMA pool for queue heads */ | 119 | struct dma_pool *qh_pool; /* DMA pool for queue heads */ |
| 105 | struct dma_pool *td_pool; /* DMA pool for transfer descs */ | 120 | struct dma_pool *td_pool; /* DMA pool for transfer descs */ |
| @@ -108,6 +123,9 @@ struct ci13xxx { | |||
| 108 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ | 123 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ |
| 109 | 124 | ||
| 110 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ | 125 | struct usb_gadget_driver *driver; /* 3rd party gadget driver */ |
| 126 | struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ | ||
| 127 | int vbus_active; /* is VBUS active */ | ||
| 128 | struct otg_transceiver *transceiver; /* Transceiver struct */ | ||
| 111 | }; | 129 | }; |
| 112 | 130 | ||
| 113 | /****************************************************************************** | 131 | /****************************************************************************** |
| @@ -157,6 +175,7 @@ struct ci13xxx { | |||
| 157 | #define USBMODE_CM_DEVICE (0x02UL << 0) | 175 | #define USBMODE_CM_DEVICE (0x02UL << 0) |
| 158 | #define USBMODE_CM_HOST (0x03UL << 0) | 176 | #define USBMODE_CM_HOST (0x03UL << 0) |
| 159 | #define USBMODE_SLOM BIT(3) | 177 | #define USBMODE_SLOM BIT(3) |
| 178 | #define USBMODE_SDIS BIT(4) | ||
| 160 | 179 | ||
| 161 | /* ENDPTCTRL */ | 180 | /* ENDPTCTRL */ |
| 162 | #define ENDPTCTRL_RXS BIT(0) | 181 | #define ENDPTCTRL_RXS BIT(0) |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 7b5cc16e4a0b..21dc0da36ab7 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
| @@ -1126,7 +1126,7 @@ static int composite_bind(struct usb_gadget *gadget) | |||
| 1126 | cdev->desc = *composite->dev; | 1126 | cdev->desc = *composite->dev; |
| 1127 | cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | 1127 | cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; |
| 1128 | 1128 | ||
| 1129 | /* stirng overrides */ | 1129 | /* string overrides */ |
| 1130 | if (iManufacturer || !cdev->desc.iManufacturer) { | 1130 | if (iManufacturer || !cdev->desc.iManufacturer) { |
| 1131 | if (!iManufacturer && !composite->iManufacturer && | 1131 | if (!iManufacturer && !composite->iManufacturer && |
| 1132 | !*composite_manufacturer) | 1132 | !*composite_manufacturer) |
| @@ -1188,6 +1188,8 @@ composite_suspend(struct usb_gadget *gadget) | |||
| 1188 | composite->suspend(cdev); | 1188 | composite->suspend(cdev); |
| 1189 | 1189 | ||
| 1190 | cdev->suspended = 1; | 1190 | cdev->suspended = 1; |
| 1191 | |||
| 1192 | usb_gadget_vbus_draw(gadget, 2); | ||
| 1191 | } | 1193 | } |
| 1192 | 1194 | ||
| 1193 | static void | 1195 | static void |
| @@ -1195,6 +1197,7 @@ composite_resume(struct usb_gadget *gadget) | |||
| 1195 | { | 1197 | { |
| 1196 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1198 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
| 1197 | struct usb_function *f; | 1199 | struct usb_function *f; |
| 1200 | u8 maxpower; | ||
| 1198 | 1201 | ||
| 1199 | /* REVISIT: should we have config level | 1202 | /* REVISIT: should we have config level |
| 1200 | * suspend/resume callbacks? | 1203 | * suspend/resume callbacks? |
| @@ -1207,6 +1210,11 @@ composite_resume(struct usb_gadget *gadget) | |||
| 1207 | if (f->resume) | 1210 | if (f->resume) |
| 1208 | f->resume(f); | 1211 | f->resume(f); |
| 1209 | } | 1212 | } |
| 1213 | |||
| 1214 | maxpower = cdev->config->bMaxPower; | ||
| 1215 | |||
| 1216 | usb_gadget_vbus_draw(gadget, maxpower ? | ||
| 1217 | (2 * maxpower) : CONFIG_USB_GADGET_VBUS_DRAW); | ||
| 1210 | } | 1218 | } |
| 1211 | 1219 | ||
| 1212 | cdev->suspended = 0; | 1220 | cdev->suspended = 0; |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 1d2a2abbfa80..13b9f47feecd 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
| @@ -1197,6 +1197,139 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) | |||
| 1197 | #define Ep_Request (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) | 1197 | #define Ep_Request (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) |
| 1198 | #define Ep_InRequest (Ep_Request | USB_DIR_IN) | 1198 | #define Ep_InRequest (Ep_Request | USB_DIR_IN) |
| 1199 | 1199 | ||
| 1200 | |||
| 1201 | /** | ||
| 1202 | * handle_control_request() - handles all control transfers | ||
| 1203 | * @dum: pointer to dummy (the_controller) | ||
| 1204 | * @urb: the urb request to handle | ||
| 1205 | * @setup: pointer to the setup data for a USB device control | ||
| 1206 | * request | ||
| 1207 | * @status: pointer to request handling status | ||
| 1208 | * | ||
| 1209 | * Return 0 - if the request was handled | ||
| 1210 | * 1 - if the request wasn't handles | ||
| 1211 | * error code on error | ||
| 1212 | */ | ||
| 1213 | static int handle_control_request(struct dummy *dum, struct urb *urb, | ||
| 1214 | struct usb_ctrlrequest *setup, | ||
| 1215 | int *status) | ||
| 1216 | { | ||
| 1217 | struct dummy_ep *ep2; | ||
| 1218 | int ret_val = 1; | ||
| 1219 | unsigned w_index; | ||
| 1220 | unsigned w_value; | ||
| 1221 | |||
| 1222 | w_index = le16_to_cpu(setup->wIndex); | ||
| 1223 | w_value = le16_to_cpu(setup->wValue); | ||
| 1224 | switch (setup->bRequest) { | ||
| 1225 | case USB_REQ_SET_ADDRESS: | ||
| 1226 | if (setup->bRequestType != Dev_Request) | ||
| 1227 | break; | ||
| 1228 | dum->address = w_value; | ||
| 1229 | *status = 0; | ||
| 1230 | dev_dbg(udc_dev(dum), "set_address = %d\n", | ||
| 1231 | w_value); | ||
| 1232 | ret_val = 0; | ||
| 1233 | break; | ||
| 1234 | case USB_REQ_SET_FEATURE: | ||
| 1235 | if (setup->bRequestType == Dev_Request) { | ||
| 1236 | ret_val = 0; | ||
| 1237 | switch (w_value) { | ||
| 1238 | case USB_DEVICE_REMOTE_WAKEUP: | ||
| 1239 | break; | ||
| 1240 | case USB_DEVICE_B_HNP_ENABLE: | ||
| 1241 | dum->gadget.b_hnp_enable = 1; | ||
| 1242 | break; | ||
| 1243 | case USB_DEVICE_A_HNP_SUPPORT: | ||
| 1244 | dum->gadget.a_hnp_support = 1; | ||
| 1245 | break; | ||
| 1246 | case USB_DEVICE_A_ALT_HNP_SUPPORT: | ||
| 1247 | dum->gadget.a_alt_hnp_support = 1; | ||
| 1248 | break; | ||
| 1249 | default: | ||
| 1250 | ret_val = -EOPNOTSUPP; | ||
| 1251 | } | ||
| 1252 | if (ret_val == 0) { | ||
| 1253 | dum->devstatus |= (1 << w_value); | ||
| 1254 | *status = 0; | ||
| 1255 | } | ||
| 1256 | } else if (setup->bRequestType == Ep_Request) { | ||
| 1257 | /* endpoint halt */ | ||
| 1258 | ep2 = find_endpoint(dum, w_index); | ||
| 1259 | if (!ep2 || ep2->ep.name == ep0name) { | ||
| 1260 | ret_val = -EOPNOTSUPP; | ||
| 1261 | break; | ||
| 1262 | } | ||
| 1263 | ep2->halted = 1; | ||
| 1264 | ret_val = 0; | ||
| 1265 | *status = 0; | ||
| 1266 | } | ||
| 1267 | break; | ||
| 1268 | case USB_REQ_CLEAR_FEATURE: | ||
| 1269 | if (setup->bRequestType == Dev_Request) { | ||
| 1270 | ret_val = 0; | ||
| 1271 | switch (w_value) { | ||
| 1272 | case USB_DEVICE_REMOTE_WAKEUP: | ||
| 1273 | w_value = USB_DEVICE_REMOTE_WAKEUP; | ||
| 1274 | break; | ||
| 1275 | default: | ||
| 1276 | ret_val = -EOPNOTSUPP; | ||
| 1277 | break; | ||
| 1278 | } | ||
| 1279 | if (ret_val == 0) { | ||
| 1280 | dum->devstatus &= ~(1 << w_value); | ||
| 1281 | *status = 0; | ||
| 1282 | } | ||
| 1283 | } else if (setup->bRequestType == Ep_Request) { | ||
| 1284 | /* endpoint halt */ | ||
| 1285 | ep2 = find_endpoint(dum, w_index); | ||
| 1286 | if (!ep2) { | ||
| 1287 | ret_val = -EOPNOTSUPP; | ||
| 1288 | break; | ||
| 1289 | } | ||
| 1290 | if (!ep2->wedged) | ||
| 1291 | ep2->halted = 0; | ||
| 1292 | ret_val = 0; | ||
| 1293 | *status = 0; | ||
| 1294 | } | ||
| 1295 | break; | ||
| 1296 | case USB_REQ_GET_STATUS: | ||
| 1297 | if (setup->bRequestType == Dev_InRequest | ||
| 1298 | || setup->bRequestType == Intf_InRequest | ||
| 1299 | || setup->bRequestType == Ep_InRequest) { | ||
| 1300 | char *buf; | ||
| 1301 | /* | ||
| 1302 | * device: remote wakeup, selfpowered | ||
| 1303 | * interface: nothing | ||
| 1304 | * endpoint: halt | ||
| 1305 | */ | ||
| 1306 | buf = (char *)urb->transfer_buffer; | ||
| 1307 | if (urb->transfer_buffer_length > 0) { | ||
| 1308 | if (setup->bRequestType == Ep_InRequest) { | ||
| 1309 | ep2 = find_endpoint(dum, w_index); | ||
| 1310 | if (!ep2) { | ||
| 1311 | ret_val = -EOPNOTSUPP; | ||
| 1312 | break; | ||
| 1313 | } | ||
| 1314 | buf[0] = ep2->halted; | ||
| 1315 | } else if (setup->bRequestType == | ||
| 1316 | Dev_InRequest) { | ||
| 1317 | buf[0] = (u8)dum->devstatus; | ||
| 1318 | } else | ||
| 1319 | buf[0] = 0; | ||
| 1320 | } | ||
| 1321 | if (urb->transfer_buffer_length > 1) | ||
| 1322 | buf[1] = 0; | ||
| 1323 | urb->actual_length = min_t(u32, 2, | ||
| 1324 | urb->transfer_buffer_length); | ||
| 1325 | ret_val = 0; | ||
| 1326 | *status = 0; | ||
| 1327 | } | ||
| 1328 | break; | ||
| 1329 | } | ||
| 1330 | return ret_val; | ||
| 1331 | } | ||
| 1332 | |||
| 1200 | /* drive both sides of the transfers; looks like irq handlers to | 1333 | /* drive both sides of the transfers; looks like irq handlers to |
| 1201 | * both drivers except the callbacks aren't in_irq(). | 1334 | * both drivers except the callbacks aren't in_irq(). |
| 1202 | */ | 1335 | */ |
| @@ -1299,14 +1432,8 @@ restart: | |||
| 1299 | if (ep == &dum->ep [0] && ep->setup_stage) { | 1432 | if (ep == &dum->ep [0] && ep->setup_stage) { |
| 1300 | struct usb_ctrlrequest setup; | 1433 | struct usb_ctrlrequest setup; |
| 1301 | int value = 1; | 1434 | int value = 1; |
| 1302 | struct dummy_ep *ep2; | ||
| 1303 | unsigned w_index; | ||
| 1304 | unsigned w_value; | ||
| 1305 | 1435 | ||
| 1306 | setup = *(struct usb_ctrlrequest*) urb->setup_packet; | 1436 | setup = *(struct usb_ctrlrequest*) urb->setup_packet; |
| 1307 | w_index = le16_to_cpu(setup.wIndex); | ||
| 1308 | w_value = le16_to_cpu(setup.wValue); | ||
| 1309 | |||
| 1310 | /* paranoia, in case of stale queued data */ | 1437 | /* paranoia, in case of stale queued data */ |
| 1311 | list_for_each_entry (req, &ep->queue, queue) { | 1438 | list_for_each_entry (req, &ep->queue, queue) { |
| 1312 | list_del_init (&req->queue); | 1439 | list_del_init (&req->queue); |
| @@ -1328,117 +1455,9 @@ restart: | |||
| 1328 | ep->last_io = jiffies; | 1455 | ep->last_io = jiffies; |
| 1329 | ep->setup_stage = 0; | 1456 | ep->setup_stage = 0; |
| 1330 | ep->halted = 0; | 1457 | ep->halted = 0; |
| 1331 | switch (setup.bRequest) { | ||
| 1332 | case USB_REQ_SET_ADDRESS: | ||
| 1333 | if (setup.bRequestType != Dev_Request) | ||
| 1334 | break; | ||
| 1335 | dum->address = w_value; | ||
| 1336 | status = 0; | ||
| 1337 | dev_dbg (udc_dev(dum), "set_address = %d\n", | ||
| 1338 | w_value); | ||
| 1339 | value = 0; | ||
| 1340 | break; | ||
| 1341 | case USB_REQ_SET_FEATURE: | ||
| 1342 | if (setup.bRequestType == Dev_Request) { | ||
| 1343 | value = 0; | ||
| 1344 | switch (w_value) { | ||
| 1345 | case USB_DEVICE_REMOTE_WAKEUP: | ||
| 1346 | break; | ||
| 1347 | case USB_DEVICE_B_HNP_ENABLE: | ||
| 1348 | dum->gadget.b_hnp_enable = 1; | ||
| 1349 | break; | ||
| 1350 | case USB_DEVICE_A_HNP_SUPPORT: | ||
| 1351 | dum->gadget.a_hnp_support = 1; | ||
| 1352 | break; | ||
| 1353 | case USB_DEVICE_A_ALT_HNP_SUPPORT: | ||
| 1354 | dum->gadget.a_alt_hnp_support | ||
| 1355 | = 1; | ||
| 1356 | break; | ||
| 1357 | default: | ||
| 1358 | value = -EOPNOTSUPP; | ||
| 1359 | } | ||
| 1360 | if (value == 0) { | ||
| 1361 | dum->devstatus |= | ||
| 1362 | (1 << w_value); | ||
| 1363 | status = 0; | ||
| 1364 | } | ||
| 1365 | 1458 | ||
| 1366 | } else if (setup.bRequestType == Ep_Request) { | 1459 | value = handle_control_request(dum, urb, &setup, |
| 1367 | // endpoint halt | 1460 | &status); |
| 1368 | ep2 = find_endpoint (dum, w_index); | ||
| 1369 | if (!ep2 || ep2->ep.name == ep0name) { | ||
| 1370 | value = -EOPNOTSUPP; | ||
| 1371 | break; | ||
| 1372 | } | ||
| 1373 | ep2->halted = 1; | ||
| 1374 | value = 0; | ||
| 1375 | status = 0; | ||
| 1376 | } | ||
| 1377 | break; | ||
| 1378 | case USB_REQ_CLEAR_FEATURE: | ||
| 1379 | if (setup.bRequestType == Dev_Request) { | ||
| 1380 | switch (w_value) { | ||
| 1381 | case USB_DEVICE_REMOTE_WAKEUP: | ||
| 1382 | dum->devstatus &= ~(1 << | ||
| 1383 | USB_DEVICE_REMOTE_WAKEUP); | ||
| 1384 | value = 0; | ||
| 1385 | status = 0; | ||
| 1386 | break; | ||
| 1387 | default: | ||
| 1388 | value = -EOPNOTSUPP; | ||
| 1389 | break; | ||
| 1390 | } | ||
| 1391 | } else if (setup.bRequestType == Ep_Request) { | ||
| 1392 | // endpoint halt | ||
| 1393 | ep2 = find_endpoint (dum, w_index); | ||
| 1394 | if (!ep2) { | ||
| 1395 | value = -EOPNOTSUPP; | ||
| 1396 | break; | ||
| 1397 | } | ||
| 1398 | if (!ep2->wedged) | ||
| 1399 | ep2->halted = 0; | ||
| 1400 | value = 0; | ||
| 1401 | status = 0; | ||
| 1402 | } | ||
| 1403 | break; | ||
| 1404 | case USB_REQ_GET_STATUS: | ||
| 1405 | if (setup.bRequestType == Dev_InRequest | ||
| 1406 | || setup.bRequestType | ||
| 1407 | == Intf_InRequest | ||
| 1408 | || setup.bRequestType | ||
| 1409 | == Ep_InRequest | ||
| 1410 | ) { | ||
| 1411 | char *buf; | ||
| 1412 | |||
| 1413 | // device: remote wakeup, selfpowered | ||
| 1414 | // interface: nothing | ||
| 1415 | // endpoint: halt | ||
| 1416 | buf = (char *)urb->transfer_buffer; | ||
| 1417 | if (urb->transfer_buffer_length > 0) { | ||
| 1418 | if (setup.bRequestType == | ||
| 1419 | Ep_InRequest) { | ||
| 1420 | ep2 = find_endpoint (dum, w_index); | ||
| 1421 | if (!ep2) { | ||
| 1422 | value = -EOPNOTSUPP; | ||
| 1423 | break; | ||
| 1424 | } | ||
| 1425 | buf [0] = ep2->halted; | ||
| 1426 | } else if (setup.bRequestType == | ||
| 1427 | Dev_InRequest) { | ||
| 1428 | buf [0] = (u8) | ||
| 1429 | dum->devstatus; | ||
| 1430 | } else | ||
| 1431 | buf [0] = 0; | ||
| 1432 | } | ||
| 1433 | if (urb->transfer_buffer_length > 1) | ||
| 1434 | buf [1] = 0; | ||
| 1435 | urb->actual_length = min_t(u32, 2, | ||
| 1436 | urb->transfer_buffer_length); | ||
| 1437 | value = 0; | ||
| 1438 | status = 0; | ||
| 1439 | } | ||
| 1440 | break; | ||
| 1441 | } | ||
| 1442 | 1461 | ||
| 1443 | /* gadget driver handles all other requests. block | 1462 | /* gadget driver handles all other requests. block |
| 1444 | * until setup() returns; no reentrancy issues etc. | 1463 | * until setup() returns; no reentrancy issues etc. |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 484c5ba5450e..1499f9e4afa8 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * f_fs.c -- user mode filesystem api for usb composite funtcion controllers | 2 | * f_fs.c -- user mode file system API for USB composite function controllers |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2010 Samsung Electronics | 4 | * Copyright (C) 2010 Samsung Electronics |
| 5 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> | 5 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> |
| 6 | * | 6 | * |
| 7 | * Based on inode.c (GadgetFS): | 7 | * Based on inode.c (GadgetFS) which was: |
| 8 | * Copyright (C) 2003-2004 David Brownell | 8 | * Copyright (C) 2003-2004 David Brownell |
| 9 | * Copyright (C) 2003 Agilent Technologies | 9 | * Copyright (C) 2003 Agilent Technologies |
| 10 | * | 10 | * |
| @@ -38,62 +38,56 @@ | |||
| 38 | #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ | 38 | #define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ |
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | /* Debuging *****************************************************************/ | 41 | /* Debugging ****************************************************************/ |
| 42 | |||
| 43 | #define ffs_printk(level, fmt, args...) printk(level "f_fs: " fmt "\n", ## args) | ||
| 44 | |||
| 45 | #define FERR(...) ffs_printk(KERN_ERR, __VA_ARGS__) | ||
| 46 | #define FINFO(...) ffs_printk(KERN_INFO, __VA_ARGS__) | ||
| 47 | |||
| 48 | #ifdef DEBUG | ||
| 49 | # define FDBG(...) ffs_printk(KERN_DEBUG, __VA_ARGS__) | ||
| 50 | #else | ||
| 51 | # define FDBG(...) do { } while (0) | ||
| 52 | #endif /* DEBUG */ | ||
| 53 | |||
| 54 | #ifdef VERBOSE_DEBUG | ||
| 55 | # define FVDBG FDBG | ||
| 56 | #else | ||
| 57 | # define FVDBG(...) do { } while (0) | ||
| 58 | #endif /* VERBOSE_DEBUG */ | ||
| 59 | |||
| 60 | #define ENTER() FVDBG("%s()", __func__) | ||
| 61 | 42 | ||
| 62 | #ifdef VERBOSE_DEBUG | 43 | #ifdef VERBOSE_DEBUG |
| 44 | # define pr_vdebug pr_debug | ||
| 63 | # define ffs_dump_mem(prefix, ptr, len) \ | 45 | # define ffs_dump_mem(prefix, ptr, len) \ |
| 64 | print_hex_dump_bytes("f_fs" prefix ": ", DUMP_PREFIX_NONE, ptr, len) | 46 | print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len) |
| 65 | #else | 47 | #else |
| 48 | # define pr_vdebug(...) do { } while (0) | ||
| 66 | # define ffs_dump_mem(prefix, ptr, len) do { } while (0) | 49 | # define ffs_dump_mem(prefix, ptr, len) do { } while (0) |
| 67 | #endif | 50 | #endif /* VERBOSE_DEBUG */ |
| 51 | |||
| 52 | #define ENTER() pr_vdebug("%s()\n", __func__) | ||
| 68 | 53 | ||
| 69 | 54 | ||
| 70 | /* The data structure and setup file ****************************************/ | 55 | /* The data structure and setup file ****************************************/ |
| 71 | 56 | ||
| 72 | enum ffs_state { | 57 | enum ffs_state { |
| 73 | /* Waiting for descriptors and strings. */ | 58 | /* |
| 74 | /* In this state no open(2), read(2) or write(2) on epfiles | 59 | * Waiting for descriptors and strings. |
| 60 | * | ||
| 61 | * In this state no open(2), read(2) or write(2) on epfiles | ||
| 75 | * may succeed (which should not be the problem as there | 62 | * may succeed (which should not be the problem as there |
| 76 | * should be no such files opened in the firts place). */ | 63 | * should be no such files opened in the first place). |
| 64 | */ | ||
| 77 | FFS_READ_DESCRIPTORS, | 65 | FFS_READ_DESCRIPTORS, |
| 78 | FFS_READ_STRINGS, | 66 | FFS_READ_STRINGS, |
| 79 | 67 | ||
| 80 | /* We've got descriptors and strings. We are or have called | 68 | /* |
| 69 | * We've got descriptors and strings. We are or have called | ||
| 81 | * functionfs_ready_callback(). functionfs_bind() may have | 70 | * functionfs_ready_callback(). functionfs_bind() may have |
| 82 | * been called but we don't know. */ | 71 | * been called but we don't know. |
| 83 | /* This is the only state in which operations on epfiles may | 72 | * |
| 84 | * succeed. */ | 73 | * This is the only state in which operations on epfiles may |
| 74 | * succeed. | ||
| 75 | */ | ||
| 85 | FFS_ACTIVE, | 76 | FFS_ACTIVE, |
| 86 | 77 | ||
| 87 | /* All endpoints have been closed. This state is also set if | 78 | /* |
| 79 | * All endpoints have been closed. This state is also set if | ||
| 88 | * we encounter an unrecoverable error. The only | 80 | * we encounter an unrecoverable error. The only |
| 89 | * unrecoverable error is situation when after reading strings | 81 | * unrecoverable error is situation when after reading strings |
| 90 | * from user space we fail to initialise EP files or | 82 | * from user space we fail to initialise epfiles or |
| 91 | * functionfs_ready_callback() returns with error (<0). */ | 83 | * functionfs_ready_callback() returns with error (<0). |
| 92 | /* In this state no open(2), read(2) or write(2) (both on ep0 | 84 | * |
| 85 | * In this state no open(2), read(2) or write(2) (both on ep0 | ||
| 93 | * as well as epfile) may succeed (at this point epfiles are | 86 | * as well as epfile) may succeed (at this point epfiles are |
| 94 | * unlinked and all closed so this is not a problem; ep0 is | 87 | * unlinked and all closed so this is not a problem; ep0 is |
| 95 | * also closed but ep0 file exists and so open(2) on ep0 must | 88 | * also closed but ep0 file exists and so open(2) on ep0 must |
| 96 | * fail). */ | 89 | * fail). |
| 90 | */ | ||
| 97 | FFS_CLOSING | 91 | FFS_CLOSING |
| 98 | }; | 92 | }; |
| 99 | 93 | ||
| @@ -101,14 +95,18 @@ enum ffs_state { | |||
| 101 | enum ffs_setup_state { | 95 | enum ffs_setup_state { |
| 102 | /* There is no setup request pending. */ | 96 | /* There is no setup request pending. */ |
| 103 | FFS_NO_SETUP, | 97 | FFS_NO_SETUP, |
| 104 | /* User has read events and there was a setup request event | 98 | /* |
| 99 | * User has read events and there was a setup request event | ||
| 105 | * there. The next read/write on ep0 will handle the | 100 | * there. The next read/write on ep0 will handle the |
| 106 | * request. */ | 101 | * request. |
| 102 | */ | ||
| 107 | FFS_SETUP_PENDING, | 103 | FFS_SETUP_PENDING, |
| 108 | /* There was event pending but before user space handled it | 104 | /* |
| 105 | * There was event pending but before user space handled it | ||
| 109 | * some other event was introduced which canceled existing | 106 | * some other event was introduced which canceled existing |
| 110 | * setup. If this state is set read/write on ep0 return | 107 | * setup. If this state is set read/write on ep0 return |
| 111 | * -EIDRM. This state is only set when adding event. */ | 108 | * -EIDRM. This state is only set when adding event. |
| 109 | */ | ||
| 112 | FFS_SETUP_CANCELED | 110 | FFS_SETUP_CANCELED |
| 113 | }; | 111 | }; |
| 114 | 112 | ||
| @@ -120,23 +118,29 @@ struct ffs_function; | |||
| 120 | struct ffs_data { | 118 | struct ffs_data { |
| 121 | struct usb_gadget *gadget; | 119 | struct usb_gadget *gadget; |
| 122 | 120 | ||
| 123 | /* Protect access read/write operations, only one read/write | 121 | /* |
| 122 | * Protect access read/write operations, only one read/write | ||
| 124 | * at a time. As a consequence protects ep0req and company. | 123 | * at a time. As a consequence protects ep0req and company. |
| 125 | * While setup request is being processed (queued) this is | 124 | * While setup request is being processed (queued) this is |
| 126 | * held. */ | 125 | * held. |
| 126 | */ | ||
| 127 | struct mutex mutex; | 127 | struct mutex mutex; |
| 128 | 128 | ||
| 129 | /* Protect access to enpoint related structures (basically | 129 | /* |
| 130 | * Protect access to endpoint related structures (basically | ||
| 130 | * usb_ep_queue(), usb_ep_dequeue(), etc. calls) except for | 131 | * usb_ep_queue(), usb_ep_dequeue(), etc. calls) except for |
| 131 | * endpint zero. */ | 132 | * endpoint zero. |
| 133 | */ | ||
| 132 | spinlock_t eps_lock; | 134 | spinlock_t eps_lock; |
| 133 | 135 | ||
| 134 | /* XXX REVISIT do we need our own request? Since we are not | 136 | /* |
| 135 | * handling setup requests immidiatelly user space may be so | 137 | * XXX REVISIT do we need our own request? Since we are not |
| 138 | * handling setup requests immediately user space may be so | ||
| 136 | * slow that another setup will be sent to the gadget but this | 139 | * slow that another setup will be sent to the gadget but this |
| 137 | * time not to us but another function and then there could be | 140 | * time not to us but another function and then there could be |
| 138 | * a race. Is that the case? Or maybe we can use cdev->req | 141 | * a race. Is that the case? Or maybe we can use cdev->req |
| 139 | * after all, maybe we just need some spinlock for that? */ | 142 | * after all, maybe we just need some spinlock for that? |
| 143 | */ | ||
| 140 | struct usb_request *ep0req; /* P: mutex */ | 144 | struct usb_request *ep0req; /* P: mutex */ |
| 141 | struct completion ep0req_completion; /* P: mutex */ | 145 | struct completion ep0req_completion; /* P: mutex */ |
| 142 | int ep0req_status; /* P: mutex */ | 146 | int ep0req_status; /* P: mutex */ |
| @@ -150,7 +154,7 @@ struct ffs_data { | |||
| 150 | enum ffs_state state; | 154 | enum ffs_state state; |
| 151 | 155 | ||
| 152 | /* | 156 | /* |
| 153 | * Possible transations: | 157 | * Possible transitions: |
| 154 | * + FFS_NO_SETUP -> FFS_SETUP_PENDING -- P: ev.waitq.lock | 158 | * + FFS_NO_SETUP -> FFS_SETUP_PENDING -- P: ev.waitq.lock |
| 155 | * happens only in ep0 read which is P: mutex | 159 | * happens only in ep0 read which is P: mutex |
| 156 | * + FFS_SETUP_PENDING -> FFS_NO_SETUP -- P: ev.waitq.lock | 160 | * + FFS_SETUP_PENDING -> FFS_NO_SETUP -- P: ev.waitq.lock |
| @@ -183,18 +187,21 @@ struct ffs_data { | |||
| 183 | /* Active function */ | 187 | /* Active function */ |
| 184 | struct ffs_function *func; | 188 | struct ffs_function *func; |
| 185 | 189 | ||
| 186 | /* Device name, write once when file system is mounted. | 190 | /* |
| 187 | * Intendet for user to read if she wants. */ | 191 | * Device name, write once when file system is mounted. |
| 192 | * Intended for user to read if she wants. | ||
| 193 | */ | ||
| 188 | const char *dev_name; | 194 | const char *dev_name; |
| 189 | /* Private data for our user (ie. gadget). Managed by | 195 | /* Private data for our user (ie. gadget). Managed by user. */ |
| 190 | * user. */ | ||
| 191 | void *private_data; | 196 | void *private_data; |
| 192 | 197 | ||
| 193 | /* filled by __ffs_data_got_descs() */ | 198 | /* filled by __ffs_data_got_descs() */ |
| 194 | /* real descriptors are 16 bytes after raw_descs (so you need | 199 | /* |
| 200 | * Real descriptors are 16 bytes after raw_descs (so you need | ||
| 195 | * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the | 201 | * to skip 16 bytes (ie. ffs->raw_descs + 16) to get to the |
| 196 | * first full speed descriptor). raw_descs_length and | 202 | * first full speed descriptor). raw_descs_length and |
| 197 | * raw_fs_descs_length do not have those 16 bytes added. */ | 203 | * raw_fs_descs_length do not have those 16 bytes added. |
| 204 | */ | ||
| 198 | const void *raw_descs; | 205 | const void *raw_descs; |
| 199 | unsigned raw_descs_length; | 206 | unsigned raw_descs_length; |
| 200 | unsigned raw_fs_descs_length; | 207 | unsigned raw_fs_descs_length; |
| @@ -211,18 +218,23 @@ struct ffs_data { | |||
| 211 | const void *raw_strings; | 218 | const void *raw_strings; |
| 212 | struct usb_gadget_strings **stringtabs; | 219 | struct usb_gadget_strings **stringtabs; |
| 213 | 220 | ||
| 214 | /* File system's super block, write once when file system is mounted. */ | 221 | /* |
| 222 | * File system's super block, write once when file system is | ||
| 223 | * mounted. | ||
| 224 | */ | ||
| 215 | struct super_block *sb; | 225 | struct super_block *sb; |
| 216 | 226 | ||
| 217 | /* File permissions, written once when fs is mounted*/ | 227 | /* File permissions, written once when fs is mounted */ |
| 218 | struct ffs_file_perms { | 228 | struct ffs_file_perms { |
| 219 | umode_t mode; | 229 | umode_t mode; |
| 220 | uid_t uid; | 230 | uid_t uid; |
| 221 | gid_t gid; | 231 | gid_t gid; |
| 222 | } file_perms; | 232 | } file_perms; |
| 223 | 233 | ||
| 224 | /* The endpoint files, filled by ffs_epfiles_create(), | 234 | /* |
| 225 | * destroyed by ffs_epfiles_destroy(). */ | 235 | * The endpoint files, filled by ffs_epfiles_create(), |
| 236 | * destroyed by ffs_epfiles_destroy(). | ||
| 237 | */ | ||
| 226 | struct ffs_epfile *epfiles; | 238 | struct ffs_epfile *epfiles; |
| 227 | }; | 239 | }; |
| 228 | 240 | ||
| @@ -236,7 +248,7 @@ static struct ffs_data *__must_check ffs_data_new(void) __attribute__((malloc)); | |||
| 236 | static void ffs_data_opened(struct ffs_data *ffs); | 248 | static void ffs_data_opened(struct ffs_data *ffs); |
| 237 | static void ffs_data_closed(struct ffs_data *ffs); | 249 | static void ffs_data_closed(struct ffs_data *ffs); |
| 238 | 250 | ||
| 239 | /* Called with ffs->mutex held; take over ownerrship of data. */ | 251 | /* Called with ffs->mutex held; take over ownership of data. */ |
| 240 | static int __must_check | 252 | static int __must_check |
| 241 | __ffs_data_got_descs(struct ffs_data *ffs, char *data, size_t len); | 253 | __ffs_data_got_descs(struct ffs_data *ffs, char *data, size_t len); |
| 242 | static int __must_check | 254 | static int __must_check |
| @@ -267,11 +279,9 @@ static struct ffs_function *ffs_func_from_usb(struct usb_function *f) | |||
| 267 | 279 | ||
| 268 | static void ffs_func_free(struct ffs_function *func); | 280 | static void ffs_func_free(struct ffs_function *func); |
| 269 | 281 | ||
| 270 | |||
| 271 | static void ffs_func_eps_disable(struct ffs_function *func); | 282 | static void ffs_func_eps_disable(struct ffs_function *func); |
| 272 | static int __must_check ffs_func_eps_enable(struct ffs_function *func); | 283 | static int __must_check ffs_func_eps_enable(struct ffs_function *func); |
| 273 | 284 | ||
| 274 | |||
| 275 | static int ffs_func_bind(struct usb_configuration *, | 285 | static int ffs_func_bind(struct usb_configuration *, |
| 276 | struct usb_function *); | 286 | struct usb_function *); |
| 277 | static void ffs_func_unbind(struct usb_configuration *, | 287 | static void ffs_func_unbind(struct usb_configuration *, |
| @@ -288,7 +298,6 @@ static int ffs_func_revmap_ep(struct ffs_function *func, u8 num); | |||
| 288 | static int ffs_func_revmap_intf(struct ffs_function *func, u8 intf); | 298 | static int ffs_func_revmap_intf(struct ffs_function *func, u8 intf); |
| 289 | 299 | ||
| 290 | 300 | ||
| 291 | |||
| 292 | /* The endpoints structures *************************************************/ | 301 | /* The endpoints structures *************************************************/ |
| 293 | 302 | ||
| 294 | struct ffs_ep { | 303 | struct ffs_ep { |
| @@ -321,7 +330,6 @@ struct ffs_epfile { | |||
| 321 | unsigned char _pad; | 330 | unsigned char _pad; |
| 322 | }; | 331 | }; |
| 323 | 332 | ||
| 324 | |||
| 325 | static int __must_check ffs_epfiles_create(struct ffs_data *ffs); | 333 | static int __must_check ffs_epfiles_create(struct ffs_data *ffs); |
| 326 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count); | 334 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count); |
| 327 | 335 | ||
| @@ -348,7 +356,6 @@ static void ffs_ep0_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 348 | complete_all(&ffs->ep0req_completion); | 356 | complete_all(&ffs->ep0req_completion); |
| 349 | } | 357 | } |
| 350 | 358 | ||
| 351 | |||
| 352 | static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len) | 359 | static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len) |
| 353 | { | 360 | { |
| 354 | struct usb_request *req = ffs->ep0req; | 361 | struct usb_request *req = ffs->ep0req; |
| @@ -380,17 +387,16 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len) | |||
| 380 | static int __ffs_ep0_stall(struct ffs_data *ffs) | 387 | static int __ffs_ep0_stall(struct ffs_data *ffs) |
| 381 | { | 388 | { |
| 382 | if (ffs->ev.can_stall) { | 389 | if (ffs->ev.can_stall) { |
| 383 | FVDBG("ep0 stall\n"); | 390 | pr_vdebug("ep0 stall\n"); |
| 384 | usb_ep_set_halt(ffs->gadget->ep0); | 391 | usb_ep_set_halt(ffs->gadget->ep0); |
| 385 | ffs->setup_state = FFS_NO_SETUP; | 392 | ffs->setup_state = FFS_NO_SETUP; |
| 386 | return -EL2HLT; | 393 | return -EL2HLT; |
| 387 | } else { | 394 | } else { |
| 388 | FDBG("bogus ep0 stall!\n"); | 395 | pr_debug("bogus ep0 stall!\n"); |
| 389 | return -ESRCH; | 396 | return -ESRCH; |
| 390 | } | 397 | } |
| 391 | } | 398 | } |
| 392 | 399 | ||
| 393 | |||
| 394 | static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | 400 | static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, |
| 395 | size_t len, loff_t *ptr) | 401 | size_t len, loff_t *ptr) |
| 396 | { | 402 | { |
| @@ -409,7 +415,6 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
| 409 | if (unlikely(ret < 0)) | 415 | if (unlikely(ret < 0)) |
| 410 | return ret; | 416 | return ret; |
| 411 | 417 | ||
| 412 | |||
| 413 | /* Check state */ | 418 | /* Check state */ |
| 414 | switch (ffs->state) { | 419 | switch (ffs->state) { |
| 415 | case FFS_READ_DESCRIPTORS: | 420 | case FFS_READ_DESCRIPTORS: |
| @@ -421,14 +426,14 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
| 421 | } | 426 | } |
| 422 | 427 | ||
| 423 | data = ffs_prepare_buffer(buf, len); | 428 | data = ffs_prepare_buffer(buf, len); |
| 424 | if (unlikely(IS_ERR(data))) { | 429 | if (IS_ERR(data)) { |
| 425 | ret = PTR_ERR(data); | 430 | ret = PTR_ERR(data); |
| 426 | break; | 431 | break; |
| 427 | } | 432 | } |
| 428 | 433 | ||
| 429 | /* Handle data */ | 434 | /* Handle data */ |
| 430 | if (ffs->state == FFS_READ_DESCRIPTORS) { | 435 | if (ffs->state == FFS_READ_DESCRIPTORS) { |
| 431 | FINFO("read descriptors"); | 436 | pr_info("read descriptors\n"); |
| 432 | ret = __ffs_data_got_descs(ffs, data, len); | 437 | ret = __ffs_data_got_descs(ffs, data, len); |
| 433 | if (unlikely(ret < 0)) | 438 | if (unlikely(ret < 0)) |
| 434 | break; | 439 | break; |
| @@ -436,7 +441,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
| 436 | ffs->state = FFS_READ_STRINGS; | 441 | ffs->state = FFS_READ_STRINGS; |
| 437 | ret = len; | 442 | ret = len; |
| 438 | } else { | 443 | } else { |
| 439 | FINFO("read strings"); | 444 | pr_info("read strings\n"); |
| 440 | ret = __ffs_data_got_strings(ffs, data, len); | 445 | ret = __ffs_data_got_strings(ffs, data, len); |
| 441 | if (unlikely(ret < 0)) | 446 | if (unlikely(ret < 0)) |
| 442 | break; | 447 | break; |
| @@ -461,11 +466,12 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
| 461 | } | 466 | } |
| 462 | break; | 467 | break; |
| 463 | 468 | ||
| 464 | |||
| 465 | case FFS_ACTIVE: | 469 | case FFS_ACTIVE: |
| 466 | data = NULL; | 470 | data = NULL; |
| 467 | /* We're called from user space, we can use _irq | 471 | /* |
| 468 | * rather then _irqsave */ | 472 | * We're called from user space, we can use _irq |
| 473 | * rather then _irqsave | ||
| 474 | */ | ||
| 469 | spin_lock_irq(&ffs->ev.waitq.lock); | 475 | spin_lock_irq(&ffs->ev.waitq.lock); |
| 470 | switch (FFS_SETUP_STATE(ffs)) { | 476 | switch (FFS_SETUP_STATE(ffs)) { |
| 471 | case FFS_SETUP_CANCELED: | 477 | case FFS_SETUP_CANCELED: |
| @@ -493,23 +499,25 @@ static ssize_t ffs_ep0_write(struct file *file, const char __user *buf, | |||
| 493 | spin_unlock_irq(&ffs->ev.waitq.lock); | 499 | spin_unlock_irq(&ffs->ev.waitq.lock); |
| 494 | 500 | ||
| 495 | data = ffs_prepare_buffer(buf, len); | 501 | data = ffs_prepare_buffer(buf, len); |
| 496 | if (unlikely(IS_ERR(data))) { | 502 | if (IS_ERR(data)) { |
| 497 | ret = PTR_ERR(data); | 503 | ret = PTR_ERR(data); |
| 498 | break; | 504 | break; |
| 499 | } | 505 | } |
| 500 | 506 | ||
| 501 | spin_lock_irq(&ffs->ev.waitq.lock); | 507 | spin_lock_irq(&ffs->ev.waitq.lock); |
| 502 | 508 | ||
| 503 | /* We are guaranteed to be still in FFS_ACTIVE state | 509 | /* |
| 510 | * We are guaranteed to be still in FFS_ACTIVE state | ||
| 504 | * but the state of setup could have changed from | 511 | * but the state of setup could have changed from |
| 505 | * FFS_SETUP_PENDING to FFS_SETUP_CANCELED so we need | 512 | * FFS_SETUP_PENDING to FFS_SETUP_CANCELED so we need |
| 506 | * to check for that. If that happened we copied data | 513 | * to check for that. If that happened we copied data |
| 507 | * from user space in vain but it's unlikely. */ | 514 | * from user space in vain but it's unlikely. |
| 508 | /* For sure we are not in FFS_NO_SETUP since this is | 515 | * |
| 516 | * For sure we are not in FFS_NO_SETUP since this is | ||
| 509 | * the only place FFS_SETUP_PENDING -> FFS_NO_SETUP | 517 | * the only place FFS_SETUP_PENDING -> FFS_NO_SETUP |
| 510 | * transition can be performed and it's protected by | 518 | * transition can be performed and it's protected by |
| 511 | * mutex. */ | 519 | * mutex. |
| 512 | 520 | */ | |
| 513 | if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) { | 521 | if (FFS_SETUP_STATE(ffs) == FFS_SETUP_CANCELED) { |
| 514 | ret = -EIDRM; | 522 | ret = -EIDRM; |
| 515 | done_spin: | 523 | done_spin: |
| @@ -521,25 +529,22 @@ done_spin: | |||
| 521 | kfree(data); | 529 | kfree(data); |
| 522 | break; | 530 | break; |
| 523 | 531 | ||
| 524 | |||
| 525 | default: | 532 | default: |
| 526 | ret = -EBADFD; | 533 | ret = -EBADFD; |
| 527 | break; | 534 | break; |
| 528 | } | 535 | } |
| 529 | 536 | ||
| 530 | |||
| 531 | mutex_unlock(&ffs->mutex); | 537 | mutex_unlock(&ffs->mutex); |
| 532 | return ret; | 538 | return ret; |
| 533 | } | 539 | } |
| 534 | 540 | ||
| 535 | |||
| 536 | |||
| 537 | static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, | 541 | static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, |
| 538 | size_t n) | 542 | size_t n) |
| 539 | { | 543 | { |
| 540 | /* We are holding ffs->ev.waitq.lock and ffs->mutex and we need | 544 | /* |
| 541 | * to release them. */ | 545 | * We are holding ffs->ev.waitq.lock and ffs->mutex and we need |
| 542 | 546 | * to release them. | |
| 547 | */ | ||
| 543 | struct usb_functionfs_event events[n]; | 548 | struct usb_functionfs_event events[n]; |
| 544 | unsigned i = 0; | 549 | unsigned i = 0; |
| 545 | 550 | ||
| @@ -568,7 +573,6 @@ static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, | |||
| 568 | ? -EFAULT : sizeof events; | 573 | ? -EFAULT : sizeof events; |
| 569 | } | 574 | } |
| 570 | 575 | ||
| 571 | |||
| 572 | static ssize_t ffs_ep0_read(struct file *file, char __user *buf, | 576 | static ssize_t ffs_ep0_read(struct file *file, char __user *buf, |
| 573 | size_t len, loff_t *ptr) | 577 | size_t len, loff_t *ptr) |
| 574 | { | 578 | { |
| @@ -588,16 +592,16 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, | |||
| 588 | if (unlikely(ret < 0)) | 592 | if (unlikely(ret < 0)) |
| 589 | return ret; | 593 | return ret; |
| 590 | 594 | ||
| 591 | |||
| 592 | /* Check state */ | 595 | /* Check state */ |
| 593 | if (ffs->state != FFS_ACTIVE) { | 596 | if (ffs->state != FFS_ACTIVE) { |
| 594 | ret = -EBADFD; | 597 | ret = -EBADFD; |
| 595 | goto done_mutex; | 598 | goto done_mutex; |
| 596 | } | 599 | } |
| 597 | 600 | ||
| 598 | 601 | /* | |
| 599 | /* We're called from user space, we can use _irq rather then | 602 | * We're called from user space, we can use _irq rather then |
| 600 | * _irqsave */ | 603 | * _irqsave |
| 604 | */ | ||
| 601 | spin_lock_irq(&ffs->ev.waitq.lock); | 605 | spin_lock_irq(&ffs->ev.waitq.lock); |
| 602 | 606 | ||
| 603 | switch (FFS_SETUP_STATE(ffs)) { | 607 | switch (FFS_SETUP_STATE(ffs)) { |
| @@ -617,7 +621,8 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, | |||
| 617 | break; | 621 | break; |
| 618 | } | 622 | } |
| 619 | 623 | ||
| 620 | if (unlikely(wait_event_interruptible_exclusive_locked_irq(ffs->ev.waitq, ffs->ev.count))) { | 624 | if (wait_event_interruptible_exclusive_locked_irq(ffs->ev.waitq, |
| 625 | ffs->ev.count)) { | ||
| 621 | ret = -EINTR; | 626 | ret = -EINTR; |
| 622 | break; | 627 | break; |
| 623 | } | 628 | } |
| @@ -625,7 +630,6 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, | |||
| 625 | return __ffs_ep0_read_events(ffs, buf, | 630 | return __ffs_ep0_read_events(ffs, buf, |
| 626 | min(n, (size_t)ffs->ev.count)); | 631 | min(n, (size_t)ffs->ev.count)); |
| 627 | 632 | ||
| 628 | |||
| 629 | case FFS_SETUP_PENDING: | 633 | case FFS_SETUP_PENDING: |
| 630 | if (ffs->ev.setup.bRequestType & USB_DIR_IN) { | 634 | if (ffs->ev.setup.bRequestType & USB_DIR_IN) { |
| 631 | spin_unlock_irq(&ffs->ev.waitq.lock); | 635 | spin_unlock_irq(&ffs->ev.waitq.lock); |
| @@ -671,8 +675,6 @@ done_mutex: | |||
| 671 | return ret; | 675 | return ret; |
| 672 | } | 676 | } |
| 673 | 677 | ||
| 674 | |||
| 675 | |||
| 676 | static int ffs_ep0_open(struct inode *inode, struct file *file) | 678 | static int ffs_ep0_open(struct inode *inode, struct file *file) |
| 677 | { | 679 | { |
| 678 | struct ffs_data *ffs = inode->i_private; | 680 | struct ffs_data *ffs = inode->i_private; |
| @@ -688,7 +690,6 @@ static int ffs_ep0_open(struct inode *inode, struct file *file) | |||
| 688 | return 0; | 690 | return 0; |
| 689 | } | 691 | } |
| 690 | 692 | ||
| 691 | |||
| 692 | static int ffs_ep0_release(struct inode *inode, struct file *file) | 693 | static int ffs_ep0_release(struct inode *inode, struct file *file) |
| 693 | { | 694 | { |
| 694 | struct ffs_data *ffs = file->private_data; | 695 | struct ffs_data *ffs = file->private_data; |
| @@ -700,7 +701,6 @@ static int ffs_ep0_release(struct inode *inode, struct file *file) | |||
| 700 | return 0; | 701 | return 0; |
| 701 | } | 702 | } |
| 702 | 703 | ||
| 703 | |||
| 704 | static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) | 704 | static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) |
| 705 | { | 705 | { |
| 706 | struct ffs_data *ffs = file->private_data; | 706 | struct ffs_data *ffs = file->private_data; |
| @@ -721,7 +721,6 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) | |||
| 721 | return ret; | 721 | return ret; |
| 722 | } | 722 | } |
| 723 | 723 | ||
| 724 | |||
| 725 | static const struct file_operations ffs_ep0_operations = { | 724 | static const struct file_operations ffs_ep0_operations = { |
| 726 | .owner = THIS_MODULE, | 725 | .owner = THIS_MODULE, |
| 727 | .llseek = no_llseek, | 726 | .llseek = no_llseek, |
| @@ -736,7 +735,6 @@ static const struct file_operations ffs_ep0_operations = { | |||
| 736 | 735 | ||
| 737 | /* "Normal" endpoints operations ********************************************/ | 736 | /* "Normal" endpoints operations ********************************************/ |
| 738 | 737 | ||
| 739 | |||
| 740 | static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) | 738 | static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) |
| 741 | { | 739 | { |
| 742 | ENTER(); | 740 | ENTER(); |
| @@ -747,7 +745,6 @@ static void ffs_epfile_io_complete(struct usb_ep *_ep, struct usb_request *req) | |||
| 747 | } | 745 | } |
| 748 | } | 746 | } |
| 749 | 747 | ||
| 750 | |||
| 751 | static ssize_t ffs_epfile_io(struct file *file, | 748 | static ssize_t ffs_epfile_io(struct file *file, |
| 752 | char __user *buf, size_t len, int read) | 749 | char __user *buf, size_t len, int read) |
| 753 | { | 750 | { |
| @@ -777,8 +774,8 @@ first_try: | |||
| 777 | goto error; | 774 | goto error; |
| 778 | } | 775 | } |
| 779 | 776 | ||
| 780 | if (unlikely(wait_event_interruptible | 777 | if (wait_event_interruptible(epfile->wait, |
| 781 | (epfile->wait, (ep = epfile->ep)))) { | 778 | (ep = epfile->ep))) { |
| 782 | ret = -EINTR; | 779 | ret = -EINTR; |
| 783 | goto error; | 780 | goto error; |
| 784 | } | 781 | } |
| @@ -810,12 +807,16 @@ first_try: | |||
| 810 | if (unlikely(ret)) | 807 | if (unlikely(ret)) |
| 811 | goto error; | 808 | goto error; |
| 812 | 809 | ||
| 813 | /* We're called from user space, we can use _irq rather then | 810 | /* |
| 814 | * _irqsave */ | 811 | * We're called from user space, we can use _irq rather then |
| 812 | * _irqsave | ||
| 813 | */ | ||
| 815 | spin_lock_irq(&epfile->ffs->eps_lock); | 814 | spin_lock_irq(&epfile->ffs->eps_lock); |
| 816 | 815 | ||
| 817 | /* While we were acquiring mutex endpoint got disabled | 816 | /* |
| 818 | * or changed? */ | 817 | * While we were acquiring mutex endpoint got disabled |
| 818 | * or changed? | ||
| 819 | */ | ||
| 819 | } while (unlikely(epfile->ep != ep)); | 820 | } while (unlikely(epfile->ep != ep)); |
| 820 | 821 | ||
| 821 | /* Halt */ | 822 | /* Halt */ |
| @@ -857,7 +858,6 @@ error: | |||
| 857 | return ret; | 858 | return ret; |
| 858 | } | 859 | } |
| 859 | 860 | ||
| 860 | |||
| 861 | static ssize_t | 861 | static ssize_t |
| 862 | ffs_epfile_write(struct file *file, const char __user *buf, size_t len, | 862 | ffs_epfile_write(struct file *file, const char __user *buf, size_t len, |
| 863 | loff_t *ptr) | 863 | loff_t *ptr) |
| @@ -903,7 +903,6 @@ ffs_epfile_release(struct inode *inode, struct file *file) | |||
| 903 | return 0; | 903 | return 0; |
| 904 | } | 904 | } |
| 905 | 905 | ||
| 906 | |||
| 907 | static long ffs_epfile_ioctl(struct file *file, unsigned code, | 906 | static long ffs_epfile_ioctl(struct file *file, unsigned code, |
| 908 | unsigned long value) | 907 | unsigned long value) |
| 909 | { | 908 | { |
| @@ -942,7 +941,6 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, | |||
| 942 | return ret; | 941 | return ret; |
| 943 | } | 942 | } |
| 944 | 943 | ||
| 945 | |||
| 946 | static const struct file_operations ffs_epfile_operations = { | 944 | static const struct file_operations ffs_epfile_operations = { |
| 947 | .owner = THIS_MODULE, | 945 | .owner = THIS_MODULE, |
| 948 | .llseek = no_llseek, | 946 | .llseek = no_llseek, |
| @@ -955,15 +953,13 @@ static const struct file_operations ffs_epfile_operations = { | |||
| 955 | }; | 953 | }; |
| 956 | 954 | ||
| 957 | 955 | ||
| 958 | |||
| 959 | /* File system and super block operations ***********************************/ | 956 | /* File system and super block operations ***********************************/ |
| 960 | 957 | ||
| 961 | /* | 958 | /* |
| 962 | * Mounting the filesystem creates a controller file, used first for | 959 | * Mounting the file system creates a controller file, used first for |
| 963 | * function configuration then later for event monitoring. | 960 | * function configuration then later for event monitoring. |
| 964 | */ | 961 | */ |
| 965 | 962 | ||
| 966 | |||
| 967 | static struct inode *__must_check | 963 | static struct inode *__must_check |
| 968 | ffs_sb_make_inode(struct super_block *sb, void *data, | 964 | ffs_sb_make_inode(struct super_block *sb, void *data, |
| 969 | const struct file_operations *fops, | 965 | const struct file_operations *fops, |
| @@ -996,9 +992,7 @@ ffs_sb_make_inode(struct super_block *sb, void *data, | |||
| 996 | return inode; | 992 | return inode; |
| 997 | } | 993 | } |
| 998 | 994 | ||
| 999 | |||
| 1000 | /* Create "regular" file */ | 995 | /* Create "regular" file */ |
| 1001 | |||
| 1002 | static struct inode *ffs_sb_create_file(struct super_block *sb, | 996 | static struct inode *ffs_sb_create_file(struct super_block *sb, |
| 1003 | const char *name, void *data, | 997 | const char *name, void *data, |
| 1004 | const struct file_operations *fops, | 998 | const struct file_operations *fops, |
| @@ -1027,9 +1021,7 @@ static struct inode *ffs_sb_create_file(struct super_block *sb, | |||
| 1027 | return inode; | 1021 | return inode; |
| 1028 | } | 1022 | } |
| 1029 | 1023 | ||
| 1030 | |||
| 1031 | /* Super block */ | 1024 | /* Super block */ |
| 1032 | |||
| 1033 | static const struct super_operations ffs_sb_operations = { | 1025 | static const struct super_operations ffs_sb_operations = { |
| 1034 | .statfs = simple_statfs, | 1026 | .statfs = simple_statfs, |
| 1035 | .drop_inode = generic_delete_inode, | 1027 | .drop_inode = generic_delete_inode, |
| @@ -1050,7 +1042,7 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) | |||
| 1050 | 1042 | ||
| 1051 | ENTER(); | 1043 | ENTER(); |
| 1052 | 1044 | ||
| 1053 | /* Initialize data */ | 1045 | /* Initialise data */ |
| 1054 | ffs = ffs_data_new(); | 1046 | ffs = ffs_data_new(); |
| 1055 | if (unlikely(!ffs)) | 1047 | if (unlikely(!ffs)) |
| 1056 | goto enomem0; | 1048 | goto enomem0; |
| @@ -1096,7 +1088,6 @@ enomem0: | |||
| 1096 | return -ENOMEM; | 1088 | return -ENOMEM; |
| 1097 | } | 1089 | } |
| 1098 | 1090 | ||
| 1099 | |||
| 1100 | static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | 1091 | static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) |
| 1101 | { | 1092 | { |
| 1102 | ENTER(); | 1093 | ENTER(); |
| @@ -1116,7 +1107,7 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | |||
| 1116 | /* Value limit */ | 1107 | /* Value limit */ |
| 1117 | eq = strchr(opts, '='); | 1108 | eq = strchr(opts, '='); |
| 1118 | if (unlikely(!eq)) { | 1109 | if (unlikely(!eq)) { |
| 1119 | FERR("'=' missing in %s", opts); | 1110 | pr_err("'=' missing in %s\n", opts); |
| 1120 | return -EINVAL; | 1111 | return -EINVAL; |
| 1121 | } | 1112 | } |
| 1122 | *eq = 0; | 1113 | *eq = 0; |
| @@ -1124,7 +1115,7 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | |||
| 1124 | /* Parse value */ | 1115 | /* Parse value */ |
| 1125 | value = simple_strtoul(eq + 1, &end, 0); | 1116 | value = simple_strtoul(eq + 1, &end, 0); |
| 1126 | if (unlikely(*end != ',' && *end != 0)) { | 1117 | if (unlikely(*end != ',' && *end != 0)) { |
| 1127 | FERR("%s: invalid value: %s", opts, eq + 1); | 1118 | pr_err("%s: invalid value: %s\n", opts, eq + 1); |
| 1128 | return -EINVAL; | 1119 | return -EINVAL; |
| 1129 | } | 1120 | } |
| 1130 | 1121 | ||
| @@ -1159,7 +1150,7 @@ static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | |||
| 1159 | 1150 | ||
| 1160 | default: | 1151 | default: |
| 1161 | invalid: | 1152 | invalid: |
| 1162 | FERR("%s: invalid option", opts); | 1153 | pr_err("%s: invalid option\n", opts); |
| 1163 | return -EINVAL; | 1154 | return -EINVAL; |
| 1164 | } | 1155 | } |
| 1165 | 1156 | ||
| @@ -1172,7 +1163,6 @@ invalid: | |||
| 1172 | return 0; | 1163 | return 0; |
| 1173 | } | 1164 | } |
| 1174 | 1165 | ||
| 1175 | |||
| 1176 | /* "mount -t functionfs dev_name /dev/function" ends up here */ | 1166 | /* "mount -t functionfs dev_name /dev/function" ends up here */ |
| 1177 | 1167 | ||
| 1178 | static struct dentry * | 1168 | static struct dentry * |
| @@ -1224,10 +1214,8 @@ static struct file_system_type ffs_fs_type = { | |||
| 1224 | }; | 1214 | }; |
| 1225 | 1215 | ||
| 1226 | 1216 | ||
| 1227 | |||
| 1228 | /* Driver's main init/cleanup functions *************************************/ | 1217 | /* Driver's main init/cleanup functions *************************************/ |
| 1229 | 1218 | ||
| 1230 | |||
| 1231 | static int functionfs_init(void) | 1219 | static int functionfs_init(void) |
| 1232 | { | 1220 | { |
| 1233 | int ret; | 1221 | int ret; |
| @@ -1236,9 +1224,9 @@ static int functionfs_init(void) | |||
| 1236 | 1224 | ||
| 1237 | ret = register_filesystem(&ffs_fs_type); | 1225 | ret = register_filesystem(&ffs_fs_type); |
| 1238 | if (likely(!ret)) | 1226 | if (likely(!ret)) |
| 1239 | FINFO("file system registered"); | 1227 | pr_info("file system registered\n"); |
| 1240 | else | 1228 | else |
| 1241 | FERR("failed registering file system (%d)", ret); | 1229 | pr_err("failed registering file system (%d)\n", ret); |
| 1242 | 1230 | ||
| 1243 | return ret; | 1231 | return ret; |
| 1244 | } | 1232 | } |
| @@ -1247,18 +1235,16 @@ static void functionfs_cleanup(void) | |||
| 1247 | { | 1235 | { |
| 1248 | ENTER(); | 1236 | ENTER(); |
| 1249 | 1237 | ||
| 1250 | FINFO("unloading"); | 1238 | pr_info("unloading\n"); |
| 1251 | unregister_filesystem(&ffs_fs_type); | 1239 | unregister_filesystem(&ffs_fs_type); |
| 1252 | } | 1240 | } |
| 1253 | 1241 | ||
| 1254 | 1242 | ||
| 1255 | |||
| 1256 | /* ffs_data and ffs_function construction and destruction code **************/ | 1243 | /* ffs_data and ffs_function construction and destruction code **************/ |
| 1257 | 1244 | ||
| 1258 | static void ffs_data_clear(struct ffs_data *ffs); | 1245 | static void ffs_data_clear(struct ffs_data *ffs); |
| 1259 | static void ffs_data_reset(struct ffs_data *ffs); | 1246 | static void ffs_data_reset(struct ffs_data *ffs); |
| 1260 | 1247 | ||
| 1261 | |||
| 1262 | static void ffs_data_get(struct ffs_data *ffs) | 1248 | static void ffs_data_get(struct ffs_data *ffs) |
| 1263 | { | 1249 | { |
| 1264 | ENTER(); | 1250 | ENTER(); |
| @@ -1279,7 +1265,7 @@ static void ffs_data_put(struct ffs_data *ffs) | |||
| 1279 | ENTER(); | 1265 | ENTER(); |
| 1280 | 1266 | ||
| 1281 | if (unlikely(atomic_dec_and_test(&ffs->ref))) { | 1267 | if (unlikely(atomic_dec_and_test(&ffs->ref))) { |
| 1282 | FINFO("%s(): freeing", __func__); | 1268 | pr_info("%s(): freeing\n", __func__); |
| 1283 | ffs_data_clear(ffs); | 1269 | ffs_data_clear(ffs); |
| 1284 | BUG_ON(mutex_is_locked(&ffs->mutex) || | 1270 | BUG_ON(mutex_is_locked(&ffs->mutex) || |
| 1285 | spin_is_locked(&ffs->ev.waitq.lock) || | 1271 | spin_is_locked(&ffs->ev.waitq.lock) || |
| @@ -1289,8 +1275,6 @@ static void ffs_data_put(struct ffs_data *ffs) | |||
| 1289 | } | 1275 | } |
| 1290 | } | 1276 | } |
| 1291 | 1277 | ||
| 1292 | |||
| 1293 | |||
| 1294 | static void ffs_data_closed(struct ffs_data *ffs) | 1278 | static void ffs_data_closed(struct ffs_data *ffs) |
| 1295 | { | 1279 | { |
| 1296 | ENTER(); | 1280 | ENTER(); |
| @@ -1303,7 +1287,6 @@ static void ffs_data_closed(struct ffs_data *ffs) | |||
| 1303 | ffs_data_put(ffs); | 1287 | ffs_data_put(ffs); |
| 1304 | } | 1288 | } |
| 1305 | 1289 | ||
| 1306 | |||
| 1307 | static struct ffs_data *ffs_data_new(void) | 1290 | static struct ffs_data *ffs_data_new(void) |
| 1308 | { | 1291 | { |
| 1309 | struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); | 1292 | struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); |
| @@ -1326,7 +1309,6 @@ static struct ffs_data *ffs_data_new(void) | |||
| 1326 | return ffs; | 1309 | return ffs; |
| 1327 | } | 1310 | } |
| 1328 | 1311 | ||
| 1329 | |||
| 1330 | static void ffs_data_clear(struct ffs_data *ffs) | 1312 | static void ffs_data_clear(struct ffs_data *ffs) |
| 1331 | { | 1313 | { |
| 1332 | ENTER(); | 1314 | ENTER(); |
| @@ -1344,7 +1326,6 @@ static void ffs_data_clear(struct ffs_data *ffs) | |||
| 1344 | kfree(ffs->stringtabs); | 1326 | kfree(ffs->stringtabs); |
| 1345 | } | 1327 | } |
| 1346 | 1328 | ||
| 1347 | |||
| 1348 | static void ffs_data_reset(struct ffs_data *ffs) | 1329 | static void ffs_data_reset(struct ffs_data *ffs) |
| 1349 | { | 1330 | { |
| 1350 | ENTER(); | 1331 | ENTER(); |
| @@ -1407,7 +1388,6 @@ static int functionfs_bind(struct ffs_data *ffs, struct usb_composite_dev *cdev) | |||
| 1407 | return 0; | 1388 | return 0; |
| 1408 | } | 1389 | } |
| 1409 | 1390 | ||
| 1410 | |||
| 1411 | static void functionfs_unbind(struct ffs_data *ffs) | 1391 | static void functionfs_unbind(struct ffs_data *ffs) |
| 1412 | { | 1392 | { |
| 1413 | ENTER(); | 1393 | ENTER(); |
| @@ -1420,7 +1400,6 @@ static void functionfs_unbind(struct ffs_data *ffs) | |||
| 1420 | } | 1400 | } |
| 1421 | } | 1401 | } |
| 1422 | 1402 | ||
| 1423 | |||
| 1424 | static int ffs_epfiles_create(struct ffs_data *ffs) | 1403 | static int ffs_epfiles_create(struct ffs_data *ffs) |
| 1425 | { | 1404 | { |
| 1426 | struct ffs_epfile *epfile, *epfiles; | 1405 | struct ffs_epfile *epfile, *epfiles; |
| @@ -1451,7 +1430,6 @@ static int ffs_epfiles_create(struct ffs_data *ffs) | |||
| 1451 | return 0; | 1430 | return 0; |
| 1452 | } | 1431 | } |
| 1453 | 1432 | ||
| 1454 | |||
| 1455 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count) | 1433 | static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count) |
| 1456 | { | 1434 | { |
| 1457 | struct ffs_epfile *epfile = epfiles; | 1435 | struct ffs_epfile *epfile = epfiles; |
| @@ -1471,7 +1449,6 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count) | |||
| 1471 | kfree(epfiles); | 1449 | kfree(epfiles); |
| 1472 | } | 1450 | } |
| 1473 | 1451 | ||
| 1474 | |||
| 1475 | static int functionfs_bind_config(struct usb_composite_dev *cdev, | 1452 | static int functionfs_bind_config(struct usb_composite_dev *cdev, |
| 1476 | struct usb_configuration *c, | 1453 | struct usb_configuration *c, |
| 1477 | struct ffs_data *ffs) | 1454 | struct ffs_data *ffs) |
| @@ -1491,7 +1468,6 @@ static int functionfs_bind_config(struct usb_composite_dev *cdev, | |||
| 1491 | func->function.bind = ffs_func_bind; | 1468 | func->function.bind = ffs_func_bind; |
| 1492 | func->function.unbind = ffs_func_unbind; | 1469 | func->function.unbind = ffs_func_unbind; |
| 1493 | func->function.set_alt = ffs_func_set_alt; | 1470 | func->function.set_alt = ffs_func_set_alt; |
| 1494 | /*func->function.get_alt = ffs_func_get_alt;*/ | ||
| 1495 | func->function.disable = ffs_func_disable; | 1471 | func->function.disable = ffs_func_disable; |
| 1496 | func->function.setup = ffs_func_setup; | 1472 | func->function.setup = ffs_func_setup; |
| 1497 | func->function.suspend = ffs_func_suspend; | 1473 | func->function.suspend = ffs_func_suspend; |
| @@ -1516,14 +1492,15 @@ static void ffs_func_free(struct ffs_function *func) | |||
| 1516 | ffs_data_put(func->ffs); | 1492 | ffs_data_put(func->ffs); |
| 1517 | 1493 | ||
| 1518 | kfree(func->eps); | 1494 | kfree(func->eps); |
| 1519 | /* eps and interfaces_nums are allocated in the same chunk so | 1495 | /* |
| 1496 | * eps and interfaces_nums are allocated in the same chunk so | ||
| 1520 | * only one free is required. Descriptors are also allocated | 1497 | * only one free is required. Descriptors are also allocated |
| 1521 | * in the same chunk. */ | 1498 | * in the same chunk. |
| 1499 | */ | ||
| 1522 | 1500 | ||
| 1523 | kfree(func); | 1501 | kfree(func); |
| 1524 | } | 1502 | } |
| 1525 | 1503 | ||
| 1526 | |||
| 1527 | static void ffs_func_eps_disable(struct ffs_function *func) | 1504 | static void ffs_func_eps_disable(struct ffs_function *func) |
| 1528 | { | 1505 | { |
| 1529 | struct ffs_ep *ep = func->eps; | 1506 | struct ffs_ep *ep = func->eps; |
| @@ -1581,11 +1558,12 @@ static int ffs_func_eps_enable(struct ffs_function *func) | |||
| 1581 | 1558 | ||
| 1582 | /* Parsing and building descriptors and strings *****************************/ | 1559 | /* Parsing and building descriptors and strings *****************************/ |
| 1583 | 1560 | ||
| 1584 | 1561 | /* | |
| 1585 | /* This validates if data pointed by data is a valid USB descriptor as | 1562 | * This validates if data pointed by data is a valid USB descriptor as |
| 1586 | * well as record how many interfaces, endpoints and strings are | 1563 | * well as record how many interfaces, endpoints and strings are |
| 1587 | * required by given configuration. Returns address afther the | 1564 | * required by given configuration. Returns address after the |
| 1588 | * descriptor or NULL if data is invalid. */ | 1565 | * descriptor or NULL if data is invalid. |
| 1566 | */ | ||
| 1589 | 1567 | ||
| 1590 | enum ffs_entity_type { | 1568 | enum ffs_entity_type { |
| 1591 | FFS_DESCRIPTOR, FFS_INTERFACE, FFS_STRING, FFS_ENDPOINT | 1569 | FFS_DESCRIPTOR, FFS_INTERFACE, FFS_STRING, FFS_ENDPOINT |
| @@ -1607,14 +1585,14 @@ static int __must_check ffs_do_desc(char *data, unsigned len, | |||
| 1607 | 1585 | ||
| 1608 | /* At least two bytes are required: length and type */ | 1586 | /* At least two bytes are required: length and type */ |
| 1609 | if (len < 2) { | 1587 | if (len < 2) { |
| 1610 | FVDBG("descriptor too short"); | 1588 | pr_vdebug("descriptor too short\n"); |
| 1611 | return -EINVAL; | 1589 | return -EINVAL; |
| 1612 | } | 1590 | } |
| 1613 | 1591 | ||
| 1614 | /* If we have at least as many bytes as the descriptor takes? */ | 1592 | /* If we have at least as many bytes as the descriptor takes? */ |
| 1615 | length = _ds->bLength; | 1593 | length = _ds->bLength; |
| 1616 | if (len < length) { | 1594 | if (len < length) { |
| 1617 | FVDBG("descriptor longer then available data"); | 1595 | pr_vdebug("descriptor longer then available data\n"); |
| 1618 | return -EINVAL; | 1596 | return -EINVAL; |
| 1619 | } | 1597 | } |
| 1620 | 1598 | ||
| @@ -1622,15 +1600,15 @@ static int __must_check ffs_do_desc(char *data, unsigned len, | |||
| 1622 | #define __entity_check_STRING(val) (val) | 1600 | #define __entity_check_STRING(val) (val) |
| 1623 | #define __entity_check_ENDPOINT(val) ((val) & USB_ENDPOINT_NUMBER_MASK) | 1601 | #define __entity_check_ENDPOINT(val) ((val) & USB_ENDPOINT_NUMBER_MASK) |
| 1624 | #define __entity(type, val) do { \ | 1602 | #define __entity(type, val) do { \ |
| 1625 | FVDBG("entity " #type "(%02x)", (val)); \ | 1603 | pr_vdebug("entity " #type "(%02x)\n", (val)); \ |
| 1626 | if (unlikely(!__entity_check_ ##type(val))) { \ | 1604 | if (unlikely(!__entity_check_ ##type(val))) { \ |
| 1627 | FVDBG("invalid entity's value"); \ | 1605 | pr_vdebug("invalid entity's value\n"); \ |
| 1628 | return -EINVAL; \ | 1606 | return -EINVAL; \ |
| 1629 | } \ | 1607 | } \ |
| 1630 | ret = entity(FFS_ ##type, &val, _ds, priv); \ | 1608 | ret = entity(FFS_ ##type, &val, _ds, priv); \ |
| 1631 | if (unlikely(ret < 0)) { \ | 1609 | if (unlikely(ret < 0)) { \ |
| 1632 | FDBG("entity " #type "(%02x); ret = %d", \ | 1610 | pr_debug("entity " #type "(%02x); ret = %d\n", \ |
| 1633 | (val), ret); \ | 1611 | (val), ret); \ |
| 1634 | return ret; \ | 1612 | return ret; \ |
| 1635 | } \ | 1613 | } \ |
| 1636 | } while (0) | 1614 | } while (0) |
| @@ -1642,12 +1620,13 @@ static int __must_check ffs_do_desc(char *data, unsigned len, | |||
| 1642 | case USB_DT_STRING: | 1620 | case USB_DT_STRING: |
| 1643 | case USB_DT_DEVICE_QUALIFIER: | 1621 | case USB_DT_DEVICE_QUALIFIER: |
| 1644 | /* function can't have any of those */ | 1622 | /* function can't have any of those */ |
| 1645 | FVDBG("descriptor reserved for gadget: %d", _ds->bDescriptorType); | 1623 | pr_vdebug("descriptor reserved for gadget: %d\n", |
| 1624 | _ds->bDescriptorType); | ||
| 1646 | return -EINVAL; | 1625 | return -EINVAL; |
| 1647 | 1626 | ||
| 1648 | case USB_DT_INTERFACE: { | 1627 | case USB_DT_INTERFACE: { |
| 1649 | struct usb_interface_descriptor *ds = (void *)_ds; | 1628 | struct usb_interface_descriptor *ds = (void *)_ds; |
| 1650 | FVDBG("interface descriptor"); | 1629 | pr_vdebug("interface descriptor\n"); |
| 1651 | if (length != sizeof *ds) | 1630 | if (length != sizeof *ds) |
| 1652 | goto inv_length; | 1631 | goto inv_length; |
| 1653 | 1632 | ||
| @@ -1659,7 +1638,7 @@ static int __must_check ffs_do_desc(char *data, unsigned len, | |||
| 1659 | 1638 | ||
| 1660 | case USB_DT_ENDPOINT: { | 1639 | case USB_DT_ENDPOINT: { |
| 1661 | struct usb_endpoint_descriptor *ds = (void *)_ds; | 1640 | struct usb_endpoint_descriptor *ds = (void *)_ds; |
| 1662 | FVDBG("endpoint descriptor"); | 1641 | pr_vdebug("endpoint descriptor\n"); |
| 1663 | if (length != USB_DT_ENDPOINT_SIZE && | 1642 | if (length != USB_DT_ENDPOINT_SIZE && |
| 1664 | length != USB_DT_ENDPOINT_AUDIO_SIZE) | 1643 | length != USB_DT_ENDPOINT_AUDIO_SIZE) |
| 1665 | goto inv_length; | 1644 | goto inv_length; |
| @@ -1674,7 +1653,7 @@ static int __must_check ffs_do_desc(char *data, unsigned len, | |||
| 1674 | 1653 | ||
| 1675 | case USB_DT_INTERFACE_ASSOCIATION: { | 1654 | case USB_DT_INTERFACE_ASSOCIATION: { |
| 1676 | struct usb_interface_assoc_descriptor *ds = (void *)_ds; | 1655 | struct usb_interface_assoc_descriptor *ds = (void *)_ds; |
| 1677 | FVDBG("interface association descriptor"); | 1656 | pr_vdebug("interface association descriptor\n"); |
| 1678 | if (length != sizeof *ds) | 1657 | if (length != sizeof *ds) |
| 1679 | goto inv_length; | 1658 | goto inv_length; |
| 1680 | if (ds->iFunction) | 1659 | if (ds->iFunction) |
| @@ -1688,17 +1667,17 @@ static int __must_check ffs_do_desc(char *data, unsigned len, | |||
| 1688 | case USB_DT_SECURITY: | 1667 | case USB_DT_SECURITY: |
| 1689 | case USB_DT_CS_RADIO_CONTROL: | 1668 | case USB_DT_CS_RADIO_CONTROL: |
| 1690 | /* TODO */ | 1669 | /* TODO */ |
| 1691 | FVDBG("unimplemented descriptor: %d", _ds->bDescriptorType); | 1670 | pr_vdebug("unimplemented descriptor: %d\n", _ds->bDescriptorType); |
| 1692 | return -EINVAL; | 1671 | return -EINVAL; |
| 1693 | 1672 | ||
| 1694 | default: | 1673 | default: |
| 1695 | /* We should never be here */ | 1674 | /* We should never be here */ |
| 1696 | FVDBG("unknown descriptor: %d", _ds->bDescriptorType); | 1675 | pr_vdebug("unknown descriptor: %d\n", _ds->bDescriptorType); |
| 1697 | return -EINVAL; | 1676 | return -EINVAL; |
| 1698 | 1677 | ||
| 1699 | inv_length: | 1678 | inv_length: |
| 1700 | FVDBG("invalid length: %d (descriptor %d)", | 1679 | pr_vdebug("invalid length: %d (descriptor %d)\n", |
| 1701 | _ds->bLength, _ds->bDescriptorType); | 1680 | _ds->bLength, _ds->bDescriptorType); |
| 1702 | return -EINVAL; | 1681 | return -EINVAL; |
| 1703 | } | 1682 | } |
| 1704 | 1683 | ||
| @@ -1711,7 +1690,6 @@ static int __must_check ffs_do_desc(char *data, unsigned len, | |||
| 1711 | return length; | 1690 | return length; |
| 1712 | } | 1691 | } |
| 1713 | 1692 | ||
| 1714 | |||
| 1715 | static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, | 1693 | static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, |
| 1716 | ffs_entity_callback entity, void *priv) | 1694 | ffs_entity_callback entity, void *priv) |
| 1717 | { | 1695 | { |
| @@ -1726,10 +1704,11 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, | |||
| 1726 | if (num == count) | 1704 | if (num == count) |
| 1727 | data = NULL; | 1705 | data = NULL; |
| 1728 | 1706 | ||
| 1729 | /* Record "descriptor" entitny */ | 1707 | /* Record "descriptor" entity */ |
| 1730 | ret = entity(FFS_DESCRIPTOR, (u8 *)num, (void *)data, priv); | 1708 | ret = entity(FFS_DESCRIPTOR, (u8 *)num, (void *)data, priv); |
| 1731 | if (unlikely(ret < 0)) { | 1709 | if (unlikely(ret < 0)) { |
| 1732 | FDBG("entity DESCRIPTOR(%02lx); ret = %d", num, ret); | 1710 | pr_debug("entity DESCRIPTOR(%02lx); ret = %d\n", |
| 1711 | num, ret); | ||
| 1733 | return ret; | 1712 | return ret; |
| 1734 | } | 1713 | } |
| 1735 | 1714 | ||
| @@ -1738,7 +1717,7 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, | |||
| 1738 | 1717 | ||
| 1739 | ret = ffs_do_desc(data, len, entity, priv); | 1718 | ret = ffs_do_desc(data, len, entity, priv); |
| 1740 | if (unlikely(ret < 0)) { | 1719 | if (unlikely(ret < 0)) { |
| 1741 | FDBG("%s returns %d", __func__, ret); | 1720 | pr_debug("%s returns %d\n", __func__, ret); |
| 1742 | return ret; | 1721 | return ret; |
| 1743 | } | 1722 | } |
| 1744 | 1723 | ||
| @@ -1748,7 +1727,6 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, | |||
| 1748 | } | 1727 | } |
| 1749 | } | 1728 | } |
| 1750 | 1729 | ||
| 1751 | |||
| 1752 | static int __ffs_data_do_entity(enum ffs_entity_type type, | 1730 | static int __ffs_data_do_entity(enum ffs_entity_type type, |
| 1753 | u8 *valuep, struct usb_descriptor_header *desc, | 1731 | u8 *valuep, struct usb_descriptor_header *desc, |
| 1754 | void *priv) | 1732 | void *priv) |
| @@ -1762,16 +1740,20 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, | |||
| 1762 | break; | 1740 | break; |
| 1763 | 1741 | ||
| 1764 | case FFS_INTERFACE: | 1742 | case FFS_INTERFACE: |
| 1765 | /* Interfaces are indexed from zero so if we | 1743 | /* |
| 1744 | * Interfaces are indexed from zero so if we | ||
| 1766 | * encountered interface "n" then there are at least | 1745 | * encountered interface "n" then there are at least |
| 1767 | * "n+1" interfaces. */ | 1746 | * "n+1" interfaces. |
| 1747 | */ | ||
| 1768 | if (*valuep >= ffs->interfaces_count) | 1748 | if (*valuep >= ffs->interfaces_count) |
| 1769 | ffs->interfaces_count = *valuep + 1; | 1749 | ffs->interfaces_count = *valuep + 1; |
| 1770 | break; | 1750 | break; |
| 1771 | 1751 | ||
| 1772 | case FFS_STRING: | 1752 | case FFS_STRING: |
| 1773 | /* Strings are indexed from 1 (0 is magic ;) reserved | 1753 | /* |
| 1774 | * for languages list or some such) */ | 1754 | * Strings are indexed from 1 (0 is magic ;) reserved |
| 1755 | * for languages list or some such) | ||
| 1756 | */ | ||
| 1775 | if (*valuep > ffs->strings_count) | 1757 | if (*valuep > ffs->strings_count) |
| 1776 | ffs->strings_count = *valuep; | 1758 | ffs->strings_count = *valuep; |
| 1777 | break; | 1759 | break; |
| @@ -1786,7 +1768,6 @@ static int __ffs_data_do_entity(enum ffs_entity_type type, | |||
| 1786 | return 0; | 1768 | return 0; |
| 1787 | } | 1769 | } |
| 1788 | 1770 | ||
| 1789 | |||
| 1790 | static int __ffs_data_got_descs(struct ffs_data *ffs, | 1771 | static int __ffs_data_got_descs(struct ffs_data *ffs, |
| 1791 | char *const _data, size_t len) | 1772 | char *const _data, size_t len) |
| 1792 | { | 1773 | { |
| @@ -1849,8 +1830,6 @@ error: | |||
| 1849 | return ret; | 1830 | return ret; |
| 1850 | } | 1831 | } |
| 1851 | 1832 | ||
| 1852 | |||
| 1853 | |||
| 1854 | static int __ffs_data_got_strings(struct ffs_data *ffs, | 1833 | static int __ffs_data_got_strings(struct ffs_data *ffs, |
| 1855 | char *const _data, size_t len) | 1834 | char *const _data, size_t len) |
| 1856 | { | 1835 | { |
| @@ -1876,17 +1855,17 @@ static int __ffs_data_got_strings(struct ffs_data *ffs, | |||
| 1876 | if (unlikely(str_count < needed_count)) | 1855 | if (unlikely(str_count < needed_count)) |
| 1877 | goto error; | 1856 | goto error; |
| 1878 | 1857 | ||
| 1879 | /* If we don't need any strings just return and free all | 1858 | /* |
| 1880 | * memory */ | 1859 | * If we don't need any strings just return and free all |
| 1860 | * memory. | ||
| 1861 | */ | ||
| 1881 | if (!needed_count) { | 1862 | if (!needed_count) { |
| 1882 | kfree(_data); | 1863 | kfree(_data); |
| 1883 | return 0; | 1864 | return 0; |
| 1884 | } | 1865 | } |
| 1885 | 1866 | ||
| 1886 | /* Allocate */ | 1867 | /* Allocate everything in one chunk so there's less maintenance. */ |
| 1887 | { | 1868 | { |
| 1888 | /* Allocate everything in one chunk so there's less | ||
| 1889 | * maintanance. */ | ||
| 1890 | struct { | 1869 | struct { |
| 1891 | struct usb_gadget_strings *stringtabs[lang_count + 1]; | 1870 | struct usb_gadget_strings *stringtabs[lang_count + 1]; |
| 1892 | struct usb_gadget_strings stringtab[lang_count]; | 1871 | struct usb_gadget_strings stringtab[lang_count]; |
| @@ -1937,13 +1916,17 @@ static int __ffs_data_got_strings(struct ffs_data *ffs, | |||
| 1937 | if (unlikely(length == len)) | 1916 | if (unlikely(length == len)) |
| 1938 | goto error_free; | 1917 | goto error_free; |
| 1939 | 1918 | ||
| 1940 | /* user may provide more strings then we need, | 1919 | /* |
| 1941 | * if that's the case we simply ingore the | 1920 | * User may provide more strings then we need, |
| 1942 | * rest */ | 1921 | * if that's the case we simply ignore the |
| 1922 | * rest | ||
| 1923 | */ | ||
| 1943 | if (likely(needed)) { | 1924 | if (likely(needed)) { |
| 1944 | /* s->id will be set while adding | 1925 | /* |
| 1926 | * s->id will be set while adding | ||
| 1945 | * function to configuration so for | 1927 | * function to configuration so for |
| 1946 | * now just leave garbage here. */ | 1928 | * now just leave garbage here. |
| 1929 | */ | ||
| 1947 | s->s = data; | 1930 | s->s = data; |
| 1948 | --needed; | 1931 | --needed; |
| 1949 | ++s; | 1932 | ++s; |
| @@ -1977,8 +1960,6 @@ error: | |||
| 1977 | } | 1960 | } |
| 1978 | 1961 | ||
| 1979 | 1962 | ||
| 1980 | |||
| 1981 | |||
| 1982 | /* Events handling and management *******************************************/ | 1963 | /* Events handling and management *******************************************/ |
| 1983 | 1964 | ||
| 1984 | static void __ffs_event_add(struct ffs_data *ffs, | 1965 | static void __ffs_event_add(struct ffs_data *ffs, |
| @@ -1987,29 +1968,32 @@ static void __ffs_event_add(struct ffs_data *ffs, | |||
| 1987 | enum usb_functionfs_event_type rem_type1, rem_type2 = type; | 1968 | enum usb_functionfs_event_type rem_type1, rem_type2 = type; |
| 1988 | int neg = 0; | 1969 | int neg = 0; |
| 1989 | 1970 | ||
| 1990 | /* Abort any unhandled setup */ | 1971 | /* |
| 1991 | /* We do not need to worry about some cmpxchg() changing value | 1972 | * Abort any unhandled setup |
| 1973 | * | ||
| 1974 | * We do not need to worry about some cmpxchg() changing value | ||
| 1992 | * of ffs->setup_state without holding the lock because when | 1975 | * of ffs->setup_state without holding the lock because when |
| 1993 | * state is FFS_SETUP_PENDING cmpxchg() in several places in | 1976 | * state is FFS_SETUP_PENDING cmpxchg() in several places in |
| 1994 | * the source does nothing. */ | 1977 | * the source does nothing. |
| 1978 | */ | ||
| 1995 | if (ffs->setup_state == FFS_SETUP_PENDING) | 1979 | if (ffs->setup_state == FFS_SETUP_PENDING) |
| 1996 | ffs->setup_state = FFS_SETUP_CANCELED; | 1980 | ffs->setup_state = FFS_SETUP_CANCELED; |
| 1997 | 1981 | ||
| 1998 | switch (type) { | 1982 | switch (type) { |
| 1999 | case FUNCTIONFS_RESUME: | 1983 | case FUNCTIONFS_RESUME: |
| 2000 | rem_type2 = FUNCTIONFS_SUSPEND; | 1984 | rem_type2 = FUNCTIONFS_SUSPEND; |
| 2001 | /* FALL THGOUTH */ | 1985 | /* FALL THROUGH */ |
| 2002 | case FUNCTIONFS_SUSPEND: | 1986 | case FUNCTIONFS_SUSPEND: |
| 2003 | case FUNCTIONFS_SETUP: | 1987 | case FUNCTIONFS_SETUP: |
| 2004 | rem_type1 = type; | 1988 | rem_type1 = type; |
| 2005 | /* discard all similar events */ | 1989 | /* Discard all similar events */ |
| 2006 | break; | 1990 | break; |
| 2007 | 1991 | ||
| 2008 | case FUNCTIONFS_BIND: | 1992 | case FUNCTIONFS_BIND: |
| 2009 | case FUNCTIONFS_UNBIND: | 1993 | case FUNCTIONFS_UNBIND: |
| 2010 | case FUNCTIONFS_DISABLE: | 1994 | case FUNCTIONFS_DISABLE: |
| 2011 | case FUNCTIONFS_ENABLE: | 1995 | case FUNCTIONFS_ENABLE: |
| 2012 | /* discard everything other then power management. */ | 1996 | /* Discard everything other then power management. */ |
| 2013 | rem_type1 = FUNCTIONFS_SUSPEND; | 1997 | rem_type1 = FUNCTIONFS_SUSPEND; |
| 2014 | rem_type2 = FUNCTIONFS_RESUME; | 1998 | rem_type2 = FUNCTIONFS_RESUME; |
| 2015 | neg = 1; | 1999 | neg = 1; |
| @@ -2026,11 +2010,11 @@ static void __ffs_event_add(struct ffs_data *ffs, | |||
| 2026 | if ((*ev == rem_type1 || *ev == rem_type2) == neg) | 2010 | if ((*ev == rem_type1 || *ev == rem_type2) == neg) |
| 2027 | *out++ = *ev; | 2011 | *out++ = *ev; |
| 2028 | else | 2012 | else |
| 2029 | FVDBG("purging event %d", *ev); | 2013 | pr_vdebug("purging event %d\n", *ev); |
| 2030 | ffs->ev.count = out - ffs->ev.types; | 2014 | ffs->ev.count = out - ffs->ev.types; |
| 2031 | } | 2015 | } |
| 2032 | 2016 | ||
| 2033 | FVDBG("adding event %d", type); | 2017 | pr_vdebug("adding event %d\n", type); |
| 2034 | ffs->ev.types[ffs->ev.count++] = type; | 2018 | ffs->ev.types[ffs->ev.count++] = type; |
| 2035 | wake_up_locked(&ffs->ev.waitq); | 2019 | wake_up_locked(&ffs->ev.waitq); |
| 2036 | } | 2020 | } |
| @@ -2055,8 +2039,10 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, | |||
| 2055 | struct ffs_function *func = priv; | 2039 | struct ffs_function *func = priv; |
| 2056 | struct ffs_ep *ffs_ep; | 2040 | struct ffs_ep *ffs_ep; |
| 2057 | 2041 | ||
| 2058 | /* If hs_descriptors is not NULL then we are reading hs | 2042 | /* |
| 2059 | * descriptors now */ | 2043 | * If hs_descriptors is not NULL then we are reading hs |
| 2044 | * descriptors now | ||
| 2045 | */ | ||
| 2060 | const int isHS = func->function.hs_descriptors != NULL; | 2046 | const int isHS = func->function.hs_descriptors != NULL; |
| 2061 | unsigned idx; | 2047 | unsigned idx; |
| 2062 | 2048 | ||
| @@ -2075,9 +2061,9 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, | |||
| 2075 | ffs_ep = func->eps + idx; | 2061 | ffs_ep = func->eps + idx; |
| 2076 | 2062 | ||
| 2077 | if (unlikely(ffs_ep->descs[isHS])) { | 2063 | if (unlikely(ffs_ep->descs[isHS])) { |
| 2078 | FVDBG("two %sspeed descriptors for EP %d", | 2064 | pr_vdebug("two %sspeed descriptors for EP %d\n", |
| 2079 | isHS ? "high" : "full", | 2065 | isHS ? "high" : "full", |
| 2080 | ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 2066 | ds->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); |
| 2081 | return -EINVAL; | 2067 | return -EINVAL; |
| 2082 | } | 2068 | } |
| 2083 | ffs_ep->descs[isHS] = ds; | 2069 | ffs_ep->descs[isHS] = ds; |
| @@ -2091,11 +2077,11 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, | |||
| 2091 | struct usb_request *req; | 2077 | struct usb_request *req; |
| 2092 | struct usb_ep *ep; | 2078 | struct usb_ep *ep; |
| 2093 | 2079 | ||
| 2094 | FVDBG("autoconfig"); | 2080 | pr_vdebug("autoconfig\n"); |
| 2095 | ep = usb_ep_autoconfig(func->gadget, ds); | 2081 | ep = usb_ep_autoconfig(func->gadget, ds); |
| 2096 | if (unlikely(!ep)) | 2082 | if (unlikely(!ep)) |
| 2097 | return -ENOTSUPP; | 2083 | return -ENOTSUPP; |
| 2098 | ep->driver_data = func->eps + idx;; | 2084 | ep->driver_data = func->eps + idx; |
| 2099 | 2085 | ||
| 2100 | req = usb_ep_alloc_request(ep, GFP_KERNEL); | 2086 | req = usb_ep_alloc_request(ep, GFP_KERNEL); |
| 2101 | if (unlikely(!req)) | 2087 | if (unlikely(!req)) |
| @@ -2111,7 +2097,6 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, | |||
| 2111 | return 0; | 2097 | return 0; |
| 2112 | } | 2098 | } |
| 2113 | 2099 | ||
| 2114 | |||
| 2115 | static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep, | 2100 | static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep, |
| 2116 | struct usb_descriptor_header *desc, | 2101 | struct usb_descriptor_header *desc, |
| 2117 | void *priv) | 2102 | void *priv) |
| @@ -2143,8 +2128,10 @@ static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep, | |||
| 2143 | break; | 2128 | break; |
| 2144 | 2129 | ||
| 2145 | case FFS_ENDPOINT: | 2130 | case FFS_ENDPOINT: |
| 2146 | /* USB_DT_ENDPOINT are handled in | 2131 | /* |
| 2147 | * __ffs_func_bind_do_descs(). */ | 2132 | * USB_DT_ENDPOINT are handled in |
| 2133 | * __ffs_func_bind_do_descs(). | ||
| 2134 | */ | ||
| 2148 | if (desc->bDescriptorType == USB_DT_ENDPOINT) | 2135 | if (desc->bDescriptorType == USB_DT_ENDPOINT) |
| 2149 | return 0; | 2136 | return 0; |
| 2150 | 2137 | ||
| @@ -2160,7 +2147,7 @@ static int __ffs_func_bind_do_nums(enum ffs_entity_type type, u8 *valuep, | |||
| 2160 | break; | 2147 | break; |
| 2161 | } | 2148 | } |
| 2162 | 2149 | ||
| 2163 | FVDBG("%02x -> %02x", *valuep, newValue); | 2150 | pr_vdebug("%02x -> %02x\n", *valuep, newValue); |
| 2164 | *valuep = newValue; | 2151 | *valuep = newValue; |
| 2165 | return 0; | 2152 | return 0; |
| 2166 | } | 2153 | } |
| @@ -2211,9 +2198,11 @@ static int ffs_func_bind(struct usb_configuration *c, | |||
| 2211 | func->eps = data->eps; | 2198 | func->eps = data->eps; |
| 2212 | func->interfaces_nums = data->inums; | 2199 | func->interfaces_nums = data->inums; |
| 2213 | 2200 | ||
| 2214 | /* Go throught all the endpoint descriptors and allocate | 2201 | /* |
| 2202 | * Go through all the endpoint descriptors and allocate | ||
| 2215 | * endpoints first, so that later we can rewrite the endpoint | 2203 | * endpoints first, so that later we can rewrite the endpoint |
| 2216 | * numbers without worying that it may be described later on. */ | 2204 | * numbers without worrying that it may be described later on. |
| 2205 | */ | ||
| 2217 | if (likely(full)) { | 2206 | if (likely(full)) { |
| 2218 | func->function.descriptors = data->fs_descs; | 2207 | func->function.descriptors = data->fs_descs; |
| 2219 | ret = ffs_do_descs(ffs->fs_descs_count, | 2208 | ret = ffs_do_descs(ffs->fs_descs_count, |
| @@ -2234,9 +2223,11 @@ static int ffs_func_bind(struct usb_configuration *c, | |||
| 2234 | __ffs_func_bind_do_descs, func); | 2223 | __ffs_func_bind_do_descs, func); |
| 2235 | } | 2224 | } |
| 2236 | 2225 | ||
| 2237 | /* Now handle interface numbers allocation and interface and | 2226 | /* |
| 2238 | * enpoint numbers rewritting. We can do that in one go | 2227 | * Now handle interface numbers allocation and interface and |
| 2239 | * now. */ | 2228 | * endpoint numbers rewriting. We can do that in one go |
| 2229 | * now. | ||
| 2230 | */ | ||
| 2240 | ret = ffs_do_descs(ffs->fs_descs_count + | 2231 | ret = ffs_do_descs(ffs->fs_descs_count + |
| 2241 | (high ? ffs->hs_descs_count : 0), | 2232 | (high ? ffs->hs_descs_count : 0), |
| 2242 | data->raw_descs, sizeof data->raw_descs, | 2233 | data->raw_descs, sizeof data->raw_descs, |
| @@ -2274,7 +2265,6 @@ static void ffs_func_unbind(struct usb_configuration *c, | |||
| 2274 | ffs_func_free(func); | 2265 | ffs_func_free(func); |
| 2275 | } | 2266 | } |
| 2276 | 2267 | ||
| 2277 | |||
| 2278 | static int ffs_func_set_alt(struct usb_function *f, | 2268 | static int ffs_func_set_alt(struct usb_function *f, |
| 2279 | unsigned interface, unsigned alt) | 2269 | unsigned interface, unsigned alt) |
| 2280 | { | 2270 | { |
| @@ -2322,20 +2312,21 @@ static int ffs_func_setup(struct usb_function *f, | |||
| 2322 | 2312 | ||
| 2323 | ENTER(); | 2313 | ENTER(); |
| 2324 | 2314 | ||
| 2325 | FVDBG("creq->bRequestType = %02x", creq->bRequestType); | 2315 | pr_vdebug("creq->bRequestType = %02x\n", creq->bRequestType); |
| 2326 | FVDBG("creq->bRequest = %02x", creq->bRequest); | 2316 | pr_vdebug("creq->bRequest = %02x\n", creq->bRequest); |
| 2327 | FVDBG("creq->wValue = %04x", le16_to_cpu(creq->wValue)); | 2317 | pr_vdebug("creq->wValue = %04x\n", le16_to_cpu(creq->wValue)); |
| 2328 | FVDBG("creq->wIndex = %04x", le16_to_cpu(creq->wIndex)); | 2318 | pr_vdebug("creq->wIndex = %04x\n", le16_to_cpu(creq->wIndex)); |
| 2329 | FVDBG("creq->wLength = %04x", le16_to_cpu(creq->wLength)); | 2319 | pr_vdebug("creq->wLength = %04x\n", le16_to_cpu(creq->wLength)); |
| 2330 | 2320 | ||
| 2331 | /* Most requests directed to interface go throught here | 2321 | /* |
| 2322 | * Most requests directed to interface go through here | ||
| 2332 | * (notable exceptions are set/get interface) so we need to | 2323 | * (notable exceptions are set/get interface) so we need to |
| 2333 | * handle them. All other either handled by composite or | 2324 | * handle them. All other either handled by composite or |
| 2334 | * passed to usb_configuration->setup() (if one is set). No | 2325 | * passed to usb_configuration->setup() (if one is set). No |
| 2335 | * matter, we will handle requests directed to endpoint here | 2326 | * matter, we will handle requests directed to endpoint here |
| 2336 | * as well (as it's straightforward) but what to do with any | 2327 | * as well (as it's straightforward) but what to do with any |
| 2337 | * other request? */ | 2328 | * other request? |
| 2338 | 2329 | */ | |
| 2339 | if (ffs->state != FFS_ACTIVE) | 2330 | if (ffs->state != FFS_ACTIVE) |
| 2340 | return -ENODEV; | 2331 | return -ENODEV; |
| 2341 | 2332 | ||
| @@ -2378,8 +2369,7 @@ static void ffs_func_resume(struct usb_function *f) | |||
| 2378 | } | 2369 | } |
| 2379 | 2370 | ||
| 2380 | 2371 | ||
| 2381 | 2372 | /* Endpoint and interface numbers reverse mapping ***************************/ | |
| 2382 | /* Enpoint and interface numbers reverse mapping ****************************/ | ||
| 2383 | 2373 | ||
| 2384 | static int ffs_func_revmap_ep(struct ffs_function *func, u8 num) | 2374 | static int ffs_func_revmap_ep(struct ffs_function *func, u8 num) |
| 2385 | { | 2375 | { |
| @@ -2410,7 +2400,6 @@ static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock) | |||
| 2410 | : mutex_lock_interruptible(mutex); | 2400 | : mutex_lock_interruptible(mutex); |
| 2411 | } | 2401 | } |
| 2412 | 2402 | ||
| 2413 | |||
| 2414 | static char *ffs_prepare_buffer(const char * __user buf, size_t len) | 2403 | static char *ffs_prepare_buffer(const char * __user buf, size_t len) |
| 2415 | { | 2404 | { |
| 2416 | char *data; | 2405 | char *data; |
| @@ -2427,7 +2416,7 @@ static char *ffs_prepare_buffer(const char * __user buf, size_t len) | |||
| 2427 | return ERR_PTR(-EFAULT); | 2416 | return ERR_PTR(-EFAULT); |
| 2428 | } | 2417 | } |
| 2429 | 2418 | ||
| 2430 | FVDBG("Buffer from user space:"); | 2419 | pr_vdebug("Buffer from user space:\n"); |
| 2431 | ffs_dump_mem("", data, len); | 2420 | ffs_dump_mem("", data, len); |
| 2432 | 2421 | ||
| 2433 | return data; | 2422 | return data; |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 838286b1cd14..b5dbb2308f56 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 37 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 38 | */ | 38 | */ |
| 39 | 39 | ||
| 40 | |||
| 41 | /* | 40 | /* |
| 42 | * The Mass Storage Function acts as a USB Mass Storage device, | 41 | * The Mass Storage Function acts as a USB Mass Storage device, |
| 43 | * appearing to the host as a disk drive or as a CD-ROM drive. In | 42 | * appearing to the host as a disk drive or as a CD-ROM drive. In |
| @@ -185,7 +184,6 @@ | |||
| 185 | * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>. | 184 | * <http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf>. |
| 186 | */ | 185 | */ |
| 187 | 186 | ||
| 188 | |||
| 189 | /* | 187 | /* |
| 190 | * Driver Design | 188 | * Driver Design |
| 191 | * | 189 | * |
| @@ -275,7 +273,6 @@ | |||
| 275 | /* #define VERBOSE_DEBUG */ | 273 | /* #define VERBOSE_DEBUG */ |
| 276 | /* #define DUMP_MSGS */ | 274 | /* #define DUMP_MSGS */ |
| 277 | 275 | ||
| 278 | |||
| 279 | #include <linux/blkdev.h> | 276 | #include <linux/blkdev.h> |
| 280 | #include <linux/completion.h> | 277 | #include <linux/completion.h> |
| 281 | #include <linux/dcache.h> | 278 | #include <linux/dcache.h> |
| @@ -300,7 +297,6 @@ | |||
| 300 | #include "gadget_chips.h" | 297 | #include "gadget_chips.h" |
| 301 | 298 | ||
| 302 | 299 | ||
| 303 | |||
| 304 | /*------------------------------------------------------------------------*/ | 300 | /*------------------------------------------------------------------------*/ |
| 305 | 301 | ||
| 306 | #define FSG_DRIVER_DESC "Mass Storage Function" | 302 | #define FSG_DRIVER_DESC "Mass Storage Function" |
| @@ -308,7 +304,6 @@ | |||
| 308 | 304 | ||
| 309 | static const char fsg_string_interface[] = "Mass Storage"; | 305 | static const char fsg_string_interface[] = "Mass Storage"; |
| 310 | 306 | ||
| 311 | |||
| 312 | #define FSG_NO_INTR_EP 1 | 307 | #define FSG_NO_INTR_EP 1 |
| 313 | #define FSG_NO_DEVICE_STRINGS 1 | 308 | #define FSG_NO_DEVICE_STRINGS 1 |
| 314 | #define FSG_NO_OTG 1 | 309 | #define FSG_NO_OTG 1 |
| @@ -324,25 +319,30 @@ struct fsg_common; | |||
| 324 | 319 | ||
| 325 | /* FSF callback functions */ | 320 | /* FSF callback functions */ |
| 326 | struct fsg_operations { | 321 | struct fsg_operations { |
| 327 | /* Callback function to call when thread exits. If no | 322 | /* |
| 323 | * Callback function to call when thread exits. If no | ||
| 328 | * callback is set or it returns value lower then zero MSF | 324 | * callback is set or it returns value lower then zero MSF |
| 329 | * will force eject all LUNs it operates on (including those | 325 | * will force eject all LUNs it operates on (including those |
| 330 | * marked as non-removable or with prevent_medium_removal flag | 326 | * marked as non-removable or with prevent_medium_removal flag |
| 331 | * set). */ | 327 | * set). |
| 328 | */ | ||
| 332 | int (*thread_exits)(struct fsg_common *common); | 329 | int (*thread_exits)(struct fsg_common *common); |
| 333 | 330 | ||
| 334 | /* Called prior to ejection. Negative return means error, | 331 | /* |
| 332 | * Called prior to ejection. Negative return means error, | ||
| 335 | * zero means to continue with ejection, positive means not to | 333 | * zero means to continue with ejection, positive means not to |
| 336 | * eject. */ | 334 | * eject. |
| 335 | */ | ||
| 337 | int (*pre_eject)(struct fsg_common *common, | 336 | int (*pre_eject)(struct fsg_common *common, |
| 338 | struct fsg_lun *lun, int num); | 337 | struct fsg_lun *lun, int num); |
| 339 | /* Called after ejection. Negative return means error, zero | 338 | /* |
| 340 | * or positive is just a success. */ | 339 | * Called after ejection. Negative return means error, zero |
| 340 | * or positive is just a success. | ||
| 341 | */ | ||
| 341 | int (*post_eject)(struct fsg_common *common, | 342 | int (*post_eject)(struct fsg_common *common, |
| 342 | struct fsg_lun *lun, int num); | 343 | struct fsg_lun *lun, int num); |
| 343 | }; | 344 | }; |
| 344 | 345 | ||
| 345 | |||
| 346 | /* Data shared by all the FSG instances. */ | 346 | /* Data shared by all the FSG instances. */ |
| 347 | struct fsg_common { | 347 | struct fsg_common { |
| 348 | struct usb_gadget *gadget; | 348 | struct usb_gadget *gadget; |
| @@ -398,14 +398,15 @@ struct fsg_common { | |||
| 398 | /* Gadget's private data. */ | 398 | /* Gadget's private data. */ |
| 399 | void *private_data; | 399 | void *private_data; |
| 400 | 400 | ||
| 401 | /* Vendor (8 chars), product (16 chars), release (4 | 401 | /* |
| 402 | * hexadecimal digits) and NUL byte */ | 402 | * Vendor (8 chars), product (16 chars), release (4 |
| 403 | * hexadecimal digits) and NUL byte | ||
| 404 | */ | ||
| 403 | char inquiry_string[8 + 16 + 4 + 1]; | 405 | char inquiry_string[8 + 16 + 4 + 1]; |
| 404 | 406 | ||
| 405 | struct kref ref; | 407 | struct kref ref; |
| 406 | }; | 408 | }; |
| 407 | 409 | ||
| 408 | |||
| 409 | struct fsg_config { | 410 | struct fsg_config { |
| 410 | unsigned nluns; | 411 | unsigned nluns; |
| 411 | struct fsg_lun_config { | 412 | struct fsg_lun_config { |
| @@ -431,7 +432,6 @@ struct fsg_config { | |||
| 431 | char can_stall; | 432 | char can_stall; |
| 432 | }; | 433 | }; |
| 433 | 434 | ||
| 434 | |||
| 435 | struct fsg_dev { | 435 | struct fsg_dev { |
| 436 | struct usb_function function; | 436 | struct usb_function function; |
| 437 | struct usb_gadget *gadget; /* Copy of cdev->gadget */ | 437 | struct usb_gadget *gadget; /* Copy of cdev->gadget */ |
| @@ -449,7 +449,6 @@ struct fsg_dev { | |||
| 449 | struct usb_ep *bulk_out; | 449 | struct usb_ep *bulk_out; |
| 450 | }; | 450 | }; |
| 451 | 451 | ||
| 452 | |||
| 453 | static inline int __fsg_is_set(struct fsg_common *common, | 452 | static inline int __fsg_is_set(struct fsg_common *common, |
| 454 | const char *func, unsigned line) | 453 | const char *func, unsigned line) |
| 455 | { | 454 | { |
| @@ -462,13 +461,11 @@ static inline int __fsg_is_set(struct fsg_common *common, | |||
| 462 | 461 | ||
| 463 | #define fsg_is_set(common) likely(__fsg_is_set(common, __func__, __LINE__)) | 462 | #define fsg_is_set(common) likely(__fsg_is_set(common, __func__, __LINE__)) |
| 464 | 463 | ||
| 465 | |||
| 466 | static inline struct fsg_dev *fsg_from_func(struct usb_function *f) | 464 | static inline struct fsg_dev *fsg_from_func(struct usb_function *f) |
| 467 | { | 465 | { |
| 468 | return container_of(f, struct fsg_dev, function); | 466 | return container_of(f, struct fsg_dev, function); |
| 469 | } | 467 | } |
| 470 | 468 | ||
| 471 | |||
| 472 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 469 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
| 473 | 470 | ||
| 474 | static int exception_in_progress(struct fsg_common *common) | 471 | static int exception_in_progress(struct fsg_common *common) |
| @@ -478,7 +475,7 @@ static int exception_in_progress(struct fsg_common *common) | |||
| 478 | 475 | ||
| 479 | /* Make bulk-out requests be divisible by the maxpacket size */ | 476 | /* Make bulk-out requests be divisible by the maxpacket size */ |
| 480 | static void set_bulk_out_req_length(struct fsg_common *common, | 477 | static void set_bulk_out_req_length(struct fsg_common *common, |
| 481 | struct fsg_buffhd *bh, unsigned int length) | 478 | struct fsg_buffhd *bh, unsigned int length) |
| 482 | { | 479 | { |
| 483 | unsigned int rem; | 480 | unsigned int rem; |
| 484 | 481 | ||
| @@ -489,6 +486,7 @@ static void set_bulk_out_req_length(struct fsg_common *common, | |||
| 489 | bh->outreq->length = length; | 486 | bh->outreq->length = length; |
| 490 | } | 487 | } |
| 491 | 488 | ||
| 489 | |||
| 492 | /*-------------------------------------------------------------------------*/ | 490 | /*-------------------------------------------------------------------------*/ |
| 493 | 491 | ||
| 494 | static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | 492 | static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) |
| @@ -519,14 +517,15 @@ static void wakeup_thread(struct fsg_common *common) | |||
| 519 | wake_up_process(common->thread_task); | 517 | wake_up_process(common->thread_task); |
| 520 | } | 518 | } |
| 521 | 519 | ||
| 522 | |||
| 523 | static void raise_exception(struct fsg_common *common, enum fsg_state new_state) | 520 | static void raise_exception(struct fsg_common *common, enum fsg_state new_state) |
| 524 | { | 521 | { |
| 525 | unsigned long flags; | 522 | unsigned long flags; |
| 526 | 523 | ||
| 527 | /* Do nothing if a higher-priority exception is already in progress. | 524 | /* |
| 525 | * Do nothing if a higher-priority exception is already in progress. | ||
| 528 | * If a lower-or-equal priority exception is in progress, preempt it | 526 | * If a lower-or-equal priority exception is in progress, preempt it |
| 529 | * and notify the main thread by sending it a signal. */ | 527 | * and notify the main thread by sending it a signal. |
| 528 | */ | ||
| 530 | spin_lock_irqsave(&common->lock, flags); | 529 | spin_lock_irqsave(&common->lock, flags); |
| 531 | if (common->state <= new_state) { | 530 | if (common->state <= new_state) { |
| 532 | common->exception_req_tag = common->ep0_req_tag; | 531 | common->exception_req_tag = common->ep0_req_tag; |
| @@ -555,10 +554,10 @@ static int ep0_queue(struct fsg_common *common) | |||
| 555 | return rc; | 554 | return rc; |
| 556 | } | 555 | } |
| 557 | 556 | ||
| 557 | |||
| 558 | /*-------------------------------------------------------------------------*/ | 558 | /*-------------------------------------------------------------------------*/ |
| 559 | 559 | ||
| 560 | /* Bulk and interrupt endpoint completion handlers. | 560 | /* Completion handlers. These always run in_irq. */ |
| 561 | * These always run in_irq. */ | ||
| 562 | 561 | ||
| 563 | static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | 562 | static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) |
| 564 | { | 563 | { |
| @@ -567,7 +566,7 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 567 | 566 | ||
| 568 | if (req->status || req->actual != req->length) | 567 | if (req->status || req->actual != req->length) |
| 569 | DBG(common, "%s --> %d, %u/%u\n", __func__, | 568 | DBG(common, "%s --> %d, %u/%u\n", __func__, |
| 570 | req->status, req->actual, req->length); | 569 | req->status, req->actual, req->length); |
| 571 | if (req->status == -ECONNRESET) /* Request was cancelled */ | 570 | if (req->status == -ECONNRESET) /* Request was cancelled */ |
| 572 | usb_ep_fifo_flush(ep); | 571 | usb_ep_fifo_flush(ep); |
| 573 | 572 | ||
| @@ -588,8 +587,7 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 588 | dump_msg(common, "bulk-out", req->buf, req->actual); | 587 | dump_msg(common, "bulk-out", req->buf, req->actual); |
| 589 | if (req->status || req->actual != bh->bulk_out_intended_length) | 588 | if (req->status || req->actual != bh->bulk_out_intended_length) |
| 590 | DBG(common, "%s --> %d, %u/%u\n", __func__, | 589 | DBG(common, "%s --> %d, %u/%u\n", __func__, |
| 591 | req->status, req->actual, | 590 | req->status, req->actual, bh->bulk_out_intended_length); |
| 592 | bh->bulk_out_intended_length); | ||
| 593 | if (req->status == -ECONNRESET) /* Request was cancelled */ | 591 | if (req->status == -ECONNRESET) /* Request was cancelled */ |
| 594 | usb_ep_fifo_flush(ep); | 592 | usb_ep_fifo_flush(ep); |
| 595 | 593 | ||
| @@ -602,13 +600,8 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
| 602 | spin_unlock(&common->lock); | 600 | spin_unlock(&common->lock); |
| 603 | } | 601 | } |
| 604 | 602 | ||
| 605 | |||
| 606 | /*-------------------------------------------------------------------------*/ | ||
| 607 | |||
| 608 | /* Ep0 class-specific handlers. These always run in_irq. */ | ||
| 609 | |||
| 610 | static int fsg_setup(struct usb_function *f, | 603 | static int fsg_setup(struct usb_function *f, |
| 611 | const struct usb_ctrlrequest *ctrl) | 604 | const struct usb_ctrlrequest *ctrl) |
| 612 | { | 605 | { |
| 613 | struct fsg_dev *fsg = fsg_from_func(f); | 606 | struct fsg_dev *fsg = fsg_from_func(f); |
| 614 | struct usb_request *req = fsg->common->ep0req; | 607 | struct usb_request *req = fsg->common->ep0req; |
| @@ -628,8 +621,10 @@ static int fsg_setup(struct usb_function *f, | |||
| 628 | if (w_index != fsg->interface_number || w_value != 0) | 621 | if (w_index != fsg->interface_number || w_value != 0) |
| 629 | return -EDOM; | 622 | return -EDOM; |
| 630 | 623 | ||
| 631 | /* Raise an exception to stop the current operation | 624 | /* |
| 632 | * and reinitialize our state. */ | 625 | * Raise an exception to stop the current operation |
| 626 | * and reinitialize our state. | ||
| 627 | */ | ||
| 633 | DBG(fsg, "bulk reset request\n"); | 628 | DBG(fsg, "bulk reset request\n"); |
| 634 | raise_exception(fsg->common, FSG_STATE_RESET); | 629 | raise_exception(fsg->common, FSG_STATE_RESET); |
| 635 | return DELAYED_STATUS; | 630 | return DELAYED_STATUS; |
| @@ -641,7 +636,7 @@ static int fsg_setup(struct usb_function *f, | |||
| 641 | if (w_index != fsg->interface_number || w_value != 0) | 636 | if (w_index != fsg->interface_number || w_value != 0) |
| 642 | return -EDOM; | 637 | return -EDOM; |
| 643 | VDBG(fsg, "get max LUN\n"); | 638 | VDBG(fsg, "get max LUN\n"); |
| 644 | *(u8 *) req->buf = fsg->common->nluns - 1; | 639 | *(u8 *)req->buf = fsg->common->nluns - 1; |
| 645 | 640 | ||
| 646 | /* Respond with data/status */ | 641 | /* Respond with data/status */ |
| 647 | req->length = min((u16)1, w_length); | 642 | req->length = min((u16)1, w_length); |
| @@ -649,8 +644,7 @@ static int fsg_setup(struct usb_function *f, | |||
| 649 | } | 644 | } |
| 650 | 645 | ||
| 651 | VDBG(fsg, | 646 | VDBG(fsg, |
| 652 | "unknown class-specific control req " | 647 | "unknown class-specific control req %02x.%02x v%04x i%04x l%u\n", |
| 653 | "%02x.%02x v%04x i%04x l%u\n", | ||
| 654 | ctrl->bRequestType, ctrl->bRequest, | 648 | ctrl->bRequestType, ctrl->bRequest, |
| 655 | le16_to_cpu(ctrl->wValue), w_index, w_length); | 649 | le16_to_cpu(ctrl->wValue), w_index, w_length); |
| 656 | return -EOPNOTSUPP; | 650 | return -EOPNOTSUPP; |
| @@ -661,11 +655,10 @@ static int fsg_setup(struct usb_function *f, | |||
| 661 | 655 | ||
| 662 | /* All the following routines run in process context */ | 656 | /* All the following routines run in process context */ |
| 663 | 657 | ||
| 664 | |||
| 665 | /* Use this for bulk or interrupt transfers, not ep0 */ | 658 | /* Use this for bulk or interrupt transfers, not ep0 */ |
| 666 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | 659 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, |
| 667 | struct usb_request *req, int *pbusy, | 660 | struct usb_request *req, int *pbusy, |
| 668 | enum fsg_buffer_state *state) | 661 | enum fsg_buffer_state *state) |
| 669 | { | 662 | { |
| 670 | int rc; | 663 | int rc; |
| 671 | 664 | ||
| @@ -683,25 +676,34 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
| 683 | 676 | ||
| 684 | /* We can't do much more than wait for a reset */ | 677 | /* We can't do much more than wait for a reset */ |
| 685 | 678 | ||
| 686 | /* Note: currently the net2280 driver fails zero-length | 679 | /* |
| 687 | * submissions if DMA is enabled. */ | 680 | * Note: currently the net2280 driver fails zero-length |
| 688 | if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP && | 681 | * submissions if DMA is enabled. |
| 689 | req->length == 0)) | 682 | */ |
| 683 | if (rc != -ESHUTDOWN && | ||
| 684 | !(rc == -EOPNOTSUPP && req->length == 0)) | ||
| 690 | WARNING(fsg, "error in submission: %s --> %d\n", | 685 | WARNING(fsg, "error in submission: %s --> %d\n", |
| 691 | ep->name, rc); | 686 | ep->name, rc); |
| 692 | } | 687 | } |
| 693 | } | 688 | } |
| 694 | 689 | ||
| 695 | #define START_TRANSFER_OR(common, ep_name, req, pbusy, state) \ | 690 | static bool start_in_transfer(struct fsg_common *common, struct fsg_buffhd *bh) |
| 696 | if (fsg_is_set(common)) \ | 691 | { |
| 697 | start_transfer((common)->fsg, (common)->fsg->ep_name, \ | 692 | if (!fsg_is_set(common)) |
| 698 | req, pbusy, state); \ | 693 | return false; |
| 699 | else | 694 | start_transfer(common->fsg, common->fsg->bulk_in, |
| 700 | 695 | bh->inreq, &bh->inreq_busy, &bh->state); | |
| 701 | #define START_TRANSFER(common, ep_name, req, pbusy, state) \ | 696 | return true; |
| 702 | START_TRANSFER_OR(common, ep_name, req, pbusy, state) (void)0 | 697 | } |
| 703 | |||
| 704 | 698 | ||
| 699 | static bool start_out_transfer(struct fsg_common *common, struct fsg_buffhd *bh) | ||
| 700 | { | ||
| 701 | if (!fsg_is_set(common)) | ||
| 702 | return false; | ||
| 703 | start_transfer(common->fsg, common->fsg->bulk_out, | ||
| 704 | bh->outreq, &bh->outreq_busy, &bh->state); | ||
| 705 | return true; | ||
| 706 | } | ||
| 705 | 707 | ||
| 706 | static int sleep_thread(struct fsg_common *common) | 708 | static int sleep_thread(struct fsg_common *common) |
| 707 | { | 709 | { |
| @@ -739,16 +741,20 @@ static int do_read(struct fsg_common *common) | |||
| 739 | unsigned int partial_page; | 741 | unsigned int partial_page; |
| 740 | ssize_t nread; | 742 | ssize_t nread; |
| 741 | 743 | ||
| 742 | /* Get the starting Logical Block Address and check that it's | 744 | /* |
| 743 | * not too big */ | 745 | * Get the starting Logical Block Address and check that it's |
| 746 | * not too big. | ||
| 747 | */ | ||
| 744 | if (common->cmnd[0] == READ_6) | 748 | if (common->cmnd[0] == READ_6) |
| 745 | lba = get_unaligned_be24(&common->cmnd[1]); | 749 | lba = get_unaligned_be24(&common->cmnd[1]); |
| 746 | else { | 750 | else { |
| 747 | lba = get_unaligned_be32(&common->cmnd[2]); | 751 | lba = get_unaligned_be32(&common->cmnd[2]); |
| 748 | 752 | ||
| 749 | /* We allow DPO (Disable Page Out = don't save data in the | 753 | /* |
| 754 | * We allow DPO (Disable Page Out = don't save data in the | ||
| 750 | * cache) and FUA (Force Unit Access = don't read from the | 755 | * cache) and FUA (Force Unit Access = don't read from the |
| 751 | * cache), but we don't implement them. */ | 756 | * cache), but we don't implement them. |
| 757 | */ | ||
| 752 | if ((common->cmnd[1] & ~0x18) != 0) { | 758 | if ((common->cmnd[1] & ~0x18) != 0) { |
| 753 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | 759 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
| 754 | return -EINVAL; | 760 | return -EINVAL; |
| @@ -766,22 +772,23 @@ static int do_read(struct fsg_common *common) | |||
| 766 | return -EIO; /* No default reply */ | 772 | return -EIO; /* No default reply */ |
| 767 | 773 | ||
| 768 | for (;;) { | 774 | for (;;) { |
| 769 | 775 | /* | |
| 770 | /* Figure out how much we need to read: | 776 | * Figure out how much we need to read: |
| 771 | * Try to read the remaining amount. | 777 | * Try to read the remaining amount. |
| 772 | * But don't read more than the buffer size. | 778 | * But don't read more than the buffer size. |
| 773 | * And don't try to read past the end of the file. | 779 | * And don't try to read past the end of the file. |
| 774 | * Finally, if we're not at a page boundary, don't read past | 780 | * Finally, if we're not at a page boundary, don't read past |
| 775 | * the next page. | 781 | * the next page. |
| 776 | * If this means reading 0 then we were asked to read past | 782 | * If this means reading 0 then we were asked to read past |
| 777 | * the end of file. */ | 783 | * the end of file. |
| 784 | */ | ||
| 778 | amount = min(amount_left, FSG_BUFLEN); | 785 | amount = min(amount_left, FSG_BUFLEN); |
| 779 | amount = min((loff_t) amount, | 786 | amount = min((loff_t)amount, |
| 780 | curlun->file_length - file_offset); | 787 | curlun->file_length - file_offset); |
| 781 | partial_page = file_offset & (PAGE_CACHE_SIZE - 1); | 788 | partial_page = file_offset & (PAGE_CACHE_SIZE - 1); |
| 782 | if (partial_page > 0) | 789 | if (partial_page > 0) |
| 783 | amount = min(amount, (unsigned int) PAGE_CACHE_SIZE - | 790 | amount = min(amount, (unsigned int)PAGE_CACHE_SIZE - |
| 784 | partial_page); | 791 | partial_page); |
| 785 | 792 | ||
| 786 | /* Wait for the next buffer to become available */ | 793 | /* Wait for the next buffer to become available */ |
| 787 | bh = common->next_buffhd_to_fill; | 794 | bh = common->next_buffhd_to_fill; |
| @@ -791,8 +798,10 @@ static int do_read(struct fsg_common *common) | |||
| 791 | return rc; | 798 | return rc; |
| 792 | } | 799 | } |
| 793 | 800 | ||
| 794 | /* If we were asked to read past the end of file, | 801 | /* |
| 795 | * end with an empty buffer. */ | 802 | * If we were asked to read past the end of file, |
| 803 | * end with an empty buffer. | ||
| 804 | */ | ||
| 796 | if (amount == 0) { | 805 | if (amount == 0) { |
| 797 | curlun->sense_data = | 806 | curlun->sense_data = |
| 798 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 807 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| @@ -806,21 +815,19 @@ static int do_read(struct fsg_common *common) | |||
| 806 | /* Perform the read */ | 815 | /* Perform the read */ |
| 807 | file_offset_tmp = file_offset; | 816 | file_offset_tmp = file_offset; |
| 808 | nread = vfs_read(curlun->filp, | 817 | nread = vfs_read(curlun->filp, |
| 809 | (char __user *) bh->buf, | 818 | (char __user *)bh->buf, |
| 810 | amount, &file_offset_tmp); | 819 | amount, &file_offset_tmp); |
| 811 | VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, | 820 | VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, |
| 812 | (unsigned long long) file_offset, | 821 | (unsigned long long)file_offset, (int)nread); |
| 813 | (int) nread); | ||
| 814 | if (signal_pending(current)) | 822 | if (signal_pending(current)) |
| 815 | return -EINTR; | 823 | return -EINTR; |
| 816 | 824 | ||
| 817 | if (nread < 0) { | 825 | if (nread < 0) { |
| 818 | LDBG(curlun, "error in file read: %d\n", | 826 | LDBG(curlun, "error in file read: %d\n", (int)nread); |
| 819 | (int) nread); | ||
| 820 | nread = 0; | 827 | nread = 0; |
| 821 | } else if (nread < amount) { | 828 | } else if (nread < amount) { |
| 822 | LDBG(curlun, "partial file read: %d/%u\n", | 829 | LDBG(curlun, "partial file read: %d/%u\n", |
| 823 | (int) nread, amount); | 830 | (int)nread, amount); |
| 824 | nread -= (nread & 511); /* Round down to a block */ | 831 | nread -= (nread & 511); /* Round down to a block */ |
| 825 | } | 832 | } |
| 826 | file_offset += nread; | 833 | file_offset += nread; |
| @@ -842,10 +849,8 @@ static int do_read(struct fsg_common *common) | |||
| 842 | 849 | ||
| 843 | /* Send this buffer and go read some more */ | 850 | /* Send this buffer and go read some more */ |
| 844 | bh->inreq->zero = 0; | 851 | bh->inreq->zero = 0; |
| 845 | START_TRANSFER_OR(common, bulk_in, bh->inreq, | 852 | if (!start_in_transfer(common, bh)) |
| 846 | &bh->inreq_busy, &bh->state) | 853 | /* Don't know what to do if common->fsg is NULL */ |
| 847 | /* Don't know what to do if | ||
| 848 | * common->fsg is NULL */ | ||
| 849 | return -EIO; | 854 | return -EIO; |
| 850 | common->next_buffhd_to_fill = bh->next; | 855 | common->next_buffhd_to_fill = bh->next; |
| 851 | } | 856 | } |
| @@ -877,17 +882,21 @@ static int do_write(struct fsg_common *common) | |||
| 877 | curlun->filp->f_flags &= ~O_SYNC; /* Default is not to wait */ | 882 | curlun->filp->f_flags &= ~O_SYNC; /* Default is not to wait */ |
| 878 | spin_unlock(&curlun->filp->f_lock); | 883 | spin_unlock(&curlun->filp->f_lock); |
| 879 | 884 | ||
| 880 | /* Get the starting Logical Block Address and check that it's | 885 | /* |
| 881 | * not too big */ | 886 | * Get the starting Logical Block Address and check that it's |
| 887 | * not too big | ||
| 888 | */ | ||
| 882 | if (common->cmnd[0] == WRITE_6) | 889 | if (common->cmnd[0] == WRITE_6) |
| 883 | lba = get_unaligned_be24(&common->cmnd[1]); | 890 | lba = get_unaligned_be24(&common->cmnd[1]); |
| 884 | else { | 891 | else { |
| 885 | lba = get_unaligned_be32(&common->cmnd[2]); | 892 | lba = get_unaligned_be32(&common->cmnd[2]); |
| 886 | 893 | ||
| 887 | /* We allow DPO (Disable Page Out = don't save data in the | 894 | /* |
| 895 | * We allow DPO (Disable Page Out = don't save data in the | ||
| 888 | * cache) and FUA (Force Unit Access = write directly to the | 896 | * cache) and FUA (Force Unit Access = write directly to the |
| 889 | * medium). We don't implement DPO; we implement FUA by | 897 | * medium). We don't implement DPO; we implement FUA by |
| 890 | * performing synchronous output. */ | 898 | * performing synchronous output. |
| 899 | */ | ||
| 891 | if (common->cmnd[1] & ~0x18) { | 900 | if (common->cmnd[1] & ~0x18) { |
| 892 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | 901 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
| 893 | return -EINVAL; | 902 | return -EINVAL; |
| @@ -915,7 +924,8 @@ static int do_write(struct fsg_common *common) | |||
| 915 | bh = common->next_buffhd_to_fill; | 924 | bh = common->next_buffhd_to_fill; |
| 916 | if (bh->state == BUF_STATE_EMPTY && get_some_more) { | 925 | if (bh->state == BUF_STATE_EMPTY && get_some_more) { |
| 917 | 926 | ||
| 918 | /* Figure out how much we want to get: | 927 | /* |
| 928 | * Figure out how much we want to get: | ||
| 919 | * Try to get the remaining amount. | 929 | * Try to get the remaining amount. |
| 920 | * But don't get more than the buffer size. | 930 | * But don't get more than the buffer size. |
| 921 | * And don't try to go past the end of the file. | 931 | * And don't try to go past the end of the file. |
| @@ -923,14 +933,15 @@ static int do_write(struct fsg_common *common) | |||
| 923 | * don't go past the next page. | 933 | * don't go past the next page. |
| 924 | * If this means getting 0, then we were asked | 934 | * If this means getting 0, then we were asked |
| 925 | * to write past the end of file. | 935 | * to write past the end of file. |
| 926 | * Finally, round down to a block boundary. */ | 936 | * Finally, round down to a block boundary. |
| 937 | */ | ||
| 927 | amount = min(amount_left_to_req, FSG_BUFLEN); | 938 | amount = min(amount_left_to_req, FSG_BUFLEN); |
| 928 | amount = min((loff_t) amount, curlun->file_length - | 939 | amount = min((loff_t)amount, |
| 929 | usb_offset); | 940 | curlun->file_length - usb_offset); |
| 930 | partial_page = usb_offset & (PAGE_CACHE_SIZE - 1); | 941 | partial_page = usb_offset & (PAGE_CACHE_SIZE - 1); |
| 931 | if (partial_page > 0) | 942 | if (partial_page > 0) |
| 932 | amount = min(amount, | 943 | amount = min(amount, |
| 933 | (unsigned int) PAGE_CACHE_SIZE - partial_page); | 944 | (unsigned int)PAGE_CACHE_SIZE - partial_page); |
| 934 | 945 | ||
| 935 | if (amount == 0) { | 946 | if (amount == 0) { |
| 936 | get_some_more = 0; | 947 | get_some_more = 0; |
| @@ -940,11 +951,13 @@ static int do_write(struct fsg_common *common) | |||
| 940 | curlun->info_valid = 1; | 951 | curlun->info_valid = 1; |
| 941 | continue; | 952 | continue; |
| 942 | } | 953 | } |
| 943 | amount -= (amount & 511); | 954 | amount -= amount & 511; |
| 944 | if (amount == 0) { | 955 | if (amount == 0) { |
| 945 | 956 | ||
| 946 | /* Why were we were asked to transfer a | 957 | /* |
| 947 | * partial block? */ | 958 | * Why were we were asked to transfer a |
| 959 | * partial block? | ||
| 960 | */ | ||
| 948 | get_some_more = 0; | 961 | get_some_more = 0; |
| 949 | continue; | 962 | continue; |
| 950 | } | 963 | } |
| @@ -956,15 +969,15 @@ static int do_write(struct fsg_common *common) | |||
| 956 | if (amount_left_to_req == 0) | 969 | if (amount_left_to_req == 0) |
| 957 | get_some_more = 0; | 970 | get_some_more = 0; |
| 958 | 971 | ||
| 959 | /* amount is always divisible by 512, hence by | 972 | /* |
| 960 | * the bulk-out maxpacket size */ | 973 | * amount is always divisible by 512, hence by |
| 974 | * the bulk-out maxpacket size | ||
| 975 | */ | ||
| 961 | bh->outreq->length = amount; | 976 | bh->outreq->length = amount; |
| 962 | bh->bulk_out_intended_length = amount; | 977 | bh->bulk_out_intended_length = amount; |
| 963 | bh->outreq->short_not_ok = 1; | 978 | bh->outreq->short_not_ok = 1; |
| 964 | START_TRANSFER_OR(common, bulk_out, bh->outreq, | 979 | if (!start_out_transfer(common, bh)) |
| 965 | &bh->outreq_busy, &bh->state) | 980 | /* Dunno what to do if common->fsg is NULL */ |
| 966 | /* Don't know what to do if | ||
| 967 | * common->fsg is NULL */ | ||
| 968 | return -EIO; | 981 | return -EIO; |
| 969 | common->next_buffhd_to_fill = bh->next; | 982 | common->next_buffhd_to_fill = bh->next; |
| 970 | continue; | 983 | continue; |
| @@ -990,30 +1003,29 @@ static int do_write(struct fsg_common *common) | |||
| 990 | amount = bh->outreq->actual; | 1003 | amount = bh->outreq->actual; |
| 991 | if (curlun->file_length - file_offset < amount) { | 1004 | if (curlun->file_length - file_offset < amount) { |
| 992 | LERROR(curlun, | 1005 | LERROR(curlun, |
| 993 | "write %u @ %llu beyond end %llu\n", | 1006 | "write %u @ %llu beyond end %llu\n", |
| 994 | amount, (unsigned long long) file_offset, | 1007 | amount, (unsigned long long)file_offset, |
| 995 | (unsigned long long) curlun->file_length); | 1008 | (unsigned long long)curlun->file_length); |
| 996 | amount = curlun->file_length - file_offset; | 1009 | amount = curlun->file_length - file_offset; |
| 997 | } | 1010 | } |
| 998 | 1011 | ||
| 999 | /* Perform the write */ | 1012 | /* Perform the write */ |
| 1000 | file_offset_tmp = file_offset; | 1013 | file_offset_tmp = file_offset; |
| 1001 | nwritten = vfs_write(curlun->filp, | 1014 | nwritten = vfs_write(curlun->filp, |
| 1002 | (char __user *) bh->buf, | 1015 | (char __user *)bh->buf, |
| 1003 | amount, &file_offset_tmp); | 1016 | amount, &file_offset_tmp); |
| 1004 | VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, | 1017 | VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, |
| 1005 | (unsigned long long) file_offset, | 1018 | (unsigned long long)file_offset, (int)nwritten); |
| 1006 | (int) nwritten); | ||
| 1007 | if (signal_pending(current)) | 1019 | if (signal_pending(current)) |
| 1008 | return -EINTR; /* Interrupted! */ | 1020 | return -EINTR; /* Interrupted! */ |
| 1009 | 1021 | ||
| 1010 | if (nwritten < 0) { | 1022 | if (nwritten < 0) { |
| 1011 | LDBG(curlun, "error in file write: %d\n", | 1023 | LDBG(curlun, "error in file write: %d\n", |
| 1012 | (int) nwritten); | 1024 | (int)nwritten); |
| 1013 | nwritten = 0; | 1025 | nwritten = 0; |
| 1014 | } else if (nwritten < amount) { | 1026 | } else if (nwritten < amount) { |
| 1015 | LDBG(curlun, "partial file write: %d/%u\n", | 1027 | LDBG(curlun, "partial file write: %d/%u\n", |
| 1016 | (int) nwritten, amount); | 1028 | (int)nwritten, amount); |
| 1017 | nwritten -= (nwritten & 511); | 1029 | nwritten -= (nwritten & 511); |
| 1018 | /* Round down to a block */ | 1030 | /* Round down to a block */ |
| 1019 | } | 1031 | } |
| @@ -1086,16 +1098,20 @@ static int do_verify(struct fsg_common *common) | |||
| 1086 | unsigned int amount; | 1098 | unsigned int amount; |
| 1087 | ssize_t nread; | 1099 | ssize_t nread; |
| 1088 | 1100 | ||
| 1089 | /* Get the starting Logical Block Address and check that it's | 1101 | /* |
| 1090 | * not too big */ | 1102 | * Get the starting Logical Block Address and check that it's |
| 1103 | * not too big. | ||
| 1104 | */ | ||
| 1091 | lba = get_unaligned_be32(&common->cmnd[2]); | 1105 | lba = get_unaligned_be32(&common->cmnd[2]); |
| 1092 | if (lba >= curlun->num_sectors) { | 1106 | if (lba >= curlun->num_sectors) { |
| 1093 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1107 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| 1094 | return -EINVAL; | 1108 | return -EINVAL; |
| 1095 | } | 1109 | } |
| 1096 | 1110 | ||
| 1097 | /* We allow DPO (Disable Page Out = don't save data in the | 1111 | /* |
| 1098 | * cache) but we don't implement it. */ | 1112 | * We allow DPO (Disable Page Out = don't save data in the |
| 1113 | * cache) but we don't implement it. | ||
| 1114 | */ | ||
| 1099 | if (common->cmnd[1] & ~0x10) { | 1115 | if (common->cmnd[1] & ~0x10) { |
| 1100 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | 1116 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
| 1101 | return -EINVAL; | 1117 | return -EINVAL; |
| @@ -1120,16 +1136,17 @@ static int do_verify(struct fsg_common *common) | |||
| 1120 | 1136 | ||
| 1121 | /* Just try to read the requested blocks */ | 1137 | /* Just try to read the requested blocks */ |
| 1122 | while (amount_left > 0) { | 1138 | while (amount_left > 0) { |
| 1123 | 1139 | /* | |
| 1124 | /* Figure out how much we need to read: | 1140 | * Figure out how much we need to read: |
| 1125 | * Try to read the remaining amount, but not more than | 1141 | * Try to read the remaining amount, but not more than |
| 1126 | * the buffer size. | 1142 | * the buffer size. |
| 1127 | * And don't try to read past the end of the file. | 1143 | * And don't try to read past the end of the file. |
| 1128 | * If this means reading 0 then we were asked to read | 1144 | * If this means reading 0 then we were asked to read |
| 1129 | * past the end of file. */ | 1145 | * past the end of file. |
| 1146 | */ | ||
| 1130 | amount = min(amount_left, FSG_BUFLEN); | 1147 | amount = min(amount_left, FSG_BUFLEN); |
| 1131 | amount = min((loff_t) amount, | 1148 | amount = min((loff_t)amount, |
| 1132 | curlun->file_length - file_offset); | 1149 | curlun->file_length - file_offset); |
| 1133 | if (amount == 0) { | 1150 | if (amount == 0) { |
| 1134 | curlun->sense_data = | 1151 | curlun->sense_data = |
| 1135 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1152 | SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| @@ -1150,13 +1167,12 @@ static int do_verify(struct fsg_common *common) | |||
| 1150 | return -EINTR; | 1167 | return -EINTR; |
| 1151 | 1168 | ||
| 1152 | if (nread < 0) { | 1169 | if (nread < 0) { |
| 1153 | LDBG(curlun, "error in file verify: %d\n", | 1170 | LDBG(curlun, "error in file verify: %d\n", (int)nread); |
| 1154 | (int) nread); | ||
| 1155 | nread = 0; | 1171 | nread = 0; |
| 1156 | } else if (nread < amount) { | 1172 | } else if (nread < amount) { |
| 1157 | LDBG(curlun, "partial file verify: %d/%u\n", | 1173 | LDBG(curlun, "partial file verify: %d/%u\n", |
| 1158 | (int) nread, amount); | 1174 | (int)nread, amount); |
| 1159 | nread -= (nread & 511); /* Round down to a sector */ | 1175 | nread -= nread & 511; /* Round down to a sector */ |
| 1160 | } | 1176 | } |
| 1161 | if (nread == 0) { | 1177 | if (nread == 0) { |
| 1162 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; | 1178 | curlun->sense_data = SS_UNRECOVERED_READ_ERROR; |
| @@ -1198,7 +1214,6 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh) | |||
| 1198 | return 36; | 1214 | return 36; |
| 1199 | } | 1215 | } |
| 1200 | 1216 | ||
| 1201 | |||
| 1202 | static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh) | 1217 | static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh) |
| 1203 | { | 1218 | { |
| 1204 | struct fsg_lun *curlun = common->curlun; | 1219 | struct fsg_lun *curlun = common->curlun; |
| @@ -1252,13 +1267,12 @@ static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh) | |||
| 1252 | return 18; | 1267 | return 18; |
| 1253 | } | 1268 | } |
| 1254 | 1269 | ||
| 1255 | |||
| 1256 | static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh) | 1270 | static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh) |
| 1257 | { | 1271 | { |
| 1258 | struct fsg_lun *curlun = common->curlun; | 1272 | struct fsg_lun *curlun = common->curlun; |
| 1259 | u32 lba = get_unaligned_be32(&common->cmnd[2]); | 1273 | u32 lba = get_unaligned_be32(&common->cmnd[2]); |
| 1260 | int pmi = common->cmnd[8]; | 1274 | int pmi = common->cmnd[8]; |
| 1261 | u8 *buf = (u8 *) bh->buf; | 1275 | u8 *buf = (u8 *)bh->buf; |
| 1262 | 1276 | ||
| 1263 | /* Check the PMI and LBA fields */ | 1277 | /* Check the PMI and LBA fields */ |
| 1264 | if (pmi > 1 || (pmi == 0 && lba != 0)) { | 1278 | if (pmi > 1 || (pmi == 0 && lba != 0)) { |
| @@ -1272,13 +1286,12 @@ static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh) | |||
| 1272 | return 8; | 1286 | return 8; |
| 1273 | } | 1287 | } |
| 1274 | 1288 | ||
| 1275 | |||
| 1276 | static int do_read_header(struct fsg_common *common, struct fsg_buffhd *bh) | 1289 | static int do_read_header(struct fsg_common *common, struct fsg_buffhd *bh) |
| 1277 | { | 1290 | { |
| 1278 | struct fsg_lun *curlun = common->curlun; | 1291 | struct fsg_lun *curlun = common->curlun; |
| 1279 | int msf = common->cmnd[1] & 0x02; | 1292 | int msf = common->cmnd[1] & 0x02; |
| 1280 | u32 lba = get_unaligned_be32(&common->cmnd[2]); | 1293 | u32 lba = get_unaligned_be32(&common->cmnd[2]); |
| 1281 | u8 *buf = (u8 *) bh->buf; | 1294 | u8 *buf = (u8 *)bh->buf; |
| 1282 | 1295 | ||
| 1283 | if (common->cmnd[1] & ~0x02) { /* Mask away MSF */ | 1296 | if (common->cmnd[1] & ~0x02) { /* Mask away MSF */ |
| 1284 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | 1297 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
| @@ -1295,13 +1308,12 @@ static int do_read_header(struct fsg_common *common, struct fsg_buffhd *bh) | |||
| 1295 | return 8; | 1308 | return 8; |
| 1296 | } | 1309 | } |
| 1297 | 1310 | ||
| 1298 | |||
| 1299 | static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) | 1311 | static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) |
| 1300 | { | 1312 | { |
| 1301 | struct fsg_lun *curlun = common->curlun; | 1313 | struct fsg_lun *curlun = common->curlun; |
| 1302 | int msf = common->cmnd[1] & 0x02; | 1314 | int msf = common->cmnd[1] & 0x02; |
| 1303 | int start_track = common->cmnd[6]; | 1315 | int start_track = common->cmnd[6]; |
| 1304 | u8 *buf = (u8 *) bh->buf; | 1316 | u8 *buf = (u8 *)bh->buf; |
| 1305 | 1317 | ||
| 1306 | if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ | 1318 | if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ |
| 1307 | start_track > 1) { | 1319 | start_track > 1) { |
| @@ -1323,7 +1335,6 @@ static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh) | |||
| 1323 | return 20; | 1335 | return 20; |
| 1324 | } | 1336 | } |
| 1325 | 1337 | ||
| 1326 | |||
| 1327 | static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) | 1338 | static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) |
| 1328 | { | 1339 | { |
| 1329 | struct fsg_lun *curlun = common->curlun; | 1340 | struct fsg_lun *curlun = common->curlun; |
| @@ -1348,10 +1359,12 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) | |||
| 1348 | changeable_values = (pc == 1); | 1359 | changeable_values = (pc == 1); |
| 1349 | all_pages = (page_code == 0x3f); | 1360 | all_pages = (page_code == 0x3f); |
| 1350 | 1361 | ||
| 1351 | /* Write the mode parameter header. Fixed values are: default | 1362 | /* |
| 1363 | * Write the mode parameter header. Fixed values are: default | ||
| 1352 | * medium type, no cache control (DPOFUA), and no block descriptors. | 1364 | * medium type, no cache control (DPOFUA), and no block descriptors. |
| 1353 | * The only variable value is the WriteProtect bit. We will fill in | 1365 | * The only variable value is the WriteProtect bit. We will fill in |
| 1354 | * the mode data length later. */ | 1366 | * the mode data length later. |
| 1367 | */ | ||
| 1355 | memset(buf, 0, 8); | 1368 | memset(buf, 0, 8); |
| 1356 | if (mscmnd == MODE_SENSE) { | 1369 | if (mscmnd == MODE_SENSE) { |
| 1357 | buf[2] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */ | 1370 | buf[2] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */ |
| @@ -1365,8 +1378,10 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) | |||
| 1365 | 1378 | ||
| 1366 | /* No block descriptors */ | 1379 | /* No block descriptors */ |
| 1367 | 1380 | ||
| 1368 | /* The mode pages, in numerical order. The only page we support | 1381 | /* |
| 1369 | * is the Caching page. */ | 1382 | * The mode pages, in numerical order. The only page we support |
| 1383 | * is the Caching page. | ||
| 1384 | */ | ||
| 1370 | if (page_code == 0x08 || all_pages) { | 1385 | if (page_code == 0x08 || all_pages) { |
| 1371 | valid_page = 1; | 1386 | valid_page = 1; |
| 1372 | buf[0] = 0x08; /* Page code */ | 1387 | buf[0] = 0x08; /* Page code */ |
| @@ -1388,8 +1403,10 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) | |||
| 1388 | buf += 12; | 1403 | buf += 12; |
| 1389 | } | 1404 | } |
| 1390 | 1405 | ||
| 1391 | /* Check that a valid page was requested and the mode data length | 1406 | /* |
| 1392 | * isn't too long. */ | 1407 | * Check that a valid page was requested and the mode data length |
| 1408 | * isn't too long. | ||
| 1409 | */ | ||
| 1393 | len = buf - buf0; | 1410 | len = buf - buf0; |
| 1394 | if (!valid_page || len > limit) { | 1411 | if (!valid_page || len > limit) { |
| 1395 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | 1412 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
| @@ -1404,7 +1421,6 @@ static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh) | |||
| 1404 | return len; | 1421 | return len; |
| 1405 | } | 1422 | } |
| 1406 | 1423 | ||
| 1407 | |||
| 1408 | static int do_start_stop(struct fsg_common *common) | 1424 | static int do_start_stop(struct fsg_common *common) |
| 1409 | { | 1425 | { |
| 1410 | struct fsg_lun *curlun = common->curlun; | 1426 | struct fsg_lun *curlun = common->curlun; |
| @@ -1424,8 +1440,10 @@ static int do_start_stop(struct fsg_common *common) | |||
| 1424 | loej = common->cmnd[4] & 0x02; | 1440 | loej = common->cmnd[4] & 0x02; |
| 1425 | start = common->cmnd[4] & 0x01; | 1441 | start = common->cmnd[4] & 0x01; |
| 1426 | 1442 | ||
| 1427 | /* Our emulation doesn't support mounting; the medium is | 1443 | /* |
| 1428 | * available for use as soon as it is loaded. */ | 1444 | * Our emulation doesn't support mounting; the medium is |
| 1445 | * available for use as soon as it is loaded. | ||
| 1446 | */ | ||
| 1429 | if (start) { | 1447 | if (start) { |
| 1430 | if (!fsg_lun_is_open(curlun)) { | 1448 | if (!fsg_lun_is_open(curlun)) { |
| 1431 | curlun->sense_data = SS_MEDIUM_NOT_PRESENT; | 1449 | curlun->sense_data = SS_MEDIUM_NOT_PRESENT; |
| @@ -1466,7 +1484,6 @@ static int do_start_stop(struct fsg_common *common) | |||
| 1466 | : 0; | 1484 | : 0; |
| 1467 | } | 1485 | } |
| 1468 | 1486 | ||
| 1469 | |||
| 1470 | static int do_prevent_allow(struct fsg_common *common) | 1487 | static int do_prevent_allow(struct fsg_common *common) |
| 1471 | { | 1488 | { |
| 1472 | struct fsg_lun *curlun = common->curlun; | 1489 | struct fsg_lun *curlun = common->curlun; |
| @@ -1491,7 +1508,6 @@ static int do_prevent_allow(struct fsg_common *common) | |||
| 1491 | return 0; | 1508 | return 0; |
| 1492 | } | 1509 | } |
| 1493 | 1510 | ||
| 1494 | |||
| 1495 | static int do_read_format_capacities(struct fsg_common *common, | 1511 | static int do_read_format_capacities(struct fsg_common *common, |
| 1496 | struct fsg_buffhd *bh) | 1512 | struct fsg_buffhd *bh) |
| 1497 | { | 1513 | { |
| @@ -1509,7 +1525,6 @@ static int do_read_format_capacities(struct fsg_common *common, | |||
| 1509 | return 12; | 1525 | return 12; |
| 1510 | } | 1526 | } |
| 1511 | 1527 | ||
| 1512 | |||
| 1513 | static int do_mode_select(struct fsg_common *common, struct fsg_buffhd *bh) | 1528 | static int do_mode_select(struct fsg_common *common, struct fsg_buffhd *bh) |
| 1514 | { | 1529 | { |
| 1515 | struct fsg_lun *curlun = common->curlun; | 1530 | struct fsg_lun *curlun = common->curlun; |
| @@ -1591,7 +1606,7 @@ static int pad_with_zeros(struct fsg_dev *fsg) | |||
| 1591 | bh->inreq->length = nsend; | 1606 | bh->inreq->length = nsend; |
| 1592 | bh->inreq->zero = 0; | 1607 | bh->inreq->zero = 0; |
| 1593 | start_transfer(fsg, fsg->bulk_in, bh->inreq, | 1608 | start_transfer(fsg, fsg->bulk_in, bh->inreq, |
| 1594 | &bh->inreq_busy, &bh->state); | 1609 | &bh->inreq_busy, &bh->state); |
| 1595 | bh = fsg->common->next_buffhd_to_fill = bh->next; | 1610 | bh = fsg->common->next_buffhd_to_fill = bh->next; |
| 1596 | fsg->common->usb_amount_left -= nsend; | 1611 | fsg->common->usb_amount_left -= nsend; |
| 1597 | nkeep = 0; | 1612 | nkeep = 0; |
| @@ -1617,7 +1632,7 @@ static int throw_away_data(struct fsg_common *common) | |||
| 1617 | 1632 | ||
| 1618 | /* A short packet or an error ends everything */ | 1633 | /* A short packet or an error ends everything */ |
| 1619 | if (bh->outreq->actual != bh->outreq->length || | 1634 | if (bh->outreq->actual != bh->outreq->length || |
| 1620 | bh->outreq->status != 0) { | 1635 | bh->outreq->status != 0) { |
| 1621 | raise_exception(common, | 1636 | raise_exception(common, |
| 1622 | FSG_STATE_ABORT_BULK_OUT); | 1637 | FSG_STATE_ABORT_BULK_OUT); |
| 1623 | return -EINTR; | 1638 | return -EINTR; |
| @@ -1631,15 +1646,15 @@ static int throw_away_data(struct fsg_common *common) | |||
| 1631 | && common->usb_amount_left > 0) { | 1646 | && common->usb_amount_left > 0) { |
| 1632 | amount = min(common->usb_amount_left, FSG_BUFLEN); | 1647 | amount = min(common->usb_amount_left, FSG_BUFLEN); |
| 1633 | 1648 | ||
| 1634 | /* amount is always divisible by 512, hence by | 1649 | /* |
| 1635 | * the bulk-out maxpacket size */ | 1650 | * amount is always divisible by 512, hence by |
| 1651 | * the bulk-out maxpacket size. | ||
| 1652 | */ | ||
| 1636 | bh->outreq->length = amount; | 1653 | bh->outreq->length = amount; |
| 1637 | bh->bulk_out_intended_length = amount; | 1654 | bh->bulk_out_intended_length = amount; |
| 1638 | bh->outreq->short_not_ok = 1; | 1655 | bh->outreq->short_not_ok = 1; |
| 1639 | START_TRANSFER_OR(common, bulk_out, bh->outreq, | 1656 | if (!start_out_transfer(common, bh)) |
| 1640 | &bh->outreq_busy, &bh->state) | 1657 | /* Dunno what to do if common->fsg is NULL */ |
| 1641 | /* Don't know what to do if | ||
| 1642 | * common->fsg is NULL */ | ||
| 1643 | return -EIO; | 1658 | return -EIO; |
| 1644 | common->next_buffhd_to_fill = bh->next; | 1659 | common->next_buffhd_to_fill = bh->next; |
| 1645 | common->usb_amount_left -= amount; | 1660 | common->usb_amount_left -= amount; |
| @@ -1654,7 +1669,6 @@ static int throw_away_data(struct fsg_common *common) | |||
| 1654 | return 0; | 1669 | return 0; |
| 1655 | } | 1670 | } |
| 1656 | 1671 | ||
| 1657 | |||
| 1658 | static int finish_reply(struct fsg_common *common) | 1672 | static int finish_reply(struct fsg_common *common) |
| 1659 | { | 1673 | { |
| 1660 | struct fsg_buffhd *bh = common->next_buffhd_to_fill; | 1674 | struct fsg_buffhd *bh = common->next_buffhd_to_fill; |
| @@ -1664,10 +1678,12 @@ static int finish_reply(struct fsg_common *common) | |||
| 1664 | case DATA_DIR_NONE: | 1678 | case DATA_DIR_NONE: |
| 1665 | break; /* Nothing to send */ | 1679 | break; /* Nothing to send */ |
| 1666 | 1680 | ||
| 1667 | /* If we don't know whether the host wants to read or write, | 1681 | /* |
| 1682 | * If we don't know whether the host wants to read or write, | ||
| 1668 | * this must be CB or CBI with an unknown command. We mustn't | 1683 | * this must be CB or CBI with an unknown command. We mustn't |
| 1669 | * try to send or receive any data. So stall both bulk pipes | 1684 | * try to send or receive any data. So stall both bulk pipes |
| 1670 | * if we can and wait for a reset. */ | 1685 | * if we can and wait for a reset. |
| 1686 | */ | ||
| 1671 | case DATA_DIR_UNKNOWN: | 1687 | case DATA_DIR_UNKNOWN: |
| 1672 | if (!common->can_stall) { | 1688 | if (!common->can_stall) { |
| 1673 | /* Nothing */ | 1689 | /* Nothing */ |
| @@ -1688,18 +1704,18 @@ static int finish_reply(struct fsg_common *common) | |||
| 1688 | /* If there's no residue, simply send the last buffer */ | 1704 | /* If there's no residue, simply send the last buffer */ |
| 1689 | } else if (common->residue == 0) { | 1705 | } else if (common->residue == 0) { |
| 1690 | bh->inreq->zero = 0; | 1706 | bh->inreq->zero = 0; |
| 1691 | START_TRANSFER_OR(common, bulk_in, bh->inreq, | 1707 | if (!start_in_transfer(common, bh)) |
| 1692 | &bh->inreq_busy, &bh->state) | ||
| 1693 | return -EIO; | 1708 | return -EIO; |
| 1694 | common->next_buffhd_to_fill = bh->next; | 1709 | common->next_buffhd_to_fill = bh->next; |
| 1695 | 1710 | ||
| 1696 | /* For Bulk-only, if we're allowed to stall then send the | 1711 | /* |
| 1712 | * For Bulk-only, if we're allowed to stall then send the | ||
| 1697 | * short packet and halt the bulk-in endpoint. If we can't | 1713 | * short packet and halt the bulk-in endpoint. If we can't |
| 1698 | * stall, pad out the remaining data with 0's. */ | 1714 | * stall, pad out the remaining data with 0's. |
| 1715 | */ | ||
| 1699 | } else if (common->can_stall) { | 1716 | } else if (common->can_stall) { |
| 1700 | bh->inreq->zero = 1; | 1717 | bh->inreq->zero = 1; |
| 1701 | START_TRANSFER_OR(common, bulk_in, bh->inreq, | 1718 | if (!start_in_transfer(common, bh)) |
| 1702 | &bh->inreq_busy, &bh->state) | ||
| 1703 | /* Don't know what to do if | 1719 | /* Don't know what to do if |
| 1704 | * common->fsg is NULL */ | 1720 | * common->fsg is NULL */ |
| 1705 | rc = -EIO; | 1721 | rc = -EIO; |
| @@ -1714,8 +1730,10 @@ static int finish_reply(struct fsg_common *common) | |||
| 1714 | } | 1730 | } |
| 1715 | break; | 1731 | break; |
| 1716 | 1732 | ||
| 1717 | /* We have processed all we want from the data the host has sent. | 1733 | /* |
| 1718 | * There may still be outstanding bulk-out requests. */ | 1734 | * We have processed all we want from the data the host has sent. |
| 1735 | * There may still be outstanding bulk-out requests. | ||
| 1736 | */ | ||
| 1719 | case DATA_DIR_FROM_HOST: | 1737 | case DATA_DIR_FROM_HOST: |
| 1720 | if (common->residue == 0) { | 1738 | if (common->residue == 0) { |
| 1721 | /* Nothing to receive */ | 1739 | /* Nothing to receive */ |
| @@ -1725,12 +1743,14 @@ static int finish_reply(struct fsg_common *common) | |||
| 1725 | raise_exception(common, FSG_STATE_ABORT_BULK_OUT); | 1743 | raise_exception(common, FSG_STATE_ABORT_BULK_OUT); |
| 1726 | rc = -EINTR; | 1744 | rc = -EINTR; |
| 1727 | 1745 | ||
| 1728 | /* We haven't processed all the incoming data. Even though | 1746 | /* |
| 1747 | * We haven't processed all the incoming data. Even though | ||
| 1729 | * we may be allowed to stall, doing so would cause a race. | 1748 | * we may be allowed to stall, doing so would cause a race. |
| 1730 | * The controller may already have ACK'ed all the remaining | 1749 | * The controller may already have ACK'ed all the remaining |
| 1731 | * bulk-out packets, in which case the host wouldn't see a | 1750 | * bulk-out packets, in which case the host wouldn't see a |
| 1732 | * STALL. Not realizing the endpoint was halted, it wouldn't | 1751 | * STALL. Not realizing the endpoint was halted, it wouldn't |
| 1733 | * clear the halt -- leading to problems later on. */ | 1752 | * clear the halt -- leading to problems later on. |
| 1753 | */ | ||
| 1734 | #if 0 | 1754 | #if 0 |
| 1735 | } else if (common->can_stall) { | 1755 | } else if (common->can_stall) { |
| 1736 | if (fsg_is_set(common)) | 1756 | if (fsg_is_set(common)) |
| @@ -1740,8 +1760,10 @@ static int finish_reply(struct fsg_common *common) | |||
| 1740 | rc = -EINTR; | 1760 | rc = -EINTR; |
| 1741 | #endif | 1761 | #endif |
| 1742 | 1762 | ||
| 1743 | /* We can't stall. Read in the excess data and throw it | 1763 | /* |
| 1744 | * all away. */ | 1764 | * We can't stall. Read in the excess data and throw it |
| 1765 | * all away. | ||
| 1766 | */ | ||
| 1745 | } else { | 1767 | } else { |
| 1746 | rc = throw_away_data(common); | 1768 | rc = throw_away_data(common); |
| 1747 | } | 1769 | } |
| @@ -1750,7 +1772,6 @@ static int finish_reply(struct fsg_common *common) | |||
| 1750 | return rc; | 1772 | return rc; |
| 1751 | } | 1773 | } |
| 1752 | 1774 | ||
| 1753 | |||
| 1754 | static int send_status(struct fsg_common *common) | 1775 | static int send_status(struct fsg_common *common) |
| 1755 | { | 1776 | { |
| 1756 | struct fsg_lun *curlun = common->curlun; | 1777 | struct fsg_lun *curlun = common->curlun; |
| @@ -1798,8 +1819,7 @@ static int send_status(struct fsg_common *common) | |||
| 1798 | 1819 | ||
| 1799 | bh->inreq->length = USB_BULK_CS_WRAP_LEN; | 1820 | bh->inreq->length = USB_BULK_CS_WRAP_LEN; |
| 1800 | bh->inreq->zero = 0; | 1821 | bh->inreq->zero = 0; |
| 1801 | START_TRANSFER_OR(common, bulk_in, bh->inreq, | 1822 | if (!start_in_transfer(common, bh)) |
| 1802 | &bh->inreq_busy, &bh->state) | ||
| 1803 | /* Don't know what to do if common->fsg is NULL */ | 1823 | /* Don't know what to do if common->fsg is NULL */ |
| 1804 | return -EIO; | 1824 | return -EIO; |
| 1805 | 1825 | ||
| @@ -1810,11 +1830,13 @@ static int send_status(struct fsg_common *common) | |||
| 1810 | 1830 | ||
| 1811 | /*-------------------------------------------------------------------------*/ | 1831 | /*-------------------------------------------------------------------------*/ |
| 1812 | 1832 | ||
| 1813 | /* Check whether the command is properly formed and whether its data size | 1833 | /* |
| 1814 | * and direction agree with the values we already have. */ | 1834 | * Check whether the command is properly formed and whether its data size |
| 1835 | * and direction agree with the values we already have. | ||
| 1836 | */ | ||
| 1815 | static int check_command(struct fsg_common *common, int cmnd_size, | 1837 | static int check_command(struct fsg_common *common, int cmnd_size, |
| 1816 | enum data_direction data_dir, unsigned int mask, | 1838 | enum data_direction data_dir, unsigned int mask, |
| 1817 | int needs_medium, const char *name) | 1839 | int needs_medium, const char *name) |
| 1818 | { | 1840 | { |
| 1819 | int i; | 1841 | int i; |
| 1820 | int lun = common->cmnd[1] >> 5; | 1842 | int lun = common->cmnd[1] >> 5; |
| @@ -1825,19 +1847,23 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
| 1825 | hdlen[0] = 0; | 1847 | hdlen[0] = 0; |
| 1826 | if (common->data_dir != DATA_DIR_UNKNOWN) | 1848 | if (common->data_dir != DATA_DIR_UNKNOWN) |
| 1827 | sprintf(hdlen, ", H%c=%u", dirletter[(int) common->data_dir], | 1849 | sprintf(hdlen, ", H%c=%u", dirletter[(int) common->data_dir], |
| 1828 | common->data_size); | 1850 | common->data_size); |
| 1829 | VDBG(common, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n", | 1851 | VDBG(common, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n", |
| 1830 | name, cmnd_size, dirletter[(int) data_dir], | 1852 | name, cmnd_size, dirletter[(int) data_dir], |
| 1831 | common->data_size_from_cmnd, common->cmnd_size, hdlen); | 1853 | common->data_size_from_cmnd, common->cmnd_size, hdlen); |
| 1832 | 1854 | ||
| 1833 | /* We can't reply at all until we know the correct data direction | 1855 | /* |
| 1834 | * and size. */ | 1856 | * We can't reply at all until we know the correct data direction |
| 1857 | * and size. | ||
| 1858 | */ | ||
| 1835 | if (common->data_size_from_cmnd == 0) | 1859 | if (common->data_size_from_cmnd == 0) |
| 1836 | data_dir = DATA_DIR_NONE; | 1860 | data_dir = DATA_DIR_NONE; |
| 1837 | if (common->data_size < common->data_size_from_cmnd) { | 1861 | if (common->data_size < common->data_size_from_cmnd) { |
| 1838 | /* Host data size < Device data size is a phase error. | 1862 | /* |
| 1863 | * Host data size < Device data size is a phase error. | ||
| 1839 | * Carry out the command, but only transfer as much as | 1864 | * Carry out the command, but only transfer as much as |
| 1840 | * we are allowed. */ | 1865 | * we are allowed. |
| 1866 | */ | ||
| 1841 | common->data_size_from_cmnd = common->data_size; | 1867 | common->data_size_from_cmnd = common->data_size; |
| 1842 | common->phase_error = 1; | 1868 | common->phase_error = 1; |
| 1843 | } | 1869 | } |
| @@ -1845,8 +1871,7 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
| 1845 | common->usb_amount_left = common->data_size; | 1871 | common->usb_amount_left = common->data_size; |
| 1846 | 1872 | ||
| 1847 | /* Conflicting data directions is a phase error */ | 1873 | /* Conflicting data directions is a phase error */ |
| 1848 | if (common->data_dir != data_dir | 1874 | if (common->data_dir != data_dir && common->data_size_from_cmnd > 0) { |
| 1849 | && common->data_size_from_cmnd > 0) { | ||
| 1850 | common->phase_error = 1; | 1875 | common->phase_error = 1; |
| 1851 | return -EINVAL; | 1876 | return -EINVAL; |
| 1852 | } | 1877 | } |
| @@ -1854,7 +1879,8 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
| 1854 | /* Verify the length of the command itself */ | 1879 | /* Verify the length of the command itself */ |
| 1855 | if (cmnd_size != common->cmnd_size) { | 1880 | if (cmnd_size != common->cmnd_size) { |
| 1856 | 1881 | ||
| 1857 | /* Special case workaround: There are plenty of buggy SCSI | 1882 | /* |
| 1883 | * Special case workaround: There are plenty of buggy SCSI | ||
| 1858 | * implementations. Many have issues with cbw->Length | 1884 | * implementations. Many have issues with cbw->Length |
| 1859 | * field passing a wrong command size. For those cases we | 1885 | * field passing a wrong command size. For those cases we |
| 1860 | * always try to work around the problem by using the length | 1886 | * always try to work around the problem by using the length |
| @@ -1896,8 +1922,10 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
| 1896 | curlun = NULL; | 1922 | curlun = NULL; |
| 1897 | common->bad_lun_okay = 0; | 1923 | common->bad_lun_okay = 0; |
| 1898 | 1924 | ||
| 1899 | /* INQUIRY and REQUEST SENSE commands are explicitly allowed | 1925 | /* |
| 1900 | * to use unsupported LUNs; all others may not. */ | 1926 | * INQUIRY and REQUEST SENSE commands are explicitly allowed |
| 1927 | * to use unsupported LUNs; all others may not. | ||
| 1928 | */ | ||
| 1901 | if (common->cmnd[0] != INQUIRY && | 1929 | if (common->cmnd[0] != INQUIRY && |
| 1902 | common->cmnd[0] != REQUEST_SENSE) { | 1930 | common->cmnd[0] != REQUEST_SENSE) { |
| 1903 | DBG(common, "unsupported LUN %d\n", common->lun); | 1931 | DBG(common, "unsupported LUN %d\n", common->lun); |
| @@ -1905,11 +1933,13 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
| 1905 | } | 1933 | } |
| 1906 | } | 1934 | } |
| 1907 | 1935 | ||
| 1908 | /* If a unit attention condition exists, only INQUIRY and | 1936 | /* |
| 1909 | * REQUEST SENSE commands are allowed; anything else must fail. */ | 1937 | * If a unit attention condition exists, only INQUIRY and |
| 1938 | * REQUEST SENSE commands are allowed; anything else must fail. | ||
| 1939 | */ | ||
| 1910 | if (curlun && curlun->unit_attention_data != SS_NO_SENSE && | 1940 | if (curlun && curlun->unit_attention_data != SS_NO_SENSE && |
| 1911 | common->cmnd[0] != INQUIRY && | 1941 | common->cmnd[0] != INQUIRY && |
| 1912 | common->cmnd[0] != REQUEST_SENSE) { | 1942 | common->cmnd[0] != REQUEST_SENSE) { |
| 1913 | curlun->sense_data = curlun->unit_attention_data; | 1943 | curlun->sense_data = curlun->unit_attention_data; |
| 1914 | curlun->unit_attention_data = SS_NO_SENSE; | 1944 | curlun->unit_attention_data = SS_NO_SENSE; |
| 1915 | return -EINVAL; | 1945 | return -EINVAL; |
| @@ -1935,7 +1965,6 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
| 1935 | return 0; | 1965 | return 0; |
| 1936 | } | 1966 | } |
| 1937 | 1967 | ||
| 1938 | |||
| 1939 | static int do_scsi_command(struct fsg_common *common) | 1968 | static int do_scsi_command(struct fsg_common *common) |
| 1940 | { | 1969 | { |
| 1941 | struct fsg_buffhd *bh; | 1970 | struct fsg_buffhd *bh; |
| @@ -2123,8 +2152,10 @@ static int do_scsi_command(struct fsg_common *common) | |||
| 2123 | "TEST UNIT READY"); | 2152 | "TEST UNIT READY"); |
| 2124 | break; | 2153 | break; |
| 2125 | 2154 | ||
| 2126 | /* Although optional, this command is used by MS-Windows. We | 2155 | /* |
| 2127 | * support a minimal version: BytChk must be 0. */ | 2156 | * Although optional, this command is used by MS-Windows. We |
| 2157 | * support a minimal version: BytChk must be 0. | ||
| 2158 | */ | ||
| 2128 | case VERIFY: | 2159 | case VERIFY: |
| 2129 | common->data_size_from_cmnd = 0; | 2160 | common->data_size_from_cmnd = 0; |
| 2130 | reply = check_command(common, 10, DATA_DIR_NONE, | 2161 | reply = check_command(common, 10, DATA_DIR_NONE, |
| @@ -2164,10 +2195,12 @@ static int do_scsi_command(struct fsg_common *common) | |||
| 2164 | reply = do_write(common); | 2195 | reply = do_write(common); |
| 2165 | break; | 2196 | break; |
| 2166 | 2197 | ||
| 2167 | /* Some mandatory commands that we recognize but don't implement. | 2198 | /* |
| 2199 | * Some mandatory commands that we recognize but don't implement. | ||
| 2168 | * They don't mean much in this setting. It's left as an exercise | 2200 | * They don't mean much in this setting. It's left as an exercise |
| 2169 | * for anyone interested to implement RESERVE and RELEASE in terms | 2201 | * for anyone interested to implement RESERVE and RELEASE in terms |
| 2170 | * of Posix locks. */ | 2202 | * of Posix locks. |
| 2203 | */ | ||
| 2171 | case FORMAT_UNIT: | 2204 | case FORMAT_UNIT: |
| 2172 | case RELEASE: | 2205 | case RELEASE: |
| 2173 | case RESERVE: | 2206 | case RESERVE: |
| @@ -2195,7 +2228,7 @@ unknown_cmnd: | |||
| 2195 | if (reply == -EINVAL) | 2228 | if (reply == -EINVAL) |
| 2196 | reply = 0; /* Error reply length */ | 2229 | reply = 0; /* Error reply length */ |
| 2197 | if (reply >= 0 && common->data_dir == DATA_DIR_TO_HOST) { | 2230 | if (reply >= 0 && common->data_dir == DATA_DIR_TO_HOST) { |
| 2198 | reply = min((u32) reply, common->data_size_from_cmnd); | 2231 | reply = min((u32)reply, common->data_size_from_cmnd); |
| 2199 | bh->inreq->length = reply; | 2232 | bh->inreq->length = reply; |
| 2200 | bh->state = BUF_STATE_FULL; | 2233 | bh->state = BUF_STATE_FULL; |
| 2201 | common->residue -= reply; | 2234 | common->residue -= reply; |
| @@ -2225,7 +2258,8 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2225 | req->actual, | 2258 | req->actual, |
| 2226 | le32_to_cpu(cbw->Signature)); | 2259 | le32_to_cpu(cbw->Signature)); |
| 2227 | 2260 | ||
| 2228 | /* The Bulk-only spec says we MUST stall the IN endpoint | 2261 | /* |
| 2262 | * The Bulk-only spec says we MUST stall the IN endpoint | ||
| 2229 | * (6.6.1), so it's unavoidable. It also says we must | 2263 | * (6.6.1), so it's unavoidable. It also says we must |
| 2230 | * retain this state until the next reset, but there's | 2264 | * retain this state until the next reset, but there's |
| 2231 | * no way to tell the controller driver it should ignore | 2265 | * no way to tell the controller driver it should ignore |
| @@ -2233,7 +2267,8 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2233 | * | 2267 | * |
| 2234 | * We aren't required to halt the OUT endpoint; instead | 2268 | * We aren't required to halt the OUT endpoint; instead |
| 2235 | * we can simply accept and discard any data received | 2269 | * we can simply accept and discard any data received |
| 2236 | * until the next reset. */ | 2270 | * until the next reset. |
| 2271 | */ | ||
| 2237 | wedge_bulk_in_endpoint(fsg); | 2272 | wedge_bulk_in_endpoint(fsg); |
| 2238 | set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); | 2273 | set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); |
| 2239 | return -EINVAL; | 2274 | return -EINVAL; |
| @@ -2246,8 +2281,10 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2246 | "cmdlen %u\n", | 2281 | "cmdlen %u\n", |
| 2247 | cbw->Lun, cbw->Flags, cbw->Length); | 2282 | cbw->Lun, cbw->Flags, cbw->Length); |
| 2248 | 2283 | ||
| 2249 | /* We can do anything we want here, so let's stall the | 2284 | /* |
| 2250 | * bulk pipes if we are allowed to. */ | 2285 | * We can do anything we want here, so let's stall the |
| 2286 | * bulk pipes if we are allowed to. | ||
| 2287 | */ | ||
| 2251 | if (common->can_stall) { | 2288 | if (common->can_stall) { |
| 2252 | fsg_set_halt(fsg, fsg->bulk_out); | 2289 | fsg_set_halt(fsg, fsg->bulk_out); |
| 2253 | halt_bulk_in_endpoint(fsg); | 2290 | halt_bulk_in_endpoint(fsg); |
| @@ -2270,7 +2307,6 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 2270 | return 0; | 2307 | return 0; |
| 2271 | } | 2308 | } |
| 2272 | 2309 | ||
| 2273 | |||
| 2274 | static int get_next_command(struct fsg_common *common) | 2310 | static int get_next_command(struct fsg_common *common) |
| 2275 | { | 2311 | { |
| 2276 | struct fsg_buffhd *bh; | 2312 | struct fsg_buffhd *bh; |
| @@ -2287,14 +2323,15 @@ static int get_next_command(struct fsg_common *common) | |||
| 2287 | /* Queue a request to read a Bulk-only CBW */ | 2323 | /* Queue a request to read a Bulk-only CBW */ |
| 2288 | set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN); | 2324 | set_bulk_out_req_length(common, bh, USB_BULK_CB_WRAP_LEN); |
| 2289 | bh->outreq->short_not_ok = 1; | 2325 | bh->outreq->short_not_ok = 1; |
| 2290 | START_TRANSFER_OR(common, bulk_out, bh->outreq, | 2326 | if (!start_out_transfer(common, bh)) |
| 2291 | &bh->outreq_busy, &bh->state) | ||
| 2292 | /* Don't know what to do if common->fsg is NULL */ | 2327 | /* Don't know what to do if common->fsg is NULL */ |
| 2293 | return -EIO; | 2328 | return -EIO; |
| 2294 | 2329 | ||
| 2295 | /* We will drain the buffer in software, which means we | 2330 | /* |
| 2331 | * We will drain the buffer in software, which means we | ||
| 2296 | * can reuse it for the next filling. No need to advance | 2332 | * can reuse it for the next filling. No need to advance |
| 2297 | * next_buffhd_to_fill. */ | 2333 | * next_buffhd_to_fill. |
| 2334 | */ | ||
| 2298 | 2335 | ||
| 2299 | /* Wait for the CBW to arrive */ | 2336 | /* Wait for the CBW to arrive */ |
| 2300 | while (bh->state != BUF_STATE_FULL) { | 2337 | while (bh->state != BUF_STATE_FULL) { |
| @@ -2425,7 +2462,6 @@ reset: | |||
| 2425 | 2462 | ||
| 2426 | /****************************** ALT CONFIGS ******************************/ | 2463 | /****************************** ALT CONFIGS ******************************/ |
| 2427 | 2464 | ||
| 2428 | |||
| 2429 | static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | 2465 | static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) |
| 2430 | { | 2466 | { |
| 2431 | struct fsg_dev *fsg = fsg_from_func(f); | 2467 | struct fsg_dev *fsg = fsg_from_func(f); |
| @@ -2453,8 +2489,10 @@ static void handle_exception(struct fsg_common *common) | |||
| 2453 | struct fsg_lun *curlun; | 2489 | struct fsg_lun *curlun; |
| 2454 | unsigned int exception_req_tag; | 2490 | unsigned int exception_req_tag; |
| 2455 | 2491 | ||
| 2456 | /* Clear the existing signals. Anything but SIGUSR1 is converted | 2492 | /* |
| 2457 | * into a high-priority EXIT exception. */ | 2493 | * Clear the existing signals. Anything but SIGUSR1 is converted |
| 2494 | * into a high-priority EXIT exception. | ||
| 2495 | */ | ||
| 2458 | for (;;) { | 2496 | for (;;) { |
| 2459 | int sig = | 2497 | int sig = |
| 2460 | dequeue_signal_lock(current, ¤t->blocked, &info); | 2498 | dequeue_signal_lock(current, ¤t->blocked, &info); |
| @@ -2498,8 +2536,10 @@ static void handle_exception(struct fsg_common *common) | |||
| 2498 | usb_ep_fifo_flush(common->fsg->bulk_out); | 2536 | usb_ep_fifo_flush(common->fsg->bulk_out); |
| 2499 | } | 2537 | } |
| 2500 | 2538 | ||
| 2501 | /* Reset the I/O buffer states and pointers, the SCSI | 2539 | /* |
| 2502 | * state, and the exception. Then invoke the handler. */ | 2540 | * Reset the I/O buffer states and pointers, the SCSI |
| 2541 | * state, and the exception. Then invoke the handler. | ||
| 2542 | */ | ||
| 2503 | spin_lock_irq(&common->lock); | 2543 | spin_lock_irq(&common->lock); |
| 2504 | 2544 | ||
| 2505 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { | 2545 | for (i = 0; i < FSG_NUM_BUFFERS; ++i) { |
| @@ -2537,9 +2577,11 @@ static void handle_exception(struct fsg_common *common) | |||
| 2537 | break; | 2577 | break; |
| 2538 | 2578 | ||
| 2539 | case FSG_STATE_RESET: | 2579 | case FSG_STATE_RESET: |
| 2540 | /* In case we were forced against our will to halt a | 2580 | /* |
| 2581 | * In case we were forced against our will to halt a | ||
| 2541 | * bulk endpoint, clear the halt now. (The SuperH UDC | 2582 | * bulk endpoint, clear the halt now. (The SuperH UDC |
| 2542 | * requires this.) */ | 2583 | * requires this.) |
| 2584 | */ | ||
| 2543 | if (!fsg_is_set(common)) | 2585 | if (!fsg_is_set(common)) |
| 2544 | break; | 2586 | break; |
| 2545 | if (test_and_clear_bit(IGNORE_BULK_OUT, | 2587 | if (test_and_clear_bit(IGNORE_BULK_OUT, |
| @@ -2549,9 +2591,11 @@ static void handle_exception(struct fsg_common *common) | |||
| 2549 | if (common->ep0_req_tag == exception_req_tag) | 2591 | if (common->ep0_req_tag == exception_req_tag) |
| 2550 | ep0_queue(common); /* Complete the status stage */ | 2592 | ep0_queue(common); /* Complete the status stage */ |
| 2551 | 2593 | ||
| 2552 | /* Technically this should go here, but it would only be | 2594 | /* |
| 2595 | * Technically this should go here, but it would only be | ||
| 2553 | * a waste of time. Ditto for the INTERFACE_CHANGE and | 2596 | * a waste of time. Ditto for the INTERFACE_CHANGE and |
| 2554 | * CONFIG_CHANGE cases. */ | 2597 | * CONFIG_CHANGE cases. |
| 2598 | */ | ||
| 2555 | /* for (i = 0; i < common->nluns; ++i) */ | 2599 | /* for (i = 0; i < common->nluns; ++i) */ |
| 2556 | /* common->luns[i].unit_attention_data = */ | 2600 | /* common->luns[i].unit_attention_data = */ |
| 2557 | /* SS_RESET_OCCURRED; */ | 2601 | /* SS_RESET_OCCURRED; */ |
| @@ -2586,8 +2630,10 @@ static int fsg_main_thread(void *common_) | |||
| 2586 | { | 2630 | { |
| 2587 | struct fsg_common *common = common_; | 2631 | struct fsg_common *common = common_; |
| 2588 | 2632 | ||
| 2589 | /* Allow the thread to be killed by a signal, but set the signal mask | 2633 | /* |
| 2590 | * to block everything but INT, TERM, KILL, and USR1. */ | 2634 | * Allow the thread to be killed by a signal, but set the signal mask |
| 2635 | * to block everything but INT, TERM, KILL, and USR1. | ||
| 2636 | */ | ||
| 2591 | allow_signal(SIGINT); | 2637 | allow_signal(SIGINT); |
| 2592 | allow_signal(SIGTERM); | 2638 | allow_signal(SIGTERM); |
| 2593 | allow_signal(SIGKILL); | 2639 | allow_signal(SIGKILL); |
| @@ -2596,9 +2642,11 @@ static int fsg_main_thread(void *common_) | |||
| 2596 | /* Allow the thread to be frozen */ | 2642 | /* Allow the thread to be frozen */ |
| 2597 | set_freezable(); | 2643 | set_freezable(); |
| 2598 | 2644 | ||
| 2599 | /* Arrange for userspace references to be interpreted as kernel | 2645 | /* |
| 2646 | * Arrange for userspace references to be interpreted as kernel | ||
| 2600 | * pointers. That way we can pass a kernel pointer to a routine | 2647 | * pointers. That way we can pass a kernel pointer to a routine |
| 2601 | * that expects a __user pointer and it will work okay. */ | 2648 | * that expects a __user pointer and it will work okay. |
| 2649 | */ | ||
| 2602 | set_fs(get_ds()); | 2650 | set_fs(get_ds()); |
| 2603 | 2651 | ||
| 2604 | /* The main loop */ | 2652 | /* The main loop */ |
| @@ -2658,7 +2706,7 @@ static int fsg_main_thread(void *common_) | |||
| 2658 | up_write(&common->filesem); | 2706 | up_write(&common->filesem); |
| 2659 | } | 2707 | } |
| 2660 | 2708 | ||
| 2661 | /* Let the unbind and cleanup routines know the thread has exited */ | 2709 | /* Let fsg_unbind() know the thread has exited */ |
| 2662 | complete_and_exit(&common->thread_notifier, 0); | 2710 | complete_and_exit(&common->thread_notifier, 0); |
| 2663 | } | 2711 | } |
| 2664 | 2712 | ||
| @@ -2690,7 +2738,6 @@ static inline void fsg_common_put(struct fsg_common *common) | |||
| 2690 | kref_put(&common->ref, fsg_common_release); | 2738 | kref_put(&common->ref, fsg_common_release); |
| 2691 | } | 2739 | } |
| 2692 | 2740 | ||
| 2693 | |||
| 2694 | static struct fsg_common *fsg_common_init(struct fsg_common *common, | 2741 | static struct fsg_common *fsg_common_init(struct fsg_common *common, |
| 2695 | struct usb_composite_dev *cdev, | 2742 | struct usb_composite_dev *cdev, |
| 2696 | struct fsg_config *cfg) | 2743 | struct fsg_config *cfg) |
| @@ -2736,8 +2783,10 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
| 2736 | fsg_intf_desc.iInterface = rc; | 2783 | fsg_intf_desc.iInterface = rc; |
| 2737 | } | 2784 | } |
| 2738 | 2785 | ||
| 2739 | /* Create the LUNs, open their backing files, and register the | 2786 | /* |
| 2740 | * LUN devices in sysfs. */ | 2787 | * Create the LUNs, open their backing files, and register the |
| 2788 | * LUN devices in sysfs. | ||
| 2789 | */ | ||
| 2741 | curlun = kzalloc(nluns * sizeof *curlun, GFP_KERNEL); | 2790 | curlun = kzalloc(nluns * sizeof *curlun, GFP_KERNEL); |
| 2742 | if (unlikely(!curlun)) { | 2791 | if (unlikely(!curlun)) { |
| 2743 | rc = -ENOMEM; | 2792 | rc = -ENOMEM; |
| @@ -2765,6 +2814,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
| 2765 | if (rc) { | 2814 | if (rc) { |
| 2766 | INFO(common, "failed to register LUN%d: %d\n", i, rc); | 2815 | INFO(common, "failed to register LUN%d: %d\n", i, rc); |
| 2767 | common->nluns = i; | 2816 | common->nluns = i; |
| 2817 | put_device(&curlun->dev); | ||
| 2768 | goto error_release; | 2818 | goto error_release; |
| 2769 | } | 2819 | } |
| 2770 | 2820 | ||
| @@ -2790,7 +2840,6 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
| 2790 | } | 2840 | } |
| 2791 | common->nluns = nluns; | 2841 | common->nluns = nluns; |
| 2792 | 2842 | ||
| 2793 | |||
| 2794 | /* Data buffers cyclic list */ | 2843 | /* Data buffers cyclic list */ |
| 2795 | bh = common->buffhds; | 2844 | bh = common->buffhds; |
| 2796 | i = FSG_NUM_BUFFERS; | 2845 | i = FSG_NUM_BUFFERS; |
| @@ -2807,7 +2856,6 @@ buffhds_first_it: | |||
| 2807 | } while (--i); | 2856 | } while (--i); |
| 2808 | bh->next = common->buffhds; | 2857 | bh->next = common->buffhds; |
| 2809 | 2858 | ||
| 2810 | |||
| 2811 | /* Prepare inquiryString */ | 2859 | /* Prepare inquiryString */ |
| 2812 | if (cfg->release != 0xffff) { | 2860 | if (cfg->release != 0xffff) { |
| 2813 | i = cfg->release; | 2861 | i = cfg->release; |
| @@ -2821,41 +2869,35 @@ buffhds_first_it: | |||
| 2821 | i = 0x0399; | 2869 | i = 0x0399; |
| 2822 | } | 2870 | } |
| 2823 | } | 2871 | } |
| 2824 | #define OR(x, y) ((x) ? (x) : (y)) | ||
| 2825 | snprintf(common->inquiry_string, sizeof common->inquiry_string, | 2872 | snprintf(common->inquiry_string, sizeof common->inquiry_string, |
| 2826 | "%-8s%-16s%04x", | 2873 | "%-8s%-16s%04x", cfg->vendor_name ?: "Linux", |
| 2827 | OR(cfg->vendor_name, "Linux "), | ||
| 2828 | /* Assume product name dependent on the first LUN */ | 2874 | /* Assume product name dependent on the first LUN */ |
| 2829 | OR(cfg->product_name, common->luns->cdrom | 2875 | cfg->product_name ?: (common->luns->cdrom |
| 2830 | ? "File-Stor Gadget" | 2876 | ? "File-Stor Gadget" |
| 2831 | : "File-CD Gadget "), | 2877 | : "File-CD Gadget"), |
| 2832 | i); | 2878 | i); |
| 2833 | 2879 | ||
| 2834 | 2880 | /* | |
| 2835 | /* Some peripheral controllers are known not to be able to | 2881 | * Some peripheral controllers are known not to be able to |
| 2836 | * halt bulk endpoints correctly. If one of them is present, | 2882 | * halt bulk endpoints correctly. If one of them is present, |
| 2837 | * disable stalls. | 2883 | * disable stalls. |
| 2838 | */ | 2884 | */ |
| 2839 | common->can_stall = cfg->can_stall && | 2885 | common->can_stall = cfg->can_stall && |
| 2840 | !(gadget_is_at91(common->gadget)); | 2886 | !(gadget_is_at91(common->gadget)); |
| 2841 | 2887 | ||
| 2842 | |||
| 2843 | spin_lock_init(&common->lock); | 2888 | spin_lock_init(&common->lock); |
| 2844 | kref_init(&common->ref); | 2889 | kref_init(&common->ref); |
| 2845 | 2890 | ||
| 2846 | |||
| 2847 | /* Tell the thread to start working */ | 2891 | /* Tell the thread to start working */ |
| 2848 | common->thread_task = | 2892 | common->thread_task = |
| 2849 | kthread_create(fsg_main_thread, common, | 2893 | kthread_create(fsg_main_thread, common, |
| 2850 | OR(cfg->thread_name, "file-storage")); | 2894 | cfg->thread_name ?: "file-storage"); |
| 2851 | if (IS_ERR(common->thread_task)) { | 2895 | if (IS_ERR(common->thread_task)) { |
| 2852 | rc = PTR_ERR(common->thread_task); | 2896 | rc = PTR_ERR(common->thread_task); |
| 2853 | goto error_release; | 2897 | goto error_release; |
| 2854 | } | 2898 | } |
| 2855 | init_completion(&common->thread_notifier); | 2899 | init_completion(&common->thread_notifier); |
| 2856 | init_waitqueue_head(&common->fsg_wait); | 2900 | init_waitqueue_head(&common->fsg_wait); |
| 2857 | #undef OR | ||
| 2858 | |||
| 2859 | 2901 | ||
| 2860 | /* Information */ | 2902 | /* Information */ |
| 2861 | INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n"); | 2903 | INFO(common, FSG_DRIVER_DESC ", version: " FSG_DRIVER_VERSION "\n"); |
| @@ -2889,18 +2931,15 @@ buffhds_first_it: | |||
| 2889 | 2931 | ||
| 2890 | return common; | 2932 | return common; |
| 2891 | 2933 | ||
| 2892 | |||
| 2893 | error_luns: | 2934 | error_luns: |
| 2894 | common->nluns = i + 1; | 2935 | common->nluns = i + 1; |
| 2895 | error_release: | 2936 | error_release: |
| 2896 | common->state = FSG_STATE_TERMINATED; /* The thread is dead */ | 2937 | common->state = FSG_STATE_TERMINATED; /* The thread is dead */ |
| 2897 | /* Call fsg_common_release() directly, ref might be not | 2938 | /* Call fsg_common_release() directly, ref might be not initialised. */ |
| 2898 | * initialised */ | ||
| 2899 | fsg_common_release(&common->ref); | 2939 | fsg_common_release(&common->ref); |
| 2900 | return ERR_PTR(rc); | 2940 | return ERR_PTR(rc); |
| 2901 | } | 2941 | } |
| 2902 | 2942 | ||
| 2903 | |||
| 2904 | static void fsg_common_release(struct kref *ref) | 2943 | static void fsg_common_release(struct kref *ref) |
| 2905 | { | 2944 | { |
| 2906 | struct fsg_common *common = container_of(ref, struct fsg_common, ref); | 2945 | struct fsg_common *common = container_of(ref, struct fsg_common, ref); |
| @@ -2909,9 +2948,6 @@ static void fsg_common_release(struct kref *ref) | |||
| 2909 | if (common->state != FSG_STATE_TERMINATED) { | 2948 | if (common->state != FSG_STATE_TERMINATED) { |
| 2910 | raise_exception(common, FSG_STATE_EXIT); | 2949 | raise_exception(common, FSG_STATE_EXIT); |
| 2911 | wait_for_completion(&common->thread_notifier); | 2950 | wait_for_completion(&common->thread_notifier); |
| 2912 | |||
| 2913 | /* The cleanup routine waits for this completion also */ | ||
| 2914 | complete(&common->thread_notifier); | ||
| 2915 | } | 2951 | } |
| 2916 | 2952 | ||
| 2917 | if (likely(common->luns)) { | 2953 | if (likely(common->luns)) { |
| @@ -2945,7 +2981,6 @@ static void fsg_common_release(struct kref *ref) | |||
| 2945 | 2981 | ||
| 2946 | /*-------------------------------------------------------------------------*/ | 2982 | /*-------------------------------------------------------------------------*/ |
| 2947 | 2983 | ||
| 2948 | |||
| 2949 | static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) | 2984 | static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) |
| 2950 | { | 2985 | { |
| 2951 | struct fsg_dev *fsg = fsg_from_func(f); | 2986 | struct fsg_dev *fsg = fsg_from_func(f); |
| @@ -2965,7 +3000,6 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) | |||
| 2965 | kfree(fsg); | 3000 | kfree(fsg); |
| 2966 | } | 3001 | } |
| 2967 | 3002 | ||
| 2968 | |||
| 2969 | static int fsg_bind(struct usb_configuration *c, struct usb_function *f) | 3003 | static int fsg_bind(struct usb_configuration *c, struct usb_function *f) |
| 2970 | { | 3004 | { |
| 2971 | struct fsg_dev *fsg = fsg_from_func(f); | 3005 | struct fsg_dev *fsg = fsg_from_func(f); |
| @@ -3048,11 +3082,13 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, | |||
| 3048 | fsg->function.disable = fsg_disable; | 3082 | fsg->function.disable = fsg_disable; |
| 3049 | 3083 | ||
| 3050 | fsg->common = common; | 3084 | fsg->common = common; |
| 3051 | /* Our caller holds a reference to common structure so we | 3085 | /* |
| 3086 | * Our caller holds a reference to common structure so we | ||
| 3052 | * don't have to be worry about it being freed until we return | 3087 | * don't have to be worry about it being freed until we return |
| 3053 | * from this function. So instead of incrementing counter now | 3088 | * from this function. So instead of incrementing counter now |
| 3054 | * and decrement in error recovery we increment it only when | 3089 | * and decrement in error recovery we increment it only when |
| 3055 | * call to usb_add_function() was successful. */ | 3090 | * call to usb_add_function() was successful. |
| 3091 | */ | ||
| 3056 | 3092 | ||
| 3057 | rc = usb_add_function(c, &fsg->function); | 3093 | rc = usb_add_function(c, &fsg->function); |
| 3058 | if (unlikely(rc)) | 3094 | if (unlikely(rc)) |
| @@ -3063,8 +3099,7 @@ static int fsg_bind_config(struct usb_composite_dev *cdev, | |||
| 3063 | } | 3099 | } |
| 3064 | 3100 | ||
| 3065 | static inline int __deprecated __maybe_unused | 3101 | static inline int __deprecated __maybe_unused |
| 3066 | fsg_add(struct usb_composite_dev *cdev, | 3102 | fsg_add(struct usb_composite_dev *cdev, struct usb_configuration *c, |
| 3067 | struct usb_configuration *c, | ||
| 3068 | struct fsg_common *common) | 3103 | struct fsg_common *common) |
| 3069 | { | 3104 | { |
| 3070 | return fsg_bind_config(cdev, c, common); | 3105 | return fsg_bind_config(cdev, c, common); |
| @@ -3073,7 +3108,6 @@ fsg_add(struct usb_composite_dev *cdev, | |||
| 3073 | 3108 | ||
| 3074 | /************************* Module parameters *************************/ | 3109 | /************************* Module parameters *************************/ |
| 3075 | 3110 | ||
| 3076 | |||
| 3077 | struct fsg_module_parameters { | 3111 | struct fsg_module_parameters { |
| 3078 | char *file[FSG_MAX_LUNS]; | 3112 | char *file[FSG_MAX_LUNS]; |
| 3079 | int ro[FSG_MAX_LUNS]; | 3113 | int ro[FSG_MAX_LUNS]; |
| @@ -3087,7 +3121,6 @@ struct fsg_module_parameters { | |||
| 3087 | int stall; /* can_stall */ | 3121 | int stall; /* can_stall */ |
| 3088 | }; | 3122 | }; |
| 3089 | 3123 | ||
| 3090 | |||
| 3091 | #define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \ | 3124 | #define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \ |
| 3092 | module_param_array_named(prefix ## name, params.name, type, \ | 3125 | module_param_array_named(prefix ## name, params.name, type, \ |
| 3093 | &prefix ## params.name ## _count, \ | 3126 | &prefix ## params.name ## _count, \ |
| @@ -3115,7 +3148,6 @@ struct fsg_module_parameters { | |||
| 3115 | _FSG_MODULE_PARAM(prefix, params, stall, bool, \ | 3148 | _FSG_MODULE_PARAM(prefix, params, stall, bool, \ |
| 3116 | "false to prevent bulk stalls") | 3149 | "false to prevent bulk stalls") |
| 3117 | 3150 | ||
| 3118 | |||
| 3119 | static void | 3151 | static void |
| 3120 | fsg_config_from_params(struct fsg_config *cfg, | 3152 | fsg_config_from_params(struct fsg_config *cfg, |
| 3121 | const struct fsg_module_parameters *params) | 3153 | const struct fsg_module_parameters *params) |
diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c new file mode 100644 index 000000000000..130eee678c8b --- /dev/null +++ b/drivers/usb/gadget/f_ncm.c | |||
| @@ -0,0 +1,1407 @@ | |||
| 1 | /* | ||
| 2 | * f_ncm.c -- USB CDC Network (NCM) link function driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Nokia Corporation | ||
| 5 | * Contact: Yauheni Kaliuta <yauheni.kaliuta@nokia.com> | ||
| 6 | * | ||
| 7 | * The driver borrows from f_ecm.c which is: | ||
| 8 | * | ||
| 9 | * Copyright (C) 2003-2005,2008 David Brownell | ||
| 10 | * Copyright (C) 2008 Nokia Corporation | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation; either version 2 of the License, or | ||
| 15 | * (at your option) any later version. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | * GNU General Public License for more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public License | ||
| 23 | * along with this program; if not, write to the Free Software | ||
| 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/kernel.h> | ||
| 28 | #include <linux/device.h> | ||
| 29 | #include <linux/etherdevice.h> | ||
| 30 | #include <linux/crc32.h> | ||
| 31 | |||
| 32 | #include <linux/usb/cdc.h> | ||
| 33 | |||
| 34 | #include "u_ether.h" | ||
| 35 | |||
| 36 | /* | ||
| 37 | * This function is a "CDC Network Control Model" (CDC NCM) Ethernet link. | ||
| 38 | * NCM is intended to be used with high-speed network attachments. | ||
| 39 | * | ||
| 40 | * Note that NCM requires the use of "alternate settings" for its data | ||
| 41 | * interface. This means that the set_alt() method has real work to do, | ||
| 42 | * and also means that a get_alt() method is required. | ||
| 43 | */ | ||
| 44 | |||
| 45 | /* to trigger crc/non-crc ndp signature */ | ||
| 46 | |||
| 47 | #define NCM_NDP_HDR_CRC_MASK 0x01000000 | ||
| 48 | #define NCM_NDP_HDR_CRC 0x01000000 | ||
| 49 | #define NCM_NDP_HDR_NOCRC 0x00000000 | ||
| 50 | |||
| 51 | struct ncm_ep_descs { | ||
| 52 | struct usb_endpoint_descriptor *in; | ||
| 53 | struct usb_endpoint_descriptor *out; | ||
| 54 | struct usb_endpoint_descriptor *notify; | ||
| 55 | }; | ||
| 56 | |||
| 57 | enum ncm_notify_state { | ||
| 58 | NCM_NOTIFY_NONE, /* don't notify */ | ||
| 59 | NCM_NOTIFY_CONNECT, /* issue CONNECT next */ | ||
| 60 | NCM_NOTIFY_SPEED, /* issue SPEED_CHANGE next */ | ||
| 61 | }; | ||
| 62 | |||
| 63 | struct f_ncm { | ||
| 64 | struct gether port; | ||
| 65 | u8 ctrl_id, data_id; | ||
| 66 | |||
| 67 | char ethaddr[14]; | ||
| 68 | |||
| 69 | struct ncm_ep_descs fs; | ||
| 70 | struct ncm_ep_descs hs; | ||
| 71 | |||
| 72 | struct usb_ep *notify; | ||
| 73 | struct usb_endpoint_descriptor *notify_desc; | ||
| 74 | struct usb_request *notify_req; | ||
| 75 | u8 notify_state; | ||
| 76 | bool is_open; | ||
| 77 | |||
| 78 | struct ndp_parser_opts *parser_opts; | ||
| 79 | bool is_crc; | ||
| 80 | |||
| 81 | /* | ||
| 82 | * for notification, it is accessed from both | ||
| 83 | * callback and ethernet open/close | ||
| 84 | */ | ||
| 85 | spinlock_t lock; | ||
| 86 | }; | ||
| 87 | |||
| 88 | static inline struct f_ncm *func_to_ncm(struct usb_function *f) | ||
| 89 | { | ||
| 90 | return container_of(f, struct f_ncm, port.func); | ||
| 91 | } | ||
| 92 | |||
| 93 | /* peak (theoretical) bulk transfer rate in bits-per-second */ | ||
| 94 | static inline unsigned ncm_bitrate(struct usb_gadget *g) | ||
| 95 | { | ||
| 96 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
| 97 | return 13 * 512 * 8 * 1000 * 8; | ||
| 98 | else | ||
| 99 | return 19 * 64 * 1 * 1000 * 8; | ||
| 100 | } | ||
| 101 | |||
| 102 | /*-------------------------------------------------------------------------*/ | ||
| 103 | |||
| 104 | /* | ||
| 105 | * We cannot group frames so use just the minimal size which ok to put | ||
| 106 | * one max-size ethernet frame. | ||
| 107 | * If the host can group frames, allow it to do that, 16K is selected, | ||
| 108 | * because it's used by default by the current linux host driver | ||
| 109 | */ | ||
| 110 | #define NTB_DEFAULT_IN_SIZE USB_CDC_NCM_NTB_MIN_IN_SIZE | ||
| 111 | #define NTB_OUT_SIZE 16384 | ||
| 112 | |||
| 113 | /* | ||
| 114 | * skbs of size less than that will not be alligned | ||
| 115 | * to NCM's dwNtbInMaxSize to save bus bandwidth | ||
| 116 | */ | ||
| 117 | |||
| 118 | #define MAX_TX_NONFIXED (512 * 3) | ||
| 119 | |||
| 120 | #define FORMATS_SUPPORTED (USB_CDC_NCM_NTB16_SUPPORTED | \ | ||
| 121 | USB_CDC_NCM_NTB32_SUPPORTED) | ||
| 122 | |||
| 123 | static struct usb_cdc_ncm_ntb_parameters ntb_parameters = { | ||
| 124 | .wLength = sizeof ntb_parameters, | ||
| 125 | .bmNtbFormatsSupported = cpu_to_le16(FORMATS_SUPPORTED), | ||
| 126 | .dwNtbInMaxSize = cpu_to_le32(NTB_DEFAULT_IN_SIZE), | ||
| 127 | .wNdpInDivisor = cpu_to_le16(4), | ||
| 128 | .wNdpInPayloadRemainder = cpu_to_le16(0), | ||
| 129 | .wNdpInAlignment = cpu_to_le16(4), | ||
| 130 | |||
| 131 | .dwNtbOutMaxSize = cpu_to_le32(NTB_OUT_SIZE), | ||
| 132 | .wNdpOutDivisor = cpu_to_le16(4), | ||
| 133 | .wNdpOutPayloadRemainder = cpu_to_le16(0), | ||
| 134 | .wNdpOutAlignment = cpu_to_le16(4), | ||
| 135 | }; | ||
| 136 | |||
| 137 | /* | ||
| 138 | * Use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one | ||
| 139 | * packet, to simplify cancellation; and a big transfer interval, to | ||
| 140 | * waste less bandwidth. | ||
| 141 | */ | ||
| 142 | |||
| 143 | #define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ | ||
| 144 | #define NCM_STATUS_BYTECOUNT 16 /* 8 byte header + data */ | ||
| 145 | |||
| 146 | static struct usb_interface_assoc_descriptor ncm_iad_desc __initdata = { | ||
| 147 | .bLength = sizeof ncm_iad_desc, | ||
| 148 | .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, | ||
| 149 | |||
| 150 | /* .bFirstInterface = DYNAMIC, */ | ||
| 151 | .bInterfaceCount = 2, /* control + data */ | ||
| 152 | .bFunctionClass = USB_CLASS_COMM, | ||
| 153 | .bFunctionSubClass = USB_CDC_SUBCLASS_NCM, | ||
| 154 | .bFunctionProtocol = USB_CDC_PROTO_NONE, | ||
| 155 | /* .iFunction = DYNAMIC */ | ||
| 156 | }; | ||
| 157 | |||
| 158 | /* interface descriptor: */ | ||
| 159 | |||
| 160 | static struct usb_interface_descriptor ncm_control_intf __initdata = { | ||
| 161 | .bLength = sizeof ncm_control_intf, | ||
| 162 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 163 | |||
| 164 | /* .bInterfaceNumber = DYNAMIC */ | ||
| 165 | .bNumEndpoints = 1, | ||
| 166 | .bInterfaceClass = USB_CLASS_COMM, | ||
| 167 | .bInterfaceSubClass = USB_CDC_SUBCLASS_NCM, | ||
| 168 | .bInterfaceProtocol = USB_CDC_PROTO_NONE, | ||
| 169 | /* .iInterface = DYNAMIC */ | ||
| 170 | }; | ||
| 171 | |||
| 172 | static struct usb_cdc_header_desc ncm_header_desc __initdata = { | ||
| 173 | .bLength = sizeof ncm_header_desc, | ||
| 174 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 175 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | ||
| 176 | |||
| 177 | .bcdCDC = cpu_to_le16(0x0110), | ||
| 178 | }; | ||
| 179 | |||
| 180 | static struct usb_cdc_union_desc ncm_union_desc __initdata = { | ||
| 181 | .bLength = sizeof(ncm_union_desc), | ||
| 182 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 183 | .bDescriptorSubType = USB_CDC_UNION_TYPE, | ||
| 184 | /* .bMasterInterface0 = DYNAMIC */ | ||
| 185 | /* .bSlaveInterface0 = DYNAMIC */ | ||
| 186 | }; | ||
| 187 | |||
| 188 | static struct usb_cdc_ether_desc ecm_desc __initdata = { | ||
| 189 | .bLength = sizeof ecm_desc, | ||
| 190 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 191 | .bDescriptorSubType = USB_CDC_ETHERNET_TYPE, | ||
| 192 | |||
| 193 | /* this descriptor actually adds value, surprise! */ | ||
| 194 | /* .iMACAddress = DYNAMIC */ | ||
| 195 | .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */ | ||
| 196 | .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN), | ||
| 197 | .wNumberMCFilters = cpu_to_le16(0), | ||
| 198 | .bNumberPowerFilters = 0, | ||
| 199 | }; | ||
| 200 | |||
| 201 | #define NCAPS (USB_CDC_NCM_NCAP_ETH_FILTER | USB_CDC_NCM_NCAP_CRC_MODE) | ||
| 202 | |||
| 203 | static struct usb_cdc_ncm_desc ncm_desc __initdata = { | ||
| 204 | .bLength = sizeof ncm_desc, | ||
| 205 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
| 206 | .bDescriptorSubType = USB_CDC_NCM_TYPE, | ||
| 207 | |||
| 208 | .bcdNcmVersion = cpu_to_le16(0x0100), | ||
| 209 | /* can process SetEthernetPacketFilter */ | ||
| 210 | .bmNetworkCapabilities = NCAPS, | ||
| 211 | }; | ||
| 212 | |||
| 213 | /* the default data interface has no endpoints ... */ | ||
| 214 | |||
| 215 | static struct usb_interface_descriptor ncm_data_nop_intf __initdata = { | ||
| 216 | .bLength = sizeof ncm_data_nop_intf, | ||
| 217 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 218 | |||
| 219 | .bInterfaceNumber = 1, | ||
| 220 | .bAlternateSetting = 0, | ||
| 221 | .bNumEndpoints = 0, | ||
| 222 | .bInterfaceClass = USB_CLASS_CDC_DATA, | ||
| 223 | .bInterfaceSubClass = 0, | ||
| 224 | .bInterfaceProtocol = USB_CDC_NCM_PROTO_NTB, | ||
| 225 | /* .iInterface = DYNAMIC */ | ||
| 226 | }; | ||
| 227 | |||
| 228 | /* ... but the "real" data interface has two bulk endpoints */ | ||
| 229 | |||
| 230 | static struct usb_interface_descriptor ncm_data_intf __initdata = { | ||
| 231 | .bLength = sizeof ncm_data_intf, | ||
| 232 | .bDescriptorType = USB_DT_INTERFACE, | ||
| 233 | |||
| 234 | .bInterfaceNumber = 1, | ||
| 235 | .bAlternateSetting = 1, | ||
| 236 | .bNumEndpoints = 2, | ||
| 237 | .bInterfaceClass = USB_CLASS_CDC_DATA, | ||
| 238 | .bInterfaceSubClass = 0, | ||
| 239 | .bInterfaceProtocol = USB_CDC_NCM_PROTO_NTB, | ||
| 240 | /* .iInterface = DYNAMIC */ | ||
| 241 | }; | ||
| 242 | |||
| 243 | /* full speed support: */ | ||
| 244 | |||
| 245 | static struct usb_endpoint_descriptor fs_ncm_notify_desc __initdata = { | ||
| 246 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 247 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 248 | |||
| 249 | .bEndpointAddress = USB_DIR_IN, | ||
| 250 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
| 251 | .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT), | ||
| 252 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, | ||
| 253 | }; | ||
| 254 | |||
| 255 | static struct usb_endpoint_descriptor fs_ncm_in_desc __initdata = { | ||
| 256 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 257 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 258 | |||
| 259 | .bEndpointAddress = USB_DIR_IN, | ||
| 260 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 261 | }; | ||
| 262 | |||
| 263 | static struct usb_endpoint_descriptor fs_ncm_out_desc __initdata = { | ||
| 264 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 265 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 266 | |||
| 267 | .bEndpointAddress = USB_DIR_OUT, | ||
| 268 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 269 | }; | ||
| 270 | |||
| 271 | static struct usb_descriptor_header *ncm_fs_function[] __initdata = { | ||
| 272 | (struct usb_descriptor_header *) &ncm_iad_desc, | ||
| 273 | /* CDC NCM control descriptors */ | ||
| 274 | (struct usb_descriptor_header *) &ncm_control_intf, | ||
| 275 | (struct usb_descriptor_header *) &ncm_header_desc, | ||
| 276 | (struct usb_descriptor_header *) &ncm_union_desc, | ||
| 277 | (struct usb_descriptor_header *) &ecm_desc, | ||
| 278 | (struct usb_descriptor_header *) &ncm_desc, | ||
| 279 | (struct usb_descriptor_header *) &fs_ncm_notify_desc, | ||
| 280 | /* data interface, altsettings 0 and 1 */ | ||
| 281 | (struct usb_descriptor_header *) &ncm_data_nop_intf, | ||
| 282 | (struct usb_descriptor_header *) &ncm_data_intf, | ||
| 283 | (struct usb_descriptor_header *) &fs_ncm_in_desc, | ||
| 284 | (struct usb_descriptor_header *) &fs_ncm_out_desc, | ||
| 285 | NULL, | ||
| 286 | }; | ||
| 287 | |||
| 288 | /* high speed support: */ | ||
| 289 | |||
| 290 | static struct usb_endpoint_descriptor hs_ncm_notify_desc __initdata = { | ||
| 291 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 292 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 293 | |||
| 294 | .bEndpointAddress = USB_DIR_IN, | ||
| 295 | .bmAttributes = USB_ENDPOINT_XFER_INT, | ||
| 296 | .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT), | ||
| 297 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, | ||
| 298 | }; | ||
| 299 | static struct usb_endpoint_descriptor hs_ncm_in_desc __initdata = { | ||
| 300 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 301 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 302 | |||
| 303 | .bEndpointAddress = USB_DIR_IN, | ||
| 304 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 305 | .wMaxPacketSize = cpu_to_le16(512), | ||
| 306 | }; | ||
| 307 | |||
| 308 | static struct usb_endpoint_descriptor hs_ncm_out_desc __initdata = { | ||
| 309 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 310 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 311 | |||
| 312 | .bEndpointAddress = USB_DIR_OUT, | ||
| 313 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
| 314 | .wMaxPacketSize = cpu_to_le16(512), | ||
| 315 | }; | ||
| 316 | |||
| 317 | static struct usb_descriptor_header *ncm_hs_function[] __initdata = { | ||
| 318 | (struct usb_descriptor_header *) &ncm_iad_desc, | ||
| 319 | /* CDC NCM control descriptors */ | ||
| 320 | (struct usb_descriptor_header *) &ncm_control_intf, | ||
| 321 | (struct usb_descriptor_header *) &ncm_header_desc, | ||
| 322 | (struct usb_descriptor_header *) &ncm_union_desc, | ||
| 323 | (struct usb_descriptor_header *) &ecm_desc, | ||
| 324 | (struct usb_descriptor_header *) &ncm_desc, | ||
| 325 | (struct usb_descriptor_header *) &hs_ncm_notify_desc, | ||
| 326 | /* data interface, altsettings 0 and 1 */ | ||
| 327 | (struct usb_descriptor_header *) &ncm_data_nop_intf, | ||
| 328 | (struct usb_descriptor_header *) &ncm_data_intf, | ||
| 329 | (struct usb_descriptor_header *) &hs_ncm_in_desc, | ||
| 330 | (struct usb_descriptor_header *) &hs_ncm_out_desc, | ||
| 331 | NULL, | ||
| 332 | }; | ||
| 333 | |||
| 334 | /* string descriptors: */ | ||
| 335 | |||
| 336 | #define STRING_CTRL_IDX 0 | ||
| 337 | #define STRING_MAC_IDX 1 | ||
| 338 | #define STRING_DATA_IDX 2 | ||
| 339 | #define STRING_IAD_IDX 3 | ||
| 340 | |||
| 341 | static struct usb_string ncm_string_defs[] = { | ||
| 342 | [STRING_CTRL_IDX].s = "CDC Network Control Model (NCM)", | ||
| 343 | [STRING_MAC_IDX].s = NULL /* DYNAMIC */, | ||
| 344 | [STRING_DATA_IDX].s = "CDC Network Data", | ||
| 345 | [STRING_IAD_IDX].s = "CDC NCM", | ||
| 346 | { } /* end of list */ | ||
| 347 | }; | ||
| 348 | |||
| 349 | static struct usb_gadget_strings ncm_string_table = { | ||
| 350 | .language = 0x0409, /* en-us */ | ||
| 351 | .strings = ncm_string_defs, | ||
| 352 | }; | ||
| 353 | |||
| 354 | static struct usb_gadget_strings *ncm_strings[] = { | ||
| 355 | &ncm_string_table, | ||
| 356 | NULL, | ||
| 357 | }; | ||
| 358 | |||
| 359 | /* | ||
| 360 | * Here are options for NCM Datagram Pointer table (NDP) parser. | ||
| 361 | * There are 2 different formats: NDP16 and NDP32 in the spec (ch. 3), | ||
| 362 | * in NDP16 offsets and sizes fields are 1 16bit word wide, | ||
| 363 | * in NDP32 -- 2 16bit words wide. Also signatures are different. | ||
| 364 | * To make the parser code the same, put the differences in the structure, | ||
| 365 | * and switch pointers to the structures when the format is changed. | ||
| 366 | */ | ||
| 367 | |||
| 368 | struct ndp_parser_opts { | ||
| 369 | u32 nth_sign; | ||
| 370 | u32 ndp_sign; | ||
| 371 | unsigned nth_size; | ||
| 372 | unsigned ndp_size; | ||
| 373 | unsigned ndplen_align; | ||
| 374 | /* sizes in u16 units */ | ||
| 375 | unsigned dgram_item_len; /* index or length */ | ||
| 376 | unsigned block_length; | ||
| 377 | unsigned fp_index; | ||
| 378 | unsigned reserved1; | ||
| 379 | unsigned reserved2; | ||
| 380 | unsigned next_fp_index; | ||
| 381 | }; | ||
| 382 | |||
| 383 | #define INIT_NDP16_OPTS { \ | ||
| 384 | .nth_sign = USB_CDC_NCM_NTH16_SIGN, \ | ||
| 385 | .ndp_sign = USB_CDC_NCM_NDP16_NOCRC_SIGN, \ | ||
| 386 | .nth_size = sizeof(struct usb_cdc_ncm_nth16), \ | ||
| 387 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp16), \ | ||
| 388 | .ndplen_align = 4, \ | ||
| 389 | .dgram_item_len = 1, \ | ||
| 390 | .block_length = 1, \ | ||
| 391 | .fp_index = 1, \ | ||
| 392 | .reserved1 = 0, \ | ||
| 393 | .reserved2 = 0, \ | ||
| 394 | .next_fp_index = 1, \ | ||
| 395 | } | ||
| 396 | |||
| 397 | |||
| 398 | #define INIT_NDP32_OPTS { \ | ||
| 399 | .nth_sign = USB_CDC_NCM_NTH32_SIGN, \ | ||
| 400 | .ndp_sign = USB_CDC_NCM_NDP32_NOCRC_SIGN, \ | ||
| 401 | .nth_size = sizeof(struct usb_cdc_ncm_nth32), \ | ||
| 402 | .ndp_size = sizeof(struct usb_cdc_ncm_ndp32), \ | ||
| 403 | .ndplen_align = 8, \ | ||
| 404 | .dgram_item_len = 2, \ | ||
| 405 | .block_length = 2, \ | ||
| 406 | .fp_index = 2, \ | ||
| 407 | .reserved1 = 1, \ | ||
| 408 | .reserved2 = 2, \ | ||
| 409 | .next_fp_index = 2, \ | ||
| 410 | } | ||
| 411 | |||
| 412 | static struct ndp_parser_opts ndp16_opts = INIT_NDP16_OPTS; | ||
| 413 | static struct ndp_parser_opts ndp32_opts = INIT_NDP32_OPTS; | ||
| 414 | |||
| 415 | static inline void put_ncm(__le16 **p, unsigned size, unsigned val) | ||
| 416 | { | ||
| 417 | switch (size) { | ||
| 418 | case 1: | ||
| 419 | put_unaligned_le16((u16)val, *p); | ||
| 420 | break; | ||
| 421 | case 2: | ||
| 422 | put_unaligned_le32((u32)val, *p); | ||
| 423 | |||
| 424 | break; | ||
| 425 | default: | ||
| 426 | BUG(); | ||
| 427 | } | ||
| 428 | |||
| 429 | *p += size; | ||
| 430 | } | ||
| 431 | |||
| 432 | static inline unsigned get_ncm(__le16 **p, unsigned size) | ||
| 433 | { | ||
| 434 | unsigned tmp; | ||
| 435 | |||
| 436 | switch (size) { | ||
| 437 | case 1: | ||
| 438 | tmp = get_unaligned_le16(*p); | ||
| 439 | break; | ||
| 440 | case 2: | ||
| 441 | tmp = get_unaligned_le32(*p); | ||
| 442 | break; | ||
| 443 | default: | ||
| 444 | BUG(); | ||
| 445 | } | ||
| 446 | |||
| 447 | *p += size; | ||
| 448 | return tmp; | ||
| 449 | } | ||
| 450 | |||
| 451 | /*-------------------------------------------------------------------------*/ | ||
| 452 | |||
| 453 | static inline void ncm_reset_values(struct f_ncm *ncm) | ||
| 454 | { | ||
| 455 | ncm->parser_opts = &ndp16_opts; | ||
| 456 | ncm->is_crc = false; | ||
| 457 | ncm->port.cdc_filter = DEFAULT_FILTER; | ||
| 458 | |||
| 459 | /* doesn't make sense for ncm, fixed size used */ | ||
| 460 | ncm->port.header_len = 0; | ||
| 461 | |||
| 462 | ncm->port.fixed_out_len = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize); | ||
| 463 | ncm->port.fixed_in_len = NTB_DEFAULT_IN_SIZE; | ||
| 464 | } | ||
| 465 | |||
| 466 | /* | ||
| 467 | * Context: ncm->lock held | ||
| 468 | */ | ||
| 469 | static void ncm_do_notify(struct f_ncm *ncm) | ||
| 470 | { | ||
| 471 | struct usb_request *req = ncm->notify_req; | ||
| 472 | struct usb_cdc_notification *event; | ||
| 473 | struct usb_composite_dev *cdev = ncm->port.func.config->cdev; | ||
| 474 | __le32 *data; | ||
| 475 | int status; | ||
| 476 | |||
| 477 | /* notification already in flight? */ | ||
| 478 | if (!req) | ||
| 479 | return; | ||
| 480 | |||
| 481 | event = req->buf; | ||
| 482 | switch (ncm->notify_state) { | ||
| 483 | case NCM_NOTIFY_NONE: | ||
| 484 | return; | ||
| 485 | |||
| 486 | case NCM_NOTIFY_CONNECT: | ||
| 487 | event->bNotificationType = USB_CDC_NOTIFY_NETWORK_CONNECTION; | ||
| 488 | if (ncm->is_open) | ||
| 489 | event->wValue = cpu_to_le16(1); | ||
| 490 | else | ||
| 491 | event->wValue = cpu_to_le16(0); | ||
| 492 | event->wLength = 0; | ||
| 493 | req->length = sizeof *event; | ||
| 494 | |||
| 495 | DBG(cdev, "notify connect %s\n", | ||
| 496 | ncm->is_open ? "true" : "false"); | ||
| 497 | ncm->notify_state = NCM_NOTIFY_NONE; | ||
| 498 | break; | ||
| 499 | |||
| 500 | case NCM_NOTIFY_SPEED: | ||
| 501 | event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE; | ||
| 502 | event->wValue = cpu_to_le16(0); | ||
| 503 | event->wLength = cpu_to_le16(8); | ||
| 504 | req->length = NCM_STATUS_BYTECOUNT; | ||
| 505 | |||
| 506 | /* SPEED_CHANGE data is up/down speeds in bits/sec */ | ||
| 507 | data = req->buf + sizeof *event; | ||
| 508 | data[0] = cpu_to_le32(ncm_bitrate(cdev->gadget)); | ||
| 509 | data[1] = data[0]; | ||
| 510 | |||
| 511 | DBG(cdev, "notify speed %d\n", ncm_bitrate(cdev->gadget)); | ||
| 512 | ncm->notify_state = NCM_NOTIFY_CONNECT; | ||
| 513 | break; | ||
| 514 | } | ||
| 515 | event->bmRequestType = 0xA1; | ||
| 516 | event->wIndex = cpu_to_le16(ncm->ctrl_id); | ||
| 517 | |||
| 518 | ncm->notify_req = NULL; | ||
| 519 | /* | ||
| 520 | * In double buffering if there is a space in FIFO, | ||
| 521 | * completion callback can be called right after the call, | ||
| 522 | * so unlocking | ||
| 523 | */ | ||
| 524 | spin_unlock(&ncm->lock); | ||
| 525 | status = usb_ep_queue(ncm->notify, req, GFP_ATOMIC); | ||
| 526 | spin_lock(&ncm->lock); | ||
| 527 | if (status < 0) { | ||
| 528 | ncm->notify_req = req; | ||
| 529 | DBG(cdev, "notify --> %d\n", status); | ||
| 530 | } | ||
| 531 | } | ||
| 532 | |||
| 533 | /* | ||
| 534 | * Context: ncm->lock held | ||
| 535 | */ | ||
| 536 | static void ncm_notify(struct f_ncm *ncm) | ||
| 537 | { | ||
| 538 | /* | ||
| 539 | * NOTE on most versions of Linux, host side cdc-ethernet | ||
| 540 | * won't listen for notifications until its netdevice opens. | ||
| 541 | * The first notification then sits in the FIFO for a long | ||
| 542 | * time, and the second one is queued. | ||
| 543 | * | ||
| 544 | * If ncm_notify() is called before the second (CONNECT) | ||
| 545 | * notification is sent, then it will reset to send the SPEED | ||
| 546 | * notificaion again (and again, and again), but it's not a problem | ||
| 547 | */ | ||
| 548 | ncm->notify_state = NCM_NOTIFY_SPEED; | ||
| 549 | ncm_do_notify(ncm); | ||
| 550 | } | ||
| 551 | |||
| 552 | static void ncm_notify_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 553 | { | ||
| 554 | struct f_ncm *ncm = req->context; | ||
| 555 | struct usb_composite_dev *cdev = ncm->port.func.config->cdev; | ||
| 556 | struct usb_cdc_notification *event = req->buf; | ||
| 557 | |||
| 558 | spin_lock(&ncm->lock); | ||
| 559 | switch (req->status) { | ||
| 560 | case 0: | ||
| 561 | VDBG(cdev, "Notification %02x sent\n", | ||
| 562 | event->bNotificationType); | ||
| 563 | break; | ||
| 564 | case -ECONNRESET: | ||
| 565 | case -ESHUTDOWN: | ||
| 566 | ncm->notify_state = NCM_NOTIFY_NONE; | ||
| 567 | break; | ||
| 568 | default: | ||
| 569 | DBG(cdev, "event %02x --> %d\n", | ||
| 570 | event->bNotificationType, req->status); | ||
| 571 | break; | ||
| 572 | } | ||
| 573 | ncm->notify_req = req; | ||
| 574 | ncm_do_notify(ncm); | ||
| 575 | spin_unlock(&ncm->lock); | ||
| 576 | } | ||
| 577 | |||
| 578 | static void ncm_ep0out_complete(struct usb_ep *ep, struct usb_request *req) | ||
| 579 | { | ||
| 580 | /* now for SET_NTB_INPUT_SIZE only */ | ||
| 581 | unsigned in_size; | ||
| 582 | struct usb_function *f = req->context; | ||
| 583 | struct f_ncm *ncm = func_to_ncm(f); | ||
| 584 | struct usb_composite_dev *cdev = ep->driver_data; | ||
| 585 | |||
| 586 | req->context = NULL; | ||
| 587 | if (req->status || req->actual != req->length) { | ||
| 588 | DBG(cdev, "Bad control-OUT transfer\n"); | ||
| 589 | goto invalid; | ||
| 590 | } | ||
| 591 | |||
| 592 | in_size = get_unaligned_le32(req->buf); | ||
| 593 | if (in_size < USB_CDC_NCM_NTB_MIN_IN_SIZE || | ||
| 594 | in_size > le32_to_cpu(ntb_parameters.dwNtbInMaxSize)) { | ||
| 595 | DBG(cdev, "Got wrong INPUT SIZE (%d) from host\n", in_size); | ||
| 596 | goto invalid; | ||
| 597 | } | ||
| 598 | |||
| 599 | ncm->port.fixed_in_len = in_size; | ||
| 600 | VDBG(cdev, "Set NTB INPUT SIZE %d\n", in_size); | ||
| 601 | return; | ||
| 602 | |||
| 603 | invalid: | ||
| 604 | usb_ep_set_halt(ep); | ||
| 605 | return; | ||
| 606 | } | ||
| 607 | |||
| 608 | static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) | ||
| 609 | { | ||
| 610 | struct f_ncm *ncm = func_to_ncm(f); | ||
| 611 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 612 | struct usb_request *req = cdev->req; | ||
| 613 | int value = -EOPNOTSUPP; | ||
| 614 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
| 615 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
| 616 | u16 w_length = le16_to_cpu(ctrl->wLength); | ||
| 617 | |||
| 618 | /* | ||
| 619 | * composite driver infrastructure handles everything except | ||
| 620 | * CDC class messages; interface activation uses set_alt(). | ||
| 621 | */ | ||
| 622 | switch ((ctrl->bRequestType << 8) | ctrl->bRequest) { | ||
| 623 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | ||
| 624 | | USB_CDC_SET_ETHERNET_PACKET_FILTER: | ||
| 625 | /* | ||
| 626 | * see 6.2.30: no data, wIndex = interface, | ||
| 627 | * wValue = packet filter bitmap | ||
| 628 | */ | ||
| 629 | if (w_length != 0 || w_index != ncm->ctrl_id) | ||
| 630 | goto invalid; | ||
| 631 | DBG(cdev, "packet filter %02x\n", w_value); | ||
| 632 | /* | ||
| 633 | * REVISIT locking of cdc_filter. This assumes the UDC | ||
| 634 | * driver won't have a concurrent packet TX irq running on | ||
| 635 | * another CPU; or that if it does, this write is atomic... | ||
| 636 | */ | ||
| 637 | ncm->port.cdc_filter = w_value; | ||
| 638 | value = 0; | ||
| 639 | break; | ||
| 640 | /* | ||
| 641 | * and optionally: | ||
| 642 | * case USB_CDC_SEND_ENCAPSULATED_COMMAND: | ||
| 643 | * case USB_CDC_GET_ENCAPSULATED_RESPONSE: | ||
| 644 | * case USB_CDC_SET_ETHERNET_MULTICAST_FILTERS: | ||
| 645 | * case USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER: | ||
| 646 | * case USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER: | ||
| 647 | * case USB_CDC_GET_ETHERNET_STATISTIC: | ||
| 648 | */ | ||
| 649 | |||
| 650 | case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | ||
| 651 | | USB_CDC_GET_NTB_PARAMETERS: | ||
| 652 | |||
| 653 | if (w_length == 0 || w_value != 0 || w_index != ncm->ctrl_id) | ||
| 654 | goto invalid; | ||
| 655 | value = w_length > sizeof ntb_parameters ? | ||
| 656 | sizeof ntb_parameters : w_length; | ||
| 657 | memcpy(req->buf, &ntb_parameters, value); | ||
| 658 | VDBG(cdev, "Host asked NTB parameters\n"); | ||
| 659 | break; | ||
| 660 | |||
| 661 | case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | ||
| 662 | | USB_CDC_GET_NTB_INPUT_SIZE: | ||
| 663 | |||
| 664 | if (w_length < 4 || w_value != 0 || w_index != ncm->ctrl_id) | ||
| 665 | goto invalid; | ||
| 666 | put_unaligned_le32(ncm->port.fixed_in_len, req->buf); | ||
| 667 | value = 4; | ||
| 668 | VDBG(cdev, "Host asked INPUT SIZE, sending %d\n", | ||
| 669 | ncm->port.fixed_in_len); | ||
| 670 | break; | ||
| 671 | |||
| 672 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | ||
| 673 | | USB_CDC_SET_NTB_INPUT_SIZE: | ||
| 674 | { | ||
| 675 | if (w_length != 4 || w_value != 0 || w_index != ncm->ctrl_id) | ||
| 676 | goto invalid; | ||
| 677 | req->complete = ncm_ep0out_complete; | ||
| 678 | req->length = w_length; | ||
| 679 | req->context = f; | ||
| 680 | |||
| 681 | value = req->length; | ||
| 682 | break; | ||
| 683 | } | ||
| 684 | |||
| 685 | case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | ||
| 686 | | USB_CDC_GET_NTB_FORMAT: | ||
| 687 | { | ||
| 688 | uint16_t format; | ||
| 689 | |||
| 690 | if (w_length < 2 || w_value != 0 || w_index != ncm->ctrl_id) | ||
| 691 | goto invalid; | ||
| 692 | format = (ncm->parser_opts == &ndp16_opts) ? 0x0000 : 0x0001; | ||
| 693 | put_unaligned_le16(format, req->buf); | ||
| 694 | value = 2; | ||
| 695 | VDBG(cdev, "Host asked NTB FORMAT, sending %d\n", format); | ||
| 696 | break; | ||
| 697 | } | ||
| 698 | |||
| 699 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | ||
| 700 | | USB_CDC_SET_NTB_FORMAT: | ||
| 701 | { | ||
| 702 | if (w_length != 0 || w_index != ncm->ctrl_id) | ||
| 703 | goto invalid; | ||
| 704 | switch (w_value) { | ||
| 705 | case 0x0000: | ||
| 706 | ncm->parser_opts = &ndp16_opts; | ||
| 707 | DBG(cdev, "NCM16 selected\n"); | ||
| 708 | break; | ||
| 709 | case 0x0001: | ||
| 710 | ncm->parser_opts = &ndp32_opts; | ||
| 711 | DBG(cdev, "NCM32 selected\n"); | ||
| 712 | break; | ||
| 713 | default: | ||
| 714 | goto invalid; | ||
| 715 | } | ||
| 716 | value = 0; | ||
| 717 | break; | ||
| 718 | } | ||
| 719 | case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | ||
| 720 | | USB_CDC_GET_CRC_MODE: | ||
| 721 | { | ||
| 722 | uint16_t is_crc; | ||
| 723 | |||
| 724 | if (w_length < 2 || w_value != 0 || w_index != ncm->ctrl_id) | ||
| 725 | goto invalid; | ||
| 726 | is_crc = ncm->is_crc ? 0x0001 : 0x0000; | ||
| 727 | put_unaligned_le16(is_crc, req->buf); | ||
| 728 | value = 2; | ||
| 729 | VDBG(cdev, "Host asked CRC MODE, sending %d\n", is_crc); | ||
| 730 | break; | ||
| 731 | } | ||
| 732 | |||
| 733 | case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8) | ||
| 734 | | USB_CDC_SET_CRC_MODE: | ||
| 735 | { | ||
| 736 | int ndp_hdr_crc = 0; | ||
| 737 | |||
| 738 | if (w_length != 0 || w_index != ncm->ctrl_id) | ||
| 739 | goto invalid; | ||
| 740 | switch (w_value) { | ||
| 741 | case 0x0000: | ||
| 742 | ncm->is_crc = false; | ||
| 743 | ndp_hdr_crc = NCM_NDP_HDR_NOCRC; | ||
| 744 | DBG(cdev, "non-CRC mode selected\n"); | ||
| 745 | break; | ||
| 746 | case 0x0001: | ||
| 747 | ncm->is_crc = true; | ||
| 748 | ndp_hdr_crc = NCM_NDP_HDR_CRC; | ||
| 749 | DBG(cdev, "CRC mode selected\n"); | ||
| 750 | break; | ||
| 751 | default: | ||
| 752 | goto invalid; | ||
| 753 | } | ||
| 754 | ncm->parser_opts->ndp_sign &= ~NCM_NDP_HDR_CRC_MASK; | ||
| 755 | ncm->parser_opts->ndp_sign |= ndp_hdr_crc; | ||
| 756 | value = 0; | ||
| 757 | break; | ||
| 758 | } | ||
| 759 | |||
| 760 | /* and disabled in ncm descriptor: */ | ||
| 761 | /* case USB_CDC_GET_NET_ADDRESS: */ | ||
| 762 | /* case USB_CDC_SET_NET_ADDRESS: */ | ||
| 763 | /* case USB_CDC_GET_MAX_DATAGRAM_SIZE: */ | ||
| 764 | /* case USB_CDC_SET_MAX_DATAGRAM_SIZE: */ | ||
| 765 | |||
| 766 | default: | ||
| 767 | invalid: | ||
| 768 | DBG(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", | ||
| 769 | ctrl->bRequestType, ctrl->bRequest, | ||
| 770 | w_value, w_index, w_length); | ||
| 771 | } | ||
| 772 | |||
| 773 | /* respond with data transfer or status phase? */ | ||
| 774 | if (value >= 0) { | ||
| 775 | DBG(cdev, "ncm req%02x.%02x v%04x i%04x l%d\n", | ||
| 776 | ctrl->bRequestType, ctrl->bRequest, | ||
| 777 | w_value, w_index, w_length); | ||
| 778 | req->zero = 0; | ||
| 779 | req->length = value; | ||
| 780 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); | ||
| 781 | if (value < 0) | ||
| 782 | ERROR(cdev, "ncm req %02x.%02x response err %d\n", | ||
| 783 | ctrl->bRequestType, ctrl->bRequest, | ||
| 784 | value); | ||
| 785 | } | ||
| 786 | |||
| 787 | /* device either stalls (value < 0) or reports success */ | ||
| 788 | return value; | ||
| 789 | } | ||
| 790 | |||
| 791 | |||
| 792 | static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | ||
| 793 | { | ||
| 794 | struct f_ncm *ncm = func_to_ncm(f); | ||
| 795 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 796 | |||
| 797 | /* Control interface has only altsetting 0 */ | ||
| 798 | if (intf == ncm->ctrl_id) { | ||
| 799 | if (alt != 0) | ||
| 800 | goto fail; | ||
| 801 | |||
| 802 | if (ncm->notify->driver_data) { | ||
| 803 | DBG(cdev, "reset ncm control %d\n", intf); | ||
| 804 | usb_ep_disable(ncm->notify); | ||
| 805 | } else { | ||
| 806 | DBG(cdev, "init ncm ctrl %d\n", intf); | ||
| 807 | ncm->notify_desc = ep_choose(cdev->gadget, | ||
| 808 | ncm->hs.notify, | ||
| 809 | ncm->fs.notify); | ||
| 810 | } | ||
| 811 | usb_ep_enable(ncm->notify, ncm->notify_desc); | ||
| 812 | ncm->notify->driver_data = ncm; | ||
| 813 | |||
| 814 | /* Data interface has two altsettings, 0 and 1 */ | ||
| 815 | } else if (intf == ncm->data_id) { | ||
| 816 | if (alt > 1) | ||
| 817 | goto fail; | ||
| 818 | |||
| 819 | if (ncm->port.in_ep->driver_data) { | ||
| 820 | DBG(cdev, "reset ncm\n"); | ||
| 821 | gether_disconnect(&ncm->port); | ||
| 822 | ncm_reset_values(ncm); | ||
| 823 | } | ||
| 824 | |||
| 825 | /* | ||
| 826 | * CDC Network only sends data in non-default altsettings. | ||
| 827 | * Changing altsettings resets filters, statistics, etc. | ||
| 828 | */ | ||
| 829 | if (alt == 1) { | ||
| 830 | struct net_device *net; | ||
| 831 | |||
| 832 | if (!ncm->port.in) { | ||
| 833 | DBG(cdev, "init ncm\n"); | ||
| 834 | ncm->port.in = ep_choose(cdev->gadget, | ||
| 835 | ncm->hs.in, | ||
| 836 | ncm->fs.in); | ||
| 837 | ncm->port.out = ep_choose(cdev->gadget, | ||
| 838 | ncm->hs.out, | ||
| 839 | ncm->fs.out); | ||
| 840 | } | ||
| 841 | |||
| 842 | /* TODO */ | ||
| 843 | /* Enable zlps by default for NCM conformance; | ||
| 844 | * override for musb_hdrc (avoids txdma ovhead) | ||
| 845 | */ | ||
| 846 | ncm->port.is_zlp_ok = !( | ||
| 847 | gadget_is_musbhdrc(cdev->gadget) | ||
| 848 | ); | ||
| 849 | ncm->port.cdc_filter = DEFAULT_FILTER; | ||
| 850 | DBG(cdev, "activate ncm\n"); | ||
| 851 | net = gether_connect(&ncm->port); | ||
| 852 | if (IS_ERR(net)) | ||
| 853 | return PTR_ERR(net); | ||
| 854 | } | ||
| 855 | |||
| 856 | spin_lock(&ncm->lock); | ||
| 857 | ncm_notify(ncm); | ||
| 858 | spin_unlock(&ncm->lock); | ||
| 859 | } else | ||
| 860 | goto fail; | ||
| 861 | |||
| 862 | return 0; | ||
| 863 | fail: | ||
| 864 | return -EINVAL; | ||
| 865 | } | ||
| 866 | |||
| 867 | /* | ||
| 868 | * Because the data interface supports multiple altsettings, | ||
| 869 | * this NCM function *MUST* implement a get_alt() method. | ||
| 870 | */ | ||
| 871 | static int ncm_get_alt(struct usb_function *f, unsigned intf) | ||
| 872 | { | ||
| 873 | struct f_ncm *ncm = func_to_ncm(f); | ||
| 874 | |||
| 875 | if (intf == ncm->ctrl_id) | ||
| 876 | return 0; | ||
| 877 | return ncm->port.in_ep->driver_data ? 1 : 0; | ||
| 878 | } | ||
| 879 | |||
| 880 | static struct sk_buff *ncm_wrap_ntb(struct gether *port, | ||
| 881 | struct sk_buff *skb) | ||
| 882 | { | ||
| 883 | struct f_ncm *ncm = func_to_ncm(&port->func); | ||
| 884 | struct sk_buff *skb2; | ||
| 885 | int ncb_len = 0; | ||
| 886 | __le16 *tmp; | ||
| 887 | int div = ntb_parameters.wNdpInDivisor; | ||
| 888 | int rem = ntb_parameters.wNdpInPayloadRemainder; | ||
| 889 | int pad; | ||
| 890 | int ndp_align = ntb_parameters.wNdpInAlignment; | ||
| 891 | int ndp_pad; | ||
| 892 | unsigned max_size = ncm->port.fixed_in_len; | ||
| 893 | struct ndp_parser_opts *opts = ncm->parser_opts; | ||
| 894 | unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; | ||
| 895 | |||
| 896 | ncb_len += opts->nth_size; | ||
| 897 | ndp_pad = ALIGN(ncb_len, ndp_align) - ncb_len; | ||
| 898 | ncb_len += ndp_pad; | ||
| 899 | ncb_len += opts->ndp_size; | ||
| 900 | ncb_len += 2 * 2 * opts->dgram_item_len; /* Datagram entry */ | ||
| 901 | ncb_len += 2 * 2 * opts->dgram_item_len; /* Zero datagram entry */ | ||
| 902 | pad = ALIGN(ncb_len, div) + rem - ncb_len; | ||
| 903 | ncb_len += pad; | ||
| 904 | |||
| 905 | if (ncb_len + skb->len + crc_len > max_size) { | ||
| 906 | dev_kfree_skb_any(skb); | ||
| 907 | return NULL; | ||
| 908 | } | ||
| 909 | |||
| 910 | skb2 = skb_copy_expand(skb, ncb_len, | ||
| 911 | max_size - skb->len - ncb_len - crc_len, | ||
| 912 | GFP_ATOMIC); | ||
| 913 | dev_kfree_skb_any(skb); | ||
| 914 | if (!skb2) | ||
| 915 | return NULL; | ||
| 916 | |||
| 917 | skb = skb2; | ||
| 918 | |||
| 919 | tmp = (void *) skb_push(skb, ncb_len); | ||
| 920 | memset(tmp, 0, ncb_len); | ||
| 921 | |||
| 922 | put_unaligned_le32(opts->nth_sign, tmp); /* dwSignature */ | ||
| 923 | tmp += 2; | ||
| 924 | /* wHeaderLength */ | ||
| 925 | put_unaligned_le16(opts->nth_size, tmp++); | ||
| 926 | tmp++; /* skip wSequence */ | ||
| 927 | put_ncm(&tmp, opts->block_length, skb->len); /* (d)wBlockLength */ | ||
| 928 | /* (d)wFpIndex */ | ||
| 929 | /* the first pointer is right after the NTH + align */ | ||
| 930 | put_ncm(&tmp, opts->fp_index, opts->nth_size + ndp_pad); | ||
| 931 | |||
| 932 | tmp = (void *)tmp + ndp_pad; | ||
| 933 | |||
| 934 | /* NDP */ | ||
| 935 | put_unaligned_le32(opts->ndp_sign, tmp); /* dwSignature */ | ||
| 936 | tmp += 2; | ||
| 937 | /* wLength */ | ||
| 938 | put_unaligned_le16(ncb_len - opts->nth_size - pad, tmp++); | ||
| 939 | |||
| 940 | tmp += opts->reserved1; | ||
| 941 | tmp += opts->next_fp_index; /* skip reserved (d)wNextFpIndex */ | ||
| 942 | tmp += opts->reserved2; | ||
| 943 | |||
| 944 | if (ncm->is_crc) { | ||
| 945 | uint32_t crc; | ||
| 946 | |||
| 947 | crc = ~crc32_le(~0, | ||
| 948 | skb->data + ncb_len, | ||
| 949 | skb->len - ncb_len); | ||
| 950 | put_unaligned_le32(crc, skb->data + skb->len); | ||
| 951 | skb_put(skb, crc_len); | ||
| 952 | } | ||
| 953 | |||
| 954 | /* (d)wDatagramIndex[0] */ | ||
| 955 | put_ncm(&tmp, opts->dgram_item_len, ncb_len); | ||
| 956 | /* (d)wDatagramLength[0] */ | ||
| 957 | put_ncm(&tmp, opts->dgram_item_len, skb->len - ncb_len); | ||
| 958 | /* (d)wDatagramIndex[1] and (d)wDatagramLength[1] already zeroed */ | ||
| 959 | |||
| 960 | if (skb->len > MAX_TX_NONFIXED) | ||
| 961 | memset(skb_put(skb, max_size - skb->len), | ||
| 962 | 0, max_size - skb->len); | ||
| 963 | |||
| 964 | return skb; | ||
| 965 | } | ||
| 966 | |||
| 967 | static int ncm_unwrap_ntb(struct gether *port, | ||
| 968 | struct sk_buff *skb, | ||
| 969 | struct sk_buff_head *list) | ||
| 970 | { | ||
| 971 | struct f_ncm *ncm = func_to_ncm(&port->func); | ||
| 972 | __le16 *tmp = (void *) skb->data; | ||
| 973 | unsigned index, index2; | ||
| 974 | unsigned dg_len, dg_len2; | ||
| 975 | unsigned ndp_len; | ||
| 976 | struct sk_buff *skb2; | ||
| 977 | int ret = -EINVAL; | ||
| 978 | unsigned max_size = le32_to_cpu(ntb_parameters.dwNtbOutMaxSize); | ||
| 979 | struct ndp_parser_opts *opts = ncm->parser_opts; | ||
| 980 | unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; | ||
| 981 | int dgram_counter; | ||
| 982 | |||
| 983 | /* dwSignature */ | ||
| 984 | if (get_unaligned_le32(tmp) != opts->nth_sign) { | ||
| 985 | INFO(port->func.config->cdev, "Wrong NTH SIGN, skblen %d\n", | ||
| 986 | skb->len); | ||
| 987 | print_hex_dump(KERN_INFO, "HEAD:", DUMP_PREFIX_ADDRESS, 32, 1, | ||
| 988 | skb->data, 32, false); | ||
| 989 | |||
| 990 | goto err; | ||
| 991 | } | ||
| 992 | tmp += 2; | ||
| 993 | /* wHeaderLength */ | ||
| 994 | if (get_unaligned_le16(tmp++) != opts->nth_size) { | ||
| 995 | INFO(port->func.config->cdev, "Wrong NTB headersize\n"); | ||
| 996 | goto err; | ||
| 997 | } | ||
| 998 | tmp++; /* skip wSequence */ | ||
| 999 | |||
| 1000 | /* (d)wBlockLength */ | ||
| 1001 | if (get_ncm(&tmp, opts->block_length) > max_size) { | ||
| 1002 | INFO(port->func.config->cdev, "OUT size exceeded\n"); | ||
| 1003 | goto err; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | index = get_ncm(&tmp, opts->fp_index); | ||
| 1007 | /* NCM 3.2 */ | ||
| 1008 | if (((index % 4) != 0) && (index < opts->nth_size)) { | ||
| 1009 | INFO(port->func.config->cdev, "Bad index: %x\n", | ||
| 1010 | index); | ||
| 1011 | goto err; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | /* walk through NDP */ | ||
| 1015 | tmp = ((void *)skb->data) + index; | ||
| 1016 | if (get_unaligned_le32(tmp) != opts->ndp_sign) { | ||
| 1017 | INFO(port->func.config->cdev, "Wrong NDP SIGN\n"); | ||
| 1018 | goto err; | ||
| 1019 | } | ||
| 1020 | tmp += 2; | ||
| 1021 | |||
| 1022 | ndp_len = get_unaligned_le16(tmp++); | ||
| 1023 | /* | ||
| 1024 | * NCM 3.3.1 | ||
| 1025 | * entry is 2 items | ||
| 1026 | * item size is 16/32 bits, opts->dgram_item_len * 2 bytes | ||
| 1027 | * minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry | ||
| 1028 | */ | ||
| 1029 | if ((ndp_len < opts->ndp_size + 2 * 2 * (opts->dgram_item_len * 2)) | ||
| 1030 | || (ndp_len % opts->ndplen_align != 0)) { | ||
| 1031 | INFO(port->func.config->cdev, "Bad NDP length: %x\n", ndp_len); | ||
| 1032 | goto err; | ||
| 1033 | } | ||
| 1034 | tmp += opts->reserved1; | ||
| 1035 | tmp += opts->next_fp_index; /* skip reserved (d)wNextFpIndex */ | ||
| 1036 | tmp += opts->reserved2; | ||
| 1037 | |||
| 1038 | ndp_len -= opts->ndp_size; | ||
| 1039 | index2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1040 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1041 | dgram_counter = 0; | ||
| 1042 | |||
| 1043 | do { | ||
| 1044 | index = index2; | ||
| 1045 | dg_len = dg_len2; | ||
| 1046 | if (dg_len < 14 + crc_len) { /* ethernet header + crc */ | ||
| 1047 | INFO(port->func.config->cdev, "Bad dgram length: %x\n", | ||
| 1048 | dg_len); | ||
| 1049 | goto err; | ||
| 1050 | } | ||
| 1051 | if (ncm->is_crc) { | ||
| 1052 | uint32_t crc, crc2; | ||
| 1053 | |||
| 1054 | crc = get_unaligned_le32(skb->data + | ||
| 1055 | index + dg_len - crc_len); | ||
| 1056 | crc2 = ~crc32_le(~0, | ||
| 1057 | skb->data + index, | ||
| 1058 | dg_len - crc_len); | ||
| 1059 | if (crc != crc2) { | ||
| 1060 | INFO(port->func.config->cdev, "Bad CRC\n"); | ||
| 1061 | goto err; | ||
| 1062 | } | ||
| 1063 | } | ||
| 1064 | |||
| 1065 | index2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1066 | dg_len2 = get_ncm(&tmp, opts->dgram_item_len); | ||
| 1067 | |||
| 1068 | if (index2 == 0 || dg_len2 == 0) { | ||
| 1069 | skb2 = skb; | ||
| 1070 | } else { | ||
| 1071 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
| 1072 | if (skb2 == NULL) | ||
| 1073 | goto err; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | if (!skb_pull(skb2, index)) { | ||
| 1077 | ret = -EOVERFLOW; | ||
| 1078 | goto err; | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | skb_trim(skb2, dg_len - crc_len); | ||
| 1082 | skb_queue_tail(list, skb2); | ||
| 1083 | |||
| 1084 | ndp_len -= 2 * (opts->dgram_item_len * 2); | ||
| 1085 | |||
| 1086 | dgram_counter++; | ||
| 1087 | |||
| 1088 | if (index2 == 0 || dg_len2 == 0) | ||
| 1089 | break; | ||
| 1090 | } while (ndp_len > 2 * (opts->dgram_item_len * 2)); /* zero entry */ | ||
| 1091 | |||
| 1092 | VDBG(port->func.config->cdev, | ||
| 1093 | "Parsed NTB with %d frames\n", dgram_counter); | ||
| 1094 | return 0; | ||
| 1095 | err: | ||
| 1096 | skb_queue_purge(list); | ||
| 1097 | dev_kfree_skb_any(skb); | ||
| 1098 | return ret; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | static void ncm_disable(struct usb_function *f) | ||
| 1102 | { | ||
| 1103 | struct f_ncm *ncm = func_to_ncm(f); | ||
| 1104 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 1105 | |||
| 1106 | DBG(cdev, "ncm deactivated\n"); | ||
| 1107 | |||
| 1108 | if (ncm->port.in_ep->driver_data) | ||
| 1109 | gether_disconnect(&ncm->port); | ||
| 1110 | |||
| 1111 | if (ncm->notify->driver_data) { | ||
| 1112 | usb_ep_disable(ncm->notify); | ||
| 1113 | ncm->notify->driver_data = NULL; | ||
| 1114 | ncm->notify_desc = NULL; | ||
| 1115 | } | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | /*-------------------------------------------------------------------------*/ | ||
| 1119 | |||
| 1120 | /* | ||
| 1121 | * Callbacks let us notify the host about connect/disconnect when the | ||
| 1122 | * net device is opened or closed. | ||
| 1123 | * | ||
| 1124 | * For testing, note that link states on this side include both opened | ||
| 1125 | * and closed variants of: | ||
| 1126 | * | ||
| 1127 | * - disconnected/unconfigured | ||
| 1128 | * - configured but inactive (data alt 0) | ||
| 1129 | * - configured and active (data alt 1) | ||
| 1130 | * | ||
| 1131 | * Each needs to be tested with unplug, rmmod, SET_CONFIGURATION, and | ||
| 1132 | * SET_INTERFACE (altsetting). Remember also that "configured" doesn't | ||
| 1133 | * imply the host is actually polling the notification endpoint, and | ||
| 1134 | * likewise that "active" doesn't imply it's actually using the data | ||
| 1135 | * endpoints for traffic. | ||
| 1136 | */ | ||
| 1137 | |||
| 1138 | static void ncm_open(struct gether *geth) | ||
| 1139 | { | ||
| 1140 | struct f_ncm *ncm = func_to_ncm(&geth->func); | ||
| 1141 | |||
| 1142 | DBG(ncm->port.func.config->cdev, "%s\n", __func__); | ||
| 1143 | |||
| 1144 | spin_lock(&ncm->lock); | ||
| 1145 | ncm->is_open = true; | ||
| 1146 | ncm_notify(ncm); | ||
| 1147 | spin_unlock(&ncm->lock); | ||
| 1148 | } | ||
| 1149 | |||
| 1150 | static void ncm_close(struct gether *geth) | ||
| 1151 | { | ||
| 1152 | struct f_ncm *ncm = func_to_ncm(&geth->func); | ||
| 1153 | |||
| 1154 | DBG(ncm->port.func.config->cdev, "%s\n", __func__); | ||
| 1155 | |||
| 1156 | spin_lock(&ncm->lock); | ||
| 1157 | ncm->is_open = false; | ||
| 1158 | ncm_notify(ncm); | ||
| 1159 | spin_unlock(&ncm->lock); | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | /*-------------------------------------------------------------------------*/ | ||
| 1163 | |||
| 1164 | /* ethernet function driver setup/binding */ | ||
| 1165 | |||
| 1166 | static int __init | ||
| 1167 | ncm_bind(struct usb_configuration *c, struct usb_function *f) | ||
| 1168 | { | ||
| 1169 | struct usb_composite_dev *cdev = c->cdev; | ||
| 1170 | struct f_ncm *ncm = func_to_ncm(f); | ||
| 1171 | int status; | ||
| 1172 | struct usb_ep *ep; | ||
| 1173 | |||
| 1174 | /* allocate instance-specific interface IDs */ | ||
| 1175 | status = usb_interface_id(c, f); | ||
| 1176 | if (status < 0) | ||
| 1177 | goto fail; | ||
| 1178 | ncm->ctrl_id = status; | ||
| 1179 | ncm_iad_desc.bFirstInterface = status; | ||
| 1180 | |||
| 1181 | ncm_control_intf.bInterfaceNumber = status; | ||
| 1182 | ncm_union_desc.bMasterInterface0 = status; | ||
| 1183 | |||
| 1184 | status = usb_interface_id(c, f); | ||
| 1185 | if (status < 0) | ||
| 1186 | goto fail; | ||
| 1187 | ncm->data_id = status; | ||
| 1188 | |||
| 1189 | ncm_data_nop_intf.bInterfaceNumber = status; | ||
| 1190 | ncm_data_intf.bInterfaceNumber = status; | ||
| 1191 | ncm_union_desc.bSlaveInterface0 = status; | ||
| 1192 | |||
| 1193 | status = -ENODEV; | ||
| 1194 | |||
| 1195 | /* allocate instance-specific endpoints */ | ||
| 1196 | ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_in_desc); | ||
| 1197 | if (!ep) | ||
| 1198 | goto fail; | ||
| 1199 | ncm->port.in_ep = ep; | ||
| 1200 | ep->driver_data = cdev; /* claim */ | ||
| 1201 | |||
| 1202 | ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc); | ||
| 1203 | if (!ep) | ||
| 1204 | goto fail; | ||
| 1205 | ncm->port.out_ep = ep; | ||
| 1206 | ep->driver_data = cdev; /* claim */ | ||
| 1207 | |||
| 1208 | ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc); | ||
| 1209 | if (!ep) | ||
| 1210 | goto fail; | ||
| 1211 | ncm->notify = ep; | ||
| 1212 | ep->driver_data = cdev; /* claim */ | ||
| 1213 | |||
| 1214 | status = -ENOMEM; | ||
| 1215 | |||
| 1216 | /* allocate notification request and buffer */ | ||
| 1217 | ncm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL); | ||
| 1218 | if (!ncm->notify_req) | ||
| 1219 | goto fail; | ||
| 1220 | ncm->notify_req->buf = kmalloc(NCM_STATUS_BYTECOUNT, GFP_KERNEL); | ||
| 1221 | if (!ncm->notify_req->buf) | ||
| 1222 | goto fail; | ||
| 1223 | ncm->notify_req->context = ncm; | ||
| 1224 | ncm->notify_req->complete = ncm_notify_complete; | ||
| 1225 | |||
| 1226 | /* copy descriptors, and track endpoint copies */ | ||
| 1227 | f->descriptors = usb_copy_descriptors(ncm_fs_function); | ||
| 1228 | if (!f->descriptors) | ||
| 1229 | goto fail; | ||
| 1230 | |||
| 1231 | ncm->fs.in = usb_find_endpoint(ncm_fs_function, | ||
| 1232 | f->descriptors, &fs_ncm_in_desc); | ||
| 1233 | ncm->fs.out = usb_find_endpoint(ncm_fs_function, | ||
| 1234 | f->descriptors, &fs_ncm_out_desc); | ||
| 1235 | ncm->fs.notify = usb_find_endpoint(ncm_fs_function, | ||
| 1236 | f->descriptors, &fs_ncm_notify_desc); | ||
| 1237 | |||
| 1238 | /* | ||
| 1239 | * support all relevant hardware speeds... we expect that when | ||
| 1240 | * hardware is dual speed, all bulk-capable endpoints work at | ||
| 1241 | * both speeds | ||
| 1242 | */ | ||
| 1243 | if (gadget_is_dualspeed(c->cdev->gadget)) { | ||
| 1244 | hs_ncm_in_desc.bEndpointAddress = | ||
| 1245 | fs_ncm_in_desc.bEndpointAddress; | ||
| 1246 | hs_ncm_out_desc.bEndpointAddress = | ||
| 1247 | fs_ncm_out_desc.bEndpointAddress; | ||
| 1248 | hs_ncm_notify_desc.bEndpointAddress = | ||
| 1249 | fs_ncm_notify_desc.bEndpointAddress; | ||
| 1250 | |||
| 1251 | /* copy descriptors, and track endpoint copies */ | ||
| 1252 | f->hs_descriptors = usb_copy_descriptors(ncm_hs_function); | ||
| 1253 | if (!f->hs_descriptors) | ||
| 1254 | goto fail; | ||
| 1255 | |||
| 1256 | ncm->hs.in = usb_find_endpoint(ncm_hs_function, | ||
| 1257 | f->hs_descriptors, &hs_ncm_in_desc); | ||
| 1258 | ncm->hs.out = usb_find_endpoint(ncm_hs_function, | ||
| 1259 | f->hs_descriptors, &hs_ncm_out_desc); | ||
| 1260 | ncm->hs.notify = usb_find_endpoint(ncm_hs_function, | ||
| 1261 | f->hs_descriptors, &hs_ncm_notify_desc); | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | /* | ||
| 1265 | * NOTE: all that is done without knowing or caring about | ||
| 1266 | * the network link ... which is unavailable to this code | ||
| 1267 | * until we're activated via set_alt(). | ||
| 1268 | */ | ||
| 1269 | |||
| 1270 | ncm->port.open = ncm_open; | ||
| 1271 | ncm->port.close = ncm_close; | ||
| 1272 | |||
| 1273 | DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n", | ||
| 1274 | gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", | ||
| 1275 | ncm->port.in_ep->name, ncm->port.out_ep->name, | ||
| 1276 | ncm->notify->name); | ||
| 1277 | return 0; | ||
| 1278 | |||
| 1279 | fail: | ||
| 1280 | if (f->descriptors) | ||
| 1281 | usb_free_descriptors(f->descriptors); | ||
| 1282 | |||
| 1283 | if (ncm->notify_req) { | ||
| 1284 | kfree(ncm->notify_req->buf); | ||
| 1285 | usb_ep_free_request(ncm->notify, ncm->notify_req); | ||
| 1286 | } | ||
| 1287 | |||
| 1288 | /* we might as well release our claims on endpoints */ | ||
| 1289 | if (ncm->notify) | ||
| 1290 | ncm->notify->driver_data = NULL; | ||
| 1291 | if (ncm->port.out) | ||
| 1292 | ncm->port.out_ep->driver_data = NULL; | ||
| 1293 | if (ncm->port.in) | ||
| 1294 | ncm->port.in_ep->driver_data = NULL; | ||
| 1295 | |||
| 1296 | ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); | ||
| 1297 | |||
| 1298 | return status; | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | static void | ||
| 1302 | ncm_unbind(struct usb_configuration *c, struct usb_function *f) | ||
| 1303 | { | ||
| 1304 | struct f_ncm *ncm = func_to_ncm(f); | ||
| 1305 | |||
| 1306 | DBG(c->cdev, "ncm unbind\n"); | ||
| 1307 | |||
| 1308 | if (gadget_is_dualspeed(c->cdev->gadget)) | ||
| 1309 | usb_free_descriptors(f->hs_descriptors); | ||
| 1310 | usb_free_descriptors(f->descriptors); | ||
| 1311 | |||
| 1312 | kfree(ncm->notify_req->buf); | ||
| 1313 | usb_ep_free_request(ncm->notify, ncm->notify_req); | ||
| 1314 | |||
| 1315 | ncm_string_defs[1].s = NULL; | ||
| 1316 | kfree(ncm); | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | /** | ||
| 1320 | * ncm_bind_config - add CDC Network link to a configuration | ||
| 1321 | * @c: the configuration to support the network link | ||
| 1322 | * @ethaddr: a buffer in which the ethernet address of the host side | ||
| 1323 | * side of the link was recorded | ||
| 1324 | * Context: single threaded during gadget setup | ||
| 1325 | * | ||
| 1326 | * Returns zero on success, else negative errno. | ||
| 1327 | * | ||
| 1328 | * Caller must have called @gether_setup(). Caller is also responsible | ||
| 1329 | * for calling @gether_cleanup() before module unload. | ||
| 1330 | */ | ||
| 1331 | int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) | ||
| 1332 | { | ||
| 1333 | struct f_ncm *ncm; | ||
| 1334 | int status; | ||
| 1335 | |||
| 1336 | if (!can_support_ecm(c->cdev->gadget) || !ethaddr) | ||
| 1337 | return -EINVAL; | ||
| 1338 | |||
| 1339 | /* maybe allocate device-global string IDs */ | ||
| 1340 | if (ncm_string_defs[0].id == 0) { | ||
| 1341 | |||
| 1342 | /* control interface label */ | ||
| 1343 | status = usb_string_id(c->cdev); | ||
| 1344 | if (status < 0) | ||
| 1345 | return status; | ||
| 1346 | ncm_string_defs[STRING_CTRL_IDX].id = status; | ||
| 1347 | ncm_control_intf.iInterface = status; | ||
| 1348 | |||
| 1349 | /* data interface label */ | ||
| 1350 | status = usb_string_id(c->cdev); | ||
| 1351 | if (status < 0) | ||
| 1352 | return status; | ||
| 1353 | ncm_string_defs[STRING_DATA_IDX].id = status; | ||
| 1354 | ncm_data_nop_intf.iInterface = status; | ||
| 1355 | ncm_data_intf.iInterface = status; | ||
| 1356 | |||
| 1357 | /* MAC address */ | ||
| 1358 | status = usb_string_id(c->cdev); | ||
| 1359 | if (status < 0) | ||
| 1360 | return status; | ||
| 1361 | ncm_string_defs[STRING_MAC_IDX].id = status; | ||
| 1362 | ecm_desc.iMACAddress = status; | ||
| 1363 | |||
| 1364 | /* IAD */ | ||
| 1365 | status = usb_string_id(c->cdev); | ||
| 1366 | if (status < 0) | ||
| 1367 | return status; | ||
| 1368 | ncm_string_defs[STRING_IAD_IDX].id = status; | ||
| 1369 | ncm_iad_desc.iFunction = status; | ||
| 1370 | } | ||
| 1371 | |||
| 1372 | /* allocate and initialize one new instance */ | ||
| 1373 | ncm = kzalloc(sizeof *ncm, GFP_KERNEL); | ||
| 1374 | if (!ncm) | ||
| 1375 | return -ENOMEM; | ||
| 1376 | |||
| 1377 | /* export host's Ethernet address in CDC format */ | ||
| 1378 | snprintf(ncm->ethaddr, sizeof ncm->ethaddr, | ||
| 1379 | "%02X%02X%02X%02X%02X%02X", | ||
| 1380 | ethaddr[0], ethaddr[1], ethaddr[2], | ||
| 1381 | ethaddr[3], ethaddr[4], ethaddr[5]); | ||
| 1382 | ncm_string_defs[1].s = ncm->ethaddr; | ||
| 1383 | |||
| 1384 | spin_lock_init(&ncm->lock); | ||
| 1385 | ncm_reset_values(ncm); | ||
| 1386 | ncm->port.is_fixed = true; | ||
| 1387 | |||
| 1388 | ncm->port.func.name = "cdc_network"; | ||
| 1389 | ncm->port.func.strings = ncm_strings; | ||
| 1390 | /* descriptors are per-instance copies */ | ||
| 1391 | ncm->port.func.bind = ncm_bind; | ||
| 1392 | ncm->port.func.unbind = ncm_unbind; | ||
| 1393 | ncm->port.func.set_alt = ncm_set_alt; | ||
| 1394 | ncm->port.func.get_alt = ncm_get_alt; | ||
| 1395 | ncm->port.func.setup = ncm_setup; | ||
| 1396 | ncm->port.func.disable = ncm_disable; | ||
| 1397 | |||
| 1398 | ncm->port.wrap = ncm_wrap_ntb; | ||
| 1399 | ncm->port.unwrap = ncm_unwrap_ntb; | ||
| 1400 | |||
| 1401 | status = usb_add_function(c, &ncm->port.func); | ||
| 1402 | if (status) { | ||
| 1403 | ncm_string_defs[1].s = NULL; | ||
| 1404 | kfree(ncm); | ||
| 1405 | } | ||
| 1406 | return status; | ||
| 1407 | } | ||
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index d4fdf65fb925..a6eacb59571b 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
| @@ -3392,25 +3392,28 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
| 3392 | dev_set_name(&curlun->dev,"%s-lun%d", | 3392 | dev_set_name(&curlun->dev,"%s-lun%d", |
| 3393 | dev_name(&gadget->dev), i); | 3393 | dev_name(&gadget->dev), i); |
| 3394 | 3394 | ||
| 3395 | if ((rc = device_register(&curlun->dev)) != 0) { | 3395 | kref_get(&fsg->ref); |
| 3396 | rc = device_register(&curlun->dev); | ||
| 3397 | if (rc) { | ||
| 3396 | INFO(fsg, "failed to register LUN%d: %d\n", i, rc); | 3398 | INFO(fsg, "failed to register LUN%d: %d\n", i, rc); |
| 3397 | goto out; | 3399 | put_device(&curlun->dev); |
| 3398 | } | ||
| 3399 | if ((rc = device_create_file(&curlun->dev, | ||
| 3400 | &dev_attr_ro)) != 0 || | ||
| 3401 | (rc = device_create_file(&curlun->dev, | ||
| 3402 | &dev_attr_nofua)) != 0 || | ||
| 3403 | (rc = device_create_file(&curlun->dev, | ||
| 3404 | &dev_attr_file)) != 0) { | ||
| 3405 | device_unregister(&curlun->dev); | ||
| 3406 | goto out; | 3400 | goto out; |
| 3407 | } | 3401 | } |
| 3408 | curlun->registered = 1; | 3402 | curlun->registered = 1; |
| 3409 | kref_get(&fsg->ref); | 3403 | |
| 3404 | rc = device_create_file(&curlun->dev, &dev_attr_ro); | ||
| 3405 | if (rc) | ||
| 3406 | goto out; | ||
| 3407 | rc = device_create_file(&curlun->dev, &dev_attr_nofua); | ||
| 3408 | if (rc) | ||
| 3409 | goto out; | ||
| 3410 | rc = device_create_file(&curlun->dev, &dev_attr_file); | ||
| 3411 | if (rc) | ||
| 3412 | goto out; | ||
| 3410 | 3413 | ||
| 3411 | if (mod_data.file[i] && *mod_data.file[i]) { | 3414 | if (mod_data.file[i] && *mod_data.file[i]) { |
| 3412 | if ((rc = fsg_lun_open(curlun, | 3415 | rc = fsg_lun_open(curlun, mod_data.file[i]); |
| 3413 | mod_data.file[i])) != 0) | 3416 | if (rc) |
| 3414 | goto out; | 3417 | goto out; |
| 3415 | } else if (!mod_data.removable) { | 3418 | } else if (!mod_data.removable) { |
| 3416 | ERROR(fsg, "no file given for LUN%d\n", i); | 3419 | ERROR(fsg, "no file given for LUN%d\n", i); |
diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index af75e3620849..ebf6970a10bf 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c | |||
| @@ -1,7 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * g_ffs.c -- user mode file system API for USB composite function controllers | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Samsung Electronics | ||
| 5 | * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | */ | ||
| 21 | |||
| 22 | #define pr_fmt(fmt) "g_ffs: " fmt | ||
| 23 | |||
| 1 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 2 | #include <linux/utsname.h> | 25 | #include <linux/utsname.h> |
| 3 | 26 | ||
| 4 | |||
| 5 | /* | 27 | /* |
| 6 | * kbuild is not very cooperative with respect to linking separately | 28 | * kbuild is not very cooperative with respect to linking separately |
| 7 | * compiled library objects into one module. So for now we won't use | 29 | * compiled library objects into one module. So for now we won't use |
| @@ -43,7 +65,6 @@ static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); | |||
| 43 | 65 | ||
| 44 | #include "f_fs.c" | 66 | #include "f_fs.c" |
| 45 | 67 | ||
| 46 | |||
| 47 | #define DRIVER_NAME "g_ffs" | 68 | #define DRIVER_NAME "g_ffs" |
| 48 | #define DRIVER_DESC "USB Function Filesystem" | 69 | #define DRIVER_DESC "USB Function Filesystem" |
| 49 | #define DRIVER_VERSION "24 Aug 2004" | 70 | #define DRIVER_VERSION "24 Aug 2004" |
| @@ -73,8 +94,6 @@ MODULE_PARM_DESC(bDeviceSubClass, "USB Device subclass"); | |||
| 73 | module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte, 0644); | 94 | module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte, 0644); |
| 74 | MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol"); | 95 | MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol"); |
| 75 | 96 | ||
| 76 | |||
| 77 | |||
| 78 | static const struct usb_descriptor_header *gfs_otg_desc[] = { | 97 | static const struct usb_descriptor_header *gfs_otg_desc[] = { |
| 79 | (const struct usb_descriptor_header *) | 98 | (const struct usb_descriptor_header *) |
| 80 | &(const struct usb_otg_descriptor) { | 99 | &(const struct usb_otg_descriptor) { |
| @@ -91,8 +110,7 @@ static const struct usb_descriptor_header *gfs_otg_desc[] = { | |||
| 91 | NULL | 110 | NULL |
| 92 | }; | 111 | }; |
| 93 | 112 | ||
| 94 | /* string IDs are assigned dynamically */ | 113 | /* String IDs are assigned dynamically */ |
| 95 | |||
| 96 | static struct usb_string gfs_strings[] = { | 114 | static struct usb_string gfs_strings[] = { |
| 97 | #ifdef CONFIG_USB_FUNCTIONFS_RNDIS | 115 | #ifdef CONFIG_USB_FUNCTIONFS_RNDIS |
| 98 | { .s = "FunctionFS + RNDIS" }, | 116 | { .s = "FunctionFS + RNDIS" }, |
| @@ -114,8 +132,6 @@ static struct usb_gadget_strings *gfs_dev_strings[] = { | |||
| 114 | NULL, | 132 | NULL, |
| 115 | }; | 133 | }; |
| 116 | 134 | ||
| 117 | |||
| 118 | |||
| 119 | struct gfs_configuration { | 135 | struct gfs_configuration { |
| 120 | struct usb_configuration c; | 136 | struct usb_configuration c; |
| 121 | int (*eth)(struct usb_configuration *c, u8 *ethaddr); | 137 | int (*eth)(struct usb_configuration *c, u8 *ethaddr); |
| @@ -138,7 +154,6 @@ struct gfs_configuration { | |||
| 138 | #endif | 154 | #endif |
| 139 | }; | 155 | }; |
| 140 | 156 | ||
| 141 | |||
| 142 | static int gfs_bind(struct usb_composite_dev *cdev); | 157 | static int gfs_bind(struct usb_composite_dev *cdev); |
| 143 | static int gfs_unbind(struct usb_composite_dev *cdev); | 158 | static int gfs_unbind(struct usb_composite_dev *cdev); |
| 144 | static int gfs_do_config(struct usb_configuration *c); | 159 | static int gfs_do_config(struct usb_configuration *c); |
| @@ -151,11 +166,9 @@ static struct usb_composite_driver gfs_driver = { | |||
| 151 | .iProduct = DRIVER_DESC, | 166 | .iProduct = DRIVER_DESC, |
| 152 | }; | 167 | }; |
| 153 | 168 | ||
| 154 | |||
| 155 | static struct ffs_data *gfs_ffs_data; | 169 | static struct ffs_data *gfs_ffs_data; |
| 156 | static unsigned long gfs_registered; | 170 | static unsigned long gfs_registered; |
| 157 | 171 | ||
| 158 | |||
| 159 | static int gfs_init(void) | 172 | static int gfs_init(void) |
| 160 | { | 173 | { |
| 161 | ENTER(); | 174 | ENTER(); |
| @@ -175,7 +188,6 @@ static void gfs_exit(void) | |||
| 175 | } | 188 | } |
| 176 | module_exit(gfs_exit); | 189 | module_exit(gfs_exit); |
| 177 | 190 | ||
| 178 | |||
| 179 | static int functionfs_ready_callback(struct ffs_data *ffs) | 191 | static int functionfs_ready_callback(struct ffs_data *ffs) |
| 180 | { | 192 | { |
| 181 | int ret; | 193 | int ret; |
| @@ -200,14 +212,11 @@ static void functionfs_closed_callback(struct ffs_data *ffs) | |||
| 200 | usb_composite_unregister(&gfs_driver); | 212 | usb_composite_unregister(&gfs_driver); |
| 201 | } | 213 | } |
| 202 | 214 | ||
| 203 | |||
| 204 | static int functionfs_check_dev_callback(const char *dev_name) | 215 | static int functionfs_check_dev_callback(const char *dev_name) |
| 205 | { | 216 | { |
| 206 | return 0; | 217 | return 0; |
| 207 | } | 218 | } |
| 208 | 219 | ||
| 209 | |||
| 210 | |||
| 211 | static int gfs_bind(struct usb_composite_dev *cdev) | 220 | static int gfs_bind(struct usb_composite_dev *cdev) |
| 212 | { | 221 | { |
| 213 | int ret, i; | 222 | int ret, i; |
| @@ -274,7 +283,6 @@ static int gfs_unbind(struct usb_composite_dev *cdev) | |||
| 274 | return 0; | 283 | return 0; |
| 275 | } | 284 | } |
| 276 | 285 | ||
| 277 | |||
| 278 | static int gfs_do_config(struct usb_configuration *c) | 286 | static int gfs_do_config(struct usb_configuration *c) |
| 279 | { | 287 | { |
| 280 | struct gfs_configuration *gc = | 288 | struct gfs_configuration *gc = |
| @@ -315,7 +323,6 @@ static int gfs_do_config(struct usb_configuration *c) | |||
| 315 | return 0; | 323 | return 0; |
| 316 | } | 324 | } |
| 317 | 325 | ||
| 318 | |||
| 319 | #ifdef CONFIG_USB_FUNCTIONFS_ETH | 326 | #ifdef CONFIG_USB_FUNCTIONFS_ETH |
| 320 | 327 | ||
| 321 | static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) | 328 | static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index e511fec9f26d..5c2720d64ffa 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
| @@ -96,7 +96,7 @@ | |||
| 96 | 96 | ||
| 97 | /* Mentor high speed "dual role" controller, in peripheral role */ | 97 | /* Mentor high speed "dual role" controller, in peripheral role */ |
| 98 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | 98 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
| 99 | #define gadget_is_musbhdrc(g) !strcmp("musb_hdrc", (g)->name) | 99 | #define gadget_is_musbhdrc(g) !strcmp("musb-hdrc", (g)->name) |
| 100 | #else | 100 | #else |
| 101 | #define gadget_is_musbhdrc(g) 0 | 101 | #define gadget_is_musbhdrc(g) 0 |
| 102 | #endif | 102 | #endif |
| @@ -120,10 +120,10 @@ | |||
| 120 | #define gadget_is_fsl_qe(g) 0 | 120 | #define gadget_is_fsl_qe(g) 0 |
| 121 | #endif | 121 | #endif |
| 122 | 122 | ||
| 123 | #ifdef CONFIG_USB_GADGET_CI13XXX | 123 | #ifdef CONFIG_USB_GADGET_CI13XXX_PCI |
| 124 | #define gadget_is_ci13xxx(g) (!strcmp("ci13xxx_udc", (g)->name)) | 124 | #define gadget_is_ci13xxx_pci(g) (!strcmp("ci13xxx_pci", (g)->name)) |
| 125 | #else | 125 | #else |
| 126 | #define gadget_is_ci13xxx(g) 0 | 126 | #define gadget_is_ci13xxx_pci(g) 0 |
| 127 | #endif | 127 | #endif |
| 128 | 128 | ||
| 129 | // CONFIG_USB_GADGET_SX2 | 129 | // CONFIG_USB_GADGET_SX2 |
| @@ -142,6 +142,17 @@ | |||
| 142 | #define gadget_is_s3c_hsotg(g) 0 | 142 | #define gadget_is_s3c_hsotg(g) 0 |
| 143 | #endif | 143 | #endif |
| 144 | 144 | ||
| 145 | #ifdef CONFIG_USB_GADGET_EG20T | ||
| 146 | #define gadget_is_pch(g) (!strcmp("pch_udc", (g)->name)) | ||
| 147 | #else | ||
| 148 | #define gadget_is_pch(g) 0 | ||
| 149 | #endif | ||
| 150 | |||
| 151 | #ifdef CONFIG_USB_GADGET_CI13XXX_MSM | ||
| 152 | #define gadget_is_ci13xxx_msm(g) (!strcmp("ci13xxx_msm", (g)->name)) | ||
| 153 | #else | ||
| 154 | #define gadget_is_ci13xxx_msm(g) 0 | ||
| 155 | #endif | ||
| 145 | 156 | ||
| 146 | /** | 157 | /** |
| 147 | * usb_gadget_controller_number - support bcdDevice id convention | 158 | * usb_gadget_controller_number - support bcdDevice id convention |
| @@ -192,7 +203,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
| 192 | return 0x21; | 203 | return 0x21; |
| 193 | else if (gadget_is_fsl_qe(gadget)) | 204 | else if (gadget_is_fsl_qe(gadget)) |
| 194 | return 0x22; | 205 | return 0x22; |
| 195 | else if (gadget_is_ci13xxx(gadget)) | 206 | else if (gadget_is_ci13xxx_pci(gadget)) |
| 196 | return 0x23; | 207 | return 0x23; |
| 197 | else if (gadget_is_langwell(gadget)) | 208 | else if (gadget_is_langwell(gadget)) |
| 198 | return 0x24; | 209 | return 0x24; |
| @@ -200,6 +211,10 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
| 200 | return 0x25; | 211 | return 0x25; |
| 201 | else if (gadget_is_s3c_hsotg(gadget)) | 212 | else if (gadget_is_s3c_hsotg(gadget)) |
| 202 | return 0x26; | 213 | return 0x26; |
| 214 | else if (gadget_is_pch(gadget)) | ||
| 215 | return 0x27; | ||
| 216 | else if (gadget_is_ci13xxx_msm(gadget)) | ||
| 217 | return 0x28; | ||
| 203 | return -ENOENT; | 218 | return -ENOENT; |
| 204 | } | 219 | } |
| 205 | 220 | ||
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index ed0266462c57..1210534822d6 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c | |||
| @@ -1191,13 +1191,17 @@ static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) | |||
| 1191 | return IRQ_HANDLED; | 1191 | return IRQ_HANDLED; |
| 1192 | } | 1192 | } |
| 1193 | 1193 | ||
| 1194 | #ifndef MX1_INT_USBD0 | ||
| 1195 | #define MX1_INT_USBD0 MX1_USBD_INT0 | ||
| 1196 | #endif | ||
| 1197 | |||
| 1194 | static irqreturn_t imx_udc_bulk_irq(int irq, void *dev) | 1198 | static irqreturn_t imx_udc_bulk_irq(int irq, void *dev) |
| 1195 | { | 1199 | { |
| 1196 | struct imx_udc_struct *imx_usb = dev; | 1200 | struct imx_udc_struct *imx_usb = dev; |
| 1197 | struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[irq - USBD_INT0]; | 1201 | struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[irq - MX1_INT_USBD0]; |
| 1198 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); | 1202 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); |
| 1199 | 1203 | ||
| 1200 | dump_ep_intr(__func__, irq - USBD_INT0, intr, imx_usb->dev); | 1204 | dump_ep_intr(__func__, irq - MX1_INT_USBD0, intr, imx_usb->dev); |
| 1201 | 1205 | ||
| 1202 | if (!imx_usb->driver) { | 1206 | if (!imx_usb->driver) { |
| 1203 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); | 1207 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); |
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h index b48ad59603d1..7136c242b4ec 100644 --- a/drivers/usb/gadget/imx_udc.h +++ b/drivers/usb/gadget/imx_udc.h | |||
| @@ -23,9 +23,6 @@ | |||
| 23 | /* Helper macros */ | 23 | /* Helper macros */ |
| 24 | #define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */ | 24 | #define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */ |
| 25 | #define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0) | 25 | #define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0) |
| 26 | #define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \ | ||
| 27 | ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/ | ||
| 28 | #define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0) | ||
| 29 | #define IMX_USB_NB_EP 6 | 26 | #define IMX_USB_NB_EP 6 |
| 30 | 27 | ||
| 31 | /* Driver structures */ | 28 | /* Driver structures */ |
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index b8ec954c0692..777972454e3e 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
| @@ -2225,6 +2225,7 @@ static void handle_setup_packet(struct langwell_udc *dev, | |||
| 2225 | u16 wValue = le16_to_cpu(setup->wValue); | 2225 | u16 wValue = le16_to_cpu(setup->wValue); |
| 2226 | u16 wIndex = le16_to_cpu(setup->wIndex); | 2226 | u16 wIndex = le16_to_cpu(setup->wIndex); |
| 2227 | u16 wLength = le16_to_cpu(setup->wLength); | 2227 | u16 wLength = le16_to_cpu(setup->wLength); |
| 2228 | u32 portsc1; | ||
| 2228 | 2229 | ||
| 2229 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); | 2230 | dev_vdbg(&dev->pdev->dev, "---> %s()\n", __func__); |
| 2230 | 2231 | ||
| @@ -2313,6 +2314,28 @@ static void handle_setup_packet(struct langwell_udc *dev, | |||
| 2313 | dev->dev_status &= ~(1 << wValue); | 2314 | dev->dev_status &= ~(1 << wValue); |
| 2314 | } | 2315 | } |
| 2315 | break; | 2316 | break; |
| 2317 | case USB_DEVICE_TEST_MODE: | ||
| 2318 | dev_dbg(&dev->pdev->dev, "SETUP: TEST MODE\n"); | ||
| 2319 | if ((wIndex & 0xff) || | ||
| 2320 | (dev->gadget.speed != USB_SPEED_HIGH)) | ||
| 2321 | ep0_stall(dev); | ||
| 2322 | |||
| 2323 | switch (wIndex >> 8) { | ||
| 2324 | case TEST_J: | ||
| 2325 | case TEST_K: | ||
| 2326 | case TEST_SE0_NAK: | ||
| 2327 | case TEST_PACKET: | ||
| 2328 | case TEST_FORCE_EN: | ||
| 2329 | if (prime_status_phase(dev, EP_DIR_IN)) | ||
| 2330 | ep0_stall(dev); | ||
| 2331 | portsc1 = readl(&dev->op_regs->portsc1); | ||
| 2332 | portsc1 |= (wIndex & 0xf00) << 8; | ||
| 2333 | writel(portsc1, &dev->op_regs->portsc1); | ||
| 2334 | goto end; | ||
| 2335 | default: | ||
| 2336 | rc = -EOPNOTSUPP; | ||
| 2337 | } | ||
| 2338 | break; | ||
| 2316 | default: | 2339 | default: |
| 2317 | rc = -EOPNOTSUPP; | 2340 | rc = -EOPNOTSUPP; |
| 2318 | break; | 2341 | break; |
diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index 0769179dbdb0..01822422c3e8 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c | |||
| @@ -102,7 +102,7 @@ static struct fsg_module_parameters mod_data = { | |||
| 102 | }; | 102 | }; |
| 103 | FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); | 103 | FSG_MODULE_PARAMETERS(/* no prefix */, mod_data); |
| 104 | 104 | ||
| 105 | static unsigned long msg_registered = 0; | 105 | static unsigned long msg_registered; |
| 106 | static void msg_cleanup(void); | 106 | static void msg_cleanup(void); |
| 107 | 107 | ||
| 108 | static int msg_thread_exits(struct fsg_common *common) | 108 | static int msg_thread_exits(struct fsg_common *common) |
diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/mv_udc.h new file mode 100644 index 000000000000..65f1f7c3bd4e --- /dev/null +++ b/drivers/usb/gadget/mv_udc.h | |||
| @@ -0,0 +1,294 @@ | |||
| 1 | |||
| 2 | #ifndef __MV_UDC_H | ||
| 3 | #define __MV_UDC_H | ||
| 4 | |||
| 5 | #define VUSBHS_MAX_PORTS 8 | ||
| 6 | |||
| 7 | #define DQH_ALIGNMENT 2048 | ||
| 8 | #define DTD_ALIGNMENT 64 | ||
| 9 | #define DMA_BOUNDARY 4096 | ||
| 10 | |||
| 11 | #define EP_DIR_IN 1 | ||
| 12 | #define EP_DIR_OUT 0 | ||
| 13 | |||
| 14 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
| 15 | |||
| 16 | #define EP0_MAX_PKT_SIZE 64 | ||
| 17 | /* ep0 transfer state */ | ||
| 18 | #define WAIT_FOR_SETUP 0 | ||
| 19 | #define DATA_STATE_XMIT 1 | ||
| 20 | #define DATA_STATE_NEED_ZLP 2 | ||
| 21 | #define WAIT_FOR_OUT_STATUS 3 | ||
| 22 | #define DATA_STATE_RECV 4 | ||
| 23 | |||
| 24 | #define CAPLENGTH_MASK (0xff) | ||
| 25 | #define DCCPARAMS_DEN_MASK (0x1f) | ||
| 26 | |||
| 27 | #define HCSPARAMS_PPC (0x10) | ||
| 28 | |||
| 29 | /* Frame Index Register Bit Masks */ | ||
| 30 | #define USB_FRINDEX_MASKS 0x3fff | ||
| 31 | |||
| 32 | /* Command Register Bit Masks */ | ||
| 33 | #define USBCMD_RUN_STOP (0x00000001) | ||
| 34 | #define USBCMD_CTRL_RESET (0x00000002) | ||
| 35 | #define USBCMD_SETUP_TRIPWIRE_SET (0x00002000) | ||
| 36 | #define USBCMD_SETUP_TRIPWIRE_CLEAR (~USBCMD_SETUP_TRIPWIRE_SET) | ||
| 37 | |||
| 38 | #define USBCMD_ATDTW_TRIPWIRE_SET (0x00004000) | ||
| 39 | #define USBCMD_ATDTW_TRIPWIRE_CLEAR (~USBCMD_ATDTW_TRIPWIRE_SET) | ||
| 40 | |||
| 41 | /* bit 15,3,2 are for frame list size */ | ||
| 42 | #define USBCMD_FRAME_SIZE_1024 (0x00000000) /* 000 */ | ||
| 43 | #define USBCMD_FRAME_SIZE_512 (0x00000004) /* 001 */ | ||
| 44 | #define USBCMD_FRAME_SIZE_256 (0x00000008) /* 010 */ | ||
| 45 | #define USBCMD_FRAME_SIZE_128 (0x0000000C) /* 011 */ | ||
| 46 | #define USBCMD_FRAME_SIZE_64 (0x00008000) /* 100 */ | ||
| 47 | #define USBCMD_FRAME_SIZE_32 (0x00008004) /* 101 */ | ||
| 48 | #define USBCMD_FRAME_SIZE_16 (0x00008008) /* 110 */ | ||
| 49 | #define USBCMD_FRAME_SIZE_8 (0x0000800C) /* 111 */ | ||
| 50 | |||
| 51 | #define EPCTRL_TX_ALL_MASK (0xFFFF0000) | ||
| 52 | #define EPCTRL_RX_ALL_MASK (0x0000FFFF) | ||
| 53 | |||
| 54 | #define EPCTRL_TX_DATA_TOGGLE_RST (0x00400000) | ||
| 55 | #define EPCTRL_TX_EP_STALL (0x00010000) | ||
| 56 | #define EPCTRL_RX_EP_STALL (0x00000001) | ||
| 57 | #define EPCTRL_RX_DATA_TOGGLE_RST (0x00000040) | ||
| 58 | #define EPCTRL_RX_ENABLE (0x00000080) | ||
| 59 | #define EPCTRL_TX_ENABLE (0x00800000) | ||
| 60 | #define EPCTRL_CONTROL (0x00000000) | ||
| 61 | #define EPCTRL_ISOCHRONOUS (0x00040000) | ||
| 62 | #define EPCTRL_BULK (0x00080000) | ||
| 63 | #define EPCTRL_INT (0x000C0000) | ||
| 64 | #define EPCTRL_TX_TYPE (0x000C0000) | ||
| 65 | #define EPCTRL_RX_TYPE (0x0000000C) | ||
| 66 | #define EPCTRL_DATA_TOGGLE_INHIBIT (0x00000020) | ||
| 67 | #define EPCTRL_TX_EP_TYPE_SHIFT (18) | ||
| 68 | #define EPCTRL_RX_EP_TYPE_SHIFT (2) | ||
| 69 | |||
| 70 | #define EPCOMPLETE_MAX_ENDPOINTS (16) | ||
| 71 | |||
| 72 | /* endpoint list address bit masks */ | ||
| 73 | #define USB_EP_LIST_ADDRESS_MASK 0xfffff800 | ||
| 74 | |||
| 75 | #define PORTSCX_W1C_BITS 0x2a | ||
| 76 | #define PORTSCX_PORT_RESET 0x00000100 | ||
| 77 | #define PORTSCX_PORT_POWER 0x00001000 | ||
| 78 | #define PORTSCX_FORCE_FULL_SPEED_CONNECT 0x01000000 | ||
| 79 | #define PORTSCX_PAR_XCVR_SELECT 0xC0000000 | ||
| 80 | #define PORTSCX_PORT_FORCE_RESUME 0x00000040 | ||
| 81 | #define PORTSCX_PORT_SUSPEND 0x00000080 | ||
| 82 | #define PORTSCX_PORT_SPEED_FULL 0x00000000 | ||
| 83 | #define PORTSCX_PORT_SPEED_LOW 0x04000000 | ||
| 84 | #define PORTSCX_PORT_SPEED_HIGH 0x08000000 | ||
| 85 | #define PORTSCX_PORT_SPEED_MASK 0x0C000000 | ||
| 86 | |||
| 87 | /* USB MODE Register Bit Masks */ | ||
| 88 | #define USBMODE_CTRL_MODE_IDLE 0x00000000 | ||
| 89 | #define USBMODE_CTRL_MODE_DEVICE 0x00000002 | ||
| 90 | #define USBMODE_CTRL_MODE_HOST 0x00000003 | ||
| 91 | #define USBMODE_CTRL_MODE_RSV 0x00000001 | ||
| 92 | #define USBMODE_SETUP_LOCK_OFF 0x00000008 | ||
| 93 | #define USBMODE_STREAM_DISABLE 0x00000010 | ||
| 94 | |||
| 95 | /* USB STS Register Bit Masks */ | ||
| 96 | #define USBSTS_INT 0x00000001 | ||
| 97 | #define USBSTS_ERR 0x00000002 | ||
| 98 | #define USBSTS_PORT_CHANGE 0x00000004 | ||
| 99 | #define USBSTS_FRM_LST_ROLL 0x00000008 | ||
| 100 | #define USBSTS_SYS_ERR 0x00000010 | ||
| 101 | #define USBSTS_IAA 0x00000020 | ||
| 102 | #define USBSTS_RESET 0x00000040 | ||
| 103 | #define USBSTS_SOF 0x00000080 | ||
| 104 | #define USBSTS_SUSPEND 0x00000100 | ||
| 105 | #define USBSTS_HC_HALTED 0x00001000 | ||
| 106 | #define USBSTS_RCL 0x00002000 | ||
| 107 | #define USBSTS_PERIODIC_SCHEDULE 0x00004000 | ||
| 108 | #define USBSTS_ASYNC_SCHEDULE 0x00008000 | ||
| 109 | |||
| 110 | |||
| 111 | /* Interrupt Enable Register Bit Masks */ | ||
| 112 | #define USBINTR_INT_EN (0x00000001) | ||
| 113 | #define USBINTR_ERR_INT_EN (0x00000002) | ||
| 114 | #define USBINTR_PORT_CHANGE_DETECT_EN (0x00000004) | ||
| 115 | |||
| 116 | #define USBINTR_ASYNC_ADV_AAE (0x00000020) | ||
| 117 | #define USBINTR_ASYNC_ADV_AAE_ENABLE (0x00000020) | ||
| 118 | #define USBINTR_ASYNC_ADV_AAE_DISABLE (0xFFFFFFDF) | ||
| 119 | |||
| 120 | #define USBINTR_RESET_EN (0x00000040) | ||
| 121 | #define USBINTR_SOF_UFRAME_EN (0x00000080) | ||
| 122 | #define USBINTR_DEVICE_SUSPEND (0x00000100) | ||
| 123 | |||
| 124 | #define USB_DEVICE_ADDRESS_MASK (0xfe000000) | ||
| 125 | #define USB_DEVICE_ADDRESS_BIT_SHIFT (25) | ||
| 126 | |||
| 127 | struct mv_cap_regs { | ||
| 128 | u32 caplength_hciversion; | ||
| 129 | u32 hcsparams; /* HC structural parameters */ | ||
| 130 | u32 hccparams; /* HC Capability Parameters*/ | ||
| 131 | u32 reserved[5]; | ||
| 132 | u32 dciversion; /* DC version number and reserved 16 bits */ | ||
| 133 | u32 dccparams; /* DC Capability Parameters */ | ||
| 134 | }; | ||
| 135 | |||
| 136 | struct mv_op_regs { | ||
| 137 | u32 usbcmd; /* Command register */ | ||
| 138 | u32 usbsts; /* Status register */ | ||
| 139 | u32 usbintr; /* Interrupt enable */ | ||
| 140 | u32 frindex; /* Frame index */ | ||
| 141 | u32 reserved1[1]; | ||
| 142 | u32 deviceaddr; /* Device Address */ | ||
| 143 | u32 eplistaddr; /* Endpoint List Address */ | ||
| 144 | u32 ttctrl; /* HOST TT status and control */ | ||
| 145 | u32 burstsize; /* Programmable Burst Size */ | ||
| 146 | u32 txfilltuning; /* Host Transmit Pre-Buffer Packet Tuning */ | ||
| 147 | u32 reserved[4]; | ||
| 148 | u32 epnak; /* Endpoint NAK */ | ||
| 149 | u32 epnaken; /* Endpoint NAK Enable */ | ||
| 150 | u32 configflag; /* Configured Flag register */ | ||
| 151 | u32 portsc[VUSBHS_MAX_PORTS]; /* Port Status/Control x, x = 1..8 */ | ||
| 152 | u32 otgsc; | ||
| 153 | u32 usbmode; /* USB Host/Device mode */ | ||
| 154 | u32 epsetupstat; /* Endpoint Setup Status */ | ||
| 155 | u32 epprime; /* Endpoint Initialize */ | ||
| 156 | u32 epflush; /* Endpoint De-initialize */ | ||
| 157 | u32 epstatus; /* Endpoint Status */ | ||
| 158 | u32 epcomplete; /* Endpoint Interrupt On Complete */ | ||
| 159 | u32 epctrlx[16]; /* Endpoint Control, where x = 0.. 15 */ | ||
| 160 | u32 mcr; /* Mux Control */ | ||
| 161 | u32 isr; /* Interrupt Status */ | ||
| 162 | u32 ier; /* Interrupt Enable */ | ||
| 163 | }; | ||
| 164 | |||
| 165 | struct mv_udc { | ||
| 166 | struct usb_gadget gadget; | ||
| 167 | struct usb_gadget_driver *driver; | ||
| 168 | spinlock_t lock; | ||
| 169 | struct completion *done; | ||
| 170 | struct platform_device *dev; | ||
| 171 | int irq; | ||
| 172 | |||
| 173 | struct mv_cap_regs __iomem *cap_regs; | ||
| 174 | struct mv_op_regs __iomem *op_regs; | ||
| 175 | unsigned int phy_regs; | ||
| 176 | unsigned int max_eps; | ||
| 177 | struct mv_dqh *ep_dqh; | ||
| 178 | size_t ep_dqh_size; | ||
| 179 | dma_addr_t ep_dqh_dma; | ||
| 180 | |||
| 181 | struct dma_pool *dtd_pool; | ||
| 182 | struct mv_ep *eps; | ||
| 183 | |||
| 184 | struct mv_dtd *dtd_head; | ||
| 185 | struct mv_dtd *dtd_tail; | ||
| 186 | unsigned int dtd_entries; | ||
| 187 | |||
| 188 | struct mv_req *status_req; | ||
| 189 | struct usb_ctrlrequest local_setup_buff; | ||
| 190 | |||
| 191 | unsigned int resume_state; /* USB state to resume */ | ||
| 192 | unsigned int usb_state; /* USB current state */ | ||
| 193 | unsigned int ep0_state; /* Endpoint zero state */ | ||
| 194 | unsigned int ep0_dir; | ||
| 195 | |||
| 196 | unsigned int dev_addr; | ||
| 197 | |||
| 198 | int errors; | ||
| 199 | unsigned softconnect:1, | ||
| 200 | vbus_active:1, | ||
| 201 | remote_wakeup:1, | ||
| 202 | softconnected:1, | ||
| 203 | force_fs:1; | ||
| 204 | struct clk *clk; | ||
| 205 | }; | ||
| 206 | |||
| 207 | /* endpoint data structure */ | ||
| 208 | struct mv_ep { | ||
| 209 | struct usb_ep ep; | ||
| 210 | struct mv_udc *udc; | ||
| 211 | struct list_head queue; | ||
| 212 | struct mv_dqh *dqh; | ||
| 213 | const struct usb_endpoint_descriptor *desc; | ||
| 214 | u32 direction; | ||
| 215 | char name[14]; | ||
| 216 | unsigned stopped:1, | ||
| 217 | wedge:1, | ||
| 218 | ep_type:2, | ||
| 219 | ep_num:8; | ||
| 220 | }; | ||
| 221 | |||
| 222 | /* request data structure */ | ||
| 223 | struct mv_req { | ||
| 224 | struct usb_request req; | ||
| 225 | struct mv_dtd *dtd, *head, *tail; | ||
| 226 | struct mv_ep *ep; | ||
| 227 | struct list_head queue; | ||
| 228 | unsigned dtd_count; | ||
| 229 | unsigned mapped:1; | ||
| 230 | }; | ||
| 231 | |||
| 232 | #define EP_QUEUE_HEAD_MULT_POS 30 | ||
| 233 | #define EP_QUEUE_HEAD_ZLT_SEL 0x20000000 | ||
| 234 | #define EP_QUEUE_HEAD_MAX_PKT_LEN_POS 16 | ||
| 235 | #define EP_QUEUE_HEAD_MAX_PKT_LEN(ep_info) (((ep_info)>>16)&0x07ff) | ||
| 236 | #define EP_QUEUE_HEAD_IOS 0x00008000 | ||
| 237 | #define EP_QUEUE_HEAD_NEXT_TERMINATE 0x00000001 | ||
| 238 | #define EP_QUEUE_HEAD_IOC 0x00008000 | ||
| 239 | #define EP_QUEUE_HEAD_MULTO 0x00000C00 | ||
| 240 | #define EP_QUEUE_HEAD_STATUS_HALT 0x00000040 | ||
| 241 | #define EP_QUEUE_HEAD_STATUS_ACTIVE 0x00000080 | ||
| 242 | #define EP_QUEUE_CURRENT_OFFSET_MASK 0x00000FFF | ||
| 243 | #define EP_QUEUE_HEAD_NEXT_POINTER_MASK 0xFFFFFFE0 | ||
| 244 | #define EP_QUEUE_FRINDEX_MASK 0x000007FF | ||
| 245 | #define EP_MAX_LENGTH_TRANSFER 0x4000 | ||
| 246 | |||
| 247 | struct mv_dqh { | ||
| 248 | /* Bits 16..26 Bit 15 is Interrupt On Setup */ | ||
| 249 | u32 max_packet_length; | ||
| 250 | u32 curr_dtd_ptr; /* Current dTD Pointer */ | ||
| 251 | u32 next_dtd_ptr; /* Next dTD Pointer */ | ||
| 252 | /* Total bytes (16..30), IOC (15), INT (8), STS (0-7) */ | ||
| 253 | u32 size_ioc_int_sts; | ||
| 254 | u32 buff_ptr0; /* Buffer pointer Page 0 (12-31) */ | ||
| 255 | u32 buff_ptr1; /* Buffer pointer Page 1 (12-31) */ | ||
| 256 | u32 buff_ptr2; /* Buffer pointer Page 2 (12-31) */ | ||
| 257 | u32 buff_ptr3; /* Buffer pointer Page 3 (12-31) */ | ||
| 258 | u32 buff_ptr4; /* Buffer pointer Page 4 (12-31) */ | ||
| 259 | u32 reserved1; | ||
| 260 | /* 8 bytes of setup data that follows the Setup PID */ | ||
| 261 | u8 setup_buffer[8]; | ||
| 262 | u32 reserved2[4]; | ||
| 263 | }; | ||
| 264 | |||
| 265 | |||
| 266 | #define DTD_NEXT_TERMINATE (0x00000001) | ||
| 267 | #define DTD_IOC (0x00008000) | ||
| 268 | #define DTD_STATUS_ACTIVE (0x00000080) | ||
| 269 | #define DTD_STATUS_HALTED (0x00000040) | ||
| 270 | #define DTD_STATUS_DATA_BUFF_ERR (0x00000020) | ||
| 271 | #define DTD_STATUS_TRANSACTION_ERR (0x00000008) | ||
| 272 | #define DTD_RESERVED_FIELDS (0x00007F00) | ||
| 273 | #define DTD_ERROR_MASK (0x68) | ||
| 274 | #define DTD_ADDR_MASK (0xFFFFFFE0) | ||
| 275 | #define DTD_PACKET_SIZE 0x7FFF0000 | ||
| 276 | #define DTD_LENGTH_BIT_POS (16) | ||
| 277 | |||
| 278 | struct mv_dtd { | ||
| 279 | u32 dtd_next; | ||
| 280 | u32 size_ioc_sts; | ||
| 281 | u32 buff_ptr0; /* Buffer pointer Page 0 */ | ||
| 282 | u32 buff_ptr1; /* Buffer pointer Page 1 */ | ||
| 283 | u32 buff_ptr2; /* Buffer pointer Page 2 */ | ||
| 284 | u32 buff_ptr3; /* Buffer pointer Page 3 */ | ||
| 285 | u32 buff_ptr4; /* Buffer pointer Page 4 */ | ||
| 286 | u32 scratch_ptr; | ||
| 287 | /* 32 bytes */ | ||
| 288 | dma_addr_t td_dma; /* dma address for this td */ | ||
| 289 | struct mv_dtd *next_dtd_virt; | ||
| 290 | }; | ||
| 291 | |||
| 292 | extern int mv_udc_phy_init(unsigned int base); | ||
| 293 | |||
| 294 | #endif | ||
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c new file mode 100644 index 000000000000..d5468a7f38e0 --- /dev/null +++ b/drivers/usb/gadget/mv_udc_core.c | |||
| @@ -0,0 +1,2149 @@ | |||
| 1 | #include <linux/module.h> | ||
| 2 | #include <linux/pci.h> | ||
| 3 | #include <linux/dma-mapping.h> | ||
| 4 | #include <linux/dmapool.h> | ||
| 5 | #include <linux/kernel.h> | ||
| 6 | #include <linux/delay.h> | ||
| 7 | #include <linux/ioport.h> | ||
| 8 | #include <linux/sched.h> | ||
| 9 | #include <linux/slab.h> | ||
| 10 | #include <linux/errno.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/timer.h> | ||
| 13 | #include <linux/list.h> | ||
| 14 | #include <linux/interrupt.h> | ||
| 15 | #include <linux/moduleparam.h> | ||
| 16 | #include <linux/device.h> | ||
| 17 | #include <linux/usb/ch9.h> | ||
| 18 | #include <linux/usb/gadget.h> | ||
| 19 | #include <linux/usb/otg.h> | ||
| 20 | #include <linux/pm.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/irq.h> | ||
| 23 | #include <linux/platform_device.h> | ||
| 24 | #include <linux/clk.h> | ||
| 25 | #include <asm/system.h> | ||
| 26 | #include <asm/unaligned.h> | ||
| 27 | |||
| 28 | #include "mv_udc.h" | ||
| 29 | |||
| 30 | #define DRIVER_DESC "Marvell PXA USB Device Controller driver" | ||
| 31 | #define DRIVER_VERSION "8 Nov 2010" | ||
| 32 | |||
| 33 | #define ep_dir(ep) (((ep)->ep_num == 0) ? \ | ||
| 34 | ((ep)->udc->ep0_dir) : ((ep)->direction)) | ||
| 35 | |||
| 36 | /* timeout value -- usec */ | ||
| 37 | #define RESET_TIMEOUT 10000 | ||
| 38 | #define FLUSH_TIMEOUT 10000 | ||
| 39 | #define EPSTATUS_TIMEOUT 10000 | ||
| 40 | #define PRIME_TIMEOUT 10000 | ||
| 41 | #define READSAFE_TIMEOUT 1000 | ||
| 42 | #define DTD_TIMEOUT 1000 | ||
| 43 | |||
| 44 | #define LOOPS_USEC_SHIFT 4 | ||
| 45 | #define LOOPS_USEC (1 << LOOPS_USEC_SHIFT) | ||
| 46 | #define LOOPS(timeout) ((timeout) >> LOOPS_USEC_SHIFT) | ||
| 47 | |||
| 48 | static const char driver_name[] = "mv_udc"; | ||
| 49 | static const char driver_desc[] = DRIVER_DESC; | ||
| 50 | |||
| 51 | /* controller device global variable */ | ||
| 52 | static struct mv_udc *the_controller; | ||
| 53 | int mv_usb_otgsc; | ||
| 54 | |||
| 55 | static void nuke(struct mv_ep *ep, int status); | ||
| 56 | |||
| 57 | /* for endpoint 0 operations */ | ||
| 58 | static const struct usb_endpoint_descriptor mv_ep0_desc = { | ||
| 59 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
| 60 | .bDescriptorType = USB_DT_ENDPOINT, | ||
| 61 | .bEndpointAddress = 0, | ||
| 62 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
| 63 | .wMaxPacketSize = EP0_MAX_PKT_SIZE, | ||
| 64 | }; | ||
| 65 | |||
| 66 | static void ep0_reset(struct mv_udc *udc) | ||
| 67 | { | ||
| 68 | struct mv_ep *ep; | ||
| 69 | u32 epctrlx; | ||
| 70 | int i = 0; | ||
| 71 | |||
| 72 | /* ep0 in and out */ | ||
| 73 | for (i = 0; i < 2; i++) { | ||
| 74 | ep = &udc->eps[i]; | ||
| 75 | ep->udc = udc; | ||
| 76 | |||
| 77 | /* ep0 dQH */ | ||
| 78 | ep->dqh = &udc->ep_dqh[i]; | ||
| 79 | |||
| 80 | /* configure ep0 endpoint capabilities in dQH */ | ||
| 81 | ep->dqh->max_packet_length = | ||
| 82 | (EP0_MAX_PKT_SIZE << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) | ||
| 83 | | EP_QUEUE_HEAD_IOS; | ||
| 84 | |||
| 85 | epctrlx = readl(&udc->op_regs->epctrlx[0]); | ||
| 86 | if (i) { /* TX */ | ||
| 87 | epctrlx |= EPCTRL_TX_ENABLE | EPCTRL_TX_DATA_TOGGLE_RST | ||
| 88 | | (USB_ENDPOINT_XFER_CONTROL | ||
| 89 | << EPCTRL_TX_EP_TYPE_SHIFT); | ||
| 90 | |||
| 91 | } else { /* RX */ | ||
| 92 | epctrlx |= EPCTRL_RX_ENABLE | EPCTRL_RX_DATA_TOGGLE_RST | ||
| 93 | | (USB_ENDPOINT_XFER_CONTROL | ||
| 94 | << EPCTRL_RX_EP_TYPE_SHIFT); | ||
| 95 | } | ||
| 96 | |||
| 97 | writel(epctrlx, &udc->op_regs->epctrlx[0]); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | /* protocol ep0 stall, will automatically be cleared on new transaction */ | ||
| 102 | static void ep0_stall(struct mv_udc *udc) | ||
| 103 | { | ||
| 104 | u32 epctrlx; | ||
| 105 | |||
| 106 | /* set TX and RX to stall */ | ||
| 107 | epctrlx = readl(&udc->op_regs->epctrlx[0]); | ||
| 108 | epctrlx |= EPCTRL_RX_EP_STALL | EPCTRL_TX_EP_STALL; | ||
| 109 | writel(epctrlx, &udc->op_regs->epctrlx[0]); | ||
| 110 | |||
| 111 | /* update ep0 state */ | ||
| 112 | udc->ep0_state = WAIT_FOR_SETUP; | ||
| 113 | udc->ep0_dir = EP_DIR_OUT; | ||
| 114 | } | ||
| 115 | |||
| 116 | static int process_ep_req(struct mv_udc *udc, int index, | ||
| 117 | struct mv_req *curr_req) | ||
| 118 | { | ||
| 119 | struct mv_dtd *curr_dtd; | ||
| 120 | struct mv_dqh *curr_dqh; | ||
| 121 | int td_complete, actual, remaining_length; | ||
| 122 | int i, direction; | ||
| 123 | int retval = 0; | ||
| 124 | u32 errors; | ||
| 125 | |||
| 126 | curr_dqh = &udc->ep_dqh[index]; | ||
| 127 | direction = index % 2; | ||
| 128 | |||
| 129 | curr_dtd = curr_req->head; | ||
| 130 | td_complete = 0; | ||
| 131 | actual = curr_req->req.length; | ||
| 132 | |||
| 133 | for (i = 0; i < curr_req->dtd_count; i++) { | ||
| 134 | if (curr_dtd->size_ioc_sts & DTD_STATUS_ACTIVE) { | ||
| 135 | dev_dbg(&udc->dev->dev, "%s, dTD not completed\n", | ||
| 136 | udc->eps[index].name); | ||
| 137 | return 1; | ||
| 138 | } | ||
| 139 | |||
| 140 | errors = curr_dtd->size_ioc_sts & DTD_ERROR_MASK; | ||
| 141 | if (!errors) { | ||
| 142 | remaining_length += | ||
| 143 | (curr_dtd->size_ioc_sts & DTD_PACKET_SIZE) | ||
| 144 | >> DTD_LENGTH_BIT_POS; | ||
| 145 | actual -= remaining_length; | ||
| 146 | } else { | ||
| 147 | dev_info(&udc->dev->dev, | ||
| 148 | "complete_tr error: ep=%d %s: error = 0x%x\n", | ||
| 149 | index >> 1, direction ? "SEND" : "RECV", | ||
| 150 | errors); | ||
| 151 | if (errors & DTD_STATUS_HALTED) { | ||
| 152 | /* Clear the errors and Halt condition */ | ||
| 153 | curr_dqh->size_ioc_int_sts &= ~errors; | ||
| 154 | retval = -EPIPE; | ||
| 155 | } else if (errors & DTD_STATUS_DATA_BUFF_ERR) { | ||
| 156 | retval = -EPROTO; | ||
| 157 | } else if (errors & DTD_STATUS_TRANSACTION_ERR) { | ||
| 158 | retval = -EILSEQ; | ||
| 159 | } | ||
| 160 | } | ||
| 161 | if (i != curr_req->dtd_count - 1) | ||
| 162 | curr_dtd = (struct mv_dtd *)curr_dtd->next_dtd_virt; | ||
| 163 | } | ||
| 164 | if (retval) | ||
| 165 | return retval; | ||
| 166 | |||
| 167 | curr_req->req.actual = actual; | ||
| 168 | |||
| 169 | return 0; | ||
| 170 | } | ||
| 171 | |||
| 172 | /* | ||
| 173 | * done() - retire a request; caller blocked irqs | ||
| 174 | * @status : request status to be set, only works when | ||
| 175 | * request is still in progress. | ||
| 176 | */ | ||
| 177 | static void done(struct mv_ep *ep, struct mv_req *req, int status) | ||
| 178 | { | ||
| 179 | struct mv_udc *udc = NULL; | ||
| 180 | unsigned char stopped = ep->stopped; | ||
| 181 | struct mv_dtd *curr_td, *next_td; | ||
| 182 | int j; | ||
| 183 | |||
| 184 | udc = (struct mv_udc *)ep->udc; | ||
| 185 | /* Removed the req from fsl_ep->queue */ | ||
| 186 | list_del_init(&req->queue); | ||
| 187 | |||
| 188 | /* req.status should be set as -EINPROGRESS in ep_queue() */ | ||
| 189 | if (req->req.status == -EINPROGRESS) | ||
| 190 | req->req.status = status; | ||
| 191 | else | ||
| 192 | status = req->req.status; | ||
| 193 | |||
| 194 | /* Free dtd for the request */ | ||
| 195 | next_td = req->head; | ||
| 196 | for (j = 0; j < req->dtd_count; j++) { | ||
| 197 | curr_td = next_td; | ||
| 198 | if (j != req->dtd_count - 1) | ||
| 199 | next_td = curr_td->next_dtd_virt; | ||
| 200 | dma_pool_free(udc->dtd_pool, curr_td, curr_td->td_dma); | ||
| 201 | } | ||
| 202 | |||
| 203 | if (req->mapped) { | ||
| 204 | dma_unmap_single(ep->udc->gadget.dev.parent, | ||
| 205 | req->req.dma, req->req.length, | ||
| 206 | ((ep_dir(ep) == EP_DIR_IN) ? | ||
| 207 | DMA_TO_DEVICE : DMA_FROM_DEVICE)); | ||
| 208 | req->req.dma = DMA_ADDR_INVALID; | ||
| 209 | req->mapped = 0; | ||
| 210 | } else | ||
| 211 | dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, | ||
| 212 | req->req.dma, req->req.length, | ||
| 213 | ((ep_dir(ep) == EP_DIR_IN) ? | ||
| 214 | DMA_TO_DEVICE : DMA_FROM_DEVICE)); | ||
| 215 | |||
| 216 | if (status && (status != -ESHUTDOWN)) | ||
| 217 | dev_info(&udc->dev->dev, "complete %s req %p stat %d len %u/%u", | ||
| 218 | ep->ep.name, &req->req, status, | ||
| 219 | req->req.actual, req->req.length); | ||
| 220 | |||
| 221 | ep->stopped = 1; | ||
| 222 | |||
| 223 | spin_unlock(&ep->udc->lock); | ||
| 224 | /* | ||
| 225 | * complete() is from gadget layer, | ||
| 226 | * eg fsg->bulk_in_complete() | ||
| 227 | */ | ||
| 228 | if (req->req.complete) | ||
| 229 | req->req.complete(&ep->ep, &req->req); | ||
| 230 | |||
| 231 | spin_lock(&ep->udc->lock); | ||
| 232 | ep->stopped = stopped; | ||
| 233 | } | ||
| 234 | |||
| 235 | static int queue_dtd(struct mv_ep *ep, struct mv_req *req) | ||
| 236 | { | ||
| 237 | u32 tmp, epstatus, bit_pos, direction; | ||
| 238 | struct mv_udc *udc; | ||
| 239 | struct mv_dqh *dqh; | ||
| 240 | unsigned int loops; | ||
| 241 | int readsafe, retval = 0; | ||
| 242 | |||
| 243 | udc = ep->udc; | ||
| 244 | direction = ep_dir(ep); | ||
| 245 | dqh = &(udc->ep_dqh[ep->ep_num * 2 + direction]); | ||
| 246 | bit_pos = 1 << (((direction == EP_DIR_OUT) ? 0 : 16) + ep->ep_num); | ||
| 247 | |||
| 248 | /* check if the pipe is empty */ | ||
| 249 | if (!(list_empty(&ep->queue))) { | ||
| 250 | struct mv_req *lastreq; | ||
| 251 | lastreq = list_entry(ep->queue.prev, struct mv_req, queue); | ||
| 252 | lastreq->tail->dtd_next = | ||
| 253 | req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; | ||
| 254 | if (readl(&udc->op_regs->epprime) & bit_pos) { | ||
| 255 | loops = LOOPS(PRIME_TIMEOUT); | ||
| 256 | while (readl(&udc->op_regs->epprime) & bit_pos) { | ||
| 257 | if (loops == 0) { | ||
| 258 | retval = -ETIME; | ||
| 259 | goto done; | ||
| 260 | } | ||
| 261 | udelay(LOOPS_USEC); | ||
| 262 | loops--; | ||
| 263 | } | ||
| 264 | if (readl(&udc->op_regs->epstatus) & bit_pos) | ||
| 265 | goto done; | ||
| 266 | } | ||
| 267 | readsafe = 0; | ||
| 268 | loops = LOOPS(READSAFE_TIMEOUT); | ||
| 269 | while (readsafe == 0) { | ||
| 270 | if (loops == 0) { | ||
| 271 | retval = -ETIME; | ||
| 272 | goto done; | ||
| 273 | } | ||
| 274 | /* start with setting the semaphores */ | ||
| 275 | tmp = readl(&udc->op_regs->usbcmd); | ||
| 276 | tmp |= USBCMD_ATDTW_TRIPWIRE_SET; | ||
| 277 | writel(tmp, &udc->op_regs->usbcmd); | ||
| 278 | |||
| 279 | /* read the endpoint status */ | ||
| 280 | epstatus = readl(&udc->op_regs->epstatus) & bit_pos; | ||
| 281 | |||
| 282 | /* | ||
| 283 | * Reread the ATDTW semaphore bit to check if it is | ||
| 284 | * cleared. When hardware see a hazard, it will clear | ||
| 285 | * the bit or else we remain set to 1 and we can | ||
| 286 | * proceed with priming of endpoint if not already | ||
| 287 | * primed. | ||
| 288 | */ | ||
| 289 | if (readl(&udc->op_regs->usbcmd) | ||
| 290 | & USBCMD_ATDTW_TRIPWIRE_SET) { | ||
| 291 | readsafe = 1; | ||
| 292 | } | ||
| 293 | loops--; | ||
| 294 | udelay(LOOPS_USEC); | ||
| 295 | } | ||
| 296 | |||
| 297 | /* Clear the semaphore */ | ||
| 298 | tmp = readl(&udc->op_regs->usbcmd); | ||
| 299 | tmp &= USBCMD_ATDTW_TRIPWIRE_CLEAR; | ||
| 300 | writel(tmp, &udc->op_regs->usbcmd); | ||
| 301 | |||
| 302 | /* If endpoint is not active, we activate it now. */ | ||
| 303 | if (!epstatus) { | ||
| 304 | if (direction == EP_DIR_IN) { | ||
| 305 | struct mv_dtd *curr_dtd = dma_to_virt( | ||
| 306 | &udc->dev->dev, dqh->curr_dtd_ptr); | ||
| 307 | |||
| 308 | loops = LOOPS(DTD_TIMEOUT); | ||
| 309 | while (curr_dtd->size_ioc_sts | ||
| 310 | & DTD_STATUS_ACTIVE) { | ||
| 311 | if (loops == 0) { | ||
| 312 | retval = -ETIME; | ||
| 313 | goto done; | ||
| 314 | } | ||
| 315 | loops--; | ||
| 316 | udelay(LOOPS_USEC); | ||
| 317 | } | ||
| 318 | } | ||
| 319 | /* No other transfers on the queue */ | ||
| 320 | |||
| 321 | /* Write dQH next pointer and terminate bit to 0 */ | ||
| 322 | dqh->next_dtd_ptr = req->head->td_dma | ||
| 323 | & EP_QUEUE_HEAD_NEXT_POINTER_MASK; | ||
| 324 | dqh->size_ioc_int_sts = 0; | ||
| 325 | |||
| 326 | /* | ||
| 327 | * Ensure that updates to the QH will | ||
| 328 | * occure before priming. | ||
| 329 | */ | ||
| 330 | wmb(); | ||
| 331 | |||
| 332 | /* Prime the Endpoint */ | ||
| 333 | writel(bit_pos, &udc->op_regs->epprime); | ||
| 334 | } | ||
| 335 | } else { | ||
| 336 | /* Write dQH next pointer and terminate bit to 0 */ | ||
| 337 | dqh->next_dtd_ptr = req->head->td_dma | ||
| 338 | & EP_QUEUE_HEAD_NEXT_POINTER_MASK;; | ||
| 339 | dqh->size_ioc_int_sts = 0; | ||
| 340 | |||
| 341 | /* Ensure that updates to the QH will occure before priming. */ | ||
| 342 | wmb(); | ||
| 343 | |||
| 344 | /* Prime the Endpoint */ | ||
| 345 | writel(bit_pos, &udc->op_regs->epprime); | ||
| 346 | |||
| 347 | if (direction == EP_DIR_IN) { | ||
| 348 | /* FIXME add status check after prime the IN ep */ | ||
| 349 | int prime_again; | ||
| 350 | u32 curr_dtd_ptr = dqh->curr_dtd_ptr; | ||
| 351 | |||
| 352 | loops = LOOPS(DTD_TIMEOUT); | ||
| 353 | prime_again = 0; | ||
| 354 | while ((curr_dtd_ptr != req->head->td_dma)) { | ||
| 355 | curr_dtd_ptr = dqh->curr_dtd_ptr; | ||
| 356 | if (loops == 0) { | ||
| 357 | dev_err(&udc->dev->dev, | ||
| 358 | "failed to prime %s\n", | ||
| 359 | ep->name); | ||
| 360 | retval = -ETIME; | ||
| 361 | goto done; | ||
| 362 | } | ||
| 363 | loops--; | ||
| 364 | udelay(LOOPS_USEC); | ||
| 365 | |||
| 366 | if (loops == (LOOPS(DTD_TIMEOUT) >> 2)) { | ||
| 367 | if (prime_again) | ||
| 368 | goto done; | ||
| 369 | dev_info(&udc->dev->dev, | ||
| 370 | "prime again\n"); | ||
| 371 | writel(bit_pos, | ||
| 372 | &udc->op_regs->epprime); | ||
| 373 | prime_again = 1; | ||
| 374 | } | ||
| 375 | } | ||
| 376 | } | ||
| 377 | } | ||
| 378 | done: | ||
| 379 | return retval;; | ||
| 380 | } | ||
| 381 | |||
| 382 | static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length, | ||
| 383 | dma_addr_t *dma, int *is_last) | ||
| 384 | { | ||
| 385 | u32 temp; | ||
| 386 | struct mv_dtd *dtd; | ||
| 387 | struct mv_udc *udc; | ||
| 388 | |||
| 389 | /* how big will this transfer be? */ | ||
| 390 | *length = min(req->req.length - req->req.actual, | ||
| 391 | (unsigned)EP_MAX_LENGTH_TRANSFER); | ||
| 392 | |||
| 393 | udc = req->ep->udc; | ||
| 394 | |||
| 395 | /* | ||
| 396 | * Be careful that no _GFP_HIGHMEM is set, | ||
| 397 | * or we can not use dma_to_virt | ||
| 398 | */ | ||
| 399 | dtd = dma_pool_alloc(udc->dtd_pool, GFP_KERNEL, dma); | ||
| 400 | if (dtd == NULL) | ||
| 401 | return dtd; | ||
| 402 | |||
| 403 | dtd->td_dma = *dma; | ||
| 404 | /* initialize buffer page pointers */ | ||
| 405 | temp = (u32)(req->req.dma + req->req.actual); | ||
| 406 | dtd->buff_ptr0 = cpu_to_le32(temp); | ||
| 407 | temp &= ~0xFFF; | ||
| 408 | dtd->buff_ptr1 = cpu_to_le32(temp + 0x1000); | ||
| 409 | dtd->buff_ptr2 = cpu_to_le32(temp + 0x2000); | ||
| 410 | dtd->buff_ptr3 = cpu_to_le32(temp + 0x3000); | ||
| 411 | dtd->buff_ptr4 = cpu_to_le32(temp + 0x4000); | ||
| 412 | |||
| 413 | req->req.actual += *length; | ||
| 414 | |||
| 415 | /* zlp is needed if req->req.zero is set */ | ||
| 416 | if (req->req.zero) { | ||
| 417 | if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0) | ||
| 418 | *is_last = 1; | ||
| 419 | else | ||
| 420 | *is_last = 0; | ||
| 421 | } else if (req->req.length == req->req.actual) | ||
| 422 | *is_last = 1; | ||
| 423 | else | ||
| 424 | *is_last = 0; | ||
| 425 | |||
| 426 | /* Fill in the transfer size; set active bit */ | ||
| 427 | temp = ((*length << DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE); | ||
| 428 | |||
| 429 | /* Enable interrupt for the last dtd of a request */ | ||
| 430 | if (*is_last && !req->req.no_interrupt) | ||
| 431 | temp |= DTD_IOC; | ||
| 432 | |||
| 433 | dtd->size_ioc_sts = temp; | ||
| 434 | |||
| 435 | mb(); | ||
| 436 | |||
| 437 | return dtd; | ||
| 438 | } | ||
| 439 | |||
| 440 | /* generate dTD linked list for a request */ | ||
| 441 | static int req_to_dtd(struct mv_req *req) | ||
| 442 | { | ||
| 443 | unsigned count; | ||
| 444 | int is_last, is_first = 1; | ||
| 445 | struct mv_dtd *dtd, *last_dtd = NULL; | ||
| 446 | struct mv_udc *udc; | ||
| 447 | dma_addr_t dma; | ||
| 448 | |||
| 449 | udc = req->ep->udc; | ||
| 450 | |||
| 451 | do { | ||
| 452 | dtd = build_dtd(req, &count, &dma, &is_last); | ||
| 453 | if (dtd == NULL) | ||
| 454 | return -ENOMEM; | ||
| 455 | |||
| 456 | if (is_first) { | ||
| 457 | is_first = 0; | ||
| 458 | req->head = dtd; | ||
| 459 | } else { | ||
| 460 | last_dtd->dtd_next = dma; | ||
| 461 | last_dtd->next_dtd_virt = dtd; | ||
| 462 | } | ||
| 463 | last_dtd = dtd; | ||
| 464 | req->dtd_count++; | ||
| 465 | } while (!is_last); | ||
| 466 | |||
| 467 | /* set terminate bit to 1 for the last dTD */ | ||
| 468 | dtd->dtd_next = DTD_NEXT_TERMINATE; | ||
| 469 | |||
| 470 | req->tail = dtd; | ||
| 471 | |||
| 472 | return 0; | ||
| 473 | } | ||
| 474 | |||
| 475 | static int mv_ep_enable(struct usb_ep *_ep, | ||
| 476 | const struct usb_endpoint_descriptor *desc) | ||
| 477 | { | ||
| 478 | struct mv_udc *udc; | ||
| 479 | struct mv_ep *ep; | ||
| 480 | struct mv_dqh *dqh; | ||
| 481 | u16 max = 0; | ||
| 482 | u32 bit_pos, epctrlx, direction; | ||
| 483 | unsigned char zlt = 0, ios = 0, mult = 0; | ||
| 484 | |||
| 485 | ep = container_of(_ep, struct mv_ep, ep); | ||
| 486 | udc = ep->udc; | ||
| 487 | |||
| 488 | if (!_ep || !desc || ep->desc | ||
| 489 | || desc->bDescriptorType != USB_DT_ENDPOINT) | ||
| 490 | return -EINVAL; | ||
| 491 | |||
| 492 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 493 | return -ESHUTDOWN; | ||
| 494 | |||
| 495 | direction = ep_dir(ep); | ||
| 496 | max = le16_to_cpu(desc->wMaxPacketSize); | ||
| 497 | |||
| 498 | /* | ||
| 499 | * disable HW zero length termination select | ||
| 500 | * driver handles zero length packet through req->req.zero | ||
| 501 | */ | ||
| 502 | zlt = 1; | ||
| 503 | |||
| 504 | /* Get the endpoint queue head address */ | ||
| 505 | dqh = (struct mv_dqh *)ep->dqh; | ||
| 506 | |||
| 507 | bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); | ||
| 508 | |||
| 509 | /* Check if the Endpoint is Primed */ | ||
| 510 | if ((readl(&udc->op_regs->epprime) & bit_pos) | ||
| 511 | || (readl(&udc->op_regs->epstatus) & bit_pos)) { | ||
| 512 | dev_info(&udc->dev->dev, | ||
| 513 | "ep=%d %s: Init ERROR: ENDPTPRIME=0x%x," | ||
| 514 | " ENDPTSTATUS=0x%x, bit_pos=0x%x\n", | ||
| 515 | (unsigned)ep->ep_num, direction ? "SEND" : "RECV", | ||
| 516 | (unsigned)readl(&udc->op_regs->epprime), | ||
| 517 | (unsigned)readl(&udc->op_regs->epstatus), | ||
| 518 | (unsigned)bit_pos); | ||
| 519 | goto en_done; | ||
| 520 | } | ||
| 521 | /* Set the max packet length, interrupt on Setup and Mult fields */ | ||
| 522 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
| 523 | case USB_ENDPOINT_XFER_BULK: | ||
| 524 | zlt = 1; | ||
| 525 | mult = 0; | ||
| 526 | break; | ||
| 527 | case USB_ENDPOINT_XFER_CONTROL: | ||
| 528 | ios = 1; | ||
| 529 | case USB_ENDPOINT_XFER_INT: | ||
| 530 | mult = 0; | ||
| 531 | break; | ||
| 532 | case USB_ENDPOINT_XFER_ISOC: | ||
| 533 | /* Calculate transactions needed for high bandwidth iso */ | ||
| 534 | mult = (unsigned char)(1 + ((max >> 11) & 0x03)); | ||
| 535 | max = max & 0x8ff; /* bit 0~10 */ | ||
| 536 | /* 3 transactions at most */ | ||
| 537 | if (mult > 3) | ||
| 538 | goto en_done; | ||
| 539 | break; | ||
| 540 | default: | ||
| 541 | goto en_done; | ||
| 542 | } | ||
| 543 | dqh->max_packet_length = (max << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) | ||
| 544 | | (mult << EP_QUEUE_HEAD_MULT_POS) | ||
| 545 | | (zlt ? EP_QUEUE_HEAD_ZLT_SEL : 0) | ||
| 546 | | (ios ? EP_QUEUE_HEAD_IOS : 0); | ||
| 547 | dqh->next_dtd_ptr = 1; | ||
| 548 | dqh->size_ioc_int_sts = 0; | ||
| 549 | |||
| 550 | ep->ep.maxpacket = max; | ||
| 551 | ep->desc = desc; | ||
| 552 | ep->stopped = 0; | ||
| 553 | |||
| 554 | /* Enable the endpoint for Rx or Tx and set the endpoint type */ | ||
| 555 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); | ||
| 556 | if (direction == EP_DIR_IN) { | ||
| 557 | epctrlx &= ~EPCTRL_TX_ALL_MASK; | ||
| 558 | epctrlx |= EPCTRL_TX_ENABLE | EPCTRL_TX_DATA_TOGGLE_RST | ||
| 559 | | ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
| 560 | << EPCTRL_TX_EP_TYPE_SHIFT); | ||
| 561 | } else { | ||
| 562 | epctrlx &= ~EPCTRL_RX_ALL_MASK; | ||
| 563 | epctrlx |= EPCTRL_RX_ENABLE | EPCTRL_RX_DATA_TOGGLE_RST | ||
| 564 | | ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
| 565 | << EPCTRL_RX_EP_TYPE_SHIFT); | ||
| 566 | } | ||
| 567 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); | ||
| 568 | |||
| 569 | /* | ||
| 570 | * Implement Guideline (GL# USB-7) The unused endpoint type must | ||
| 571 | * be programmed to bulk. | ||
| 572 | */ | ||
| 573 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); | ||
| 574 | if ((epctrlx & EPCTRL_RX_ENABLE) == 0) { | ||
| 575 | epctrlx |= ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
| 576 | << EPCTRL_RX_EP_TYPE_SHIFT); | ||
| 577 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); | ||
| 578 | } | ||
| 579 | |||
| 580 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); | ||
| 581 | if ((epctrlx & EPCTRL_TX_ENABLE) == 0) { | ||
| 582 | epctrlx |= ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | ||
| 583 | << EPCTRL_TX_EP_TYPE_SHIFT); | ||
| 584 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); | ||
| 585 | } | ||
| 586 | |||
| 587 | return 0; | ||
| 588 | en_done: | ||
| 589 | return -EINVAL; | ||
| 590 | } | ||
| 591 | |||
| 592 | static int mv_ep_disable(struct usb_ep *_ep) | ||
| 593 | { | ||
| 594 | struct mv_udc *udc; | ||
| 595 | struct mv_ep *ep; | ||
| 596 | struct mv_dqh *dqh; | ||
| 597 | u32 bit_pos, epctrlx, direction; | ||
| 598 | |||
| 599 | ep = container_of(_ep, struct mv_ep, ep); | ||
| 600 | if ((_ep == NULL) || !ep->desc) | ||
| 601 | return -EINVAL; | ||
| 602 | |||
| 603 | udc = ep->udc; | ||
| 604 | |||
| 605 | /* Get the endpoint queue head address */ | ||
| 606 | dqh = ep->dqh; | ||
| 607 | |||
| 608 | direction = ep_dir(ep); | ||
| 609 | bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); | ||
| 610 | |||
| 611 | /* Reset the max packet length and the interrupt on Setup */ | ||
| 612 | dqh->max_packet_length = 0; | ||
| 613 | |||
| 614 | /* Disable the endpoint for Rx or Tx and reset the endpoint type */ | ||
| 615 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); | ||
| 616 | epctrlx &= ~((direction == EP_DIR_IN) | ||
| 617 | ? (EPCTRL_TX_ENABLE | EPCTRL_TX_TYPE) | ||
| 618 | : (EPCTRL_RX_ENABLE | EPCTRL_RX_TYPE)); | ||
| 619 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); | ||
| 620 | |||
| 621 | /* nuke all pending requests (does flush) */ | ||
| 622 | nuke(ep, -ESHUTDOWN); | ||
| 623 | |||
| 624 | ep->desc = NULL; | ||
| 625 | ep->stopped = 1; | ||
| 626 | return 0; | ||
| 627 | } | ||
| 628 | |||
| 629 | static struct usb_request * | ||
| 630 | mv_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) | ||
| 631 | { | ||
| 632 | struct mv_req *req = NULL; | ||
| 633 | |||
| 634 | req = kzalloc(sizeof *req, gfp_flags); | ||
| 635 | if (!req) | ||
| 636 | return NULL; | ||
| 637 | |||
| 638 | req->req.dma = DMA_ADDR_INVALID; | ||
| 639 | INIT_LIST_HEAD(&req->queue); | ||
| 640 | |||
| 641 | return &req->req; | ||
| 642 | } | ||
| 643 | |||
| 644 | static void mv_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
| 645 | { | ||
| 646 | struct mv_req *req = NULL; | ||
| 647 | |||
| 648 | req = container_of(_req, struct mv_req, req); | ||
| 649 | |||
| 650 | if (_req) | ||
| 651 | kfree(req); | ||
| 652 | } | ||
| 653 | |||
| 654 | static void mv_ep_fifo_flush(struct usb_ep *_ep) | ||
| 655 | { | ||
| 656 | struct mv_udc *udc; | ||
| 657 | u32 bit_pos, direction; | ||
| 658 | struct mv_ep *ep = container_of(_ep, struct mv_ep, ep); | ||
| 659 | unsigned int loops; | ||
| 660 | |||
| 661 | udc = ep->udc; | ||
| 662 | direction = ep_dir(ep); | ||
| 663 | bit_pos = 1 << ((direction == EP_DIR_OUT ? 0 : 16) + ep->ep_num); | ||
| 664 | /* | ||
| 665 | * Flushing will halt the pipe | ||
| 666 | * Write 1 to the Flush register | ||
| 667 | */ | ||
| 668 | writel(bit_pos, &udc->op_regs->epflush); | ||
| 669 | |||
| 670 | /* Wait until flushing completed */ | ||
| 671 | loops = LOOPS(FLUSH_TIMEOUT); | ||
| 672 | while (readl(&udc->op_regs->epflush) & bit_pos) { | ||
| 673 | /* | ||
| 674 | * ENDPTFLUSH bit should be cleared to indicate this | ||
| 675 | * operation is complete | ||
| 676 | */ | ||
| 677 | if (loops == 0) { | ||
| 678 | dev_err(&udc->dev->dev, | ||
| 679 | "TIMEOUT for ENDPTFLUSH=0x%x, bit_pos=0x%x\n", | ||
| 680 | (unsigned)readl(&udc->op_regs->epflush), | ||
| 681 | (unsigned)bit_pos); | ||
| 682 | return; | ||
| 683 | } | ||
| 684 | loops--; | ||
| 685 | udelay(LOOPS_USEC); | ||
| 686 | } | ||
| 687 | loops = LOOPS(EPSTATUS_TIMEOUT); | ||
| 688 | while (readl(&udc->op_regs->epstatus) & bit_pos) { | ||
| 689 | unsigned int inter_loops; | ||
| 690 | |||
| 691 | if (loops == 0) { | ||
| 692 | dev_err(&udc->dev->dev, | ||
| 693 | "TIMEOUT for ENDPTSTATUS=0x%x, bit_pos=0x%x\n", | ||
| 694 | (unsigned)readl(&udc->op_regs->epstatus), | ||
| 695 | (unsigned)bit_pos); | ||
| 696 | return; | ||
| 697 | } | ||
| 698 | /* Write 1 to the Flush register */ | ||
| 699 | writel(bit_pos, &udc->op_regs->epflush); | ||
| 700 | |||
| 701 | /* Wait until flushing completed */ | ||
| 702 | inter_loops = LOOPS(FLUSH_TIMEOUT); | ||
| 703 | while (readl(&udc->op_regs->epflush) & bit_pos) { | ||
| 704 | /* | ||
| 705 | * ENDPTFLUSH bit should be cleared to indicate this | ||
| 706 | * operation is complete | ||
| 707 | */ | ||
| 708 | if (inter_loops == 0) { | ||
| 709 | dev_err(&udc->dev->dev, | ||
| 710 | "TIMEOUT for ENDPTFLUSH=0x%x," | ||
| 711 | "bit_pos=0x%x\n", | ||
| 712 | (unsigned)readl(&udc->op_regs->epflush), | ||
| 713 | (unsigned)bit_pos); | ||
| 714 | return; | ||
| 715 | } | ||
| 716 | inter_loops--; | ||
| 717 | udelay(LOOPS_USEC); | ||
| 718 | } | ||
| 719 | loops--; | ||
| 720 | } | ||
| 721 | } | ||
| 722 | |||
| 723 | /* queues (submits) an I/O request to an endpoint */ | ||
| 724 | static int | ||
| 725 | mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | ||
| 726 | { | ||
| 727 | struct mv_ep *ep = container_of(_ep, struct mv_ep, ep); | ||
| 728 | struct mv_req *req = container_of(_req, struct mv_req, req); | ||
| 729 | struct mv_udc *udc = ep->udc; | ||
| 730 | unsigned long flags; | ||
| 731 | |||
| 732 | /* catch various bogus parameters */ | ||
| 733 | if (!_req || !req->req.complete || !req->req.buf | ||
| 734 | || !list_empty(&req->queue)) { | ||
| 735 | dev_err(&udc->dev->dev, "%s, bad params", __func__); | ||
| 736 | return -EINVAL; | ||
| 737 | } | ||
| 738 | if (unlikely(!_ep || !ep->desc)) { | ||
| 739 | dev_err(&udc->dev->dev, "%s, bad ep", __func__); | ||
| 740 | return -EINVAL; | ||
| 741 | } | ||
| 742 | if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { | ||
| 743 | if (req->req.length > ep->ep.maxpacket) | ||
| 744 | return -EMSGSIZE; | ||
| 745 | } | ||
| 746 | |||
| 747 | udc = ep->udc; | ||
| 748 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) | ||
| 749 | return -ESHUTDOWN; | ||
| 750 | |||
| 751 | req->ep = ep; | ||
| 752 | |||
| 753 | /* map virtual address to hardware */ | ||
| 754 | if (req->req.dma == DMA_ADDR_INVALID) { | ||
| 755 | req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, | ||
| 756 | req->req.buf, | ||
| 757 | req->req.length, ep_dir(ep) | ||
| 758 | ? DMA_TO_DEVICE | ||
| 759 | : DMA_FROM_DEVICE); | ||
| 760 | req->mapped = 1; | ||
| 761 | } else { | ||
| 762 | dma_sync_single_for_device(ep->udc->gadget.dev.parent, | ||
| 763 | req->req.dma, req->req.length, | ||
| 764 | ep_dir(ep) | ||
| 765 | ? DMA_TO_DEVICE | ||
| 766 | : DMA_FROM_DEVICE); | ||
| 767 | req->mapped = 0; | ||
| 768 | } | ||
| 769 | |||
| 770 | req->req.status = -EINPROGRESS; | ||
| 771 | req->req.actual = 0; | ||
| 772 | req->dtd_count = 0; | ||
| 773 | |||
| 774 | spin_lock_irqsave(&udc->lock, flags); | ||
| 775 | |||
| 776 | /* build dtds and push them to device queue */ | ||
| 777 | if (!req_to_dtd(req)) { | ||
| 778 | int retval; | ||
| 779 | retval = queue_dtd(ep, req); | ||
| 780 | if (retval) { | ||
| 781 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 782 | return retval; | ||
| 783 | } | ||
| 784 | } else { | ||
| 785 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 786 | return -ENOMEM; | ||
| 787 | } | ||
| 788 | |||
| 789 | /* Update ep0 state */ | ||
| 790 | if (ep->ep_num == 0) | ||
| 791 | udc->ep0_state = DATA_STATE_XMIT; | ||
| 792 | |||
| 793 | /* irq handler advances the queue */ | ||
| 794 | if (req != NULL) | ||
| 795 | list_add_tail(&req->queue, &ep->queue); | ||
| 796 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 797 | |||
| 798 | return 0; | ||
| 799 | } | ||
| 800 | |||
| 801 | /* dequeues (cancels, unlinks) an I/O request from an endpoint */ | ||
| 802 | static int mv_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
| 803 | { | ||
| 804 | struct mv_ep *ep = container_of(_ep, struct mv_ep, ep); | ||
| 805 | struct mv_req *req; | ||
| 806 | struct mv_udc *udc = ep->udc; | ||
| 807 | unsigned long flags; | ||
| 808 | int stopped, ret = 0; | ||
| 809 | u32 epctrlx; | ||
| 810 | |||
| 811 | if (!_ep || !_req) | ||
| 812 | return -EINVAL; | ||
| 813 | |||
| 814 | spin_lock_irqsave(&ep->udc->lock, flags); | ||
| 815 | stopped = ep->stopped; | ||
| 816 | |||
| 817 | /* Stop the ep before we deal with the queue */ | ||
| 818 | ep->stopped = 1; | ||
| 819 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); | ||
| 820 | if (ep_dir(ep) == EP_DIR_IN) | ||
| 821 | epctrlx &= ~EPCTRL_TX_ENABLE; | ||
| 822 | else | ||
| 823 | epctrlx &= ~EPCTRL_RX_ENABLE; | ||
| 824 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); | ||
| 825 | |||
| 826 | /* make sure it's actually queued on this endpoint */ | ||
| 827 | list_for_each_entry(req, &ep->queue, queue) { | ||
| 828 | if (&req->req == _req) | ||
| 829 | break; | ||
| 830 | } | ||
| 831 | if (&req->req != _req) { | ||
| 832 | ret = -EINVAL; | ||
| 833 | goto out; | ||
| 834 | } | ||
| 835 | |||
| 836 | /* The request is in progress, or completed but not dequeued */ | ||
| 837 | if (ep->queue.next == &req->queue) { | ||
| 838 | _req->status = -ECONNRESET; | ||
| 839 | mv_ep_fifo_flush(_ep); /* flush current transfer */ | ||
| 840 | |||
| 841 | /* The request isn't the last request in this ep queue */ | ||
| 842 | if (req->queue.next != &ep->queue) { | ||
| 843 | struct mv_dqh *qh; | ||
| 844 | struct mv_req *next_req; | ||
| 845 | |||
| 846 | qh = ep->dqh; | ||
| 847 | next_req = list_entry(req->queue.next, struct mv_req, | ||
| 848 | queue); | ||
| 849 | |||
| 850 | /* Point the QH to the first TD of next request */ | ||
| 851 | writel((u32) next_req->head, &qh->curr_dtd_ptr); | ||
| 852 | } else { | ||
| 853 | struct mv_dqh *qh; | ||
| 854 | |||
| 855 | qh = ep->dqh; | ||
| 856 | qh->next_dtd_ptr = 1; | ||
| 857 | qh->size_ioc_int_sts = 0; | ||
| 858 | } | ||
| 859 | |||
| 860 | /* The request hasn't been processed, patch up the TD chain */ | ||
| 861 | } else { | ||
| 862 | struct mv_req *prev_req; | ||
| 863 | |||
| 864 | prev_req = list_entry(req->queue.prev, struct mv_req, queue); | ||
| 865 | writel(readl(&req->tail->dtd_next), | ||
| 866 | &prev_req->tail->dtd_next); | ||
| 867 | |||
| 868 | } | ||
| 869 | |||
| 870 | done(ep, req, -ECONNRESET); | ||
| 871 | |||
| 872 | /* Enable EP */ | ||
| 873 | out: | ||
| 874 | epctrlx = readl(&udc->op_regs->epctrlx[ep->ep_num]); | ||
| 875 | if (ep_dir(ep) == EP_DIR_IN) | ||
| 876 | epctrlx |= EPCTRL_TX_ENABLE; | ||
| 877 | else | ||
| 878 | epctrlx |= EPCTRL_RX_ENABLE; | ||
| 879 | writel(epctrlx, &udc->op_regs->epctrlx[ep->ep_num]); | ||
| 880 | ep->stopped = stopped; | ||
| 881 | |||
| 882 | spin_unlock_irqrestore(&ep->udc->lock, flags); | ||
| 883 | return ret; | ||
| 884 | } | ||
| 885 | |||
| 886 | static void ep_set_stall(struct mv_udc *udc, u8 ep_num, u8 direction, int stall) | ||
| 887 | { | ||
| 888 | u32 epctrlx; | ||
| 889 | |||
| 890 | epctrlx = readl(&udc->op_regs->epctrlx[ep_num]); | ||
| 891 | |||
| 892 | if (stall) { | ||
| 893 | if (direction == EP_DIR_IN) | ||
| 894 | epctrlx |= EPCTRL_TX_EP_STALL; | ||
| 895 | else | ||
| 896 | epctrlx |= EPCTRL_RX_EP_STALL; | ||
| 897 | } else { | ||
| 898 | if (direction == EP_DIR_IN) { | ||
| 899 | epctrlx &= ~EPCTRL_TX_EP_STALL; | ||
| 900 | epctrlx |= EPCTRL_TX_DATA_TOGGLE_RST; | ||
| 901 | } else { | ||
| 902 | epctrlx &= ~EPCTRL_RX_EP_STALL; | ||
| 903 | epctrlx |= EPCTRL_RX_DATA_TOGGLE_RST; | ||
| 904 | } | ||
| 905 | } | ||
| 906 | writel(epctrlx, &udc->op_regs->epctrlx[ep_num]); | ||
| 907 | } | ||
| 908 | |||
| 909 | static int ep_is_stall(struct mv_udc *udc, u8 ep_num, u8 direction) | ||
| 910 | { | ||
| 911 | u32 epctrlx; | ||
| 912 | |||
| 913 | epctrlx = readl(&udc->op_regs->epctrlx[ep_num]); | ||
| 914 | |||
| 915 | if (direction == EP_DIR_OUT) | ||
| 916 | return (epctrlx & EPCTRL_RX_EP_STALL) ? 1 : 0; | ||
| 917 | else | ||
| 918 | return (epctrlx & EPCTRL_TX_EP_STALL) ? 1 : 0; | ||
| 919 | } | ||
| 920 | |||
| 921 | static int mv_ep_set_halt_wedge(struct usb_ep *_ep, int halt, int wedge) | ||
| 922 | { | ||
| 923 | struct mv_ep *ep; | ||
| 924 | unsigned long flags = 0; | ||
| 925 | int status = 0; | ||
| 926 | struct mv_udc *udc; | ||
| 927 | |||
| 928 | ep = container_of(_ep, struct mv_ep, ep); | ||
| 929 | udc = ep->udc; | ||
| 930 | if (!_ep || !ep->desc) { | ||
| 931 | status = -EINVAL; | ||
| 932 | goto out; | ||
| 933 | } | ||
| 934 | |||
| 935 | if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { | ||
| 936 | status = -EOPNOTSUPP; | ||
| 937 | goto out; | ||
| 938 | } | ||
| 939 | |||
| 940 | /* | ||
| 941 | * Attempt to halt IN ep will fail if any transfer requests | ||
| 942 | * are still queue | ||
| 943 | */ | ||
| 944 | if (halt && (ep_dir(ep) == EP_DIR_IN) && !list_empty(&ep->queue)) { | ||
| 945 | status = -EAGAIN; | ||
| 946 | goto out; | ||
| 947 | } | ||
| 948 | |||
| 949 | spin_lock_irqsave(&ep->udc->lock, flags); | ||
| 950 | ep_set_stall(udc, ep->ep_num, ep_dir(ep), halt); | ||
| 951 | if (halt && wedge) | ||
| 952 | ep->wedge = 1; | ||
| 953 | else if (!halt) | ||
| 954 | ep->wedge = 0; | ||
| 955 | spin_unlock_irqrestore(&ep->udc->lock, flags); | ||
| 956 | |||
| 957 | if (ep->ep_num == 0) { | ||
| 958 | udc->ep0_state = WAIT_FOR_SETUP; | ||
| 959 | udc->ep0_dir = EP_DIR_OUT; | ||
| 960 | } | ||
| 961 | out: | ||
| 962 | return status; | ||
| 963 | } | ||
| 964 | |||
| 965 | static int mv_ep_set_halt(struct usb_ep *_ep, int halt) | ||
| 966 | { | ||
| 967 | return mv_ep_set_halt_wedge(_ep, halt, 0); | ||
| 968 | } | ||
| 969 | |||
| 970 | static int mv_ep_set_wedge(struct usb_ep *_ep) | ||
| 971 | { | ||
| 972 | return mv_ep_set_halt_wedge(_ep, 1, 1); | ||
| 973 | } | ||
| 974 | |||
| 975 | static struct usb_ep_ops mv_ep_ops = { | ||
| 976 | .enable = mv_ep_enable, | ||
| 977 | .disable = mv_ep_disable, | ||
| 978 | |||
| 979 | .alloc_request = mv_alloc_request, | ||
| 980 | .free_request = mv_free_request, | ||
| 981 | |||
| 982 | .queue = mv_ep_queue, | ||
| 983 | .dequeue = mv_ep_dequeue, | ||
| 984 | |||
| 985 | .set_wedge = mv_ep_set_wedge, | ||
| 986 | .set_halt = mv_ep_set_halt, | ||
| 987 | .fifo_flush = mv_ep_fifo_flush, /* flush fifo */ | ||
| 988 | }; | ||
| 989 | |||
| 990 | static void udc_stop(struct mv_udc *udc) | ||
| 991 | { | ||
| 992 | u32 tmp; | ||
| 993 | |||
| 994 | /* Disable interrupts */ | ||
| 995 | tmp = readl(&udc->op_regs->usbintr); | ||
| 996 | tmp &= ~(USBINTR_INT_EN | USBINTR_ERR_INT_EN | | ||
| 997 | USBINTR_PORT_CHANGE_DETECT_EN | USBINTR_RESET_EN); | ||
| 998 | writel(tmp, &udc->op_regs->usbintr); | ||
| 999 | |||
| 1000 | /* Reset the Run the bit in the command register to stop VUSB */ | ||
| 1001 | tmp = readl(&udc->op_regs->usbcmd); | ||
| 1002 | tmp &= ~USBCMD_RUN_STOP; | ||
| 1003 | writel(tmp, &udc->op_regs->usbcmd); | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | static void udc_start(struct mv_udc *udc) | ||
| 1007 | { | ||
| 1008 | u32 usbintr; | ||
| 1009 | |||
| 1010 | usbintr = USBINTR_INT_EN | USBINTR_ERR_INT_EN | ||
| 1011 | | USBINTR_PORT_CHANGE_DETECT_EN | ||
| 1012 | | USBINTR_RESET_EN | USBINTR_DEVICE_SUSPEND; | ||
| 1013 | /* Enable interrupts */ | ||
| 1014 | writel(usbintr, &udc->op_regs->usbintr); | ||
| 1015 | |||
| 1016 | /* Set the Run bit in the command register */ | ||
| 1017 | writel(USBCMD_RUN_STOP, &udc->op_regs->usbcmd); | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | static int udc_reset(struct mv_udc *udc) | ||
| 1021 | { | ||
| 1022 | unsigned int loops; | ||
| 1023 | u32 tmp, portsc; | ||
| 1024 | |||
| 1025 | /* Stop the controller */ | ||
| 1026 | tmp = readl(&udc->op_regs->usbcmd); | ||
| 1027 | tmp &= ~USBCMD_RUN_STOP; | ||
| 1028 | writel(tmp, &udc->op_regs->usbcmd); | ||
| 1029 | |||
| 1030 | /* Reset the controller to get default values */ | ||
| 1031 | writel(USBCMD_CTRL_RESET, &udc->op_regs->usbcmd); | ||
| 1032 | |||
| 1033 | /* wait for reset to complete */ | ||
| 1034 | loops = LOOPS(RESET_TIMEOUT); | ||
| 1035 | while (readl(&udc->op_regs->usbcmd) & USBCMD_CTRL_RESET) { | ||
| 1036 | if (loops == 0) { | ||
| 1037 | dev_err(&udc->dev->dev, | ||
| 1038 | "Wait for RESET completed TIMEOUT\n"); | ||
| 1039 | return -ETIMEDOUT; | ||
| 1040 | } | ||
| 1041 | loops--; | ||
| 1042 | udelay(LOOPS_USEC); | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | /* set controller to device mode */ | ||
| 1046 | tmp = readl(&udc->op_regs->usbmode); | ||
| 1047 | tmp |= USBMODE_CTRL_MODE_DEVICE; | ||
| 1048 | |||
| 1049 | /* turn setup lockout off, require setup tripwire in usbcmd */ | ||
| 1050 | tmp |= USBMODE_SETUP_LOCK_OFF | USBMODE_STREAM_DISABLE; | ||
| 1051 | |||
| 1052 | writel(tmp, &udc->op_regs->usbmode); | ||
| 1053 | |||
| 1054 | writel(0x0, &udc->op_regs->epsetupstat); | ||
| 1055 | |||
| 1056 | /* Configure the Endpoint List Address */ | ||
| 1057 | writel(udc->ep_dqh_dma & USB_EP_LIST_ADDRESS_MASK, | ||
| 1058 | &udc->op_regs->eplistaddr); | ||
| 1059 | |||
| 1060 | portsc = readl(&udc->op_regs->portsc[0]); | ||
| 1061 | if (readl(&udc->cap_regs->hcsparams) & HCSPARAMS_PPC) | ||
| 1062 | portsc &= (~PORTSCX_W1C_BITS | ~PORTSCX_PORT_POWER); | ||
| 1063 | |||
| 1064 | if (udc->force_fs) | ||
| 1065 | portsc |= PORTSCX_FORCE_FULL_SPEED_CONNECT; | ||
| 1066 | else | ||
| 1067 | portsc &= (~PORTSCX_FORCE_FULL_SPEED_CONNECT); | ||
| 1068 | |||
| 1069 | writel(portsc, &udc->op_regs->portsc[0]); | ||
| 1070 | |||
| 1071 | tmp = readl(&udc->op_regs->epctrlx[0]); | ||
| 1072 | tmp &= ~(EPCTRL_TX_EP_STALL | EPCTRL_RX_EP_STALL); | ||
| 1073 | writel(tmp, &udc->op_regs->epctrlx[0]); | ||
| 1074 | |||
| 1075 | return 0; | ||
| 1076 | } | ||
| 1077 | |||
| 1078 | static int mv_udc_get_frame(struct usb_gadget *gadget) | ||
| 1079 | { | ||
| 1080 | struct mv_udc *udc; | ||
| 1081 | u16 retval; | ||
| 1082 | |||
| 1083 | if (!gadget) | ||
| 1084 | return -ENODEV; | ||
| 1085 | |||
| 1086 | udc = container_of(gadget, struct mv_udc, gadget); | ||
| 1087 | |||
| 1088 | retval = readl(udc->op_regs->frindex) & USB_FRINDEX_MASKS; | ||
| 1089 | |||
| 1090 | return retval; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | /* Tries to wake up the host connected to this gadget */ | ||
| 1094 | static int mv_udc_wakeup(struct usb_gadget *gadget) | ||
| 1095 | { | ||
| 1096 | struct mv_udc *udc = container_of(gadget, struct mv_udc, gadget); | ||
| 1097 | u32 portsc; | ||
| 1098 | |||
| 1099 | /* Remote wakeup feature not enabled by host */ | ||
| 1100 | if (!udc->remote_wakeup) | ||
| 1101 | return -ENOTSUPP; | ||
| 1102 | |||
| 1103 | portsc = readl(&udc->op_regs->portsc); | ||
| 1104 | /* not suspended? */ | ||
| 1105 | if (!(portsc & PORTSCX_PORT_SUSPEND)) | ||
| 1106 | return 0; | ||
| 1107 | /* trigger force resume */ | ||
| 1108 | portsc |= PORTSCX_PORT_FORCE_RESUME; | ||
| 1109 | writel(portsc, &udc->op_regs->portsc[0]); | ||
| 1110 | return 0; | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) | ||
| 1114 | { | ||
| 1115 | struct mv_udc *udc; | ||
| 1116 | unsigned long flags; | ||
| 1117 | |||
| 1118 | udc = container_of(gadget, struct mv_udc, gadget); | ||
| 1119 | spin_lock_irqsave(&udc->lock, flags); | ||
| 1120 | |||
| 1121 | udc->softconnect = (is_on != 0); | ||
| 1122 | if (udc->driver && udc->softconnect) | ||
| 1123 | udc_start(udc); | ||
| 1124 | else | ||
| 1125 | udc_stop(udc); | ||
| 1126 | |||
| 1127 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 1128 | return 0; | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | /* device controller usb_gadget_ops structure */ | ||
| 1132 | static const struct usb_gadget_ops mv_ops = { | ||
| 1133 | |||
| 1134 | /* returns the current frame number */ | ||
| 1135 | .get_frame = mv_udc_get_frame, | ||
| 1136 | |||
| 1137 | /* tries to wake up the host connected to this gadget */ | ||
| 1138 | .wakeup = mv_udc_wakeup, | ||
| 1139 | |||
| 1140 | /* D+ pullup, software-controlled connect/disconnect to USB host */ | ||
| 1141 | .pullup = mv_udc_pullup, | ||
| 1142 | }; | ||
| 1143 | |||
| 1144 | static void mv_udc_testmode(struct mv_udc *udc, u16 index, bool enter) | ||
| 1145 | { | ||
| 1146 | dev_info(&udc->dev->dev, "Test Mode is not support yet\n"); | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | static int eps_init(struct mv_udc *udc) | ||
| 1150 | { | ||
| 1151 | struct mv_ep *ep; | ||
| 1152 | char name[14]; | ||
| 1153 | int i; | ||
| 1154 | |||
| 1155 | /* initialize ep0 */ | ||
| 1156 | ep = &udc->eps[0]; | ||
| 1157 | ep->udc = udc; | ||
| 1158 | strncpy(ep->name, "ep0", sizeof(ep->name)); | ||
| 1159 | ep->ep.name = ep->name; | ||
| 1160 | ep->ep.ops = &mv_ep_ops; | ||
| 1161 | ep->wedge = 0; | ||
| 1162 | ep->stopped = 0; | ||
| 1163 | ep->ep.maxpacket = EP0_MAX_PKT_SIZE; | ||
| 1164 | ep->ep_num = 0; | ||
| 1165 | ep->desc = &mv_ep0_desc; | ||
| 1166 | INIT_LIST_HEAD(&ep->queue); | ||
| 1167 | |||
| 1168 | ep->ep_type = USB_ENDPOINT_XFER_CONTROL; | ||
| 1169 | |||
| 1170 | /* initialize other endpoints */ | ||
| 1171 | for (i = 2; i < udc->max_eps * 2; i++) { | ||
| 1172 | ep = &udc->eps[i]; | ||
| 1173 | if (i % 2) { | ||
| 1174 | snprintf(name, sizeof(name), "ep%din", i / 2); | ||
| 1175 | ep->direction = EP_DIR_IN; | ||
| 1176 | } else { | ||
| 1177 | snprintf(name, sizeof(name), "ep%dout", i / 2); | ||
| 1178 | ep->direction = EP_DIR_OUT; | ||
| 1179 | } | ||
| 1180 | ep->udc = udc; | ||
| 1181 | strncpy(ep->name, name, sizeof(ep->name)); | ||
| 1182 | ep->ep.name = ep->name; | ||
| 1183 | |||
| 1184 | ep->ep.ops = &mv_ep_ops; | ||
| 1185 | ep->stopped = 0; | ||
| 1186 | ep->ep.maxpacket = (unsigned short) ~0; | ||
| 1187 | ep->ep_num = i / 2; | ||
| 1188 | |||
| 1189 | INIT_LIST_HEAD(&ep->queue); | ||
| 1190 | list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); | ||
| 1191 | |||
| 1192 | ep->dqh = &udc->ep_dqh[i]; | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | return 0; | ||
| 1196 | } | ||
| 1197 | |||
| 1198 | /* delete all endpoint requests, called with spinlock held */ | ||
| 1199 | static void nuke(struct mv_ep *ep, int status) | ||
| 1200 | { | ||
| 1201 | /* called with spinlock held */ | ||
| 1202 | ep->stopped = 1; | ||
| 1203 | |||
| 1204 | /* endpoint fifo flush */ | ||
| 1205 | mv_ep_fifo_flush(&ep->ep); | ||
| 1206 | |||
| 1207 | while (!list_empty(&ep->queue)) { | ||
| 1208 | struct mv_req *req = NULL; | ||
| 1209 | req = list_entry(ep->queue.next, struct mv_req, queue); | ||
| 1210 | done(ep, req, status); | ||
| 1211 | } | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | /* stop all USB activities */ | ||
| 1215 | static void stop_activity(struct mv_udc *udc, struct usb_gadget_driver *driver) | ||
| 1216 | { | ||
| 1217 | struct mv_ep *ep; | ||
| 1218 | |||
| 1219 | nuke(&udc->eps[0], -ESHUTDOWN); | ||
| 1220 | |||
| 1221 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { | ||
| 1222 | nuke(ep, -ESHUTDOWN); | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | /* report disconnect; the driver is already quiesced */ | ||
| 1226 | if (driver) { | ||
| 1227 | spin_unlock(&udc->lock); | ||
| 1228 | driver->disconnect(&udc->gadget); | ||
| 1229 | spin_lock(&udc->lock); | ||
| 1230 | } | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | ||
| 1234 | int (*bind)(struct usb_gadget *)) | ||
| 1235 | { | ||
| 1236 | struct mv_udc *udc = the_controller; | ||
| 1237 | int retval = 0; | ||
| 1238 | unsigned long flags; | ||
| 1239 | |||
| 1240 | if (!udc) | ||
| 1241 | return -ENODEV; | ||
| 1242 | |||
| 1243 | if (udc->driver) | ||
| 1244 | return -EBUSY; | ||
| 1245 | |||
| 1246 | spin_lock_irqsave(&udc->lock, flags); | ||
| 1247 | |||
| 1248 | /* hook up the driver ... */ | ||
| 1249 | driver->driver.bus = NULL; | ||
| 1250 | udc->driver = driver; | ||
| 1251 | udc->gadget.dev.driver = &driver->driver; | ||
| 1252 | |||
| 1253 | udc->usb_state = USB_STATE_ATTACHED; | ||
| 1254 | udc->ep0_state = WAIT_FOR_SETUP; | ||
| 1255 | udc->ep0_dir = USB_DIR_OUT; | ||
| 1256 | |||
| 1257 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 1258 | |||
| 1259 | retval = bind(&udc->gadget); | ||
| 1260 | if (retval) { | ||
| 1261 | dev_err(&udc->dev->dev, "bind to driver %s --> %d\n", | ||
| 1262 | driver->driver.name, retval); | ||
| 1263 | udc->driver = NULL; | ||
| 1264 | udc->gadget.dev.driver = NULL; | ||
| 1265 | return retval; | ||
| 1266 | } | ||
| 1267 | udc_reset(udc); | ||
| 1268 | ep0_reset(udc); | ||
| 1269 | udc_start(udc); | ||
| 1270 | |||
| 1271 | return 0; | ||
| 1272 | } | ||
| 1273 | EXPORT_SYMBOL(usb_gadget_probe_driver); | ||
| 1274 | |||
| 1275 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
| 1276 | { | ||
| 1277 | struct mv_udc *udc = the_controller; | ||
| 1278 | unsigned long flags; | ||
| 1279 | |||
| 1280 | if (!udc) | ||
| 1281 | return -ENODEV; | ||
| 1282 | |||
| 1283 | udc_stop(udc); | ||
| 1284 | |||
| 1285 | spin_lock_irqsave(&udc->lock, flags); | ||
| 1286 | |||
| 1287 | /* stop all usb activities */ | ||
| 1288 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1289 | stop_activity(udc, driver); | ||
| 1290 | spin_unlock_irqrestore(&udc->lock, flags); | ||
| 1291 | |||
| 1292 | /* unbind gadget driver */ | ||
| 1293 | driver->unbind(&udc->gadget); | ||
| 1294 | udc->gadget.dev.driver = NULL; | ||
| 1295 | udc->driver = NULL; | ||
| 1296 | |||
| 1297 | return 0; | ||
| 1298 | } | ||
| 1299 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
| 1300 | |||
| 1301 | static int | ||
| 1302 | udc_prime_status(struct mv_udc *udc, u8 direction, u16 status, bool empty) | ||
| 1303 | { | ||
| 1304 | int retval = 0; | ||
| 1305 | struct mv_req *req; | ||
| 1306 | struct mv_ep *ep; | ||
| 1307 | |||
| 1308 | ep = &udc->eps[0]; | ||
| 1309 | udc->ep0_dir = direction; | ||
| 1310 | |||
| 1311 | req = udc->status_req; | ||
| 1312 | |||
| 1313 | /* fill in the reqest structure */ | ||
| 1314 | if (empty == false) { | ||
| 1315 | *((u16 *) req->req.buf) = cpu_to_le16(status); | ||
| 1316 | req->req.length = 2; | ||
| 1317 | } else | ||
| 1318 | req->req.length = 0; | ||
| 1319 | |||
| 1320 | req->ep = ep; | ||
| 1321 | req->req.status = -EINPROGRESS; | ||
| 1322 | req->req.actual = 0; | ||
| 1323 | req->req.complete = NULL; | ||
| 1324 | req->dtd_count = 0; | ||
| 1325 | |||
| 1326 | /* prime the data phase */ | ||
| 1327 | if (!req_to_dtd(req)) | ||
| 1328 | retval = queue_dtd(ep, req); | ||
| 1329 | else{ /* no mem */ | ||
| 1330 | retval = -ENOMEM; | ||
| 1331 | goto out; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | if (retval) { | ||
| 1335 | dev_err(&udc->dev->dev, "response error on GET_STATUS request\n"); | ||
| 1336 | goto out; | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | list_add_tail(&req->queue, &ep->queue); | ||
| 1340 | |||
| 1341 | return 0; | ||
| 1342 | out: | ||
| 1343 | return retval; | ||
| 1344 | } | ||
| 1345 | |||
| 1346 | static void ch9setaddress(struct mv_udc *udc, struct usb_ctrlrequest *setup) | ||
| 1347 | { | ||
| 1348 | udc->dev_addr = (u8)setup->wValue; | ||
| 1349 | |||
| 1350 | /* update usb state */ | ||
| 1351 | udc->usb_state = USB_STATE_ADDRESS; | ||
| 1352 | |||
| 1353 | if (udc_prime_status(udc, EP_DIR_IN, 0, true)) | ||
| 1354 | ep0_stall(udc); | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | static void ch9getstatus(struct mv_udc *udc, u8 ep_num, | ||
| 1358 | struct usb_ctrlrequest *setup) | ||
| 1359 | { | ||
| 1360 | u16 status; | ||
| 1361 | int retval; | ||
| 1362 | |||
| 1363 | if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) | ||
| 1364 | != (USB_DIR_IN | USB_TYPE_STANDARD)) | ||
| 1365 | return; | ||
| 1366 | |||
| 1367 | if ((setup->bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) { | ||
| 1368 | status = 1 << USB_DEVICE_SELF_POWERED; | ||
| 1369 | status |= udc->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP; | ||
| 1370 | } else if ((setup->bRequestType & USB_RECIP_MASK) | ||
| 1371 | == USB_RECIP_INTERFACE) { | ||
| 1372 | /* get interface status */ | ||
| 1373 | status = 0; | ||
| 1374 | } else if ((setup->bRequestType & USB_RECIP_MASK) | ||
| 1375 | == USB_RECIP_ENDPOINT) { | ||
| 1376 | u8 ep_num, direction; | ||
| 1377 | |||
| 1378 | ep_num = setup->wIndex & USB_ENDPOINT_NUMBER_MASK; | ||
| 1379 | direction = (setup->wIndex & USB_ENDPOINT_DIR_MASK) | ||
| 1380 | ? EP_DIR_IN : EP_DIR_OUT; | ||
| 1381 | status = ep_is_stall(udc, ep_num, direction) | ||
| 1382 | << USB_ENDPOINT_HALT; | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | retval = udc_prime_status(udc, EP_DIR_IN, status, false); | ||
| 1386 | if (retval) | ||
| 1387 | ep0_stall(udc); | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | static void ch9clearfeature(struct mv_udc *udc, struct usb_ctrlrequest *setup) | ||
| 1391 | { | ||
| 1392 | u8 ep_num; | ||
| 1393 | u8 direction; | ||
| 1394 | struct mv_ep *ep; | ||
| 1395 | |||
| 1396 | if ((setup->bRequestType & (USB_TYPE_MASK | USB_RECIP_MASK)) | ||
| 1397 | == ((USB_TYPE_STANDARD | USB_RECIP_DEVICE))) { | ||
| 1398 | switch (setup->wValue) { | ||
| 1399 | case USB_DEVICE_REMOTE_WAKEUP: | ||
| 1400 | udc->remote_wakeup = 0; | ||
| 1401 | break; | ||
| 1402 | case USB_DEVICE_TEST_MODE: | ||
| 1403 | mv_udc_testmode(udc, 0, false); | ||
| 1404 | break; | ||
| 1405 | default: | ||
| 1406 | goto out; | ||
| 1407 | } | ||
| 1408 | } else if ((setup->bRequestType & (USB_TYPE_MASK | USB_RECIP_MASK)) | ||
| 1409 | == ((USB_TYPE_STANDARD | USB_RECIP_ENDPOINT))) { | ||
| 1410 | switch (setup->wValue) { | ||
| 1411 | case USB_ENDPOINT_HALT: | ||
| 1412 | ep_num = setup->wIndex & USB_ENDPOINT_NUMBER_MASK; | ||
| 1413 | direction = (setup->wIndex & USB_ENDPOINT_DIR_MASK) | ||
| 1414 | ? EP_DIR_IN : EP_DIR_OUT; | ||
| 1415 | if (setup->wValue != 0 || setup->wLength != 0 | ||
| 1416 | || ep_num > udc->max_eps) | ||
| 1417 | goto out; | ||
| 1418 | ep = &udc->eps[ep_num * 2 + direction]; | ||
| 1419 | if (ep->wedge == 1) | ||
| 1420 | break; | ||
| 1421 | spin_unlock(&udc->lock); | ||
| 1422 | ep_set_stall(udc, ep_num, direction, 0); | ||
| 1423 | spin_lock(&udc->lock); | ||
| 1424 | break; | ||
| 1425 | default: | ||
| 1426 | goto out; | ||
| 1427 | } | ||
| 1428 | } else | ||
| 1429 | goto out; | ||
| 1430 | |||
| 1431 | if (udc_prime_status(udc, EP_DIR_IN, 0, true)) | ||
| 1432 | ep0_stall(udc); | ||
| 1433 | else | ||
| 1434 | udc->ep0_state = DATA_STATE_XMIT; | ||
| 1435 | out: | ||
| 1436 | return; | ||
| 1437 | } | ||
| 1438 | |||
| 1439 | static void ch9setfeature(struct mv_udc *udc, struct usb_ctrlrequest *setup) | ||
| 1440 | { | ||
| 1441 | u8 ep_num; | ||
| 1442 | u8 direction; | ||
| 1443 | |||
| 1444 | if ((setup->bRequestType & (USB_TYPE_MASK | USB_RECIP_MASK)) | ||
| 1445 | == ((USB_TYPE_STANDARD | USB_RECIP_DEVICE))) { | ||
| 1446 | switch (setup->wValue) { | ||
| 1447 | case USB_DEVICE_REMOTE_WAKEUP: | ||
| 1448 | udc->remote_wakeup = 1; | ||
| 1449 | break; | ||
| 1450 | case USB_DEVICE_TEST_MODE: | ||
| 1451 | if (setup->wIndex & 0xFF | ||
| 1452 | && udc->gadget.speed != USB_SPEED_HIGH) | ||
| 1453 | goto out; | ||
| 1454 | if (udc->usb_state == USB_STATE_CONFIGURED | ||
| 1455 | || udc->usb_state == USB_STATE_ADDRESS | ||
| 1456 | || udc->usb_state == USB_STATE_DEFAULT) | ||
| 1457 | mv_udc_testmode(udc, | ||
| 1458 | setup->wIndex & 0xFF00, true); | ||
| 1459 | else | ||
| 1460 | goto out; | ||
| 1461 | break; | ||
| 1462 | default: | ||
| 1463 | goto out; | ||
| 1464 | } | ||
| 1465 | } else if ((setup->bRequestType & (USB_TYPE_MASK | USB_RECIP_MASK)) | ||
| 1466 | == ((USB_TYPE_STANDARD | USB_RECIP_ENDPOINT))) { | ||
| 1467 | switch (setup->wValue) { | ||
| 1468 | case USB_ENDPOINT_HALT: | ||
| 1469 | ep_num = setup->wIndex & USB_ENDPOINT_NUMBER_MASK; | ||
| 1470 | direction = (setup->wIndex & USB_ENDPOINT_DIR_MASK) | ||
| 1471 | ? EP_DIR_IN : EP_DIR_OUT; | ||
| 1472 | if (setup->wValue != 0 || setup->wLength != 0 | ||
| 1473 | || ep_num > udc->max_eps) | ||
| 1474 | goto out; | ||
| 1475 | spin_unlock(&udc->lock); | ||
| 1476 | ep_set_stall(udc, ep_num, direction, 1); | ||
| 1477 | spin_lock(&udc->lock); | ||
| 1478 | break; | ||
| 1479 | default: | ||
| 1480 | goto out; | ||
| 1481 | } | ||
| 1482 | } else | ||
| 1483 | goto out; | ||
| 1484 | |||
| 1485 | if (udc_prime_status(udc, EP_DIR_IN, 0, true)) | ||
| 1486 | ep0_stall(udc); | ||
| 1487 | out: | ||
| 1488 | return; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | static void handle_setup_packet(struct mv_udc *udc, u8 ep_num, | ||
| 1492 | struct usb_ctrlrequest *setup) | ||
| 1493 | { | ||
| 1494 | bool delegate = false; | ||
| 1495 | |||
| 1496 | nuke(&udc->eps[ep_num * 2 + EP_DIR_OUT], -ESHUTDOWN); | ||
| 1497 | |||
| 1498 | dev_dbg(&udc->dev->dev, "SETUP %02x.%02x v%04x i%04x l%04x\n", | ||
| 1499 | setup->bRequestType, setup->bRequest, | ||
| 1500 | setup->wValue, setup->wIndex, setup->wLength); | ||
| 1501 | /* We process some stardard setup requests here */ | ||
| 1502 | if ((setup->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | ||
| 1503 | switch (setup->bRequest) { | ||
| 1504 | case USB_REQ_GET_STATUS: | ||
| 1505 | ch9getstatus(udc, ep_num, setup); | ||
| 1506 | break; | ||
| 1507 | |||
| 1508 | case USB_REQ_SET_ADDRESS: | ||
| 1509 | ch9setaddress(udc, setup); | ||
| 1510 | break; | ||
| 1511 | |||
| 1512 | case USB_REQ_CLEAR_FEATURE: | ||
| 1513 | ch9clearfeature(udc, setup); | ||
| 1514 | break; | ||
| 1515 | |||
| 1516 | case USB_REQ_SET_FEATURE: | ||
| 1517 | ch9setfeature(udc, setup); | ||
| 1518 | break; | ||
| 1519 | |||
| 1520 | default: | ||
| 1521 | delegate = true; | ||
| 1522 | } | ||
| 1523 | } else | ||
| 1524 | delegate = true; | ||
| 1525 | |||
| 1526 | /* delegate USB standard requests to the gadget driver */ | ||
| 1527 | if (delegate == true) { | ||
| 1528 | /* USB requests handled by gadget */ | ||
| 1529 | if (setup->wLength) { | ||
| 1530 | /* DATA phase from gadget, STATUS phase from udc */ | ||
| 1531 | udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) | ||
| 1532 | ? EP_DIR_IN : EP_DIR_OUT; | ||
| 1533 | spin_unlock(&udc->lock); | ||
| 1534 | if (udc->driver->setup(&udc->gadget, | ||
| 1535 | &udc->local_setup_buff) < 0) | ||
| 1536 | ep0_stall(udc); | ||
| 1537 | spin_lock(&udc->lock); | ||
| 1538 | udc->ep0_state = (setup->bRequestType & USB_DIR_IN) | ||
| 1539 | ? DATA_STATE_XMIT : DATA_STATE_RECV; | ||
| 1540 | } else { | ||
| 1541 | /* no DATA phase, IN STATUS phase from gadget */ | ||
| 1542 | udc->ep0_dir = EP_DIR_IN; | ||
| 1543 | spin_unlock(&udc->lock); | ||
| 1544 | if (udc->driver->setup(&udc->gadget, | ||
| 1545 | &udc->local_setup_buff) < 0) | ||
| 1546 | ep0_stall(udc); | ||
| 1547 | spin_lock(&udc->lock); | ||
| 1548 | udc->ep0_state = WAIT_FOR_OUT_STATUS; | ||
| 1549 | } | ||
| 1550 | } | ||
| 1551 | } | ||
| 1552 | |||
| 1553 | /* complete DATA or STATUS phase of ep0 prime status phase if needed */ | ||
| 1554 | static void ep0_req_complete(struct mv_udc *udc, | ||
| 1555 | struct mv_ep *ep0, struct mv_req *req) | ||
| 1556 | { | ||
| 1557 | u32 new_addr; | ||
| 1558 | |||
| 1559 | if (udc->usb_state == USB_STATE_ADDRESS) { | ||
| 1560 | /* set the new address */ | ||
| 1561 | new_addr = (u32)udc->dev_addr; | ||
| 1562 | writel(new_addr << USB_DEVICE_ADDRESS_BIT_SHIFT, | ||
| 1563 | &udc->op_regs->deviceaddr); | ||
| 1564 | } | ||
| 1565 | |||
| 1566 | done(ep0, req, 0); | ||
| 1567 | |||
| 1568 | switch (udc->ep0_state) { | ||
| 1569 | case DATA_STATE_XMIT: | ||
| 1570 | /* receive status phase */ | ||
| 1571 | if (udc_prime_status(udc, EP_DIR_OUT, 0, true)) | ||
| 1572 | ep0_stall(udc); | ||
| 1573 | break; | ||
| 1574 | case DATA_STATE_RECV: | ||
| 1575 | /* send status phase */ | ||
| 1576 | if (udc_prime_status(udc, EP_DIR_IN, 0 , true)) | ||
| 1577 | ep0_stall(udc); | ||
| 1578 | break; | ||
| 1579 | case WAIT_FOR_OUT_STATUS: | ||
| 1580 | udc->ep0_state = WAIT_FOR_SETUP; | ||
| 1581 | break; | ||
| 1582 | case WAIT_FOR_SETUP: | ||
| 1583 | dev_err(&udc->dev->dev, "unexpect ep0 packets\n"); | ||
| 1584 | break; | ||
| 1585 | default: | ||
| 1586 | ep0_stall(udc); | ||
| 1587 | break; | ||
| 1588 | } | ||
| 1589 | } | ||
| 1590 | |||
| 1591 | static void get_setup_data(struct mv_udc *udc, u8 ep_num, u8 *buffer_ptr) | ||
| 1592 | { | ||
| 1593 | u32 temp; | ||
| 1594 | struct mv_dqh *dqh; | ||
| 1595 | |||
| 1596 | dqh = &udc->ep_dqh[ep_num * 2 + EP_DIR_OUT]; | ||
| 1597 | |||
| 1598 | /* Clear bit in ENDPTSETUPSTAT */ | ||
| 1599 | temp = readl(&udc->op_regs->epsetupstat); | ||
| 1600 | writel(temp | (1 << ep_num), &udc->op_regs->epsetupstat); | ||
| 1601 | |||
| 1602 | /* while a hazard exists when setup package arrives */ | ||
| 1603 | do { | ||
| 1604 | /* Set Setup Tripwire */ | ||
| 1605 | temp = readl(&udc->op_regs->usbcmd); | ||
| 1606 | writel(temp | USBCMD_SETUP_TRIPWIRE_SET, &udc->op_regs->usbcmd); | ||
| 1607 | |||
| 1608 | /* Copy the setup packet to local buffer */ | ||
| 1609 | memcpy(buffer_ptr, (u8 *) dqh->setup_buffer, 8); | ||
| 1610 | } while (!(readl(&udc->op_regs->usbcmd) & USBCMD_SETUP_TRIPWIRE_SET)); | ||
| 1611 | |||
| 1612 | /* Clear Setup Tripwire */ | ||
| 1613 | temp = readl(&udc->op_regs->usbcmd); | ||
| 1614 | writel(temp & ~USBCMD_SETUP_TRIPWIRE_SET, &udc->op_regs->usbcmd); | ||
| 1615 | } | ||
| 1616 | |||
| 1617 | static void irq_process_tr_complete(struct mv_udc *udc) | ||
| 1618 | { | ||
| 1619 | u32 tmp, bit_pos; | ||
| 1620 | int i, ep_num = 0, direction = 0; | ||
| 1621 | struct mv_ep *curr_ep; | ||
| 1622 | struct mv_req *curr_req, *temp_req; | ||
| 1623 | int status; | ||
| 1624 | |||
| 1625 | /* | ||
| 1626 | * We use separate loops for ENDPTSETUPSTAT and ENDPTCOMPLETE | ||
| 1627 | * because the setup packets are to be read ASAP | ||
| 1628 | */ | ||
| 1629 | |||
| 1630 | /* Process all Setup packet received interrupts */ | ||
| 1631 | tmp = readl(&udc->op_regs->epsetupstat); | ||
| 1632 | |||
| 1633 | if (tmp) { | ||
| 1634 | for (i = 0; i < udc->max_eps; i++) { | ||
| 1635 | if (tmp & (1 << i)) { | ||
| 1636 | get_setup_data(udc, i, | ||
| 1637 | (u8 *)(&udc->local_setup_buff)); | ||
| 1638 | handle_setup_packet(udc, i, | ||
| 1639 | &udc->local_setup_buff); | ||
| 1640 | } | ||
| 1641 | } | ||
| 1642 | } | ||
| 1643 | |||
| 1644 | /* Don't clear the endpoint setup status register here. | ||
| 1645 | * It is cleared as a setup packet is read out of the buffer | ||
| 1646 | */ | ||
| 1647 | |||
| 1648 | /* Process non-setup transaction complete interrupts */ | ||
| 1649 | tmp = readl(&udc->op_regs->epcomplete); | ||
| 1650 | |||
| 1651 | if (!tmp) | ||
| 1652 | return; | ||
| 1653 | |||
| 1654 | writel(tmp, &udc->op_regs->epcomplete); | ||
| 1655 | |||
| 1656 | for (i = 0; i < udc->max_eps * 2; i++) { | ||
| 1657 | ep_num = i >> 1; | ||
| 1658 | direction = i % 2; | ||
| 1659 | |||
| 1660 | bit_pos = 1 << (ep_num + 16 * direction); | ||
| 1661 | |||
| 1662 | if (!(bit_pos & tmp)) | ||
| 1663 | continue; | ||
| 1664 | |||
| 1665 | if (i == 1) | ||
| 1666 | curr_ep = &udc->eps[0]; | ||
| 1667 | else | ||
| 1668 | curr_ep = &udc->eps[i]; | ||
| 1669 | /* process the req queue until an uncomplete request */ | ||
| 1670 | list_for_each_entry_safe(curr_req, temp_req, | ||
| 1671 | &curr_ep->queue, queue) { | ||
| 1672 | status = process_ep_req(udc, i, curr_req); | ||
| 1673 | if (status) | ||
| 1674 | break; | ||
| 1675 | |||
| 1676 | /* write back status to req */ | ||
| 1677 | curr_req->req.status = status; | ||
| 1678 | |||
| 1679 | /* ep0 request completion */ | ||
| 1680 | if (ep_num == 0) { | ||
| 1681 | ep0_req_complete(udc, curr_ep, curr_req); | ||
| 1682 | break; | ||
| 1683 | } else { | ||
| 1684 | done(curr_ep, curr_req, status); | ||
| 1685 | } | ||
| 1686 | } | ||
| 1687 | } | ||
| 1688 | } | ||
| 1689 | |||
| 1690 | void irq_process_reset(struct mv_udc *udc) | ||
| 1691 | { | ||
| 1692 | u32 tmp; | ||
| 1693 | unsigned int loops; | ||
| 1694 | |||
| 1695 | udc->ep0_dir = EP_DIR_OUT; | ||
| 1696 | udc->ep0_state = WAIT_FOR_SETUP; | ||
| 1697 | udc->remote_wakeup = 0; /* default to 0 on reset */ | ||
| 1698 | |||
| 1699 | /* The address bits are past bit 25-31. Set the address */ | ||
| 1700 | tmp = readl(&udc->op_regs->deviceaddr); | ||
| 1701 | tmp &= ~(USB_DEVICE_ADDRESS_MASK); | ||
| 1702 | writel(tmp, &udc->op_regs->deviceaddr); | ||
| 1703 | |||
| 1704 | /* Clear all the setup token semaphores */ | ||
| 1705 | tmp = readl(&udc->op_regs->epsetupstat); | ||
| 1706 | writel(tmp, &udc->op_regs->epsetupstat); | ||
| 1707 | |||
| 1708 | /* Clear all the endpoint complete status bits */ | ||
| 1709 | tmp = readl(&udc->op_regs->epcomplete); | ||
| 1710 | writel(tmp, &udc->op_regs->epcomplete); | ||
| 1711 | |||
| 1712 | /* wait until all endptprime bits cleared */ | ||
| 1713 | loops = LOOPS(PRIME_TIMEOUT); | ||
| 1714 | while (readl(&udc->op_regs->epprime) & 0xFFFFFFFF) { | ||
| 1715 | if (loops == 0) { | ||
| 1716 | dev_err(&udc->dev->dev, | ||
| 1717 | "Timeout for ENDPTPRIME = 0x%x\n", | ||
| 1718 | readl(&udc->op_regs->epprime)); | ||
| 1719 | break; | ||
| 1720 | } | ||
| 1721 | loops--; | ||
| 1722 | udelay(LOOPS_USEC); | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | /* Write 1s to the Flush register */ | ||
| 1726 | writel((u32)~0, &udc->op_regs->epflush); | ||
| 1727 | |||
| 1728 | if (readl(&udc->op_regs->portsc[0]) & PORTSCX_PORT_RESET) { | ||
| 1729 | dev_info(&udc->dev->dev, "usb bus reset\n"); | ||
| 1730 | udc->usb_state = USB_STATE_DEFAULT; | ||
| 1731 | /* reset all the queues, stop all USB activities */ | ||
| 1732 | stop_activity(udc, udc->driver); | ||
| 1733 | } else { | ||
| 1734 | dev_info(&udc->dev->dev, "USB reset portsc 0x%x\n", | ||
| 1735 | readl(&udc->op_regs->portsc)); | ||
| 1736 | |||
| 1737 | /* | ||
| 1738 | * re-initialize | ||
| 1739 | * controller reset | ||
| 1740 | */ | ||
| 1741 | udc_reset(udc); | ||
| 1742 | |||
| 1743 | /* reset all the queues, stop all USB activities */ | ||
| 1744 | stop_activity(udc, udc->driver); | ||
| 1745 | |||
| 1746 | /* reset ep0 dQH and endptctrl */ | ||
| 1747 | ep0_reset(udc); | ||
| 1748 | |||
| 1749 | /* enable interrupt and set controller to run state */ | ||
| 1750 | udc_start(udc); | ||
| 1751 | |||
| 1752 | udc->usb_state = USB_STATE_ATTACHED; | ||
| 1753 | } | ||
| 1754 | } | ||
| 1755 | |||
| 1756 | static void handle_bus_resume(struct mv_udc *udc) | ||
| 1757 | { | ||
| 1758 | udc->usb_state = udc->resume_state; | ||
| 1759 | udc->resume_state = 0; | ||
| 1760 | |||
| 1761 | /* report resume to the driver */ | ||
| 1762 | if (udc->driver) { | ||
| 1763 | if (udc->driver->resume) { | ||
| 1764 | spin_unlock(&udc->lock); | ||
| 1765 | udc->driver->resume(&udc->gadget); | ||
| 1766 | spin_lock(&udc->lock); | ||
| 1767 | } | ||
| 1768 | } | ||
| 1769 | } | ||
| 1770 | |||
| 1771 | static void irq_process_suspend(struct mv_udc *udc) | ||
| 1772 | { | ||
| 1773 | udc->resume_state = udc->usb_state; | ||
| 1774 | udc->usb_state = USB_STATE_SUSPENDED; | ||
| 1775 | |||
| 1776 | if (udc->driver->suspend) { | ||
| 1777 | spin_unlock(&udc->lock); | ||
| 1778 | udc->driver->suspend(&udc->gadget); | ||
| 1779 | spin_lock(&udc->lock); | ||
| 1780 | } | ||
| 1781 | } | ||
| 1782 | |||
| 1783 | static void irq_process_port_change(struct mv_udc *udc) | ||
| 1784 | { | ||
| 1785 | u32 portsc; | ||
| 1786 | |||
| 1787 | portsc = readl(&udc->op_regs->portsc[0]); | ||
| 1788 | if (!(portsc & PORTSCX_PORT_RESET)) { | ||
| 1789 | /* Get the speed */ | ||
| 1790 | u32 speed = portsc & PORTSCX_PORT_SPEED_MASK; | ||
| 1791 | switch (speed) { | ||
| 1792 | case PORTSCX_PORT_SPEED_HIGH: | ||
| 1793 | udc->gadget.speed = USB_SPEED_HIGH; | ||
| 1794 | break; | ||
| 1795 | case PORTSCX_PORT_SPEED_FULL: | ||
| 1796 | udc->gadget.speed = USB_SPEED_FULL; | ||
| 1797 | break; | ||
| 1798 | case PORTSCX_PORT_SPEED_LOW: | ||
| 1799 | udc->gadget.speed = USB_SPEED_LOW; | ||
| 1800 | break; | ||
| 1801 | default: | ||
| 1802 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1803 | break; | ||
| 1804 | } | ||
| 1805 | } | ||
| 1806 | |||
| 1807 | if (portsc & PORTSCX_PORT_SUSPEND) { | ||
| 1808 | udc->resume_state = udc->usb_state; | ||
| 1809 | udc->usb_state = USB_STATE_SUSPENDED; | ||
| 1810 | if (udc->driver->suspend) { | ||
| 1811 | spin_unlock(&udc->lock); | ||
| 1812 | udc->driver->suspend(&udc->gadget); | ||
| 1813 | spin_lock(&udc->lock); | ||
| 1814 | } | ||
| 1815 | } | ||
| 1816 | |||
| 1817 | if (!(portsc & PORTSCX_PORT_SUSPEND) | ||
| 1818 | && udc->usb_state == USB_STATE_SUSPENDED) { | ||
| 1819 | handle_bus_resume(udc); | ||
| 1820 | } | ||
| 1821 | |||
| 1822 | if (!udc->resume_state) | ||
| 1823 | udc->usb_state = USB_STATE_DEFAULT; | ||
| 1824 | } | ||
| 1825 | |||
| 1826 | static void irq_process_error(struct mv_udc *udc) | ||
| 1827 | { | ||
| 1828 | /* Increment the error count */ | ||
| 1829 | udc->errors++; | ||
| 1830 | } | ||
| 1831 | |||
| 1832 | static irqreturn_t mv_udc_irq(int irq, void *dev) | ||
| 1833 | { | ||
| 1834 | struct mv_udc *udc = (struct mv_udc *)dev; | ||
| 1835 | u32 status, intr; | ||
| 1836 | |||
| 1837 | spin_lock(&udc->lock); | ||
| 1838 | |||
| 1839 | status = readl(&udc->op_regs->usbsts); | ||
| 1840 | intr = readl(&udc->op_regs->usbintr); | ||
| 1841 | status &= intr; | ||
| 1842 | |||
| 1843 | if (status == 0) { | ||
| 1844 | spin_unlock(&udc->lock); | ||
| 1845 | return IRQ_NONE; | ||
| 1846 | } | ||
| 1847 | |||
| 1848 | /* Clear all the interrupts occured */ | ||
| 1849 | writel(status, &udc->op_regs->usbsts); | ||
| 1850 | |||
| 1851 | if (status & USBSTS_ERR) | ||
| 1852 | irq_process_error(udc); | ||
| 1853 | |||
| 1854 | if (status & USBSTS_RESET) | ||
| 1855 | irq_process_reset(udc); | ||
| 1856 | |||
| 1857 | if (status & USBSTS_PORT_CHANGE) | ||
| 1858 | irq_process_port_change(udc); | ||
| 1859 | |||
| 1860 | if (status & USBSTS_INT) | ||
| 1861 | irq_process_tr_complete(udc); | ||
| 1862 | |||
| 1863 | if (status & USBSTS_SUSPEND) | ||
| 1864 | irq_process_suspend(udc); | ||
| 1865 | |||
| 1866 | spin_unlock(&udc->lock); | ||
| 1867 | |||
| 1868 | return IRQ_HANDLED; | ||
| 1869 | } | ||
| 1870 | |||
| 1871 | /* release device structure */ | ||
| 1872 | static void gadget_release(struct device *_dev) | ||
| 1873 | { | ||
| 1874 | struct mv_udc *udc = the_controller; | ||
| 1875 | |||
| 1876 | complete(udc->done); | ||
| 1877 | kfree(udc); | ||
| 1878 | } | ||
| 1879 | |||
| 1880 | static int mv_udc_remove(struct platform_device *dev) | ||
| 1881 | { | ||
| 1882 | struct mv_udc *udc = the_controller; | ||
| 1883 | |||
| 1884 | DECLARE_COMPLETION(done); | ||
| 1885 | |||
| 1886 | udc->done = &done; | ||
| 1887 | |||
| 1888 | /* free memory allocated in probe */ | ||
| 1889 | if (udc->dtd_pool) | ||
| 1890 | dma_pool_destroy(udc->dtd_pool); | ||
| 1891 | |||
| 1892 | if (udc->ep_dqh) | ||
| 1893 | dma_free_coherent(&dev->dev, udc->ep_dqh_size, | ||
| 1894 | udc->ep_dqh, udc->ep_dqh_dma); | ||
| 1895 | |||
| 1896 | kfree(udc->eps); | ||
| 1897 | |||
| 1898 | if (udc->irq) | ||
| 1899 | free_irq(udc->irq, &dev->dev); | ||
| 1900 | |||
| 1901 | if (udc->cap_regs) | ||
| 1902 | iounmap(udc->cap_regs); | ||
| 1903 | udc->cap_regs = NULL; | ||
| 1904 | |||
| 1905 | if (udc->phy_regs) | ||
| 1906 | iounmap((void *)udc->phy_regs); | ||
| 1907 | udc->phy_regs = 0; | ||
| 1908 | |||
| 1909 | if (udc->status_req) { | ||
| 1910 | kfree(udc->status_req->req.buf); | ||
| 1911 | kfree(udc->status_req); | ||
| 1912 | } | ||
| 1913 | |||
| 1914 | device_unregister(&udc->gadget.dev); | ||
| 1915 | |||
| 1916 | /* free dev, wait for the release() finished */ | ||
| 1917 | wait_for_completion(&done); | ||
| 1918 | |||
| 1919 | the_controller = NULL; | ||
| 1920 | |||
| 1921 | return 0; | ||
| 1922 | } | ||
| 1923 | |||
| 1924 | int mv_udc_probe(struct platform_device *dev) | ||
| 1925 | { | ||
| 1926 | struct mv_udc *udc; | ||
| 1927 | int retval = 0; | ||
| 1928 | struct resource *r; | ||
| 1929 | size_t size; | ||
| 1930 | |||
| 1931 | udc = kzalloc(sizeof *udc, GFP_KERNEL); | ||
| 1932 | if (udc == NULL) { | ||
| 1933 | dev_err(&dev->dev, "failed to allocate memory for udc\n"); | ||
| 1934 | retval = -ENOMEM; | ||
| 1935 | goto error; | ||
| 1936 | } | ||
| 1937 | |||
| 1938 | spin_lock_init(&udc->lock); | ||
| 1939 | |||
| 1940 | udc->dev = dev; | ||
| 1941 | |||
| 1942 | udc->clk = clk_get(&dev->dev, "U2OCLK"); | ||
| 1943 | if (IS_ERR(udc->clk)) { | ||
| 1944 | retval = PTR_ERR(udc->clk); | ||
| 1945 | goto error; | ||
| 1946 | } | ||
| 1947 | |||
| 1948 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "u2o"); | ||
| 1949 | if (r == NULL) { | ||
| 1950 | dev_err(&dev->dev, "no I/O memory resource defined\n"); | ||
| 1951 | retval = -ENODEV; | ||
| 1952 | goto error; | ||
| 1953 | } | ||
| 1954 | |||
| 1955 | udc->cap_regs = (struct mv_cap_regs __iomem *) | ||
| 1956 | ioremap(r->start, resource_size(r)); | ||
| 1957 | if (udc->cap_regs == NULL) { | ||
| 1958 | dev_err(&dev->dev, "failed to map I/O memory\n"); | ||
| 1959 | retval = -EBUSY; | ||
| 1960 | goto error; | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | r = platform_get_resource_byname(udc->dev, IORESOURCE_MEM, "u2ophy"); | ||
| 1964 | if (r == NULL) { | ||
| 1965 | dev_err(&dev->dev, "no phy I/O memory resource defined\n"); | ||
| 1966 | retval = -ENODEV; | ||
| 1967 | goto error; | ||
| 1968 | } | ||
| 1969 | |||
| 1970 | udc->phy_regs = (unsigned int)ioremap(r->start, resource_size(r)); | ||
| 1971 | if (udc->phy_regs == 0) { | ||
| 1972 | dev_err(&dev->dev, "failed to map phy I/O memory\n"); | ||
| 1973 | retval = -EBUSY; | ||
| 1974 | goto error; | ||
| 1975 | } | ||
| 1976 | |||
| 1977 | /* we will acces controller register, so enable the clk */ | ||
| 1978 | clk_enable(udc->clk); | ||
| 1979 | retval = mv_udc_phy_init(udc->phy_regs); | ||
| 1980 | if (retval) { | ||
| 1981 | dev_err(&dev->dev, "phy initialization error %d\n", retval); | ||
| 1982 | goto error; | ||
| 1983 | } | ||
| 1984 | |||
| 1985 | udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs | ||
| 1986 | + (readl(&udc->cap_regs->caplength_hciversion) | ||
| 1987 | & CAPLENGTH_MASK)); | ||
| 1988 | udc->max_eps = readl(&udc->cap_regs->dccparams) & DCCPARAMS_DEN_MASK; | ||
| 1989 | |||
| 1990 | size = udc->max_eps * sizeof(struct mv_dqh) *2; | ||
| 1991 | size = (size + DQH_ALIGNMENT - 1) & ~(DQH_ALIGNMENT - 1); | ||
| 1992 | udc->ep_dqh = dma_alloc_coherent(&dev->dev, size, | ||
| 1993 | &udc->ep_dqh_dma, GFP_KERNEL); | ||
| 1994 | |||
| 1995 | if (udc->ep_dqh == NULL) { | ||
| 1996 | dev_err(&dev->dev, "allocate dQH memory failed\n"); | ||
| 1997 | retval = -ENOMEM; | ||
| 1998 | goto error; | ||
| 1999 | } | ||
| 2000 | udc->ep_dqh_size = size; | ||
| 2001 | |||
| 2002 | /* create dTD dma_pool resource */ | ||
| 2003 | udc->dtd_pool = dma_pool_create("mv_dtd", | ||
| 2004 | &dev->dev, | ||
| 2005 | sizeof(struct mv_dtd), | ||
| 2006 | DTD_ALIGNMENT, | ||
| 2007 | DMA_BOUNDARY); | ||
| 2008 | |||
| 2009 | if (!udc->dtd_pool) { | ||
| 2010 | retval = -ENOMEM; | ||
| 2011 | goto error; | ||
| 2012 | } | ||
| 2013 | |||
| 2014 | size = udc->max_eps * sizeof(struct mv_ep) *2; | ||
| 2015 | udc->eps = kzalloc(size, GFP_KERNEL); | ||
| 2016 | if (udc->eps == NULL) { | ||
| 2017 | dev_err(&dev->dev, "allocate ep memory failed\n"); | ||
| 2018 | retval = -ENOMEM; | ||
| 2019 | goto error; | ||
| 2020 | } | ||
| 2021 | |||
| 2022 | /* initialize ep0 status request structure */ | ||
| 2023 | udc->status_req = kzalloc(sizeof(struct mv_req), GFP_KERNEL); | ||
| 2024 | if (!udc->status_req) { | ||
| 2025 | dev_err(&dev->dev, "allocate status_req memory failed\n"); | ||
| 2026 | retval = -ENOMEM; | ||
| 2027 | goto error; | ||
| 2028 | } | ||
| 2029 | INIT_LIST_HEAD(&udc->status_req->queue); | ||
| 2030 | |||
| 2031 | /* allocate a small amount of memory to get valid address */ | ||
| 2032 | udc->status_req->req.buf = kzalloc(8, GFP_KERNEL); | ||
| 2033 | udc->status_req->req.dma = virt_to_phys(udc->status_req->req.buf); | ||
| 2034 | |||
| 2035 | udc->resume_state = USB_STATE_NOTATTACHED; | ||
| 2036 | udc->usb_state = USB_STATE_POWERED; | ||
| 2037 | udc->ep0_dir = EP_DIR_OUT; | ||
| 2038 | udc->remote_wakeup = 0; | ||
| 2039 | |||
| 2040 | r = platform_get_resource(udc->dev, IORESOURCE_IRQ, 0); | ||
| 2041 | if (r == NULL) { | ||
| 2042 | dev_err(&dev->dev, "no IRQ resource defined\n"); | ||
| 2043 | retval = -ENODEV; | ||
| 2044 | goto error; | ||
| 2045 | } | ||
| 2046 | udc->irq = r->start; | ||
| 2047 | if (request_irq(udc->irq, mv_udc_irq, | ||
| 2048 | IRQF_DISABLED | IRQF_SHARED, driver_name, udc)) { | ||
| 2049 | dev_err(&dev->dev, "Request irq %d for UDC failed\n", | ||
| 2050 | udc->irq); | ||
| 2051 | retval = -ENODEV; | ||
| 2052 | goto error; | ||
| 2053 | } | ||
| 2054 | |||
| 2055 | /* initialize gadget structure */ | ||
| 2056 | udc->gadget.ops = &mv_ops; /* usb_gadget_ops */ | ||
| 2057 | udc->gadget.ep0 = &udc->eps[0].ep; /* gadget ep0 */ | ||
| 2058 | INIT_LIST_HEAD(&udc->gadget.ep_list); /* ep_list */ | ||
| 2059 | udc->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ | ||
| 2060 | udc->gadget.is_dualspeed = 1; /* support dual speed */ | ||
| 2061 | |||
| 2062 | /* the "gadget" abstracts/virtualizes the controller */ | ||
| 2063 | dev_set_name(&udc->gadget.dev, "gadget"); | ||
| 2064 | udc->gadget.dev.parent = &dev->dev; | ||
| 2065 | udc->gadget.dev.dma_mask = dev->dev.dma_mask; | ||
| 2066 | udc->gadget.dev.release = gadget_release; | ||
| 2067 | udc->gadget.name = driver_name; /* gadget name */ | ||
| 2068 | |||
| 2069 | retval = device_register(&udc->gadget.dev); | ||
| 2070 | if (retval) | ||
| 2071 | goto error; | ||
| 2072 | |||
| 2073 | eps_init(udc); | ||
| 2074 | |||
| 2075 | the_controller = udc; | ||
| 2076 | |||
| 2077 | goto out; | ||
| 2078 | error: | ||
| 2079 | if (udc) | ||
| 2080 | mv_udc_remove(udc->dev); | ||
| 2081 | out: | ||
| 2082 | return retval; | ||
| 2083 | } | ||
| 2084 | |||
| 2085 | #ifdef CONFIG_PM | ||
| 2086 | static int mv_udc_suspend(struct platform_device *_dev, pm_message_t state) | ||
| 2087 | { | ||
| 2088 | struct mv_udc *udc = the_controller; | ||
| 2089 | |||
| 2090 | udc_stop(udc); | ||
| 2091 | |||
| 2092 | return 0; | ||
| 2093 | } | ||
| 2094 | |||
| 2095 | static int mv_udc_resume(struct platform_device *_dev) | ||
| 2096 | { | ||
| 2097 | struct mv_udc *udc = the_controller; | ||
| 2098 | int retval; | ||
| 2099 | |||
| 2100 | retval = mv_udc_phy_init(udc->phy_regs); | ||
| 2101 | if (retval) { | ||
| 2102 | dev_err(_dev, "phy initialization error %d\n", retval); | ||
| 2103 | goto error; | ||
| 2104 | } | ||
| 2105 | udc_reset(udc); | ||
| 2106 | ep0_reset(udc); | ||
| 2107 | udc_start(udc); | ||
| 2108 | |||
| 2109 | return 0; | ||
| 2110 | } | ||
| 2111 | |||
| 2112 | static const struct dev_pm_ops mv_udc_pm_ops = { | ||
| 2113 | .suspend = mv_udc_suspend, | ||
| 2114 | .resume = mv_udc_resume, | ||
| 2115 | }; | ||
| 2116 | #endif | ||
| 2117 | |||
| 2118 | static struct platform_driver udc_driver = { | ||
| 2119 | .probe = mv_udc_probe, | ||
| 2120 | .remove = __exit_p(mv_udc_remove), | ||
| 2121 | .driver = { | ||
| 2122 | .owner = THIS_MODULE, | ||
| 2123 | .name = "pxa-u2o", | ||
| 2124 | #ifdef CONFIG_PM | ||
| 2125 | .pm = mv_udc_pm_ops, | ||
| 2126 | #endif | ||
| 2127 | }, | ||
| 2128 | }; | ||
| 2129 | |||
| 2130 | |||
| 2131 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 2132 | MODULE_AUTHOR("Chao Xie <chao.xie@marvell.com>"); | ||
| 2133 | MODULE_VERSION(DRIVER_VERSION); | ||
| 2134 | MODULE_LICENSE("GPL"); | ||
| 2135 | |||
| 2136 | |||
| 2137 | static int __init init(void) | ||
| 2138 | { | ||
| 2139 | return platform_driver_register(&udc_driver); | ||
| 2140 | } | ||
| 2141 | module_init(init); | ||
| 2142 | |||
| 2143 | |||
| 2144 | static void __exit cleanup(void) | ||
| 2145 | { | ||
| 2146 | platform_driver_unregister(&udc_driver); | ||
| 2147 | } | ||
| 2148 | module_exit(cleanup); | ||
| 2149 | |||
diff --git a/drivers/usb/gadget/mv_udc_phy.c b/drivers/usb/gadget/mv_udc_phy.c new file mode 100644 index 000000000000..d4dea97e38a5 --- /dev/null +++ b/drivers/usb/gadget/mv_udc_phy.c | |||
| @@ -0,0 +1,214 @@ | |||
| 1 | #include <linux/delay.h> | ||
| 2 | #include <linux/timer.h> | ||
| 3 | #include <linux/io.h> | ||
| 4 | #include <linux/errno.h> | ||
| 5 | |||
| 6 | #include <mach/cputype.h> | ||
| 7 | |||
| 8 | #ifdef CONFIG_ARCH_MMP | ||
| 9 | |||
| 10 | #define UTMI_REVISION 0x0 | ||
| 11 | #define UTMI_CTRL 0x4 | ||
| 12 | #define UTMI_PLL 0x8 | ||
| 13 | #define UTMI_TX 0xc | ||
| 14 | #define UTMI_RX 0x10 | ||
| 15 | #define UTMI_IVREF 0x14 | ||
| 16 | #define UTMI_T0 0x18 | ||
| 17 | #define UTMI_T1 0x1c | ||
| 18 | #define UTMI_T2 0x20 | ||
| 19 | #define UTMI_T3 0x24 | ||
| 20 | #define UTMI_T4 0x28 | ||
| 21 | #define UTMI_T5 0x2c | ||
| 22 | #define UTMI_RESERVE 0x30 | ||
| 23 | #define UTMI_USB_INT 0x34 | ||
| 24 | #define UTMI_DBG_CTL 0x38 | ||
| 25 | #define UTMI_OTG_ADDON 0x3c | ||
| 26 | |||
| 27 | /* For UTMICTRL Register */ | ||
| 28 | #define UTMI_CTRL_USB_CLK_EN (1 << 31) | ||
| 29 | /* pxa168 */ | ||
| 30 | #define UTMI_CTRL_SUSPEND_SET1 (1 << 30) | ||
| 31 | #define UTMI_CTRL_SUSPEND_SET2 (1 << 29) | ||
| 32 | #define UTMI_CTRL_RXBUF_PDWN (1 << 24) | ||
| 33 | #define UTMI_CTRL_TXBUF_PDWN (1 << 11) | ||
| 34 | |||
| 35 | #define UTMI_CTRL_INPKT_DELAY_SHIFT 30 | ||
| 36 | #define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT 28 | ||
| 37 | #define UTMI_CTRL_PU_REF_SHIFT 20 | ||
| 38 | #define UTMI_CTRL_ARC_PULLDN_SHIFT 12 | ||
| 39 | #define UTMI_CTRL_PLL_PWR_UP_SHIFT 1 | ||
| 40 | #define UTMI_CTRL_PWR_UP_SHIFT 0 | ||
| 41 | /* For UTMI_PLL Register */ | ||
| 42 | #define UTMI_PLL_CLK_BLK_EN_SHIFT 24 | ||
| 43 | #define UTMI_PLL_FBDIV_SHIFT 4 | ||
| 44 | #define UTMI_PLL_REFDIV_SHIFT 0 | ||
| 45 | #define UTMI_PLL_FBDIV_MASK 0x00000FF0 | ||
| 46 | #define UTMI_PLL_REFDIV_MASK 0x0000000F | ||
| 47 | #define UTMI_PLL_ICP_MASK 0x00007000 | ||
| 48 | #define UTMI_PLL_KVCO_MASK 0x00031000 | ||
| 49 | #define UTMI_PLL_PLLCALI12_SHIFT 29 | ||
| 50 | #define UTMI_PLL_PLLCALI12_MASK (0x3 << 29) | ||
| 51 | #define UTMI_PLL_PLLVDD18_SHIFT 27 | ||
| 52 | #define UTMI_PLL_PLLVDD18_MASK (0x3 << 27) | ||
| 53 | #define UTMI_PLL_PLLVDD12_SHIFT 25 | ||
| 54 | #define UTMI_PLL_PLLVDD12_MASK (0x3 << 25) | ||
| 55 | #define UTMI_PLL_KVCO_SHIFT 15 | ||
| 56 | #define UTMI_PLL_ICP_SHIFT 12 | ||
| 57 | /* For UTMI_TX Register */ | ||
| 58 | #define UTMI_TX_REG_EXT_FS_RCAL_SHIFT 27 | ||
| 59 | #define UTMI_TX_REG_EXT_FS_RCAL_MASK (0xf << 27) | ||
| 60 | #define UTMI_TX_REG_EXT_FS_RCAL_EN_MASK 26 | ||
| 61 | #define UTMI_TX_REG_EXT_FS_RCAL_EN (0x1 << 26) | ||
| 62 | #define UTMI_TX_LOW_VDD_EN_SHIFT 11 | ||
| 63 | #define UTMI_TX_IMPCAL_VTH_SHIFT 14 | ||
| 64 | #define UTMI_TX_IMPCAL_VTH_MASK (0x7 << 14) | ||
| 65 | #define UTMI_TX_CK60_PHSEL_SHIFT 17 | ||
| 66 | #define UTMI_TX_CK60_PHSEL_MASK (0xf << 17) | ||
| 67 | #define UTMI_TX_TXVDD12_SHIFT 22 | ||
| 68 | #define UTMI_TX_TXVDD12_MASK (0x3 << 22) | ||
| 69 | #define UTMI_TX_AMP_SHIFT 0 | ||
| 70 | #define UTMI_TX_AMP_MASK (0x7 << 0) | ||
| 71 | /* For UTMI_RX Register */ | ||
| 72 | #define UTMI_RX_SQ_THRESH_SHIFT 4 | ||
| 73 | #define UTMI_RX_SQ_THRESH_MASK (0xf << 4) | ||
| 74 | #define UTMI_REG_SQ_LENGTH_SHIFT 15 | ||
| 75 | #define UTMI_REG_SQ_LENGTH_MASK (0x3 << 15) | ||
| 76 | |||
| 77 | #define REG_RCAL_START 0x00001000 | ||
| 78 | #define VCOCAL_START 0x00200000 | ||
| 79 | #define KVCO_EXT 0x00400000 | ||
| 80 | #define PLL_READY 0x00800000 | ||
| 81 | #define CLK_BLK_EN 0x01000000 | ||
| 82 | #endif | ||
| 83 | |||
| 84 | static unsigned int u2o_read(unsigned int base, unsigned int offset) | ||
| 85 | { | ||
| 86 | return readl(base + offset); | ||
| 87 | } | ||
| 88 | |||
| 89 | static void u2o_set(unsigned int base, unsigned int offset, unsigned int value) | ||
| 90 | { | ||
| 91 | unsigned int reg; | ||
| 92 | |||
| 93 | reg = readl(base + offset); | ||
| 94 | reg |= value; | ||
| 95 | writel(reg, base + offset); | ||
| 96 | readl(base + offset); | ||
| 97 | } | ||
| 98 | |||
| 99 | static void u2o_clear(unsigned int base, unsigned int offset, | ||
| 100 | unsigned int value) | ||
| 101 | { | ||
| 102 | unsigned int reg; | ||
| 103 | |||
| 104 | reg = readl(base + offset); | ||
| 105 | reg &= ~value; | ||
| 106 | writel(reg, base + offset); | ||
| 107 | readl(base + offset); | ||
| 108 | } | ||
| 109 | |||
| 110 | static void u2o_write(unsigned int base, unsigned int offset, | ||
| 111 | unsigned int value) | ||
| 112 | { | ||
| 113 | writel(value, base + offset); | ||
| 114 | readl(base + offset); | ||
| 115 | } | ||
| 116 | |||
| 117 | #ifdef CONFIG_ARCH_MMP | ||
| 118 | int mv_udc_phy_init(unsigned int base) | ||
| 119 | { | ||
| 120 | unsigned long timeout; | ||
| 121 | |||
| 122 | /* Initialize the USB PHY power */ | ||
| 123 | if (cpu_is_pxa910()) { | ||
| 124 | u2o_set(base, UTMI_CTRL, (1 << UTMI_CTRL_INPKT_DELAY_SOF_SHIFT) | ||
| 125 | | (1 << UTMI_CTRL_PU_REF_SHIFT)); | ||
| 126 | } | ||
| 127 | |||
| 128 | u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PLL_PWR_UP_SHIFT); | ||
| 129 | u2o_set(base, UTMI_CTRL, 1 << UTMI_CTRL_PWR_UP_SHIFT); | ||
| 130 | |||
| 131 | /* UTMI_PLL settings */ | ||
| 132 | u2o_clear(base, UTMI_PLL, UTMI_PLL_PLLVDD18_MASK | ||
| 133 | | UTMI_PLL_PLLVDD12_MASK | UTMI_PLL_PLLCALI12_MASK | ||
| 134 | | UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK | ||
| 135 | | UTMI_PLL_ICP_MASK | UTMI_PLL_KVCO_MASK); | ||
| 136 | |||
| 137 | u2o_set(base, UTMI_PLL, (0xee << UTMI_PLL_FBDIV_SHIFT) | ||
| 138 | | (0xb << UTMI_PLL_REFDIV_SHIFT) | ||
| 139 | | (3 << UTMI_PLL_PLLVDD18_SHIFT) | ||
| 140 | | (3 << UTMI_PLL_PLLVDD12_SHIFT) | ||
| 141 | | (3 << UTMI_PLL_PLLCALI12_SHIFT) | ||
| 142 | | (1 << UTMI_PLL_ICP_SHIFT) | (3 << UTMI_PLL_KVCO_SHIFT)); | ||
| 143 | |||
| 144 | /* UTMI_TX */ | ||
| 145 | u2o_clear(base, UTMI_TX, UTMI_TX_REG_EXT_FS_RCAL_EN_MASK | ||
| 146 | | UTMI_TX_TXVDD12_MASK | ||
| 147 | | UTMI_TX_CK60_PHSEL_MASK | UTMI_TX_IMPCAL_VTH_MASK | ||
| 148 | | UTMI_TX_REG_EXT_FS_RCAL_MASK | UTMI_TX_AMP_MASK); | ||
| 149 | u2o_set(base, UTMI_TX, (3 << UTMI_TX_TXVDD12_SHIFT) | ||
| 150 | | (4 << UTMI_TX_CK60_PHSEL_SHIFT) | ||
| 151 | | (4 << UTMI_TX_IMPCAL_VTH_SHIFT) | ||
| 152 | | (8 << UTMI_TX_REG_EXT_FS_RCAL_SHIFT) | ||
| 153 | | (3 << UTMI_TX_AMP_SHIFT)); | ||
| 154 | |||
| 155 | /* UTMI_RX */ | ||
| 156 | u2o_clear(base, UTMI_RX, UTMI_RX_SQ_THRESH_MASK | ||
| 157 | | UTMI_REG_SQ_LENGTH_MASK); | ||
| 158 | if (cpu_is_pxa168()) | ||
| 159 | u2o_set(base, UTMI_RX, (7 << UTMI_RX_SQ_THRESH_SHIFT) | ||
| 160 | | (2 << UTMI_REG_SQ_LENGTH_SHIFT)); | ||
| 161 | else | ||
| 162 | u2o_set(base, UTMI_RX, (0x7 << UTMI_RX_SQ_THRESH_SHIFT) | ||
| 163 | | (2 << UTMI_REG_SQ_LENGTH_SHIFT)); | ||
| 164 | |||
| 165 | /* UTMI_IVREF */ | ||
| 166 | if (cpu_is_pxa168()) | ||
| 167 | /* | ||
| 168 | * fixing Microsoft Altair board interface with NEC hub issue - | ||
| 169 | * Set UTMI_IVREF from 0x4a3 to 0x4bf | ||
| 170 | */ | ||
| 171 | u2o_write(base, UTMI_IVREF, 0x4bf); | ||
| 172 | |||
| 173 | /* calibrate */ | ||
| 174 | timeout = jiffies + 100; | ||
| 175 | while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) { | ||
| 176 | if (time_after(jiffies, timeout)) | ||
| 177 | return -ETIME; | ||
| 178 | cpu_relax(); | ||
| 179 | } | ||
| 180 | |||
| 181 | /* toggle VCOCAL_START bit of UTMI_PLL */ | ||
| 182 | udelay(200); | ||
| 183 | u2o_set(base, UTMI_PLL, VCOCAL_START); | ||
| 184 | udelay(40); | ||
| 185 | u2o_clear(base, UTMI_PLL, VCOCAL_START); | ||
| 186 | |||
| 187 | /* toggle REG_RCAL_START bit of UTMI_TX */ | ||
| 188 | udelay(200); | ||
| 189 | u2o_set(base, UTMI_TX, REG_RCAL_START); | ||
| 190 | udelay(40); | ||
| 191 | u2o_clear(base, UTMI_TX, REG_RCAL_START); | ||
| 192 | udelay(200); | ||
| 193 | |||
| 194 | /* make sure phy is ready */ | ||
| 195 | timeout = jiffies + 100; | ||
| 196 | while ((u2o_read(base, UTMI_PLL) & PLL_READY) == 0) { | ||
| 197 | if (time_after(jiffies, timeout)) | ||
| 198 | return -ETIME; | ||
| 199 | cpu_relax(); | ||
| 200 | } | ||
| 201 | |||
| 202 | if (cpu_is_pxa168()) { | ||
| 203 | u2o_set(base, UTMI_RESERVE, 1 << 5); | ||
| 204 | /* Turn on UTMI PHY OTG extension */ | ||
| 205 | u2o_write(base, UTMI_OTG_ADDON, 1); | ||
| 206 | } | ||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | #else | ||
| 210 | int mv_udc_phy_init(unsigned int base) | ||
| 211 | { | ||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | #endif | ||
diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c new file mode 100644 index 000000000000..99c179ad729d --- /dev/null +++ b/drivers/usb/gadget/ncm.c | |||
| @@ -0,0 +1,248 @@ | |||
| 1 | /* | ||
| 2 | * ncm.c -- NCM gadget driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Nokia Corporation | ||
| 5 | * Contact: Yauheni Kaliuta <yauheni.kaliuta@nokia.com> | ||
| 6 | * | ||
| 7 | * The driver borrows from ether.c which is: | ||
| 8 | * | ||
| 9 | * Copyright (C) 2003-2005,2008 David Brownell | ||
| 10 | * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger | ||
| 11 | * Copyright (C) 2008 Nokia Corporation | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation; either version 2 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, | ||
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | * GNU General Public License for more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License | ||
| 24 | * along with this program; if not, write to the Free Software | ||
| 25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 26 | */ | ||
| 27 | |||
| 28 | /* #define DEBUG */ | ||
| 29 | /* #define VERBOSE_DEBUG */ | ||
| 30 | |||
| 31 | #include <linux/kernel.h> | ||
| 32 | #include <linux/utsname.h> | ||
| 33 | |||
| 34 | |||
| 35 | #include "u_ether.h" | ||
| 36 | |||
| 37 | #define DRIVER_DESC "NCM Gadget" | ||
| 38 | |||
| 39 | /*-------------------------------------------------------------------------*/ | ||
| 40 | |||
| 41 | /* | ||
| 42 | * Kbuild is not very cooperative with respect to linking separately | ||
| 43 | * compiled library objects into one module. So for now we won't use | ||
| 44 | * separate compilation ... ensuring init/exit sections work to shrink | ||
| 45 | * the runtime footprint, and giving us at least some parts of what | ||
| 46 | * a "gcc --combine ... part1.c part2.c part3.c ... " build would. | ||
| 47 | */ | ||
| 48 | #include "composite.c" | ||
| 49 | #include "usbstring.c" | ||
| 50 | #include "config.c" | ||
| 51 | #include "epautoconf.c" | ||
| 52 | |||
| 53 | #include "f_ncm.c" | ||
| 54 | #include "u_ether.c" | ||
| 55 | |||
| 56 | /*-------------------------------------------------------------------------*/ | ||
| 57 | |||
| 58 | /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! | ||
| 59 | * Instead: allocate your own, using normal USB-IF procedures. | ||
| 60 | */ | ||
| 61 | |||
| 62 | /* Thanks to NetChip Technologies for donating this product ID. | ||
| 63 | * It's for devices with only CDC Ethernet configurations. | ||
| 64 | */ | ||
| 65 | #define CDC_VENDOR_NUM 0x0525 /* NetChip */ | ||
| 66 | #define CDC_PRODUCT_NUM 0xa4a1 /* Linux-USB Ethernet Gadget */ | ||
| 67 | |||
| 68 | /*-------------------------------------------------------------------------*/ | ||
| 69 | |||
| 70 | static struct usb_device_descriptor device_desc = { | ||
| 71 | .bLength = sizeof device_desc, | ||
| 72 | .bDescriptorType = USB_DT_DEVICE, | ||
| 73 | |||
| 74 | .bcdUSB = cpu_to_le16 (0x0200), | ||
| 75 | |||
| 76 | .bDeviceClass = USB_CLASS_COMM, | ||
| 77 | .bDeviceSubClass = 0, | ||
| 78 | .bDeviceProtocol = 0, | ||
| 79 | /* .bMaxPacketSize0 = f(hardware) */ | ||
| 80 | |||
| 81 | /* Vendor and product id defaults change according to what configs | ||
| 82 | * we support. (As does bNumConfigurations.) These values can | ||
| 83 | * also be overridden by module parameters. | ||
| 84 | */ | ||
| 85 | .idVendor = cpu_to_le16 (CDC_VENDOR_NUM), | ||
| 86 | .idProduct = cpu_to_le16 (CDC_PRODUCT_NUM), | ||
| 87 | /* .bcdDevice = f(hardware) */ | ||
| 88 | /* .iManufacturer = DYNAMIC */ | ||
| 89 | /* .iProduct = DYNAMIC */ | ||
| 90 | /* NO SERIAL NUMBER */ | ||
| 91 | .bNumConfigurations = 1, | ||
| 92 | }; | ||
| 93 | |||
| 94 | static struct usb_otg_descriptor otg_descriptor = { | ||
| 95 | .bLength = sizeof otg_descriptor, | ||
| 96 | .bDescriptorType = USB_DT_OTG, | ||
| 97 | |||
| 98 | /* REVISIT SRP-only hardware is possible, although | ||
| 99 | * it would not be called "OTG" ... | ||
| 100 | */ | ||
| 101 | .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, | ||
| 102 | }; | ||
| 103 | |||
| 104 | static const struct usb_descriptor_header *otg_desc[] = { | ||
| 105 | (struct usb_descriptor_header *) &otg_descriptor, | ||
| 106 | NULL, | ||
| 107 | }; | ||
| 108 | |||
| 109 | |||
| 110 | /* string IDs are assigned dynamically */ | ||
| 111 | |||
| 112 | #define STRING_MANUFACTURER_IDX 0 | ||
| 113 | #define STRING_PRODUCT_IDX 1 | ||
| 114 | |||
| 115 | static char manufacturer[50]; | ||
| 116 | |||
| 117 | static struct usb_string strings_dev[] = { | ||
| 118 | [STRING_MANUFACTURER_IDX].s = manufacturer, | ||
| 119 | [STRING_PRODUCT_IDX].s = DRIVER_DESC, | ||
| 120 | { } /* end of list */ | ||
| 121 | }; | ||
| 122 | |||
| 123 | static struct usb_gadget_strings stringtab_dev = { | ||
| 124 | .language = 0x0409, /* en-us */ | ||
| 125 | .strings = strings_dev, | ||
| 126 | }; | ||
| 127 | |||
| 128 | static struct usb_gadget_strings *dev_strings[] = { | ||
| 129 | &stringtab_dev, | ||
| 130 | NULL, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static u8 hostaddr[ETH_ALEN]; | ||
| 134 | |||
| 135 | /*-------------------------------------------------------------------------*/ | ||
| 136 | |||
| 137 | static int __init ncm_do_config(struct usb_configuration *c) | ||
| 138 | { | ||
| 139 | /* FIXME alloc iConfiguration string, set it in c->strings */ | ||
| 140 | |||
| 141 | if (gadget_is_otg(c->cdev->gadget)) { | ||
| 142 | c->descriptors = otg_desc; | ||
| 143 | c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
| 144 | } | ||
| 145 | |||
| 146 | return ncm_bind_config(c, hostaddr); | ||
| 147 | } | ||
| 148 | |||
| 149 | static struct usb_configuration ncm_config_driver = { | ||
| 150 | /* .label = f(hardware) */ | ||
| 151 | .label = "CDC Ethernet (NCM)", | ||
| 152 | .bConfigurationValue = 1, | ||
| 153 | /* .iConfiguration = DYNAMIC */ | ||
| 154 | .bmAttributes = USB_CONFIG_ATT_SELFPOWER, | ||
| 155 | }; | ||
| 156 | |||
| 157 | /*-------------------------------------------------------------------------*/ | ||
| 158 | |||
| 159 | static int __init gncm_bind(struct usb_composite_dev *cdev) | ||
| 160 | { | ||
| 161 | int gcnum; | ||
| 162 | struct usb_gadget *gadget = cdev->gadget; | ||
| 163 | int status; | ||
| 164 | |||
| 165 | /* set up network link layer */ | ||
| 166 | status = gether_setup(cdev->gadget, hostaddr); | ||
| 167 | if (status < 0) | ||
| 168 | return status; | ||
| 169 | |||
| 170 | gcnum = usb_gadget_controller_number(gadget); | ||
| 171 | if (gcnum >= 0) | ||
| 172 | device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); | ||
| 173 | else { | ||
| 174 | /* We assume that can_support_ecm() tells the truth; | ||
| 175 | * but if the controller isn't recognized at all then | ||
| 176 | * that assumption is a bit more likely to be wrong. | ||
| 177 | */ | ||
| 178 | dev_warn(&gadget->dev, | ||
| 179 | "controller '%s' not recognized; trying %s\n", | ||
| 180 | gadget->name, | ||
| 181 | ncm_config_driver.label); | ||
| 182 | device_desc.bcdDevice = | ||
| 183 | cpu_to_le16(0x0300 | 0x0099); | ||
| 184 | } | ||
| 185 | |||
| 186 | |||
| 187 | /* Allocate string descriptor numbers ... note that string | ||
| 188 | * contents can be overridden by the composite_dev glue. | ||
| 189 | */ | ||
| 190 | |||
| 191 | /* device descriptor strings: manufacturer, product */ | ||
| 192 | snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", | ||
| 193 | init_utsname()->sysname, init_utsname()->release, | ||
| 194 | gadget->name); | ||
| 195 | status = usb_string_id(cdev); | ||
| 196 | if (status < 0) | ||
| 197 | goto fail; | ||
| 198 | strings_dev[STRING_MANUFACTURER_IDX].id = status; | ||
| 199 | device_desc.iManufacturer = status; | ||
| 200 | |||
| 201 | status = usb_string_id(cdev); | ||
| 202 | if (status < 0) | ||
| 203 | goto fail; | ||
| 204 | strings_dev[STRING_PRODUCT_IDX].id = status; | ||
| 205 | device_desc.iProduct = status; | ||
| 206 | |||
| 207 | status = usb_add_config(cdev, &ncm_config_driver, | ||
| 208 | ncm_do_config); | ||
| 209 | if (status < 0) | ||
| 210 | goto fail; | ||
| 211 | |||
| 212 | dev_info(&gadget->dev, "%s\n", DRIVER_DESC); | ||
| 213 | |||
| 214 | return 0; | ||
| 215 | |||
| 216 | fail: | ||
| 217 | gether_cleanup(); | ||
| 218 | return status; | ||
| 219 | } | ||
| 220 | |||
| 221 | static int __exit gncm_unbind(struct usb_composite_dev *cdev) | ||
| 222 | { | ||
| 223 | gether_cleanup(); | ||
| 224 | return 0; | ||
| 225 | } | ||
| 226 | |||
| 227 | static struct usb_composite_driver ncm_driver = { | ||
| 228 | .name = "g_ncm", | ||
| 229 | .dev = &device_desc, | ||
| 230 | .strings = dev_strings, | ||
| 231 | .unbind = __exit_p(gncm_unbind), | ||
| 232 | }; | ||
| 233 | |||
| 234 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 235 | MODULE_AUTHOR("Yauheni Kaliuta"); | ||
| 236 | MODULE_LICENSE("GPL"); | ||
| 237 | |||
| 238 | static int __init init(void) | ||
| 239 | { | ||
| 240 | return usb_composite_probe(&ncm_driver, gncm_bind); | ||
| 241 | } | ||
| 242 | module_init(init); | ||
| 243 | |||
| 244 | static void __exit cleanup(void) | ||
| 245 | { | ||
| 246 | usb_composite_unregister(&ncm_driver); | ||
| 247 | } | ||
| 248 | module_exit(cleanup); | ||
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c new file mode 100644 index 000000000000..0c8dd81dddca --- /dev/null +++ b/drivers/usb/gadget/pch_udc.c | |||
| @@ -0,0 +1,2947 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; version 2 of the License. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
| 16 | */ | ||
| 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/pci.h> | ||
| 21 | #include <linux/delay.h> | ||
| 22 | #include <linux/errno.h> | ||
| 23 | #include <linux/list.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/usb/ch9.h> | ||
| 26 | #include <linux/usb/gadget.h> | ||
| 27 | |||
| 28 | /* Address offset of Registers */ | ||
| 29 | #define UDC_EP_REG_SHIFT 0x20 /* Offset to next EP */ | ||
| 30 | |||
| 31 | #define UDC_EPCTL_ADDR 0x00 /* Endpoint control */ | ||
| 32 | #define UDC_EPSTS_ADDR 0x04 /* Endpoint status */ | ||
| 33 | #define UDC_BUFIN_FRAMENUM_ADDR 0x08 /* buffer size in / frame number out */ | ||
| 34 | #define UDC_BUFOUT_MAXPKT_ADDR 0x0C /* buffer size out / maxpkt in */ | ||
| 35 | #define UDC_SUBPTR_ADDR 0x10 /* setup buffer pointer */ | ||
| 36 | #define UDC_DESPTR_ADDR 0x14 /* Data descriptor pointer */ | ||
| 37 | #define UDC_CONFIRM_ADDR 0x18 /* Write/Read confirmation */ | ||
| 38 | |||
| 39 | #define UDC_DEVCFG_ADDR 0x400 /* Device configuration */ | ||
| 40 | #define UDC_DEVCTL_ADDR 0x404 /* Device control */ | ||
| 41 | #define UDC_DEVSTS_ADDR 0x408 /* Device status */ | ||
| 42 | #define UDC_DEVIRQSTS_ADDR 0x40C /* Device irq status */ | ||
| 43 | #define UDC_DEVIRQMSK_ADDR 0x410 /* Device irq mask */ | ||
| 44 | #define UDC_EPIRQSTS_ADDR 0x414 /* Endpoint irq status */ | ||
| 45 | #define UDC_EPIRQMSK_ADDR 0x418 /* Endpoint irq mask */ | ||
| 46 | #define UDC_DEVLPM_ADDR 0x41C /* LPM control / status */ | ||
| 47 | #define UDC_CSR_BUSY_ADDR 0x4f0 /* UDC_CSR_BUSY Status register */ | ||
| 48 | #define UDC_SRST_ADDR 0x4fc /* SOFT RESET register */ | ||
| 49 | #define UDC_CSR_ADDR 0x500 /* USB_DEVICE endpoint register */ | ||
| 50 | |||
| 51 | /* Endpoint control register */ | ||
| 52 | /* Bit position */ | ||
| 53 | #define UDC_EPCTL_MRXFLUSH (1 << 12) | ||
| 54 | #define UDC_EPCTL_RRDY (1 << 9) | ||
| 55 | #define UDC_EPCTL_CNAK (1 << 8) | ||
| 56 | #define UDC_EPCTL_SNAK (1 << 7) | ||
| 57 | #define UDC_EPCTL_NAK (1 << 6) | ||
| 58 | #define UDC_EPCTL_P (1 << 3) | ||
| 59 | #define UDC_EPCTL_F (1 << 1) | ||
| 60 | #define UDC_EPCTL_S (1 << 0) | ||
| 61 | #define UDC_EPCTL_ET_SHIFT 4 | ||
| 62 | /* Mask patern */ | ||
| 63 | #define UDC_EPCTL_ET_MASK 0x00000030 | ||
| 64 | /* Value for ET field */ | ||
| 65 | #define UDC_EPCTL_ET_CONTROL 0 | ||
| 66 | #define UDC_EPCTL_ET_ISO 1 | ||
| 67 | #define UDC_EPCTL_ET_BULK 2 | ||
| 68 | #define UDC_EPCTL_ET_INTERRUPT 3 | ||
| 69 | |||
| 70 | /* Endpoint status register */ | ||
| 71 | /* Bit position */ | ||
| 72 | #define UDC_EPSTS_XFERDONE (1 << 27) | ||
| 73 | #define UDC_EPSTS_RSS (1 << 26) | ||
| 74 | #define UDC_EPSTS_RCS (1 << 25) | ||
| 75 | #define UDC_EPSTS_TXEMPTY (1 << 24) | ||
| 76 | #define UDC_EPSTS_TDC (1 << 10) | ||
| 77 | #define UDC_EPSTS_HE (1 << 9) | ||
| 78 | #define UDC_EPSTS_MRXFIFO_EMP (1 << 8) | ||
| 79 | #define UDC_EPSTS_BNA (1 << 7) | ||
| 80 | #define UDC_EPSTS_IN (1 << 6) | ||
| 81 | #define UDC_EPSTS_OUT_SHIFT 4 | ||
| 82 | /* Mask patern */ | ||
| 83 | #define UDC_EPSTS_OUT_MASK 0x00000030 | ||
| 84 | #define UDC_EPSTS_ALL_CLR_MASK 0x1F0006F0 | ||
| 85 | /* Value for OUT field */ | ||
| 86 | #define UDC_EPSTS_OUT_SETUP 2 | ||
| 87 | #define UDC_EPSTS_OUT_DATA 1 | ||
| 88 | |||
| 89 | /* Device configuration register */ | ||
| 90 | /* Bit position */ | ||
| 91 | #define UDC_DEVCFG_CSR_PRG (1 << 17) | ||
| 92 | #define UDC_DEVCFG_SP (1 << 3) | ||
| 93 | /* SPD Valee */ | ||
| 94 | #define UDC_DEVCFG_SPD_HS 0x0 | ||
| 95 | #define UDC_DEVCFG_SPD_FS 0x1 | ||
| 96 | #define UDC_DEVCFG_SPD_LS 0x2 | ||
| 97 | |||
| 98 | /* Device control register */ | ||
| 99 | /* Bit position */ | ||
| 100 | #define UDC_DEVCTL_THLEN_SHIFT 24 | ||
| 101 | #define UDC_DEVCTL_BRLEN_SHIFT 16 | ||
| 102 | #define UDC_DEVCTL_CSR_DONE (1 << 13) | ||
| 103 | #define UDC_DEVCTL_SD (1 << 10) | ||
| 104 | #define UDC_DEVCTL_MODE (1 << 9) | ||
| 105 | #define UDC_DEVCTL_BREN (1 << 8) | ||
| 106 | #define UDC_DEVCTL_THE (1 << 7) | ||
| 107 | #define UDC_DEVCTL_DU (1 << 4) | ||
| 108 | #define UDC_DEVCTL_TDE (1 << 3) | ||
| 109 | #define UDC_DEVCTL_RDE (1 << 2) | ||
| 110 | #define UDC_DEVCTL_RES (1 << 0) | ||
| 111 | |||
| 112 | /* Device status register */ | ||
| 113 | /* Bit position */ | ||
| 114 | #define UDC_DEVSTS_TS_SHIFT 18 | ||
| 115 | #define UDC_DEVSTS_ENUM_SPEED_SHIFT 13 | ||
| 116 | #define UDC_DEVSTS_ALT_SHIFT 8 | ||
| 117 | #define UDC_DEVSTS_INTF_SHIFT 4 | ||
| 118 | #define UDC_DEVSTS_CFG_SHIFT 0 | ||
| 119 | /* Mask patern */ | ||
| 120 | #define UDC_DEVSTS_TS_MASK 0xfffc0000 | ||
| 121 | #define UDC_DEVSTS_ENUM_SPEED_MASK 0x00006000 | ||
| 122 | #define UDC_DEVSTS_ALT_MASK 0x00000f00 | ||
| 123 | #define UDC_DEVSTS_INTF_MASK 0x000000f0 | ||
| 124 | #define UDC_DEVSTS_CFG_MASK 0x0000000f | ||
| 125 | /* value for maximum speed for SPEED field */ | ||
| 126 | #define UDC_DEVSTS_ENUM_SPEED_FULL 1 | ||
| 127 | #define UDC_DEVSTS_ENUM_SPEED_HIGH 0 | ||
| 128 | #define UDC_DEVSTS_ENUM_SPEED_LOW 2 | ||
| 129 | #define UDC_DEVSTS_ENUM_SPEED_FULLX 3 | ||
| 130 | |||
| 131 | /* Device irq register */ | ||
| 132 | /* Bit position */ | ||
| 133 | #define UDC_DEVINT_RWKP (1 << 7) | ||
| 134 | #define UDC_DEVINT_ENUM (1 << 6) | ||
| 135 | #define UDC_DEVINT_SOF (1 << 5) | ||
| 136 | #define UDC_DEVINT_US (1 << 4) | ||
| 137 | #define UDC_DEVINT_UR (1 << 3) | ||
| 138 | #define UDC_DEVINT_ES (1 << 2) | ||
| 139 | #define UDC_DEVINT_SI (1 << 1) | ||
| 140 | #define UDC_DEVINT_SC (1 << 0) | ||
| 141 | /* Mask patern */ | ||
| 142 | #define UDC_DEVINT_MSK 0x7f | ||
| 143 | |||
| 144 | /* Endpoint irq register */ | ||
| 145 | /* Bit position */ | ||
| 146 | #define UDC_EPINT_IN_SHIFT 0 | ||
| 147 | #define UDC_EPINT_OUT_SHIFT 16 | ||
| 148 | #define UDC_EPINT_IN_EP0 (1 << 0) | ||
| 149 | #define UDC_EPINT_OUT_EP0 (1 << 16) | ||
| 150 | /* Mask patern */ | ||
| 151 | #define UDC_EPINT_MSK_DISABLE_ALL 0xffffffff | ||
| 152 | |||
| 153 | /* UDC_CSR_BUSY Status register */ | ||
| 154 | /* Bit position */ | ||
| 155 | #define UDC_CSR_BUSY (1 << 0) | ||
| 156 | |||
| 157 | /* SOFT RESET register */ | ||
| 158 | /* Bit position */ | ||
| 159 | #define UDC_PSRST (1 << 1) | ||
| 160 | #define UDC_SRST (1 << 0) | ||
| 161 | |||
| 162 | /* USB_DEVICE endpoint register */ | ||
| 163 | /* Bit position */ | ||
| 164 | #define UDC_CSR_NE_NUM_SHIFT 0 | ||
| 165 | #define UDC_CSR_NE_DIR_SHIFT 4 | ||
| 166 | #define UDC_CSR_NE_TYPE_SHIFT 5 | ||
| 167 | #define UDC_CSR_NE_CFG_SHIFT 7 | ||
| 168 | #define UDC_CSR_NE_INTF_SHIFT 11 | ||
| 169 | #define UDC_CSR_NE_ALT_SHIFT 15 | ||
| 170 | #define UDC_CSR_NE_MAX_PKT_SHIFT 19 | ||
| 171 | /* Mask patern */ | ||
| 172 | #define UDC_CSR_NE_NUM_MASK 0x0000000f | ||
| 173 | #define UDC_CSR_NE_DIR_MASK 0x00000010 | ||
| 174 | #define UDC_CSR_NE_TYPE_MASK 0x00000060 | ||
| 175 | #define UDC_CSR_NE_CFG_MASK 0x00000780 | ||
| 176 | #define UDC_CSR_NE_INTF_MASK 0x00007800 | ||
| 177 | #define UDC_CSR_NE_ALT_MASK 0x00078000 | ||
| 178 | #define UDC_CSR_NE_MAX_PKT_MASK 0x3ff80000 | ||
| 179 | |||
| 180 | #define PCH_UDC_CSR(ep) (UDC_CSR_ADDR + ep*4) | ||
| 181 | #define PCH_UDC_EPINT(in, num)\ | ||
| 182 | (1 << (num + (in ? UDC_EPINT_IN_SHIFT : UDC_EPINT_OUT_SHIFT))) | ||
| 183 | |||
| 184 | /* Index of endpoint */ | ||
| 185 | #define UDC_EP0IN_IDX 0 | ||
| 186 | #define UDC_EP0OUT_IDX 1 | ||
| 187 | #define UDC_EPIN_IDX(ep) (ep * 2) | ||
| 188 | #define UDC_EPOUT_IDX(ep) (ep * 2 + 1) | ||
| 189 | #define PCH_UDC_EP0 0 | ||
| 190 | #define PCH_UDC_EP1 1 | ||
| 191 | #define PCH_UDC_EP2 2 | ||
| 192 | #define PCH_UDC_EP3 3 | ||
| 193 | |||
| 194 | /* Number of endpoint */ | ||
| 195 | #define PCH_UDC_EP_NUM 32 /* Total number of EPs (16 IN,16 OUT) */ | ||
| 196 | #define PCH_UDC_USED_EP_NUM 4 /* EP number of EP's really used */ | ||
| 197 | /* Length Value */ | ||
| 198 | #define PCH_UDC_BRLEN 0x0F /* Burst length */ | ||
| 199 | #define PCH_UDC_THLEN 0x1F /* Threshold length */ | ||
| 200 | /* Value of EP Buffer Size */ | ||
| 201 | #define UDC_EP0IN_BUFF_SIZE 64 | ||
| 202 | #define UDC_EPIN_BUFF_SIZE 512 | ||
| 203 | #define UDC_EP0OUT_BUFF_SIZE 64 | ||
| 204 | #define UDC_EPOUT_BUFF_SIZE 512 | ||
| 205 | /* Value of EP maximum packet size */ | ||
| 206 | #define UDC_EP0IN_MAX_PKT_SIZE 64 | ||
| 207 | #define UDC_EP0OUT_MAX_PKT_SIZE 64 | ||
| 208 | #define UDC_BULK_MAX_PKT_SIZE 512 | ||
| 209 | |||
| 210 | /* DMA */ | ||
| 211 | #define DMA_DIR_RX 1 /* DMA for data receive */ | ||
| 212 | #define DMA_DIR_TX 2 /* DMA for data transmit */ | ||
| 213 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
| 214 | #define UDC_DMA_MAXPACKET 65536 /* maximum packet size for DMA */ | ||
| 215 | |||
| 216 | /** | ||
| 217 | * struct pch_udc_data_dma_desc - Structure to hold DMA descriptor information | ||
| 218 | * for data | ||
| 219 | * @status: Status quadlet | ||
| 220 | * @reserved: Reserved | ||
| 221 | * @dataptr: Buffer descriptor | ||
| 222 | * @next: Next descriptor | ||
| 223 | */ | ||
| 224 | struct pch_udc_data_dma_desc { | ||
| 225 | u32 status; | ||
| 226 | u32 reserved; | ||
| 227 | u32 dataptr; | ||
| 228 | u32 next; | ||
| 229 | }; | ||
| 230 | |||
| 231 | /** | ||
| 232 | * struct pch_udc_stp_dma_desc - Structure to hold DMA descriptor information | ||
| 233 | * for control data | ||
| 234 | * @status: Status | ||
| 235 | * @reserved: Reserved | ||
| 236 | * @data12: First setup word | ||
| 237 | * @data34: Second setup word | ||
| 238 | */ | ||
| 239 | struct pch_udc_stp_dma_desc { | ||
| 240 | u32 status; | ||
| 241 | u32 reserved; | ||
| 242 | struct usb_ctrlrequest request; | ||
| 243 | } __attribute((packed)); | ||
| 244 | |||
| 245 | /* DMA status definitions */ | ||
| 246 | /* Buffer status */ | ||
| 247 | #define PCH_UDC_BUFF_STS 0xC0000000 | ||
| 248 | #define PCH_UDC_BS_HST_RDY 0x00000000 | ||
| 249 | #define PCH_UDC_BS_DMA_BSY 0x40000000 | ||
| 250 | #define PCH_UDC_BS_DMA_DONE 0x80000000 | ||
| 251 | #define PCH_UDC_BS_HST_BSY 0xC0000000 | ||
| 252 | /* Rx/Tx Status */ | ||
| 253 | #define PCH_UDC_RXTX_STS 0x30000000 | ||
| 254 | #define PCH_UDC_RTS_SUCC 0x00000000 | ||
| 255 | #define PCH_UDC_RTS_DESERR 0x10000000 | ||
| 256 | #define PCH_UDC_RTS_BUFERR 0x30000000 | ||
| 257 | /* Last Descriptor Indication */ | ||
| 258 | #define PCH_UDC_DMA_LAST 0x08000000 | ||
| 259 | /* Number of Rx/Tx Bytes Mask */ | ||
| 260 | #define PCH_UDC_RXTX_BYTES 0x0000ffff | ||
| 261 | |||
| 262 | /** | ||
| 263 | * struct pch_udc_cfg_data - Structure to hold current configuration | ||
| 264 | * and interface information | ||
| 265 | * @cur_cfg: current configuration in use | ||
| 266 | * @cur_intf: current interface in use | ||
| 267 | * @cur_alt: current alt interface in use | ||
| 268 | */ | ||
| 269 | struct pch_udc_cfg_data { | ||
| 270 | u16 cur_cfg; | ||
| 271 | u16 cur_intf; | ||
| 272 | u16 cur_alt; | ||
| 273 | }; | ||
| 274 | |||
| 275 | /** | ||
| 276 | * struct pch_udc_ep - Structure holding a PCH USB device Endpoint information | ||
| 277 | * @ep: embedded ep request | ||
| 278 | * @td_stp_phys: for setup request | ||
| 279 | * @td_data_phys: for data request | ||
| 280 | * @td_stp: for setup request | ||
| 281 | * @td_data: for data request | ||
| 282 | * @dev: reference to device struct | ||
| 283 | * @offset_addr: offset address of ep register | ||
| 284 | * @desc: for this ep | ||
| 285 | * @queue: queue for requests | ||
| 286 | * @num: endpoint number | ||
| 287 | * @in: endpoint is IN | ||
| 288 | * @halted: endpoint halted? | ||
| 289 | * @epsts: Endpoint status | ||
| 290 | */ | ||
| 291 | struct pch_udc_ep { | ||
| 292 | struct usb_ep ep; | ||
| 293 | dma_addr_t td_stp_phys; | ||
| 294 | dma_addr_t td_data_phys; | ||
| 295 | struct pch_udc_stp_dma_desc *td_stp; | ||
| 296 | struct pch_udc_data_dma_desc *td_data; | ||
| 297 | struct pch_udc_dev *dev; | ||
| 298 | unsigned long offset_addr; | ||
| 299 | const struct usb_endpoint_descriptor *desc; | ||
| 300 | struct list_head queue; | ||
| 301 | unsigned num:5, | ||
| 302 | in:1, | ||
| 303 | halted:1; | ||
| 304 | unsigned long epsts; | ||
| 305 | }; | ||
| 306 | |||
| 307 | /** | ||
| 308 | * struct pch_udc_dev - Structure holding complete information | ||
| 309 | * of the PCH USB device | ||
| 310 | * @gadget: gadget driver data | ||
| 311 | * @driver: reference to gadget driver bound | ||
| 312 | * @pdev: reference to the PCI device | ||
| 313 | * @ep: array of endpoints | ||
| 314 | * @lock: protects all state | ||
| 315 | * @active: enabled the PCI device | ||
| 316 | * @stall: stall requested | ||
| 317 | * @prot_stall: protcol stall requested | ||
| 318 | * @irq_registered: irq registered with system | ||
| 319 | * @mem_region: device memory mapped | ||
| 320 | * @registered: driver regsitered with system | ||
| 321 | * @suspended: driver in suspended state | ||
| 322 | * @connected: gadget driver associated | ||
| 323 | * @set_cfg_not_acked: pending acknowledgement 4 setup | ||
| 324 | * @waiting_zlp_ack: pending acknowledgement 4 ZLP | ||
| 325 | * @data_requests: DMA pool for data requests | ||
| 326 | * @stp_requests: DMA pool for setup requests | ||
| 327 | * @dma_addr: DMA pool for received | ||
| 328 | * @ep0out_buf: Buffer for DMA | ||
| 329 | * @setup_data: Received setup data | ||
| 330 | * @phys_addr: of device memory | ||
| 331 | * @base_addr: for mapped device memory | ||
| 332 | * @irq: IRQ line for the device | ||
| 333 | * @cfg_data: current cfg, intf, and alt in use | ||
| 334 | */ | ||
| 335 | struct pch_udc_dev { | ||
| 336 | struct usb_gadget gadget; | ||
| 337 | struct usb_gadget_driver *driver; | ||
| 338 | struct pci_dev *pdev; | ||
| 339 | struct pch_udc_ep ep[PCH_UDC_EP_NUM]; | ||
| 340 | spinlock_t lock; /* protects all state */ | ||
| 341 | unsigned active:1, | ||
| 342 | stall:1, | ||
| 343 | prot_stall:1, | ||
| 344 | irq_registered:1, | ||
| 345 | mem_region:1, | ||
| 346 | registered:1, | ||
| 347 | suspended:1, | ||
| 348 | connected:1, | ||
| 349 | set_cfg_not_acked:1, | ||
| 350 | waiting_zlp_ack:1; | ||
| 351 | struct pci_pool *data_requests; | ||
| 352 | struct pci_pool *stp_requests; | ||
| 353 | dma_addr_t dma_addr; | ||
| 354 | unsigned long ep0out_buf[64]; | ||
| 355 | struct usb_ctrlrequest setup_data; | ||
| 356 | unsigned long phys_addr; | ||
| 357 | void __iomem *base_addr; | ||
| 358 | unsigned irq; | ||
| 359 | struct pch_udc_cfg_data cfg_data; | ||
| 360 | }; | ||
| 361 | |||
| 362 | #define PCH_UDC_PCI_BAR 1 | ||
| 363 | #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 | ||
| 364 | |||
| 365 | static const char ep0_string[] = "ep0in"; | ||
| 366 | static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ | ||
| 367 | struct pch_udc_dev *pch_udc; /* pointer to device object */ | ||
| 368 | |||
| 369 | static int speed_fs; | ||
| 370 | module_param_named(speed_fs, speed_fs, bool, S_IRUGO); | ||
| 371 | MODULE_PARM_DESC(speed_fs, "true for Full speed operation"); | ||
| 372 | |||
| 373 | /** | ||
| 374 | * struct pch_udc_request - Structure holding a PCH USB device request packet | ||
| 375 | * @req: embedded ep request | ||
| 376 | * @td_data_phys: phys. address | ||
| 377 | * @td_data: first dma desc. of chain | ||
| 378 | * @td_data_last: last dma desc. of chain | ||
| 379 | * @queue: associated queue | ||
| 380 | * @dma_going: DMA in progress for request | ||
| 381 | * @dma_mapped: DMA memory mapped for request | ||
| 382 | * @dma_done: DMA completed for request | ||
| 383 | * @chain_len: chain length | ||
| 384 | */ | ||
| 385 | struct pch_udc_request { | ||
| 386 | struct usb_request req; | ||
| 387 | dma_addr_t td_data_phys; | ||
| 388 | struct pch_udc_data_dma_desc *td_data; | ||
| 389 | struct pch_udc_data_dma_desc *td_data_last; | ||
| 390 | struct list_head queue; | ||
| 391 | unsigned dma_going:1, | ||
| 392 | dma_mapped:1, | ||
| 393 | dma_done:1; | ||
| 394 | unsigned chain_len; | ||
| 395 | }; | ||
| 396 | |||
| 397 | static inline u32 pch_udc_readl(struct pch_udc_dev *dev, unsigned long reg) | ||
| 398 | { | ||
| 399 | return ioread32(dev->base_addr + reg); | ||
| 400 | } | ||
| 401 | |||
| 402 | static inline void pch_udc_writel(struct pch_udc_dev *dev, | ||
| 403 | unsigned long val, unsigned long reg) | ||
| 404 | { | ||
| 405 | iowrite32(val, dev->base_addr + reg); | ||
| 406 | } | ||
| 407 | |||
| 408 | static inline void pch_udc_bit_set(struct pch_udc_dev *dev, | ||
| 409 | unsigned long reg, | ||
| 410 | unsigned long bitmask) | ||
| 411 | { | ||
| 412 | pch_udc_writel(dev, pch_udc_readl(dev, reg) | bitmask, reg); | ||
| 413 | } | ||
| 414 | |||
| 415 | static inline void pch_udc_bit_clr(struct pch_udc_dev *dev, | ||
| 416 | unsigned long reg, | ||
| 417 | unsigned long bitmask) | ||
| 418 | { | ||
| 419 | pch_udc_writel(dev, pch_udc_readl(dev, reg) & ~(bitmask), reg); | ||
| 420 | } | ||
| 421 | |||
| 422 | static inline u32 pch_udc_ep_readl(struct pch_udc_ep *ep, unsigned long reg) | ||
| 423 | { | ||
| 424 | return ioread32(ep->dev->base_addr + ep->offset_addr + reg); | ||
| 425 | } | ||
| 426 | |||
| 427 | static inline void pch_udc_ep_writel(struct pch_udc_ep *ep, | ||
| 428 | unsigned long val, unsigned long reg) | ||
| 429 | { | ||
| 430 | iowrite32(val, ep->dev->base_addr + ep->offset_addr + reg); | ||
| 431 | } | ||
| 432 | |||
| 433 | static inline void pch_udc_ep_bit_set(struct pch_udc_ep *ep, | ||
| 434 | unsigned long reg, | ||
| 435 | unsigned long bitmask) | ||
| 436 | { | ||
| 437 | pch_udc_ep_writel(ep, pch_udc_ep_readl(ep, reg) | bitmask, reg); | ||
| 438 | } | ||
| 439 | |||
| 440 | static inline void pch_udc_ep_bit_clr(struct pch_udc_ep *ep, | ||
| 441 | unsigned long reg, | ||
| 442 | unsigned long bitmask) | ||
| 443 | { | ||
| 444 | pch_udc_ep_writel(ep, pch_udc_ep_readl(ep, reg) & ~(bitmask), reg); | ||
| 445 | } | ||
| 446 | |||
| 447 | /** | ||
| 448 | * pch_udc_csr_busy() - Wait till idle. | ||
| 449 | * @dev: Reference to pch_udc_dev structure | ||
| 450 | */ | ||
| 451 | static void pch_udc_csr_busy(struct pch_udc_dev *dev) | ||
| 452 | { | ||
| 453 | unsigned int count = 200; | ||
| 454 | |||
| 455 | /* Wait till idle */ | ||
| 456 | while ((pch_udc_readl(dev, UDC_CSR_BUSY_ADDR) & UDC_CSR_BUSY) | ||
| 457 | && --count) | ||
| 458 | cpu_relax(); | ||
| 459 | if (!count) | ||
| 460 | dev_err(&dev->pdev->dev, "%s: wait error\n", __func__); | ||
| 461 | } | ||
| 462 | |||
| 463 | /** | ||
| 464 | * pch_udc_write_csr() - Write the command and status registers. | ||
| 465 | * @dev: Reference to pch_udc_dev structure | ||
| 466 | * @val: value to be written to CSR register | ||
| 467 | * @addr: address of CSR register | ||
| 468 | */ | ||
| 469 | static void pch_udc_write_csr(struct pch_udc_dev *dev, unsigned long val, | ||
| 470 | unsigned int ep) | ||
| 471 | { | ||
| 472 | unsigned long reg = PCH_UDC_CSR(ep); | ||
| 473 | |||
| 474 | pch_udc_csr_busy(dev); /* Wait till idle */ | ||
| 475 | pch_udc_writel(dev, val, reg); | ||
| 476 | pch_udc_csr_busy(dev); /* Wait till idle */ | ||
| 477 | } | ||
| 478 | |||
| 479 | /** | ||
| 480 | * pch_udc_read_csr() - Read the command and status registers. | ||
| 481 | * @dev: Reference to pch_udc_dev structure | ||
| 482 | * @addr: address of CSR register | ||
| 483 | * | ||
| 484 | * Return codes: content of CSR register | ||
| 485 | */ | ||
| 486 | static u32 pch_udc_read_csr(struct pch_udc_dev *dev, unsigned int ep) | ||
| 487 | { | ||
| 488 | unsigned long reg = PCH_UDC_CSR(ep); | ||
| 489 | |||
| 490 | pch_udc_csr_busy(dev); /* Wait till idle */ | ||
| 491 | pch_udc_readl(dev, reg); /* Dummy read */ | ||
| 492 | pch_udc_csr_busy(dev); /* Wait till idle */ | ||
| 493 | return pch_udc_readl(dev, reg); | ||
| 494 | } | ||
| 495 | |||
| 496 | /** | ||
| 497 | * pch_udc_rmt_wakeup() - Initiate for remote wakeup | ||
| 498 | * @dev: Reference to pch_udc_dev structure | ||
| 499 | */ | ||
| 500 | static inline void pch_udc_rmt_wakeup(struct pch_udc_dev *dev) | ||
| 501 | { | ||
| 502 | pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); | ||
| 503 | mdelay(1); | ||
| 504 | pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); | ||
| 505 | } | ||
| 506 | |||
| 507 | /** | ||
| 508 | * pch_udc_get_frame() - Get the current frame from device status register | ||
| 509 | * @dev: Reference to pch_udc_dev structure | ||
| 510 | * Retern current frame | ||
| 511 | */ | ||
| 512 | static inline int pch_udc_get_frame(struct pch_udc_dev *dev) | ||
| 513 | { | ||
| 514 | u32 frame = pch_udc_readl(dev, UDC_DEVSTS_ADDR); | ||
| 515 | return (frame & UDC_DEVSTS_TS_MASK) >> UDC_DEVSTS_TS_SHIFT; | ||
| 516 | } | ||
| 517 | |||
| 518 | /** | ||
| 519 | * pch_udc_clear_selfpowered() - Clear the self power control | ||
| 520 | * @dev: Reference to pch_udc_regs structure | ||
| 521 | */ | ||
| 522 | static inline void pch_udc_clear_selfpowered(struct pch_udc_dev *dev) | ||
| 523 | { | ||
| 524 | pch_udc_bit_clr(dev, UDC_DEVCFG_ADDR, UDC_DEVCFG_SP); | ||
| 525 | } | ||
| 526 | |||
| 527 | /** | ||
| 528 | * pch_udc_set_selfpowered() - Set the self power control | ||
| 529 | * @dev: Reference to pch_udc_regs structure | ||
| 530 | */ | ||
| 531 | static inline void pch_udc_set_selfpowered(struct pch_udc_dev *dev) | ||
| 532 | { | ||
| 533 | pch_udc_bit_set(dev, UDC_DEVCFG_ADDR, UDC_DEVCFG_SP); | ||
| 534 | } | ||
| 535 | |||
| 536 | /** | ||
| 537 | * pch_udc_set_disconnect() - Set the disconnect status. | ||
| 538 | * @dev: Reference to pch_udc_regs structure | ||
| 539 | */ | ||
| 540 | static inline void pch_udc_set_disconnect(struct pch_udc_dev *dev) | ||
| 541 | { | ||
| 542 | pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_SD); | ||
| 543 | } | ||
| 544 | |||
| 545 | /** | ||
| 546 | * pch_udc_clear_disconnect() - Clear the disconnect status. | ||
| 547 | * @dev: Reference to pch_udc_regs structure | ||
| 548 | */ | ||
| 549 | static void pch_udc_clear_disconnect(struct pch_udc_dev *dev) | ||
| 550 | { | ||
| 551 | /* Clear the disconnect */ | ||
| 552 | pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); | ||
| 553 | pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_SD); | ||
| 554 | mdelay(1); | ||
| 555 | /* Resume USB signalling */ | ||
| 556 | pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); | ||
| 557 | } | ||
| 558 | |||
| 559 | /** | ||
| 560 | * pch_udc_vbus_session() - set or clearr the disconnect status. | ||
| 561 | * @dev: Reference to pch_udc_regs structure | ||
| 562 | * @is_active: Parameter specifying the action | ||
| 563 | * 0: indicating VBUS power is ending | ||
| 564 | * !0: indicating VBUS power is starting | ||
| 565 | */ | ||
| 566 | static inline void pch_udc_vbus_session(struct pch_udc_dev *dev, | ||
| 567 | int is_active) | ||
| 568 | { | ||
| 569 | if (is_active) | ||
| 570 | pch_udc_clear_disconnect(dev); | ||
| 571 | else | ||
| 572 | pch_udc_set_disconnect(dev); | ||
| 573 | } | ||
| 574 | |||
| 575 | /** | ||
| 576 | * pch_udc_ep_set_stall() - Set the stall of endpoint | ||
| 577 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 578 | */ | ||
| 579 | static void pch_udc_ep_set_stall(struct pch_udc_ep *ep) | ||
| 580 | { | ||
| 581 | if (ep->in) { | ||
| 582 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_F); | ||
| 583 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_S); | ||
| 584 | } else { | ||
| 585 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_S); | ||
| 586 | } | ||
| 587 | } | ||
| 588 | |||
| 589 | /** | ||
| 590 | * pch_udc_ep_clear_stall() - Clear the stall of endpoint | ||
| 591 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 592 | */ | ||
| 593 | static inline void pch_udc_ep_clear_stall(struct pch_udc_ep *ep) | ||
| 594 | { | ||
| 595 | /* Clear the stall */ | ||
| 596 | pch_udc_ep_bit_clr(ep, UDC_EPCTL_ADDR, UDC_EPCTL_S); | ||
| 597 | /* Clear NAK by writing CNAK */ | ||
| 598 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_CNAK); | ||
| 599 | } | ||
| 600 | |||
| 601 | /** | ||
| 602 | * pch_udc_ep_set_trfr_type() - Set the transfer type of endpoint | ||
| 603 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 604 | * @type: Type of endpoint | ||
| 605 | */ | ||
| 606 | static inline void pch_udc_ep_set_trfr_type(struct pch_udc_ep *ep, | ||
| 607 | u8 type) | ||
| 608 | { | ||
| 609 | pch_udc_ep_writel(ep, ((type << UDC_EPCTL_ET_SHIFT) & | ||
| 610 | UDC_EPCTL_ET_MASK), UDC_EPCTL_ADDR); | ||
| 611 | } | ||
| 612 | |||
| 613 | /** | ||
| 614 | * pch_udc_ep_set_bufsz() - Set the maximum packet size for the endpoint | ||
| 615 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 616 | * @buf_size: The buffer size | ||
| 617 | */ | ||
| 618 | static void pch_udc_ep_set_bufsz(struct pch_udc_ep *ep, | ||
| 619 | u32 buf_size, u32 ep_in) | ||
| 620 | { | ||
| 621 | u32 data; | ||
| 622 | if (ep_in) { | ||
| 623 | data = pch_udc_ep_readl(ep, UDC_BUFIN_FRAMENUM_ADDR); | ||
| 624 | data = (data & 0xffff0000) | (buf_size & 0xffff); | ||
| 625 | pch_udc_ep_writel(ep, data, UDC_BUFIN_FRAMENUM_ADDR); | ||
| 626 | } else { | ||
| 627 | data = pch_udc_ep_readl(ep, UDC_BUFOUT_MAXPKT_ADDR); | ||
| 628 | data = (buf_size << 16) | (data & 0xffff); | ||
| 629 | pch_udc_ep_writel(ep, data, UDC_BUFOUT_MAXPKT_ADDR); | ||
| 630 | } | ||
| 631 | } | ||
| 632 | |||
| 633 | /** | ||
| 634 | * pch_udc_ep_set_maxpkt() - Set the Max packet size for the endpoint | ||
| 635 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 636 | * @pkt_size: The packet size | ||
| 637 | */ | ||
| 638 | static void pch_udc_ep_set_maxpkt(struct pch_udc_ep *ep, u32 pkt_size) | ||
| 639 | { | ||
| 640 | u32 data = pch_udc_ep_readl(ep, UDC_BUFOUT_MAXPKT_ADDR); | ||
| 641 | data = (data & 0xffff0000) | (pkt_size & 0xffff); | ||
| 642 | pch_udc_ep_writel(ep, data, UDC_BUFOUT_MAXPKT_ADDR); | ||
| 643 | } | ||
| 644 | |||
| 645 | /** | ||
| 646 | * pch_udc_ep_set_subptr() - Set the Setup buffer pointer for the endpoint | ||
| 647 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 648 | * @addr: Address of the register | ||
| 649 | */ | ||
| 650 | static inline void pch_udc_ep_set_subptr(struct pch_udc_ep *ep, u32 addr) | ||
| 651 | { | ||
| 652 | pch_udc_ep_writel(ep, addr, UDC_SUBPTR_ADDR); | ||
| 653 | } | ||
| 654 | |||
| 655 | /** | ||
| 656 | * pch_udc_ep_set_ddptr() - Set the Data descriptor pointer for the endpoint | ||
| 657 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 658 | * @addr: Address of the register | ||
| 659 | */ | ||
| 660 | static inline void pch_udc_ep_set_ddptr(struct pch_udc_ep *ep, u32 addr) | ||
| 661 | { | ||
| 662 | pch_udc_ep_writel(ep, addr, UDC_DESPTR_ADDR); | ||
| 663 | } | ||
| 664 | |||
| 665 | /** | ||
| 666 | * pch_udc_ep_set_pd() - Set the poll demand bit for the endpoint | ||
| 667 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 668 | */ | ||
| 669 | static inline void pch_udc_ep_set_pd(struct pch_udc_ep *ep) | ||
| 670 | { | ||
| 671 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_P); | ||
| 672 | } | ||
| 673 | |||
| 674 | /** | ||
| 675 | * pch_udc_ep_set_rrdy() - Set the receive ready bit for the endpoint | ||
| 676 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 677 | */ | ||
| 678 | static inline void pch_udc_ep_set_rrdy(struct pch_udc_ep *ep) | ||
| 679 | { | ||
| 680 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_RRDY); | ||
| 681 | } | ||
| 682 | |||
| 683 | /** | ||
| 684 | * pch_udc_ep_clear_rrdy() - Clear the receive ready bit for the endpoint | ||
| 685 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 686 | */ | ||
| 687 | static inline void pch_udc_ep_clear_rrdy(struct pch_udc_ep *ep) | ||
| 688 | { | ||
| 689 | pch_udc_ep_bit_clr(ep, UDC_EPCTL_ADDR, UDC_EPCTL_RRDY); | ||
| 690 | } | ||
| 691 | |||
| 692 | /** | ||
| 693 | * pch_udc_set_dma() - Set the 'TDE' or RDE bit of device control | ||
| 694 | * register depending on the direction specified | ||
| 695 | * @dev: Reference to structure of type pch_udc_regs | ||
| 696 | * @dir: whether Tx or Rx | ||
| 697 | * DMA_DIR_RX: Receive | ||
| 698 | * DMA_DIR_TX: Transmit | ||
| 699 | */ | ||
| 700 | static inline void pch_udc_set_dma(struct pch_udc_dev *dev, int dir) | ||
| 701 | { | ||
| 702 | if (dir == DMA_DIR_RX) | ||
| 703 | pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RDE); | ||
| 704 | else if (dir == DMA_DIR_TX) | ||
| 705 | pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_TDE); | ||
| 706 | } | ||
| 707 | |||
| 708 | /** | ||
| 709 | * pch_udc_clear_dma() - Clear the 'TDE' or RDE bit of device control | ||
| 710 | * register depending on the direction specified | ||
| 711 | * @dev: Reference to structure of type pch_udc_regs | ||
| 712 | * @dir: Whether Tx or Rx | ||
| 713 | * DMA_DIR_RX: Receive | ||
| 714 | * DMA_DIR_TX: Transmit | ||
| 715 | */ | ||
| 716 | static inline void pch_udc_clear_dma(struct pch_udc_dev *dev, int dir) | ||
| 717 | { | ||
| 718 | if (dir == DMA_DIR_RX) | ||
| 719 | pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RDE); | ||
| 720 | else if (dir == DMA_DIR_TX) | ||
| 721 | pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_TDE); | ||
| 722 | } | ||
| 723 | |||
| 724 | /** | ||
| 725 | * pch_udc_set_csr_done() - Set the device control register | ||
| 726 | * CSR done field (bit 13) | ||
| 727 | * @dev: reference to structure of type pch_udc_regs | ||
| 728 | */ | ||
| 729 | static inline void pch_udc_set_csr_done(struct pch_udc_dev *dev) | ||
| 730 | { | ||
| 731 | pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_CSR_DONE); | ||
| 732 | } | ||
| 733 | |||
| 734 | /** | ||
| 735 | * pch_udc_disable_interrupts() - Disables the specified interrupts | ||
| 736 | * @dev: Reference to structure of type pch_udc_regs | ||
| 737 | * @mask: Mask to disable interrupts | ||
| 738 | */ | ||
| 739 | static inline void pch_udc_disable_interrupts(struct pch_udc_dev *dev, | ||
| 740 | u32 mask) | ||
| 741 | { | ||
| 742 | pch_udc_bit_set(dev, UDC_DEVIRQMSK_ADDR, mask); | ||
| 743 | } | ||
| 744 | |||
| 745 | /** | ||
| 746 | * pch_udc_enable_interrupts() - Enable the specified interrupts | ||
| 747 | * @dev: Reference to structure of type pch_udc_regs | ||
| 748 | * @mask: Mask to enable interrupts | ||
| 749 | */ | ||
| 750 | static inline void pch_udc_enable_interrupts(struct pch_udc_dev *dev, | ||
| 751 | u32 mask) | ||
| 752 | { | ||
| 753 | pch_udc_bit_clr(dev, UDC_DEVIRQMSK_ADDR, mask); | ||
| 754 | } | ||
| 755 | |||
| 756 | /** | ||
| 757 | * pch_udc_disable_ep_interrupts() - Disable endpoint interrupts | ||
| 758 | * @dev: Reference to structure of type pch_udc_regs | ||
| 759 | * @mask: Mask to disable interrupts | ||
| 760 | */ | ||
| 761 | static inline void pch_udc_disable_ep_interrupts(struct pch_udc_dev *dev, | ||
| 762 | u32 mask) | ||
| 763 | { | ||
| 764 | pch_udc_bit_set(dev, UDC_EPIRQMSK_ADDR, mask); | ||
| 765 | } | ||
| 766 | |||
| 767 | /** | ||
| 768 | * pch_udc_enable_ep_interrupts() - Enable endpoint interrupts | ||
| 769 | * @dev: Reference to structure of type pch_udc_regs | ||
| 770 | * @mask: Mask to enable interrupts | ||
| 771 | */ | ||
| 772 | static inline void pch_udc_enable_ep_interrupts(struct pch_udc_dev *dev, | ||
| 773 | u32 mask) | ||
| 774 | { | ||
| 775 | pch_udc_bit_clr(dev, UDC_EPIRQMSK_ADDR, mask); | ||
| 776 | } | ||
| 777 | |||
| 778 | /** | ||
| 779 | * pch_udc_read_device_interrupts() - Read the device interrupts | ||
| 780 | * @dev: Reference to structure of type pch_udc_regs | ||
| 781 | * Retern The device interrupts | ||
| 782 | */ | ||
| 783 | static inline u32 pch_udc_read_device_interrupts(struct pch_udc_dev *dev) | ||
| 784 | { | ||
| 785 | return pch_udc_readl(dev, UDC_DEVIRQSTS_ADDR); | ||
| 786 | } | ||
| 787 | |||
| 788 | /** | ||
| 789 | * pch_udc_write_device_interrupts() - Write device interrupts | ||
| 790 | * @dev: Reference to structure of type pch_udc_regs | ||
| 791 | * @val: The value to be written to interrupt register | ||
| 792 | */ | ||
| 793 | static inline void pch_udc_write_device_interrupts(struct pch_udc_dev *dev, | ||
| 794 | u32 val) | ||
| 795 | { | ||
| 796 | pch_udc_writel(dev, val, UDC_DEVIRQSTS_ADDR); | ||
| 797 | } | ||
| 798 | |||
| 799 | /** | ||
| 800 | * pch_udc_read_ep_interrupts() - Read the endpoint interrupts | ||
| 801 | * @dev: Reference to structure of type pch_udc_regs | ||
| 802 | * Retern The endpoint interrupt | ||
| 803 | */ | ||
| 804 | static inline u32 pch_udc_read_ep_interrupts(struct pch_udc_dev *dev) | ||
| 805 | { | ||
| 806 | return pch_udc_readl(dev, UDC_EPIRQSTS_ADDR); | ||
| 807 | } | ||
| 808 | |||
| 809 | /** | ||
| 810 | * pch_udc_write_ep_interrupts() - Clear endpoint interupts | ||
| 811 | * @dev: Reference to structure of type pch_udc_regs | ||
| 812 | * @val: The value to be written to interrupt register | ||
| 813 | */ | ||
| 814 | static inline void pch_udc_write_ep_interrupts(struct pch_udc_dev *dev, | ||
| 815 | u32 val) | ||
| 816 | { | ||
| 817 | pch_udc_writel(dev, val, UDC_EPIRQSTS_ADDR); | ||
| 818 | } | ||
| 819 | |||
| 820 | /** | ||
| 821 | * pch_udc_read_device_status() - Read the device status | ||
| 822 | * @dev: Reference to structure of type pch_udc_regs | ||
| 823 | * Retern The device status | ||
| 824 | */ | ||
| 825 | static inline u32 pch_udc_read_device_status(struct pch_udc_dev *dev) | ||
| 826 | { | ||
| 827 | return pch_udc_readl(dev, UDC_DEVSTS_ADDR); | ||
| 828 | } | ||
| 829 | |||
| 830 | /** | ||
| 831 | * pch_udc_read_ep_control() - Read the endpoint control | ||
| 832 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 833 | * Retern The endpoint control register value | ||
| 834 | */ | ||
| 835 | static inline u32 pch_udc_read_ep_control(struct pch_udc_ep *ep) | ||
| 836 | { | ||
| 837 | return pch_udc_ep_readl(ep, UDC_EPCTL_ADDR); | ||
| 838 | } | ||
| 839 | |||
| 840 | /** | ||
| 841 | * pch_udc_clear_ep_control() - Clear the endpoint control register | ||
| 842 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 843 | * Retern The endpoint control register value | ||
| 844 | */ | ||
| 845 | static inline void pch_udc_clear_ep_control(struct pch_udc_ep *ep) | ||
| 846 | { | ||
| 847 | return pch_udc_ep_writel(ep, 0, UDC_EPCTL_ADDR); | ||
| 848 | } | ||
| 849 | |||
| 850 | /** | ||
| 851 | * pch_udc_read_ep_status() - Read the endpoint status | ||
| 852 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 853 | * Retern The endpoint status | ||
| 854 | */ | ||
| 855 | static inline u32 pch_udc_read_ep_status(struct pch_udc_ep *ep) | ||
| 856 | { | ||
| 857 | return pch_udc_ep_readl(ep, UDC_EPSTS_ADDR); | ||
| 858 | } | ||
| 859 | |||
| 860 | /** | ||
| 861 | * pch_udc_clear_ep_status() - Clear the endpoint status | ||
| 862 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 863 | * @stat: Endpoint status | ||
| 864 | */ | ||
| 865 | static inline void pch_udc_clear_ep_status(struct pch_udc_ep *ep, | ||
| 866 | u32 stat) | ||
| 867 | { | ||
| 868 | return pch_udc_ep_writel(ep, stat, UDC_EPSTS_ADDR); | ||
| 869 | } | ||
| 870 | |||
| 871 | /** | ||
| 872 | * pch_udc_ep_set_nak() - Set the bit 7 (SNAK field) | ||
| 873 | * of the endpoint control register | ||
| 874 | * @ep: Reference to structure of type pch_udc_ep_regs | ||
| 875 | */ | ||
| 876 | static inline void pch_udc_ep_set_nak(struct pch_udc_ep *ep) | ||
| 877 | { | ||
| 878 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_SNAK); | ||
| 879 | } | ||
| 880 | |||
| 881 | /** | ||
| 882 | * pch_udc_ep_clear_nak() - Set the bit 8 (CNAK field) | ||
| 883 | * of the endpoint control register | ||
| 884 | * @ep: reference to structure of type pch_udc_ep_regs | ||
| 885 | */ | ||
| 886 | static void pch_udc_ep_clear_nak(struct pch_udc_ep *ep) | ||
| 887 | { | ||
| 888 | unsigned int loopcnt = 0; | ||
| 889 | struct pch_udc_dev *dev = ep->dev; | ||
| 890 | |||
| 891 | if (!(pch_udc_ep_readl(ep, UDC_EPCTL_ADDR) & UDC_EPCTL_NAK)) | ||
| 892 | return; | ||
| 893 | if (!ep->in) { | ||
| 894 | loopcnt = 10000; | ||
| 895 | while (!(pch_udc_read_ep_status(ep) & UDC_EPSTS_MRXFIFO_EMP) && | ||
| 896 | --loopcnt) | ||
| 897 | udelay(5); | ||
| 898 | if (!loopcnt) | ||
| 899 | dev_err(&dev->pdev->dev, "%s: RxFIFO not Empty\n", | ||
| 900 | __func__); | ||
| 901 | } | ||
| 902 | loopcnt = 10000; | ||
| 903 | while ((pch_udc_read_ep_control(ep) & UDC_EPCTL_NAK) && --loopcnt) { | ||
| 904 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_CNAK); | ||
| 905 | udelay(5); | ||
| 906 | } | ||
| 907 | if (!loopcnt) | ||
| 908 | dev_err(&dev->pdev->dev, "%s: Clear NAK not set for ep%d%s\n", | ||
| 909 | __func__, ep->num, (ep->in ? "in" : "out")); | ||
| 910 | } | ||
| 911 | |||
| 912 | /** | ||
| 913 | * pch_udc_ep_fifo_flush() - Flush the endpoint fifo | ||
| 914 | * @ep: reference to structure of type pch_udc_ep_regs | ||
| 915 | * @dir: direction of endpoint | ||
| 916 | * 0: endpoint is OUT | ||
| 917 | * !0: endpoint is IN | ||
| 918 | */ | ||
| 919 | static void pch_udc_ep_fifo_flush(struct pch_udc_ep *ep, int dir) | ||
| 920 | { | ||
| 921 | unsigned int loopcnt = 0; | ||
| 922 | struct pch_udc_dev *dev = ep->dev; | ||
| 923 | |||
| 924 | if (dir) { /* IN ep */ | ||
| 925 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_F); | ||
| 926 | return; | ||
| 927 | } | ||
| 928 | |||
| 929 | if (pch_udc_read_ep_status(ep) & UDC_EPSTS_MRXFIFO_EMP) | ||
| 930 | return; | ||
| 931 | pch_udc_ep_bit_set(ep, UDC_EPCTL_ADDR, UDC_EPCTL_MRXFLUSH); | ||
| 932 | /* Wait for RxFIFO Empty */ | ||
| 933 | loopcnt = 10000; | ||
| 934 | while (!(pch_udc_read_ep_status(ep) & UDC_EPSTS_MRXFIFO_EMP) && | ||
| 935 | --loopcnt) | ||
| 936 | udelay(5); | ||
| 937 | if (!loopcnt) | ||
| 938 | dev_err(&dev->pdev->dev, "RxFIFO not Empty\n"); | ||
| 939 | pch_udc_ep_bit_clr(ep, UDC_EPCTL_ADDR, UDC_EPCTL_MRXFLUSH); | ||
| 940 | } | ||
| 941 | |||
| 942 | /** | ||
| 943 | * pch_udc_ep_enable() - This api enables endpoint | ||
| 944 | * @regs: Reference to structure pch_udc_ep_regs | ||
| 945 | * @desc: endpoint descriptor | ||
| 946 | */ | ||
| 947 | static void pch_udc_ep_enable(struct pch_udc_ep *ep, | ||
| 948 | struct pch_udc_cfg_data *cfg, | ||
| 949 | const struct usb_endpoint_descriptor *desc) | ||
| 950 | { | ||
| 951 | u32 val = 0; | ||
| 952 | u32 buff_size = 0; | ||
| 953 | |||
| 954 | pch_udc_ep_set_trfr_type(ep, desc->bmAttributes); | ||
| 955 | if (ep->in) | ||
| 956 | buff_size = UDC_EPIN_BUFF_SIZE; | ||
| 957 | else | ||
| 958 | buff_size = UDC_EPOUT_BUFF_SIZE; | ||
| 959 | pch_udc_ep_set_bufsz(ep, buff_size, ep->in); | ||
| 960 | pch_udc_ep_set_maxpkt(ep, le16_to_cpu(desc->wMaxPacketSize)); | ||
| 961 | pch_udc_ep_set_nak(ep); | ||
| 962 | pch_udc_ep_fifo_flush(ep, ep->in); | ||
| 963 | /* Configure the endpoint */ | ||
| 964 | val = ep->num << UDC_CSR_NE_NUM_SHIFT | ep->in << UDC_CSR_NE_DIR_SHIFT | | ||
| 965 | ((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) << | ||
| 966 | UDC_CSR_NE_TYPE_SHIFT) | | ||
| 967 | (cfg->cur_cfg << UDC_CSR_NE_CFG_SHIFT) | | ||
| 968 | (cfg->cur_intf << UDC_CSR_NE_INTF_SHIFT) | | ||
| 969 | (cfg->cur_alt << UDC_CSR_NE_ALT_SHIFT) | | ||
| 970 | le16_to_cpu(desc->wMaxPacketSize) << UDC_CSR_NE_MAX_PKT_SHIFT; | ||
| 971 | |||
| 972 | if (ep->in) | ||
| 973 | pch_udc_write_csr(ep->dev, val, UDC_EPIN_IDX(ep->num)); | ||
| 974 | else | ||
| 975 | pch_udc_write_csr(ep->dev, val, UDC_EPOUT_IDX(ep->num)); | ||
| 976 | } | ||
| 977 | |||
| 978 | /** | ||
| 979 | * pch_udc_ep_disable() - This api disables endpoint | ||
| 980 | * @regs: Reference to structure pch_udc_ep_regs | ||
| 981 | */ | ||
| 982 | static void pch_udc_ep_disable(struct pch_udc_ep *ep) | ||
| 983 | { | ||
| 984 | if (ep->in) { | ||
| 985 | /* flush the fifo */ | ||
| 986 | pch_udc_ep_writel(ep, UDC_EPCTL_F, UDC_EPCTL_ADDR); | ||
| 987 | /* set NAK */ | ||
| 988 | pch_udc_ep_writel(ep, UDC_EPCTL_SNAK, UDC_EPCTL_ADDR); | ||
| 989 | pch_udc_ep_bit_set(ep, UDC_EPSTS_ADDR, UDC_EPSTS_IN); | ||
| 990 | } else { | ||
| 991 | /* set NAK */ | ||
| 992 | pch_udc_ep_writel(ep, UDC_EPCTL_SNAK, UDC_EPCTL_ADDR); | ||
| 993 | } | ||
| 994 | /* reset desc pointer */ | ||
| 995 | pch_udc_ep_writel(ep, 0, UDC_DESPTR_ADDR); | ||
| 996 | } | ||
| 997 | |||
| 998 | /** | ||
| 999 | * pch_udc_wait_ep_stall() - Wait EP stall. | ||
| 1000 | * @dev: Reference to pch_udc_dev structure | ||
| 1001 | */ | ||
| 1002 | static void pch_udc_wait_ep_stall(struct pch_udc_ep *ep) | ||
| 1003 | { | ||
| 1004 | unsigned int count = 10000; | ||
| 1005 | |||
| 1006 | /* Wait till idle */ | ||
| 1007 | while ((pch_udc_read_ep_control(ep) & UDC_EPCTL_S) && --count) | ||
| 1008 | udelay(5); | ||
| 1009 | if (!count) | ||
| 1010 | dev_err(&ep->dev->pdev->dev, "%s: wait error\n", __func__); | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | /** | ||
| 1014 | * pch_udc_init() - This API initializes usb device controller | ||
| 1015 | * @dev: Rreference to pch_udc_regs structure | ||
| 1016 | */ | ||
| 1017 | static void pch_udc_init(struct pch_udc_dev *dev) | ||
| 1018 | { | ||
| 1019 | if (NULL == dev) { | ||
| 1020 | pr_err("%s: Invalid address\n", __func__); | ||
| 1021 | return; | ||
| 1022 | } | ||
| 1023 | /* Soft Reset and Reset PHY */ | ||
| 1024 | pch_udc_writel(dev, UDC_SRST, UDC_SRST_ADDR); | ||
| 1025 | pch_udc_writel(dev, UDC_SRST | UDC_PSRST, UDC_SRST_ADDR); | ||
| 1026 | mdelay(1); | ||
| 1027 | pch_udc_writel(dev, UDC_SRST, UDC_SRST_ADDR); | ||
| 1028 | pch_udc_writel(dev, 0x00, UDC_SRST_ADDR); | ||
| 1029 | mdelay(1); | ||
| 1030 | /* mask and clear all device interrupts */ | ||
| 1031 | pch_udc_bit_set(dev, UDC_DEVIRQMSK_ADDR, UDC_DEVINT_MSK); | ||
| 1032 | pch_udc_bit_set(dev, UDC_DEVIRQSTS_ADDR, UDC_DEVINT_MSK); | ||
| 1033 | |||
| 1034 | /* mask and clear all ep interrupts */ | ||
| 1035 | pch_udc_bit_set(dev, UDC_EPIRQMSK_ADDR, UDC_EPINT_MSK_DISABLE_ALL); | ||
| 1036 | pch_udc_bit_set(dev, UDC_EPIRQSTS_ADDR, UDC_EPINT_MSK_DISABLE_ALL); | ||
| 1037 | |||
| 1038 | /* enable dynamic CSR programmingi, self powered and device speed */ | ||
| 1039 | if (speed_fs) | ||
| 1040 | pch_udc_bit_set(dev, UDC_DEVCFG_ADDR, UDC_DEVCFG_CSR_PRG | | ||
| 1041 | UDC_DEVCFG_SP | UDC_DEVCFG_SPD_FS); | ||
| 1042 | else /* defaul high speed */ | ||
| 1043 | pch_udc_bit_set(dev, UDC_DEVCFG_ADDR, UDC_DEVCFG_CSR_PRG | | ||
| 1044 | UDC_DEVCFG_SP | UDC_DEVCFG_SPD_HS); | ||
| 1045 | pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, | ||
| 1046 | (PCH_UDC_THLEN << UDC_DEVCTL_THLEN_SHIFT) | | ||
| 1047 | (PCH_UDC_BRLEN << UDC_DEVCTL_BRLEN_SHIFT) | | ||
| 1048 | UDC_DEVCTL_MODE | UDC_DEVCTL_BREN | | ||
| 1049 | UDC_DEVCTL_THE); | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | /** | ||
| 1053 | * pch_udc_exit() - This API exit usb device controller | ||
| 1054 | * @dev: Reference to pch_udc_regs structure | ||
| 1055 | */ | ||
| 1056 | static void pch_udc_exit(struct pch_udc_dev *dev) | ||
| 1057 | { | ||
| 1058 | /* mask all device interrupts */ | ||
| 1059 | pch_udc_bit_set(dev, UDC_DEVIRQMSK_ADDR, UDC_DEVINT_MSK); | ||
| 1060 | /* mask all ep interrupts */ | ||
| 1061 | pch_udc_bit_set(dev, UDC_EPIRQMSK_ADDR, UDC_EPINT_MSK_DISABLE_ALL); | ||
| 1062 | /* put device in disconnected state */ | ||
| 1063 | pch_udc_set_disconnect(dev); | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | /** | ||
| 1067 | * pch_udc_pcd_get_frame() - This API is invoked to get the current frame number | ||
| 1068 | * @gadget: Reference to the gadget driver | ||
| 1069 | * | ||
| 1070 | * Return codes: | ||
| 1071 | * 0: Success | ||
| 1072 | * -EINVAL: If the gadget passed is NULL | ||
| 1073 | */ | ||
| 1074 | static int pch_udc_pcd_get_frame(struct usb_gadget *gadget) | ||
| 1075 | { | ||
| 1076 | struct pch_udc_dev *dev; | ||
| 1077 | |||
| 1078 | if (!gadget) | ||
| 1079 | return -EINVAL; | ||
| 1080 | dev = container_of(gadget, struct pch_udc_dev, gadget); | ||
| 1081 | return pch_udc_get_frame(dev); | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | /** | ||
| 1085 | * pch_udc_pcd_wakeup() - This API is invoked to initiate a remote wakeup | ||
| 1086 | * @gadget: Reference to the gadget driver | ||
| 1087 | * | ||
| 1088 | * Return codes: | ||
| 1089 | * 0: Success | ||
| 1090 | * -EINVAL: If the gadget passed is NULL | ||
| 1091 | */ | ||
| 1092 | static int pch_udc_pcd_wakeup(struct usb_gadget *gadget) | ||
| 1093 | { | ||
| 1094 | struct pch_udc_dev *dev; | ||
| 1095 | unsigned long flags; | ||
| 1096 | |||
| 1097 | if (!gadget) | ||
| 1098 | return -EINVAL; | ||
| 1099 | dev = container_of(gadget, struct pch_udc_dev, gadget); | ||
| 1100 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1101 | pch_udc_rmt_wakeup(dev); | ||
| 1102 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1103 | return 0; | ||
| 1104 | } | ||
| 1105 | |||
| 1106 | /** | ||
| 1107 | * pch_udc_pcd_selfpowered() - This API is invoked to specify whether the device | ||
| 1108 | * is self powered or not | ||
| 1109 | * @gadget: Reference to the gadget driver | ||
| 1110 | * @value: Specifies self powered or not | ||
| 1111 | * | ||
| 1112 | * Return codes: | ||
| 1113 | * 0: Success | ||
| 1114 | * -EINVAL: If the gadget passed is NULL | ||
| 1115 | */ | ||
| 1116 | static int pch_udc_pcd_selfpowered(struct usb_gadget *gadget, int value) | ||
| 1117 | { | ||
| 1118 | struct pch_udc_dev *dev; | ||
| 1119 | |||
| 1120 | if (!gadget) | ||
| 1121 | return -EINVAL; | ||
| 1122 | dev = container_of(gadget, struct pch_udc_dev, gadget); | ||
| 1123 | if (value) | ||
| 1124 | pch_udc_set_selfpowered(dev); | ||
| 1125 | else | ||
| 1126 | pch_udc_clear_selfpowered(dev); | ||
| 1127 | return 0; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | /** | ||
| 1131 | * pch_udc_pcd_pullup() - This API is invoked to make the device | ||
| 1132 | * visible/invisible to the host | ||
| 1133 | * @gadget: Reference to the gadget driver | ||
| 1134 | * @is_on: Specifies whether the pull up is made active or inactive | ||
| 1135 | * | ||
| 1136 | * Return codes: | ||
| 1137 | * 0: Success | ||
| 1138 | * -EINVAL: If the gadget passed is NULL | ||
| 1139 | */ | ||
| 1140 | static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on) | ||
| 1141 | { | ||
| 1142 | struct pch_udc_dev *dev; | ||
| 1143 | |||
| 1144 | if (!gadget) | ||
| 1145 | return -EINVAL; | ||
| 1146 | dev = container_of(gadget, struct pch_udc_dev, gadget); | ||
| 1147 | pch_udc_vbus_session(dev, is_on); | ||
| 1148 | return 0; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | /** | ||
| 1152 | * pch_udc_pcd_vbus_session() - This API is used by a driver for an external | ||
| 1153 | * transceiver (or GPIO) that | ||
| 1154 | * detects a VBUS power session starting/ending | ||
| 1155 | * @gadget: Reference to the gadget driver | ||
| 1156 | * @is_active: specifies whether the session is starting or ending | ||
| 1157 | * | ||
| 1158 | * Return codes: | ||
| 1159 | * 0: Success | ||
| 1160 | * -EINVAL: If the gadget passed is NULL | ||
| 1161 | */ | ||
| 1162 | static int pch_udc_pcd_vbus_session(struct usb_gadget *gadget, int is_active) | ||
| 1163 | { | ||
| 1164 | struct pch_udc_dev *dev; | ||
| 1165 | |||
| 1166 | if (!gadget) | ||
| 1167 | return -EINVAL; | ||
| 1168 | dev = container_of(gadget, struct pch_udc_dev, gadget); | ||
| 1169 | pch_udc_vbus_session(dev, is_active); | ||
| 1170 | return 0; | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | /** | ||
| 1174 | * pch_udc_pcd_vbus_draw() - This API is used by gadget drivers during | ||
| 1175 | * SET_CONFIGURATION calls to | ||
| 1176 | * specify how much power the device can consume | ||
| 1177 | * @gadget: Reference to the gadget driver | ||
| 1178 | * @mA: specifies the current limit in 2mA unit | ||
| 1179 | * | ||
| 1180 | * Return codes: | ||
| 1181 | * -EINVAL: If the gadget passed is NULL | ||
| 1182 | * -EOPNOTSUPP: | ||
| 1183 | */ | ||
| 1184 | static int pch_udc_pcd_vbus_draw(struct usb_gadget *gadget, unsigned int mA) | ||
| 1185 | { | ||
| 1186 | return -EOPNOTSUPP; | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | static const struct usb_gadget_ops pch_udc_ops = { | ||
| 1190 | .get_frame = pch_udc_pcd_get_frame, | ||
| 1191 | .wakeup = pch_udc_pcd_wakeup, | ||
| 1192 | .set_selfpowered = pch_udc_pcd_selfpowered, | ||
| 1193 | .pullup = pch_udc_pcd_pullup, | ||
| 1194 | .vbus_session = pch_udc_pcd_vbus_session, | ||
| 1195 | .vbus_draw = pch_udc_pcd_vbus_draw, | ||
| 1196 | }; | ||
| 1197 | |||
| 1198 | /** | ||
| 1199 | * complete_req() - This API is invoked from the driver when processing | ||
| 1200 | * of a request is complete | ||
| 1201 | * @ep: Reference to the endpoint structure | ||
| 1202 | * @req: Reference to the request structure | ||
| 1203 | * @status: Indicates the success/failure of completion | ||
| 1204 | */ | ||
| 1205 | static void complete_req(struct pch_udc_ep *ep, struct pch_udc_request *req, | ||
| 1206 | int status) | ||
| 1207 | { | ||
| 1208 | struct pch_udc_dev *dev; | ||
| 1209 | unsigned halted = ep->halted; | ||
| 1210 | |||
| 1211 | list_del_init(&req->queue); | ||
| 1212 | |||
| 1213 | /* set new status if pending */ | ||
| 1214 | if (req->req.status == -EINPROGRESS) | ||
| 1215 | req->req.status = status; | ||
| 1216 | else | ||
| 1217 | status = req->req.status; | ||
| 1218 | |||
| 1219 | dev = ep->dev; | ||
| 1220 | if (req->dma_mapped) { | ||
| 1221 | if (ep->in) | ||
| 1222 | pci_unmap_single(dev->pdev, req->req.dma, | ||
| 1223 | req->req.length, PCI_DMA_TODEVICE); | ||
| 1224 | else | ||
| 1225 | pci_unmap_single(dev->pdev, req->req.dma, | ||
| 1226 | req->req.length, PCI_DMA_FROMDEVICE); | ||
| 1227 | req->dma_mapped = 0; | ||
| 1228 | req->req.dma = DMA_ADDR_INVALID; | ||
| 1229 | } | ||
| 1230 | ep->halted = 1; | ||
| 1231 | spin_unlock(&dev->lock); | ||
| 1232 | if (!ep->in) | ||
| 1233 | pch_udc_ep_clear_rrdy(ep); | ||
| 1234 | req->req.complete(&ep->ep, &req->req); | ||
| 1235 | spin_lock(&dev->lock); | ||
| 1236 | ep->halted = halted; | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | /** | ||
| 1240 | * empty_req_queue() - This API empties the request queue of an endpoint | ||
| 1241 | * @ep: Reference to the endpoint structure | ||
| 1242 | */ | ||
| 1243 | static void empty_req_queue(struct pch_udc_ep *ep) | ||
| 1244 | { | ||
| 1245 | struct pch_udc_request *req; | ||
| 1246 | |||
| 1247 | ep->halted = 1; | ||
| 1248 | while (!list_empty(&ep->queue)) { | ||
| 1249 | req = list_entry(ep->queue.next, struct pch_udc_request, queue); | ||
| 1250 | complete_req(ep, req, -ESHUTDOWN); /* Remove from list */ | ||
| 1251 | } | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | /** | ||
| 1255 | * pch_udc_free_dma_chain() - This function frees the DMA chain created | ||
| 1256 | * for the request | ||
| 1257 | * @dev Reference to the driver structure | ||
| 1258 | * @req Reference to the request to be freed | ||
| 1259 | * | ||
| 1260 | * Return codes: | ||
| 1261 | * 0: Success | ||
| 1262 | */ | ||
| 1263 | static void pch_udc_free_dma_chain(struct pch_udc_dev *dev, | ||
| 1264 | struct pch_udc_request *req) | ||
| 1265 | { | ||
| 1266 | struct pch_udc_data_dma_desc *td = req->td_data; | ||
| 1267 | unsigned i = req->chain_len; | ||
| 1268 | |||
| 1269 | for (; i > 1; --i) { | ||
| 1270 | dma_addr_t addr = (dma_addr_t)td->next; | ||
| 1271 | /* do not free first desc., will be done by free for request */ | ||
| 1272 | td = phys_to_virt(addr); | ||
| 1273 | pci_pool_free(dev->data_requests, td, addr); | ||
| 1274 | } | ||
| 1275 | } | ||
| 1276 | |||
| 1277 | /** | ||
| 1278 | * pch_udc_create_dma_chain() - This function creates or reinitializes | ||
| 1279 | * a DMA chain | ||
| 1280 | * @ep: Reference to the endpoint structure | ||
| 1281 | * @req: Reference to the request | ||
| 1282 | * @buf_len: The buffer length | ||
| 1283 | * @gfp_flags: Flags to be used while mapping the data buffer | ||
| 1284 | * | ||
| 1285 | * Return codes: | ||
| 1286 | * 0: success, | ||
| 1287 | * -ENOMEM: pci_pool_alloc invocation fails | ||
| 1288 | */ | ||
| 1289 | static int pch_udc_create_dma_chain(struct pch_udc_ep *ep, | ||
| 1290 | struct pch_udc_request *req, | ||
| 1291 | unsigned long buf_len, | ||
| 1292 | gfp_t gfp_flags) | ||
| 1293 | { | ||
| 1294 | struct pch_udc_data_dma_desc *td = req->td_data, *last; | ||
| 1295 | unsigned long bytes = req->req.length, i = 0; | ||
| 1296 | dma_addr_t dma_addr; | ||
| 1297 | unsigned len = 1; | ||
| 1298 | |||
| 1299 | if (req->chain_len > 1) | ||
| 1300 | pch_udc_free_dma_chain(ep->dev, req); | ||
| 1301 | |||
| 1302 | for (; ; bytes -= buf_len, ++len) { | ||
| 1303 | if (ep->in) | ||
| 1304 | td->status = PCH_UDC_BS_HST_BSY | min(buf_len, bytes); | ||
| 1305 | else | ||
| 1306 | td->status = PCH_UDC_BS_HST_BSY; | ||
| 1307 | |||
| 1308 | if (bytes <= buf_len) | ||
| 1309 | break; | ||
| 1310 | |||
| 1311 | last = td; | ||
| 1312 | td = pci_pool_alloc(ep->dev->data_requests, gfp_flags, | ||
| 1313 | &dma_addr); | ||
| 1314 | if (!td) | ||
| 1315 | goto nomem; | ||
| 1316 | |||
| 1317 | i += buf_len; | ||
| 1318 | td->dataptr = req->req.dma + i; | ||
| 1319 | last->next = dma_addr; | ||
| 1320 | } | ||
| 1321 | |||
| 1322 | req->td_data_last = td; | ||
| 1323 | td->status |= PCH_UDC_DMA_LAST; | ||
| 1324 | td->next = req->td_data_phys; | ||
| 1325 | req->chain_len = len; | ||
| 1326 | return 0; | ||
| 1327 | |||
| 1328 | nomem: | ||
| 1329 | if (len > 1) { | ||
| 1330 | req->chain_len = len; | ||
| 1331 | pch_udc_free_dma_chain(ep->dev, req); | ||
| 1332 | } | ||
| 1333 | req->chain_len = 1; | ||
| 1334 | return -ENOMEM; | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | /** | ||
| 1338 | * prepare_dma() - This function creates and initializes the DMA chain | ||
| 1339 | * for the request | ||
| 1340 | * @ep: Reference to the endpoint structure | ||
| 1341 | * @req: Reference to the request | ||
| 1342 | * @gfp: Flag to be used while mapping the data buffer | ||
| 1343 | * | ||
| 1344 | * Return codes: | ||
| 1345 | * 0: Success | ||
| 1346 | * Other 0: linux error number on failure | ||
| 1347 | */ | ||
| 1348 | static int prepare_dma(struct pch_udc_ep *ep, struct pch_udc_request *req, | ||
| 1349 | gfp_t gfp) | ||
| 1350 | { | ||
| 1351 | int retval; | ||
| 1352 | |||
| 1353 | req->td_data->dataptr = req->req.dma; | ||
| 1354 | req->td_data->status |= PCH_UDC_DMA_LAST; | ||
| 1355 | /* Allocate and create a DMA chain */ | ||
| 1356 | retval = pch_udc_create_dma_chain(ep, req, ep->ep.maxpacket, gfp); | ||
| 1357 | if (retval) { | ||
| 1358 | pr_err("%s: could not create DMA chain: %d\n", | ||
| 1359 | __func__, retval); | ||
| 1360 | return retval; | ||
| 1361 | } | ||
| 1362 | if (!ep->in) | ||
| 1363 | return 0; | ||
| 1364 | if (req->req.length <= ep->ep.maxpacket) | ||
| 1365 | req->td_data->status = PCH_UDC_DMA_LAST | PCH_UDC_BS_HST_BSY | | ||
| 1366 | req->req.length; | ||
| 1367 | /* if bytes < max packet then tx bytes must | ||
| 1368 | * be written in packet per buffer mode | ||
| 1369 | */ | ||
| 1370 | if ((req->req.length < ep->ep.maxpacket) || !ep->num) | ||
| 1371 | req->td_data->status = (req->td_data->status & | ||
| 1372 | ~PCH_UDC_RXTX_BYTES) | req->req.length; | ||
| 1373 | req->td_data->status = (req->td_data->status & | ||
| 1374 | ~PCH_UDC_BUFF_STS) | PCH_UDC_BS_HST_BSY; | ||
| 1375 | return 0; | ||
| 1376 | } | ||
| 1377 | |||
| 1378 | /** | ||
| 1379 | * process_zlp() - This function process zero length packets | ||
| 1380 | * from the gadget driver | ||
| 1381 | * @ep: Reference to the endpoint structure | ||
| 1382 | * @req: Reference to the request | ||
| 1383 | */ | ||
| 1384 | static void process_zlp(struct pch_udc_ep *ep, struct pch_udc_request *req) | ||
| 1385 | { | ||
| 1386 | struct pch_udc_dev *dev = ep->dev; | ||
| 1387 | |||
| 1388 | /* IN zlp's are handled by hardware */ | ||
| 1389 | complete_req(ep, req, 0); | ||
| 1390 | |||
| 1391 | /* if set_config or set_intf is waiting for ack by zlp | ||
| 1392 | * then set CSR_DONE | ||
| 1393 | */ | ||
| 1394 | if (dev->set_cfg_not_acked) { | ||
| 1395 | pch_udc_set_csr_done(dev); | ||
| 1396 | dev->set_cfg_not_acked = 0; | ||
| 1397 | } | ||
| 1398 | /* setup command is ACK'ed now by zlp */ | ||
| 1399 | if (!dev->stall && dev->waiting_zlp_ack) { | ||
| 1400 | pch_udc_ep_clear_nak(&(dev->ep[UDC_EP0IN_IDX])); | ||
| 1401 | dev->waiting_zlp_ack = 0; | ||
| 1402 | } | ||
| 1403 | } | ||
| 1404 | |||
| 1405 | /** | ||
| 1406 | * pch_udc_start_rxrequest() - This function starts the receive requirement. | ||
| 1407 | * @ep: Reference to the endpoint structure | ||
| 1408 | * @req: Reference to the request structure | ||
| 1409 | */ | ||
| 1410 | static void pch_udc_start_rxrequest(struct pch_udc_ep *ep, | ||
| 1411 | struct pch_udc_request *req) | ||
| 1412 | { | ||
| 1413 | struct pch_udc_data_dma_desc *td_data; | ||
| 1414 | |||
| 1415 | pch_udc_clear_dma(ep->dev, DMA_DIR_RX); | ||
| 1416 | td_data = req->td_data; | ||
| 1417 | ep->td_data = req->td_data; | ||
| 1418 | /* Set the status bits for all descriptors */ | ||
| 1419 | while (1) { | ||
| 1420 | td_data->status = (td_data->status & ~PCH_UDC_BUFF_STS) | | ||
| 1421 | PCH_UDC_BS_HST_RDY; | ||
| 1422 | if ((td_data->status & PCH_UDC_DMA_LAST) == PCH_UDC_DMA_LAST) | ||
| 1423 | break; | ||
| 1424 | td_data = phys_to_virt(td_data->next); | ||
| 1425 | } | ||
| 1426 | /* Write the descriptor pointer */ | ||
| 1427 | pch_udc_ep_set_ddptr(ep, req->td_data_phys); | ||
| 1428 | req->dma_going = 1; | ||
| 1429 | pch_udc_enable_ep_interrupts(ep->dev, UDC_EPINT_OUT_EP0 << ep->num); | ||
| 1430 | pch_udc_set_dma(ep->dev, DMA_DIR_RX); | ||
| 1431 | pch_udc_ep_clear_nak(ep); | ||
| 1432 | pch_udc_ep_set_rrdy(ep); | ||
| 1433 | } | ||
| 1434 | |||
| 1435 | /** | ||
| 1436 | * pch_udc_pcd_ep_enable() - This API enables the endpoint. It is called | ||
| 1437 | * from gadget driver | ||
| 1438 | * @usbep: Reference to the USB endpoint structure | ||
| 1439 | * @desc: Reference to the USB endpoint descriptor structure | ||
| 1440 | * | ||
| 1441 | * Return codes: | ||
| 1442 | * 0: Success | ||
| 1443 | * -EINVAL: | ||
| 1444 | * -ESHUTDOWN: | ||
| 1445 | */ | ||
| 1446 | static int pch_udc_pcd_ep_enable(struct usb_ep *usbep, | ||
| 1447 | const struct usb_endpoint_descriptor *desc) | ||
| 1448 | { | ||
| 1449 | struct pch_udc_ep *ep; | ||
| 1450 | struct pch_udc_dev *dev; | ||
| 1451 | unsigned long iflags; | ||
| 1452 | |||
| 1453 | if (!usbep || (usbep->name == ep0_string) || !desc || | ||
| 1454 | (desc->bDescriptorType != USB_DT_ENDPOINT) || !desc->wMaxPacketSize) | ||
| 1455 | return -EINVAL; | ||
| 1456 | |||
| 1457 | ep = container_of(usbep, struct pch_udc_ep, ep); | ||
| 1458 | dev = ep->dev; | ||
| 1459 | if (!dev->driver || (dev->gadget.speed == USB_SPEED_UNKNOWN)) | ||
| 1460 | return -ESHUTDOWN; | ||
| 1461 | spin_lock_irqsave(&dev->lock, iflags); | ||
| 1462 | ep->desc = desc; | ||
| 1463 | ep->halted = 0; | ||
| 1464 | pch_udc_ep_enable(ep, &ep->dev->cfg_data, desc); | ||
| 1465 | ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); | ||
| 1466 | pch_udc_enable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 1467 | spin_unlock_irqrestore(&dev->lock, iflags); | ||
| 1468 | return 0; | ||
| 1469 | } | ||
| 1470 | |||
| 1471 | /** | ||
| 1472 | * pch_udc_pcd_ep_disable() - This API disables endpoint and is called | ||
| 1473 | * from gadget driver | ||
| 1474 | * @usbep Reference to the USB endpoint structure | ||
| 1475 | * | ||
| 1476 | * Return codes: | ||
| 1477 | * 0: Success | ||
| 1478 | * -EINVAL: | ||
| 1479 | */ | ||
| 1480 | static int pch_udc_pcd_ep_disable(struct usb_ep *usbep) | ||
| 1481 | { | ||
| 1482 | struct pch_udc_ep *ep; | ||
| 1483 | struct pch_udc_dev *dev; | ||
| 1484 | unsigned long iflags; | ||
| 1485 | |||
| 1486 | if (!usbep) | ||
| 1487 | return -EINVAL; | ||
| 1488 | |||
| 1489 | ep = container_of(usbep, struct pch_udc_ep, ep); | ||
| 1490 | dev = ep->dev; | ||
| 1491 | if ((usbep->name == ep0_string) || !ep->desc) | ||
| 1492 | return -EINVAL; | ||
| 1493 | |||
| 1494 | spin_lock_irqsave(&ep->dev->lock, iflags); | ||
| 1495 | empty_req_queue(ep); | ||
| 1496 | ep->halted = 1; | ||
| 1497 | pch_udc_ep_disable(ep); | ||
| 1498 | pch_udc_disable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 1499 | ep->desc = NULL; | ||
| 1500 | INIT_LIST_HEAD(&ep->queue); | ||
| 1501 | spin_unlock_irqrestore(&ep->dev->lock, iflags); | ||
| 1502 | return 0; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | /** | ||
| 1506 | * pch_udc_alloc_request() - This function allocates request structure. | ||
| 1507 | * It is called by gadget driver | ||
| 1508 | * @usbep: Reference to the USB endpoint structure | ||
| 1509 | * @gfp: Flag to be used while allocating memory | ||
| 1510 | * | ||
| 1511 | * Return codes: | ||
| 1512 | * NULL: Failure | ||
| 1513 | * Allocated address: Success | ||
| 1514 | */ | ||
| 1515 | static struct usb_request *pch_udc_alloc_request(struct usb_ep *usbep, | ||
| 1516 | gfp_t gfp) | ||
| 1517 | { | ||
| 1518 | struct pch_udc_request *req; | ||
| 1519 | struct pch_udc_ep *ep; | ||
| 1520 | struct pch_udc_data_dma_desc *dma_desc; | ||
| 1521 | struct pch_udc_dev *dev; | ||
| 1522 | |||
| 1523 | if (!usbep) | ||
| 1524 | return NULL; | ||
| 1525 | ep = container_of(usbep, struct pch_udc_ep, ep); | ||
| 1526 | dev = ep->dev; | ||
| 1527 | req = kzalloc(sizeof *req, gfp); | ||
| 1528 | if (!req) | ||
| 1529 | return NULL; | ||
| 1530 | req->req.dma = DMA_ADDR_INVALID; | ||
| 1531 | INIT_LIST_HEAD(&req->queue); | ||
| 1532 | if (!ep->dev->dma_addr) | ||
| 1533 | return &req->req; | ||
| 1534 | /* ep0 in requests are allocated from data pool here */ | ||
| 1535 | dma_desc = pci_pool_alloc(ep->dev->data_requests, gfp, | ||
| 1536 | &req->td_data_phys); | ||
| 1537 | if (NULL == dma_desc) { | ||
| 1538 | kfree(req); | ||
| 1539 | return NULL; | ||
| 1540 | } | ||
| 1541 | /* prevent from using desc. - set HOST BUSY */ | ||
| 1542 | dma_desc->status |= PCH_UDC_BS_HST_BSY; | ||
| 1543 | dma_desc->dataptr = __constant_cpu_to_le32(DMA_ADDR_INVALID); | ||
| 1544 | req->td_data = dma_desc; | ||
| 1545 | req->td_data_last = dma_desc; | ||
| 1546 | req->chain_len = 1; | ||
| 1547 | return &req->req; | ||
| 1548 | } | ||
| 1549 | |||
| 1550 | /** | ||
| 1551 | * pch_udc_free_request() - This function frees request structure. | ||
| 1552 | * It is called by gadget driver | ||
| 1553 | * @usbep: Reference to the USB endpoint structure | ||
| 1554 | * @usbreq: Reference to the USB request | ||
| 1555 | */ | ||
| 1556 | static void pch_udc_free_request(struct usb_ep *usbep, | ||
| 1557 | struct usb_request *usbreq) | ||
| 1558 | { | ||
| 1559 | struct pch_udc_ep *ep; | ||
| 1560 | struct pch_udc_request *req; | ||
| 1561 | struct pch_udc_dev *dev; | ||
| 1562 | |||
| 1563 | if (!usbep || !usbreq) | ||
| 1564 | return; | ||
| 1565 | ep = container_of(usbep, struct pch_udc_ep, ep); | ||
| 1566 | req = container_of(usbreq, struct pch_udc_request, req); | ||
| 1567 | dev = ep->dev; | ||
| 1568 | if (!list_empty(&req->queue)) | ||
| 1569 | dev_err(&dev->pdev->dev, "%s: %s req=0x%p queue not empty\n", | ||
| 1570 | __func__, usbep->name, req); | ||
| 1571 | if (req->td_data != NULL) { | ||
| 1572 | if (req->chain_len > 1) | ||
| 1573 | pch_udc_free_dma_chain(ep->dev, req); | ||
| 1574 | pci_pool_free(ep->dev->data_requests, req->td_data, | ||
| 1575 | req->td_data_phys); | ||
| 1576 | } | ||
| 1577 | kfree(req); | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | /** | ||
| 1581 | * pch_udc_pcd_queue() - This function queues a request packet. It is called | ||
| 1582 | * by gadget driver | ||
| 1583 | * @usbep: Reference to the USB endpoint structure | ||
| 1584 | * @usbreq: Reference to the USB request | ||
| 1585 | * @gfp: Flag to be used while mapping the data buffer | ||
| 1586 | * | ||
| 1587 | * Return codes: | ||
| 1588 | * 0: Success | ||
| 1589 | * linux error number: Failure | ||
| 1590 | */ | ||
| 1591 | static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq, | ||
| 1592 | gfp_t gfp) | ||
| 1593 | { | ||
| 1594 | int retval = 0; | ||
| 1595 | struct pch_udc_ep *ep; | ||
| 1596 | struct pch_udc_dev *dev; | ||
| 1597 | struct pch_udc_request *req; | ||
| 1598 | unsigned long iflags; | ||
| 1599 | |||
| 1600 | if (!usbep || !usbreq || !usbreq->complete || !usbreq->buf) | ||
| 1601 | return -EINVAL; | ||
| 1602 | ep = container_of(usbep, struct pch_udc_ep, ep); | ||
| 1603 | dev = ep->dev; | ||
| 1604 | if (!ep->desc && ep->num) | ||
| 1605 | return -EINVAL; | ||
| 1606 | req = container_of(usbreq, struct pch_udc_request, req); | ||
| 1607 | if (!list_empty(&req->queue)) | ||
| 1608 | return -EINVAL; | ||
| 1609 | if (!dev->driver || (dev->gadget.speed == USB_SPEED_UNKNOWN)) | ||
| 1610 | return -ESHUTDOWN; | ||
| 1611 | spin_lock_irqsave(&ep->dev->lock, iflags); | ||
| 1612 | /* map the buffer for dma */ | ||
| 1613 | if (usbreq->length && | ||
| 1614 | ((usbreq->dma == DMA_ADDR_INVALID) || !usbreq->dma)) { | ||
| 1615 | if (ep->in) | ||
| 1616 | usbreq->dma = pci_map_single(dev->pdev, usbreq->buf, | ||
| 1617 | usbreq->length, PCI_DMA_TODEVICE); | ||
| 1618 | else | ||
| 1619 | usbreq->dma = pci_map_single(dev->pdev, usbreq->buf, | ||
| 1620 | usbreq->length, PCI_DMA_FROMDEVICE); | ||
| 1621 | req->dma_mapped = 1; | ||
| 1622 | } | ||
| 1623 | if (usbreq->length > 0) { | ||
| 1624 | retval = prepare_dma(ep, req, gfp); | ||
| 1625 | if (retval) | ||
| 1626 | goto probe_end; | ||
| 1627 | } | ||
| 1628 | usbreq->actual = 0; | ||
| 1629 | usbreq->status = -EINPROGRESS; | ||
| 1630 | req->dma_done = 0; | ||
| 1631 | if (list_empty(&ep->queue) && !ep->halted) { | ||
| 1632 | /* no pending transfer, so start this req */ | ||
| 1633 | if (!usbreq->length) { | ||
| 1634 | process_zlp(ep, req); | ||
| 1635 | retval = 0; | ||
| 1636 | goto probe_end; | ||
| 1637 | } | ||
| 1638 | if (!ep->in) { | ||
| 1639 | pch_udc_start_rxrequest(ep, req); | ||
| 1640 | } else { | ||
| 1641 | /* | ||
| 1642 | * For IN trfr the descriptors will be programmed and | ||
| 1643 | * P bit will be set when | ||
| 1644 | * we get an IN token | ||
| 1645 | */ | ||
| 1646 | pch_udc_wait_ep_stall(ep); | ||
| 1647 | pch_udc_ep_clear_nak(ep); | ||
| 1648 | pch_udc_enable_ep_interrupts(ep->dev, (1 << ep->num)); | ||
| 1649 | pch_udc_set_dma(dev, DMA_DIR_TX); | ||
| 1650 | } | ||
| 1651 | } | ||
| 1652 | /* Now add this request to the ep's pending requests */ | ||
| 1653 | if (req != NULL) | ||
| 1654 | list_add_tail(&req->queue, &ep->queue); | ||
| 1655 | |||
| 1656 | probe_end: | ||
| 1657 | spin_unlock_irqrestore(&dev->lock, iflags); | ||
| 1658 | return retval; | ||
| 1659 | } | ||
| 1660 | |||
| 1661 | /** | ||
| 1662 | * pch_udc_pcd_dequeue() - This function de-queues a request packet. | ||
| 1663 | * It is called by gadget driver | ||
| 1664 | * @usbep: Reference to the USB endpoint structure | ||
| 1665 | * @usbreq: Reference to the USB request | ||
| 1666 | * | ||
| 1667 | * Return codes: | ||
| 1668 | * 0: Success | ||
| 1669 | * linux error number: Failure | ||
| 1670 | */ | ||
| 1671 | static int pch_udc_pcd_dequeue(struct usb_ep *usbep, | ||
| 1672 | struct usb_request *usbreq) | ||
| 1673 | { | ||
| 1674 | struct pch_udc_ep *ep; | ||
| 1675 | struct pch_udc_request *req; | ||
| 1676 | struct pch_udc_dev *dev; | ||
| 1677 | unsigned long flags; | ||
| 1678 | int ret = -EINVAL; | ||
| 1679 | |||
| 1680 | ep = container_of(usbep, struct pch_udc_ep, ep); | ||
| 1681 | dev = ep->dev; | ||
| 1682 | if (!usbep || !usbreq || (!ep->desc && ep->num)) | ||
| 1683 | return ret; | ||
| 1684 | req = container_of(usbreq, struct pch_udc_request, req); | ||
| 1685 | spin_lock_irqsave(&ep->dev->lock, flags); | ||
| 1686 | /* make sure it's still queued on this endpoint */ | ||
| 1687 | list_for_each_entry(req, &ep->queue, queue) { | ||
| 1688 | if (&req->req == usbreq) { | ||
| 1689 | pch_udc_ep_set_nak(ep); | ||
| 1690 | if (!list_empty(&req->queue)) | ||
| 1691 | complete_req(ep, req, -ECONNRESET); | ||
| 1692 | ret = 0; | ||
| 1693 | break; | ||
| 1694 | } | ||
| 1695 | } | ||
| 1696 | spin_unlock_irqrestore(&ep->dev->lock, flags); | ||
| 1697 | return ret; | ||
| 1698 | } | ||
| 1699 | |||
| 1700 | /** | ||
| 1701 | * pch_udc_pcd_set_halt() - This function Sets or clear the endpoint halt | ||
| 1702 | * feature | ||
| 1703 | * @usbep: Reference to the USB endpoint structure | ||
| 1704 | * @halt: Specifies whether to set or clear the feature | ||
| 1705 | * | ||
| 1706 | * Return codes: | ||
| 1707 | * 0: Success | ||
| 1708 | * linux error number: Failure | ||
| 1709 | */ | ||
| 1710 | static int pch_udc_pcd_set_halt(struct usb_ep *usbep, int halt) | ||
| 1711 | { | ||
| 1712 | struct pch_udc_ep *ep; | ||
| 1713 | struct pch_udc_dev *dev; | ||
| 1714 | unsigned long iflags; | ||
| 1715 | int ret; | ||
| 1716 | |||
| 1717 | if (!usbep) | ||
| 1718 | return -EINVAL; | ||
| 1719 | ep = container_of(usbep, struct pch_udc_ep, ep); | ||
| 1720 | dev = ep->dev; | ||
| 1721 | if (!ep->desc && !ep->num) | ||
| 1722 | return -EINVAL; | ||
| 1723 | if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN)) | ||
| 1724 | return -ESHUTDOWN; | ||
| 1725 | spin_lock_irqsave(&udc_stall_spinlock, iflags); | ||
| 1726 | if (list_empty(&ep->queue)) { | ||
| 1727 | if (halt) { | ||
| 1728 | if (ep->num == PCH_UDC_EP0) | ||
| 1729 | ep->dev->stall = 1; | ||
| 1730 | pch_udc_ep_set_stall(ep); | ||
| 1731 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 1732 | PCH_UDC_EPINT(ep->in, | ||
| 1733 | ep->num)); | ||
| 1734 | } else { | ||
| 1735 | pch_udc_ep_clear_stall(ep); | ||
| 1736 | } | ||
| 1737 | ret = 0; | ||
| 1738 | } else { | ||
| 1739 | ret = -EAGAIN; | ||
| 1740 | } | ||
| 1741 | spin_unlock_irqrestore(&udc_stall_spinlock, iflags); | ||
| 1742 | return ret; | ||
| 1743 | } | ||
| 1744 | |||
| 1745 | /** | ||
| 1746 | * pch_udc_pcd_set_wedge() - This function Sets or clear the endpoint | ||
| 1747 | * halt feature | ||
| 1748 | * @usbep: Reference to the USB endpoint structure | ||
| 1749 | * @halt: Specifies whether to set or clear the feature | ||
| 1750 | * | ||
| 1751 | * Return codes: | ||
| 1752 | * 0: Success | ||
| 1753 | * linux error number: Failure | ||
| 1754 | */ | ||
| 1755 | static int pch_udc_pcd_set_wedge(struct usb_ep *usbep) | ||
| 1756 | { | ||
| 1757 | struct pch_udc_ep *ep; | ||
| 1758 | struct pch_udc_dev *dev; | ||
| 1759 | unsigned long iflags; | ||
| 1760 | int ret; | ||
| 1761 | |||
| 1762 | if (!usbep) | ||
| 1763 | return -EINVAL; | ||
| 1764 | ep = container_of(usbep, struct pch_udc_ep, ep); | ||
| 1765 | dev = ep->dev; | ||
| 1766 | if (!ep->desc && !ep->num) | ||
| 1767 | return -EINVAL; | ||
| 1768 | if (!ep->dev->driver || (ep->dev->gadget.speed == USB_SPEED_UNKNOWN)) | ||
| 1769 | return -ESHUTDOWN; | ||
| 1770 | spin_lock_irqsave(&udc_stall_spinlock, iflags); | ||
| 1771 | if (!list_empty(&ep->queue)) { | ||
| 1772 | ret = -EAGAIN; | ||
| 1773 | } else { | ||
| 1774 | if (ep->num == PCH_UDC_EP0) | ||
| 1775 | ep->dev->stall = 1; | ||
| 1776 | pch_udc_ep_set_stall(ep); | ||
| 1777 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 1778 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 1779 | ep->dev->prot_stall = 1; | ||
| 1780 | ret = 0; | ||
| 1781 | } | ||
| 1782 | spin_unlock_irqrestore(&udc_stall_spinlock, iflags); | ||
| 1783 | return ret; | ||
| 1784 | } | ||
| 1785 | |||
| 1786 | /** | ||
| 1787 | * pch_udc_pcd_fifo_flush() - This function Flush the FIFO of specified endpoint | ||
| 1788 | * @usbep: Reference to the USB endpoint structure | ||
| 1789 | */ | ||
| 1790 | static void pch_udc_pcd_fifo_flush(struct usb_ep *usbep) | ||
| 1791 | { | ||
| 1792 | struct pch_udc_ep *ep; | ||
| 1793 | |||
| 1794 | if (!usbep) | ||
| 1795 | return; | ||
| 1796 | |||
| 1797 | ep = container_of(usbep, struct pch_udc_ep, ep); | ||
| 1798 | if (ep->desc || !ep->num) | ||
| 1799 | pch_udc_ep_fifo_flush(ep, ep->in); | ||
| 1800 | } | ||
| 1801 | |||
| 1802 | static const struct usb_ep_ops pch_udc_ep_ops = { | ||
| 1803 | .enable = pch_udc_pcd_ep_enable, | ||
| 1804 | .disable = pch_udc_pcd_ep_disable, | ||
| 1805 | .alloc_request = pch_udc_alloc_request, | ||
| 1806 | .free_request = pch_udc_free_request, | ||
| 1807 | .queue = pch_udc_pcd_queue, | ||
| 1808 | .dequeue = pch_udc_pcd_dequeue, | ||
| 1809 | .set_halt = pch_udc_pcd_set_halt, | ||
| 1810 | .set_wedge = pch_udc_pcd_set_wedge, | ||
| 1811 | .fifo_status = NULL, | ||
| 1812 | .fifo_flush = pch_udc_pcd_fifo_flush, | ||
| 1813 | }; | ||
| 1814 | |||
| 1815 | /** | ||
| 1816 | * pch_udc_init_setup_buff() - This function initializes the SETUP buffer | ||
| 1817 | * @td_stp: Reference to the SETP buffer structure | ||
| 1818 | */ | ||
| 1819 | static void pch_udc_init_setup_buff(struct pch_udc_stp_dma_desc *td_stp) | ||
| 1820 | { | ||
| 1821 | static u32 pky_marker; | ||
| 1822 | |||
| 1823 | if (!td_stp) | ||
| 1824 | return; | ||
| 1825 | td_stp->reserved = ++pky_marker; | ||
| 1826 | memset(&td_stp->request, 0xFF, sizeof td_stp->request); | ||
| 1827 | td_stp->status = PCH_UDC_BS_HST_RDY; | ||
| 1828 | } | ||
| 1829 | |||
| 1830 | /** | ||
| 1831 | * pch_udc_start_next_txrequest() - This function starts | ||
| 1832 | * the next transmission requirement | ||
| 1833 | * @ep: Reference to the endpoint structure | ||
| 1834 | */ | ||
| 1835 | static void pch_udc_start_next_txrequest(struct pch_udc_ep *ep) | ||
| 1836 | { | ||
| 1837 | struct pch_udc_request *req; | ||
| 1838 | struct pch_udc_data_dma_desc *td_data; | ||
| 1839 | |||
| 1840 | if (pch_udc_read_ep_control(ep) & UDC_EPCTL_P) | ||
| 1841 | return; | ||
| 1842 | |||
| 1843 | if (list_empty(&ep->queue)) | ||
| 1844 | return; | ||
| 1845 | |||
| 1846 | /* next request */ | ||
| 1847 | req = list_entry(ep->queue.next, struct pch_udc_request, queue); | ||
| 1848 | if (req->dma_going) | ||
| 1849 | return; | ||
| 1850 | if (!req->td_data) | ||
| 1851 | return; | ||
| 1852 | pch_udc_wait_ep_stall(ep); | ||
| 1853 | req->dma_going = 1; | ||
| 1854 | pch_udc_ep_set_ddptr(ep, 0); | ||
| 1855 | td_data = req->td_data; | ||
| 1856 | while (1) { | ||
| 1857 | td_data->status = (td_data->status & ~PCH_UDC_BUFF_STS) | | ||
| 1858 | PCH_UDC_BS_HST_RDY; | ||
| 1859 | if ((td_data->status & PCH_UDC_DMA_LAST) == PCH_UDC_DMA_LAST) | ||
| 1860 | break; | ||
| 1861 | td_data = phys_to_virt(td_data->next); | ||
| 1862 | } | ||
| 1863 | pch_udc_ep_set_ddptr(ep, req->td_data_phys); | ||
| 1864 | pch_udc_set_dma(ep->dev, DMA_DIR_TX); | ||
| 1865 | pch_udc_ep_set_pd(ep); | ||
| 1866 | pch_udc_enable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 1867 | pch_udc_ep_clear_nak(ep); | ||
| 1868 | } | ||
| 1869 | |||
| 1870 | /** | ||
| 1871 | * pch_udc_complete_transfer() - This function completes a transfer | ||
| 1872 | * @ep: Reference to the endpoint structure | ||
| 1873 | */ | ||
| 1874 | static void pch_udc_complete_transfer(struct pch_udc_ep *ep) | ||
| 1875 | { | ||
| 1876 | struct pch_udc_request *req; | ||
| 1877 | struct pch_udc_dev *dev = ep->dev; | ||
| 1878 | |||
| 1879 | if (list_empty(&ep->queue)) | ||
| 1880 | return; | ||
| 1881 | req = list_entry(ep->queue.next, struct pch_udc_request, queue); | ||
| 1882 | if ((req->td_data_last->status & PCH_UDC_BUFF_STS) != | ||
| 1883 | PCH_UDC_BS_DMA_DONE) | ||
| 1884 | return; | ||
| 1885 | if ((req->td_data_last->status & PCH_UDC_RXTX_STS) != | ||
| 1886 | PCH_UDC_RTS_SUCC) { | ||
| 1887 | dev_err(&dev->pdev->dev, "Invalid RXTX status (0x%08x) " | ||
| 1888 | "epstatus=0x%08x\n", | ||
| 1889 | (req->td_data_last->status & PCH_UDC_RXTX_STS), | ||
| 1890 | (int)(ep->epsts)); | ||
| 1891 | return; | ||
| 1892 | } | ||
| 1893 | |||
| 1894 | req->req.actual = req->req.length; | ||
| 1895 | req->td_data_last->status = PCH_UDC_BS_HST_BSY | PCH_UDC_DMA_LAST; | ||
| 1896 | req->td_data->status = PCH_UDC_BS_HST_BSY | PCH_UDC_DMA_LAST; | ||
| 1897 | complete_req(ep, req, 0); | ||
| 1898 | req->dma_going = 0; | ||
| 1899 | if (!list_empty(&ep->queue)) { | ||
| 1900 | pch_udc_wait_ep_stall(ep); | ||
| 1901 | pch_udc_ep_clear_nak(ep); | ||
| 1902 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 1903 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 1904 | } else { | ||
| 1905 | pch_udc_disable_ep_interrupts(ep->dev, | ||
| 1906 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 1907 | } | ||
| 1908 | } | ||
| 1909 | |||
| 1910 | /** | ||
| 1911 | * pch_udc_complete_receiver() - This function completes a receiver | ||
| 1912 | * @ep: Reference to the endpoint structure | ||
| 1913 | */ | ||
| 1914 | static void pch_udc_complete_receiver(struct pch_udc_ep *ep) | ||
| 1915 | { | ||
| 1916 | struct pch_udc_request *req; | ||
| 1917 | struct pch_udc_dev *dev = ep->dev; | ||
| 1918 | unsigned int count; | ||
| 1919 | |||
| 1920 | if (list_empty(&ep->queue)) | ||
| 1921 | return; | ||
| 1922 | |||
| 1923 | /* next request */ | ||
| 1924 | req = list_entry(ep->queue.next, struct pch_udc_request, queue); | ||
| 1925 | if ((req->td_data_last->status & PCH_UDC_BUFF_STS) != | ||
| 1926 | PCH_UDC_BS_DMA_DONE) | ||
| 1927 | return; | ||
| 1928 | pch_udc_clear_dma(ep->dev, DMA_DIR_RX); | ||
| 1929 | if ((req->td_data_last->status & PCH_UDC_RXTX_STS) != | ||
| 1930 | PCH_UDC_RTS_SUCC) { | ||
| 1931 | dev_err(&dev->pdev->dev, "Invalid RXTX status (0x%08x) " | ||
| 1932 | "epstatus=0x%08x\n", | ||
| 1933 | (req->td_data_last->status & PCH_UDC_RXTX_STS), | ||
| 1934 | (int)(ep->epsts)); | ||
| 1935 | return; | ||
| 1936 | } | ||
| 1937 | count = req->td_data_last->status & PCH_UDC_RXTX_BYTES; | ||
| 1938 | |||
| 1939 | /* on 64k packets the RXBYTES field is zero */ | ||
| 1940 | if (!count && (req->req.length == UDC_DMA_MAXPACKET)) | ||
| 1941 | count = UDC_DMA_MAXPACKET; | ||
| 1942 | req->td_data->status |= PCH_UDC_DMA_LAST; | ||
| 1943 | req->td_data_last->status |= PCH_UDC_BS_HST_BSY; | ||
| 1944 | |||
| 1945 | req->dma_going = 0; | ||
| 1946 | req->req.actual = count; | ||
| 1947 | complete_req(ep, req, 0); | ||
| 1948 | /* If there is a new/failed requests try that now */ | ||
| 1949 | if (!list_empty(&ep->queue)) { | ||
| 1950 | req = list_entry(ep->queue.next, struct pch_udc_request, queue); | ||
| 1951 | pch_udc_start_rxrequest(ep, req); | ||
| 1952 | } | ||
| 1953 | } | ||
| 1954 | |||
| 1955 | /** | ||
| 1956 | * pch_udc_svc_data_in() - This function process endpoint interrupts | ||
| 1957 | * for IN endpoints | ||
| 1958 | * @dev: Reference to the device structure | ||
| 1959 | * @ep_num: Endpoint that generated the interrupt | ||
| 1960 | */ | ||
| 1961 | static void pch_udc_svc_data_in(struct pch_udc_dev *dev, int ep_num) | ||
| 1962 | { | ||
| 1963 | u32 epsts; | ||
| 1964 | struct pch_udc_ep *ep; | ||
| 1965 | |||
| 1966 | ep = &dev->ep[2*ep_num]; | ||
| 1967 | epsts = ep->epsts; | ||
| 1968 | ep->epsts = 0; | ||
| 1969 | |||
| 1970 | if (!(epsts & (UDC_EPSTS_IN | UDC_EPSTS_BNA | UDC_EPSTS_HE | | ||
| 1971 | UDC_EPSTS_TDC | UDC_EPSTS_RCS | UDC_EPSTS_TXEMPTY | | ||
| 1972 | UDC_EPSTS_RSS | UDC_EPSTS_XFERDONE))) | ||
| 1973 | return; | ||
| 1974 | if ((epsts & UDC_EPSTS_BNA)) | ||
| 1975 | return; | ||
| 1976 | if (epsts & UDC_EPSTS_HE) | ||
| 1977 | return; | ||
| 1978 | if (epsts & UDC_EPSTS_RSS) { | ||
| 1979 | pch_udc_ep_set_stall(ep); | ||
| 1980 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 1981 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 1982 | } | ||
| 1983 | if (epsts & UDC_EPSTS_RCS) { | ||
| 1984 | if (!dev->prot_stall) { | ||
| 1985 | pch_udc_ep_clear_stall(ep); | ||
| 1986 | } else { | ||
| 1987 | pch_udc_ep_set_stall(ep); | ||
| 1988 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 1989 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 1990 | } | ||
| 1991 | } | ||
| 1992 | if (epsts & UDC_EPSTS_TDC) | ||
| 1993 | pch_udc_complete_transfer(ep); | ||
| 1994 | /* On IN interrupt, provide data if we have any */ | ||
| 1995 | if ((epsts & UDC_EPSTS_IN) && !(epsts & UDC_EPSTS_RSS) && | ||
| 1996 | !(epsts & UDC_EPSTS_TDC) && !(epsts & UDC_EPSTS_TXEMPTY)) | ||
| 1997 | pch_udc_start_next_txrequest(ep); | ||
| 1998 | } | ||
| 1999 | |||
| 2000 | /** | ||
| 2001 | * pch_udc_svc_data_out() - Handles interrupts from OUT endpoint | ||
| 2002 | * @dev: Reference to the device structure | ||
| 2003 | * @ep_num: Endpoint that generated the interrupt | ||
| 2004 | */ | ||
| 2005 | static void pch_udc_svc_data_out(struct pch_udc_dev *dev, int ep_num) | ||
| 2006 | { | ||
| 2007 | u32 epsts; | ||
| 2008 | struct pch_udc_ep *ep; | ||
| 2009 | struct pch_udc_request *req = NULL; | ||
| 2010 | |||
| 2011 | ep = &dev->ep[2*ep_num + 1]; | ||
| 2012 | epsts = ep->epsts; | ||
| 2013 | ep->epsts = 0; | ||
| 2014 | |||
| 2015 | if ((epsts & UDC_EPSTS_BNA) && (!list_empty(&ep->queue))) { | ||
| 2016 | /* next request */ | ||
| 2017 | req = list_entry(ep->queue.next, struct pch_udc_request, | ||
| 2018 | queue); | ||
| 2019 | if ((req->td_data_last->status & PCH_UDC_BUFF_STS) != | ||
| 2020 | PCH_UDC_BS_DMA_DONE) { | ||
| 2021 | if (!req->dma_going) | ||
| 2022 | pch_udc_start_rxrequest(ep, req); | ||
| 2023 | return; | ||
| 2024 | } | ||
| 2025 | } | ||
| 2026 | if (epsts & UDC_EPSTS_HE) | ||
| 2027 | return; | ||
| 2028 | if (epsts & UDC_EPSTS_RSS) | ||
| 2029 | pch_udc_ep_set_stall(ep); | ||
| 2030 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 2031 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 2032 | if (epsts & UDC_EPSTS_RCS) { | ||
| 2033 | if (!dev->prot_stall) { | ||
| 2034 | pch_udc_ep_clear_stall(ep); | ||
| 2035 | } else { | ||
| 2036 | pch_udc_ep_set_stall(ep); | ||
| 2037 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 2038 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 2039 | } | ||
| 2040 | } | ||
| 2041 | if (((epsts & UDC_EPSTS_OUT_MASK) >> UDC_EPSTS_OUT_SHIFT) == | ||
| 2042 | UDC_EPSTS_OUT_DATA) { | ||
| 2043 | if (ep->dev->prot_stall == 1) { | ||
| 2044 | pch_udc_ep_set_stall(ep); | ||
| 2045 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 2046 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 2047 | } else { | ||
| 2048 | pch_udc_complete_receiver(ep); | ||
| 2049 | } | ||
| 2050 | } | ||
| 2051 | if (list_empty(&ep->queue)) | ||
| 2052 | pch_udc_set_dma(dev, DMA_DIR_RX); | ||
| 2053 | } | ||
| 2054 | |||
| 2055 | /** | ||
| 2056 | * pch_udc_svc_control_in() - Handle Control IN endpoint interrupts | ||
| 2057 | * @dev: Reference to the device structure | ||
| 2058 | */ | ||
| 2059 | static void pch_udc_svc_control_in(struct pch_udc_dev *dev) | ||
| 2060 | { | ||
| 2061 | u32 epsts; | ||
| 2062 | struct pch_udc_ep *ep; | ||
| 2063 | |||
| 2064 | ep = &dev->ep[UDC_EP0IN_IDX]; | ||
| 2065 | epsts = ep->epsts; | ||
| 2066 | ep->epsts = 0; | ||
| 2067 | |||
| 2068 | if (!(epsts & (UDC_EPSTS_IN | UDC_EPSTS_BNA | UDC_EPSTS_HE | | ||
| 2069 | UDC_EPSTS_TDC | UDC_EPSTS_RCS | UDC_EPSTS_TXEMPTY | | ||
| 2070 | UDC_EPSTS_XFERDONE))) | ||
| 2071 | return; | ||
| 2072 | if ((epsts & UDC_EPSTS_BNA)) | ||
| 2073 | return; | ||
| 2074 | if (epsts & UDC_EPSTS_HE) | ||
| 2075 | return; | ||
| 2076 | if ((epsts & UDC_EPSTS_TDC) && (!dev->stall)) | ||
| 2077 | pch_udc_complete_transfer(ep); | ||
| 2078 | /* On IN interrupt, provide data if we have any */ | ||
| 2079 | if ((epsts & UDC_EPSTS_IN) && !(epsts & UDC_EPSTS_TDC) && | ||
| 2080 | !(epsts & UDC_EPSTS_TXEMPTY)) | ||
| 2081 | pch_udc_start_next_txrequest(ep); | ||
| 2082 | } | ||
| 2083 | |||
| 2084 | /** | ||
| 2085 | * pch_udc_svc_control_out() - Routine that handle Control | ||
| 2086 | * OUT endpoint interrupts | ||
| 2087 | * @dev: Reference to the device structure | ||
| 2088 | */ | ||
| 2089 | static void pch_udc_svc_control_out(struct pch_udc_dev *dev) | ||
| 2090 | { | ||
| 2091 | u32 stat; | ||
| 2092 | int setup_supported; | ||
| 2093 | struct pch_udc_ep *ep; | ||
| 2094 | |||
| 2095 | ep = &dev->ep[UDC_EP0OUT_IDX]; | ||
| 2096 | stat = ep->epsts; | ||
| 2097 | ep->epsts = 0; | ||
| 2098 | |||
| 2099 | /* If setup data */ | ||
| 2100 | if (((stat & UDC_EPSTS_OUT_MASK) >> UDC_EPSTS_OUT_SHIFT) == | ||
| 2101 | UDC_EPSTS_OUT_SETUP) { | ||
| 2102 | dev->stall = 0; | ||
| 2103 | dev->ep[UDC_EP0IN_IDX].halted = 0; | ||
| 2104 | dev->ep[UDC_EP0OUT_IDX].halted = 0; | ||
| 2105 | /* In data not ready */ | ||
| 2106 | pch_udc_ep_set_nak(&(dev->ep[UDC_EP0IN_IDX])); | ||
| 2107 | dev->setup_data = ep->td_stp->request; | ||
| 2108 | pch_udc_init_setup_buff(ep->td_stp); | ||
| 2109 | pch_udc_clear_dma(dev, DMA_DIR_TX); | ||
| 2110 | pch_udc_ep_fifo_flush(&(dev->ep[UDC_EP0IN_IDX]), | ||
| 2111 | dev->ep[UDC_EP0IN_IDX].in); | ||
| 2112 | if ((dev->setup_data.bRequestType & USB_DIR_IN)) | ||
| 2113 | dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IDX].ep; | ||
| 2114 | else /* OUT */ | ||
| 2115 | dev->gadget.ep0 = &ep->ep; | ||
| 2116 | spin_unlock(&dev->lock); | ||
| 2117 | /* If Mass storage Reset */ | ||
| 2118 | if ((dev->setup_data.bRequestType == 0x21) && | ||
| 2119 | (dev->setup_data.bRequest == 0xFF)) | ||
| 2120 | dev->prot_stall = 0; | ||
| 2121 | /* call gadget with setup data received */ | ||
| 2122 | setup_supported = dev->driver->setup(&dev->gadget, | ||
| 2123 | &dev->setup_data); | ||
| 2124 | spin_lock(&dev->lock); | ||
| 2125 | /* ep0 in returns data on IN phase */ | ||
| 2126 | if (setup_supported >= 0 && setup_supported < | ||
| 2127 | UDC_EP0IN_MAX_PKT_SIZE) { | ||
| 2128 | pch_udc_ep_clear_nak(&(dev->ep[UDC_EP0IN_IDX])); | ||
| 2129 | /* Gadget would have queued a request when | ||
| 2130 | * we called the setup */ | ||
| 2131 | pch_udc_set_dma(dev, DMA_DIR_RX); | ||
| 2132 | pch_udc_ep_clear_nak(ep); | ||
| 2133 | } else if (setup_supported < 0) { | ||
| 2134 | /* if unsupported request, then stall */ | ||
| 2135 | pch_udc_ep_set_stall(&(dev->ep[UDC_EP0IN_IDX])); | ||
| 2136 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 2137 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 2138 | dev->stall = 0; | ||
| 2139 | pch_udc_set_dma(dev, DMA_DIR_RX); | ||
| 2140 | } else { | ||
| 2141 | dev->waiting_zlp_ack = 1; | ||
| 2142 | } | ||
| 2143 | } else if ((((stat & UDC_EPSTS_OUT_MASK) >> UDC_EPSTS_OUT_SHIFT) == | ||
| 2144 | UDC_EPSTS_OUT_DATA) && !dev->stall) { | ||
| 2145 | if (list_empty(&ep->queue)) { | ||
| 2146 | dev_err(&dev->pdev->dev, "%s: No request\n", __func__); | ||
| 2147 | ep->td_data->status = (ep->td_data->status & | ||
| 2148 | ~PCH_UDC_BUFF_STS) | | ||
| 2149 | PCH_UDC_BS_HST_RDY; | ||
| 2150 | pch_udc_set_dma(dev, DMA_DIR_RX); | ||
| 2151 | } else { | ||
| 2152 | /* control write */ | ||
| 2153 | /* next function will pickuo an clear the status */ | ||
| 2154 | ep->epsts = stat; | ||
| 2155 | |||
| 2156 | pch_udc_svc_data_out(dev, 0); | ||
| 2157 | /* re-program desc. pointer for possible ZLPs */ | ||
| 2158 | pch_udc_ep_set_ddptr(ep, ep->td_data_phys); | ||
| 2159 | pch_udc_set_dma(dev, DMA_DIR_RX); | ||
| 2160 | } | ||
| 2161 | } | ||
| 2162 | pch_udc_ep_set_rrdy(ep); | ||
| 2163 | } | ||
| 2164 | |||
| 2165 | |||
| 2166 | /** | ||
| 2167 | * pch_udc_postsvc_epinters() - This function enables end point interrupts | ||
| 2168 | * and clears NAK status | ||
| 2169 | * @dev: Reference to the device structure | ||
| 2170 | * @ep_num: End point number | ||
| 2171 | */ | ||
| 2172 | static void pch_udc_postsvc_epinters(struct pch_udc_dev *dev, int ep_num) | ||
| 2173 | { | ||
| 2174 | struct pch_udc_ep *ep; | ||
| 2175 | struct pch_udc_request *req; | ||
| 2176 | |||
| 2177 | ep = &dev->ep[2*ep_num]; | ||
| 2178 | if (!list_empty(&ep->queue)) { | ||
| 2179 | req = list_entry(ep->queue.next, struct pch_udc_request, queue); | ||
| 2180 | pch_udc_enable_ep_interrupts(ep->dev, | ||
| 2181 | PCH_UDC_EPINT(ep->in, ep->num)); | ||
| 2182 | pch_udc_ep_clear_nak(ep); | ||
| 2183 | } | ||
| 2184 | } | ||
| 2185 | |||
| 2186 | /** | ||
| 2187 | * pch_udc_read_all_epstatus() - This function read all endpoint status | ||
| 2188 | * @dev: Reference to the device structure | ||
| 2189 | * @ep_intr: Status of endpoint interrupt | ||
| 2190 | */ | ||
| 2191 | static void pch_udc_read_all_epstatus(struct pch_udc_dev *dev, u32 ep_intr) | ||
| 2192 | { | ||
| 2193 | int i; | ||
| 2194 | struct pch_udc_ep *ep; | ||
| 2195 | |||
| 2196 | for (i = 0; i < PCH_UDC_USED_EP_NUM; i++) { | ||
| 2197 | /* IN */ | ||
| 2198 | if (ep_intr & (0x1 << i)) { | ||
| 2199 | ep = &dev->ep[2*i]; | ||
| 2200 | ep->epsts = pch_udc_read_ep_status(ep); | ||
| 2201 | pch_udc_clear_ep_status(ep, ep->epsts); | ||
| 2202 | } | ||
| 2203 | /* OUT */ | ||
| 2204 | if (ep_intr & (0x10000 << i)) { | ||
| 2205 | ep = &dev->ep[2*i+1]; | ||
| 2206 | ep->epsts = pch_udc_read_ep_status(ep); | ||
| 2207 | pch_udc_clear_ep_status(ep, ep->epsts); | ||
| 2208 | } | ||
| 2209 | } | ||
| 2210 | } | ||
| 2211 | |||
| 2212 | /** | ||
| 2213 | * pch_udc_activate_control_ep() - This function enables the control endpoints | ||
| 2214 | * for traffic after a reset | ||
| 2215 | * @dev: Reference to the device structure | ||
| 2216 | */ | ||
| 2217 | static void pch_udc_activate_control_ep(struct pch_udc_dev *dev) | ||
| 2218 | { | ||
| 2219 | struct pch_udc_ep *ep; | ||
| 2220 | u32 val; | ||
| 2221 | |||
| 2222 | /* Setup the IN endpoint */ | ||
| 2223 | ep = &dev->ep[UDC_EP0IN_IDX]; | ||
| 2224 | pch_udc_clear_ep_control(ep); | ||
| 2225 | pch_udc_ep_fifo_flush(ep, ep->in); | ||
| 2226 | pch_udc_ep_set_bufsz(ep, UDC_EP0IN_BUFF_SIZE, ep->in); | ||
| 2227 | pch_udc_ep_set_maxpkt(ep, UDC_EP0IN_MAX_PKT_SIZE); | ||
| 2228 | /* Initialize the IN EP Descriptor */ | ||
| 2229 | ep->td_data = NULL; | ||
| 2230 | ep->td_stp = NULL; | ||
| 2231 | ep->td_data_phys = 0; | ||
| 2232 | ep->td_stp_phys = 0; | ||
| 2233 | |||
| 2234 | /* Setup the OUT endpoint */ | ||
| 2235 | ep = &dev->ep[UDC_EP0OUT_IDX]; | ||
| 2236 | pch_udc_clear_ep_control(ep); | ||
| 2237 | pch_udc_ep_fifo_flush(ep, ep->in); | ||
| 2238 | pch_udc_ep_set_bufsz(ep, UDC_EP0OUT_BUFF_SIZE, ep->in); | ||
| 2239 | pch_udc_ep_set_maxpkt(ep, UDC_EP0OUT_MAX_PKT_SIZE); | ||
| 2240 | val = UDC_EP0OUT_MAX_PKT_SIZE << UDC_CSR_NE_MAX_PKT_SHIFT; | ||
| 2241 | pch_udc_write_csr(ep->dev, val, UDC_EP0OUT_IDX); | ||
| 2242 | |||
| 2243 | /* Initialize the SETUP buffer */ | ||
| 2244 | pch_udc_init_setup_buff(ep->td_stp); | ||
| 2245 | /* Write the pointer address of dma descriptor */ | ||
| 2246 | pch_udc_ep_set_subptr(ep, ep->td_stp_phys); | ||
| 2247 | /* Write the pointer address of Setup descriptor */ | ||
| 2248 | pch_udc_ep_set_ddptr(ep, ep->td_data_phys); | ||
| 2249 | |||
| 2250 | /* Initialize the dma descriptor */ | ||
| 2251 | ep->td_data->status = PCH_UDC_DMA_LAST; | ||
| 2252 | ep->td_data->dataptr = dev->dma_addr; | ||
| 2253 | ep->td_data->next = ep->td_data_phys; | ||
| 2254 | |||
| 2255 | pch_udc_ep_clear_nak(ep); | ||
| 2256 | } | ||
| 2257 | |||
| 2258 | |||
| 2259 | /** | ||
| 2260 | * pch_udc_svc_ur_interrupt() - This function handles a USB reset interrupt | ||
| 2261 | * @dev: Reference to driver structure | ||
| 2262 | */ | ||
| 2263 | static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev) | ||
| 2264 | { | ||
| 2265 | struct pch_udc_ep *ep; | ||
| 2266 | int i; | ||
| 2267 | |||
| 2268 | pch_udc_clear_dma(dev, DMA_DIR_TX); | ||
| 2269 | pch_udc_clear_dma(dev, DMA_DIR_RX); | ||
| 2270 | /* Mask all endpoint interrupts */ | ||
| 2271 | pch_udc_disable_ep_interrupts(dev, UDC_EPINT_MSK_DISABLE_ALL); | ||
| 2272 | /* clear all endpoint interrupts */ | ||
| 2273 | pch_udc_write_ep_interrupts(dev, UDC_EPINT_MSK_DISABLE_ALL); | ||
| 2274 | |||
| 2275 | for (i = 0; i < PCH_UDC_EP_NUM; i++) { | ||
| 2276 | ep = &dev->ep[i]; | ||
| 2277 | pch_udc_clear_ep_status(ep, UDC_EPSTS_ALL_CLR_MASK); | ||
| 2278 | pch_udc_clear_ep_control(ep); | ||
| 2279 | pch_udc_ep_set_ddptr(ep, 0); | ||
| 2280 | pch_udc_write_csr(ep->dev, 0x00, i); | ||
| 2281 | } | ||
| 2282 | dev->stall = 0; | ||
| 2283 | dev->prot_stall = 0; | ||
| 2284 | dev->waiting_zlp_ack = 0; | ||
| 2285 | dev->set_cfg_not_acked = 0; | ||
| 2286 | |||
| 2287 | /* disable ep to empty req queue. Skip the control EP's */ | ||
| 2288 | for (i = 0; i < (PCH_UDC_USED_EP_NUM*2); i++) { | ||
| 2289 | ep = &dev->ep[i]; | ||
| 2290 | pch_udc_ep_set_nak(ep); | ||
| 2291 | pch_udc_ep_fifo_flush(ep, ep->in); | ||
| 2292 | /* Complete request queue */ | ||
| 2293 | empty_req_queue(ep); | ||
| 2294 | } | ||
| 2295 | if (dev->driver && dev->driver->disconnect) | ||
| 2296 | dev->driver->disconnect(&dev->gadget); | ||
| 2297 | } | ||
| 2298 | |||
| 2299 | /** | ||
| 2300 | * pch_udc_svc_enum_interrupt() - This function handles a USB speed enumeration | ||
| 2301 | * done interrupt | ||
| 2302 | * @dev: Reference to driver structure | ||
| 2303 | */ | ||
| 2304 | static void pch_udc_svc_enum_interrupt(struct pch_udc_dev *dev) | ||
| 2305 | { | ||
| 2306 | u32 dev_stat, dev_speed; | ||
| 2307 | u32 speed = USB_SPEED_FULL; | ||
| 2308 | |||
| 2309 | dev_stat = pch_udc_read_device_status(dev); | ||
| 2310 | dev_speed = (dev_stat & UDC_DEVSTS_ENUM_SPEED_MASK) >> | ||
| 2311 | UDC_DEVSTS_ENUM_SPEED_SHIFT; | ||
| 2312 | switch (dev_speed) { | ||
| 2313 | case UDC_DEVSTS_ENUM_SPEED_HIGH: | ||
| 2314 | speed = USB_SPEED_HIGH; | ||
| 2315 | break; | ||
| 2316 | case UDC_DEVSTS_ENUM_SPEED_FULL: | ||
| 2317 | speed = USB_SPEED_FULL; | ||
| 2318 | break; | ||
| 2319 | case UDC_DEVSTS_ENUM_SPEED_LOW: | ||
| 2320 | speed = USB_SPEED_LOW; | ||
| 2321 | break; | ||
| 2322 | default: | ||
| 2323 | BUG(); | ||
| 2324 | } | ||
| 2325 | dev->gadget.speed = speed; | ||
| 2326 | pch_udc_activate_control_ep(dev); | ||
| 2327 | pch_udc_enable_ep_interrupts(dev, UDC_EPINT_IN_EP0 | UDC_EPINT_OUT_EP0); | ||
| 2328 | pch_udc_set_dma(dev, DMA_DIR_TX); | ||
| 2329 | pch_udc_set_dma(dev, DMA_DIR_RX); | ||
| 2330 | pch_udc_ep_set_rrdy(&(dev->ep[UDC_EP0OUT_IDX])); | ||
| 2331 | } | ||
| 2332 | |||
| 2333 | /** | ||
| 2334 | * pch_udc_svc_intf_interrupt() - This function handles a set interface | ||
| 2335 | * interrupt | ||
| 2336 | * @dev: Reference to driver structure | ||
| 2337 | */ | ||
| 2338 | static void pch_udc_svc_intf_interrupt(struct pch_udc_dev *dev) | ||
| 2339 | { | ||
| 2340 | u32 reg, dev_stat = 0; | ||
| 2341 | int i, ret; | ||
| 2342 | |||
| 2343 | dev_stat = pch_udc_read_device_status(dev); | ||
| 2344 | dev->cfg_data.cur_intf = (dev_stat & UDC_DEVSTS_INTF_MASK) >> | ||
| 2345 | UDC_DEVSTS_INTF_SHIFT; | ||
| 2346 | dev->cfg_data.cur_alt = (dev_stat & UDC_DEVSTS_ALT_MASK) >> | ||
| 2347 | UDC_DEVSTS_ALT_SHIFT; | ||
| 2348 | dev->set_cfg_not_acked = 1; | ||
| 2349 | /* Construct the usb request for gadget driver and inform it */ | ||
| 2350 | memset(&dev->setup_data, 0 , sizeof dev->setup_data); | ||
| 2351 | dev->setup_data.bRequest = USB_REQ_SET_INTERFACE; | ||
| 2352 | dev->setup_data.bRequestType = USB_RECIP_INTERFACE; | ||
| 2353 | dev->setup_data.wValue = cpu_to_le16(dev->cfg_data.cur_alt); | ||
| 2354 | dev->setup_data.wIndex = cpu_to_le16(dev->cfg_data.cur_intf); | ||
| 2355 | /* programm the Endpoint Cfg registers */ | ||
| 2356 | /* Only one end point cfg register */ | ||
| 2357 | reg = pch_udc_read_csr(dev, UDC_EP0OUT_IDX); | ||
| 2358 | reg = (reg & ~UDC_CSR_NE_INTF_MASK) | | ||
| 2359 | (dev->cfg_data.cur_intf << UDC_CSR_NE_INTF_SHIFT); | ||
| 2360 | reg = (reg & ~UDC_CSR_NE_ALT_MASK) | | ||
| 2361 | (dev->cfg_data.cur_alt << UDC_CSR_NE_ALT_SHIFT); | ||
| 2362 | pch_udc_write_csr(dev, reg, UDC_EP0OUT_IDX); | ||
| 2363 | for (i = 0; i < PCH_UDC_USED_EP_NUM * 2; i++) { | ||
| 2364 | /* clear stall bits */ | ||
| 2365 | pch_udc_ep_clear_stall(&(dev->ep[i])); | ||
| 2366 | dev->ep[i].halted = 0; | ||
| 2367 | } | ||
| 2368 | dev->stall = 0; | ||
| 2369 | spin_unlock(&dev->lock); | ||
| 2370 | ret = dev->driver->setup(&dev->gadget, &dev->setup_data); | ||
| 2371 | spin_lock(&dev->lock); | ||
| 2372 | } | ||
| 2373 | |||
| 2374 | /** | ||
| 2375 | * pch_udc_svc_cfg_interrupt() - This function handles a set configuration | ||
| 2376 | * interrupt | ||
| 2377 | * @dev: Reference to driver structure | ||
| 2378 | */ | ||
| 2379 | static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev) | ||
| 2380 | { | ||
| 2381 | int i, ret; | ||
| 2382 | u32 reg, dev_stat = 0; | ||
| 2383 | |||
| 2384 | dev_stat = pch_udc_read_device_status(dev); | ||
| 2385 | dev->set_cfg_not_acked = 1; | ||
| 2386 | dev->cfg_data.cur_cfg = (dev_stat & UDC_DEVSTS_CFG_MASK) >> | ||
| 2387 | UDC_DEVSTS_CFG_SHIFT; | ||
| 2388 | /* make usb request for gadget driver */ | ||
| 2389 | memset(&dev->setup_data, 0 , sizeof dev->setup_data); | ||
| 2390 | dev->setup_data.bRequest = USB_REQ_SET_CONFIGURATION; | ||
| 2391 | dev->setup_data.wValue = cpu_to_le16(dev->cfg_data.cur_cfg); | ||
| 2392 | /* program the NE registers */ | ||
| 2393 | /* Only one end point cfg register */ | ||
| 2394 | reg = pch_udc_read_csr(dev, UDC_EP0OUT_IDX); | ||
| 2395 | reg = (reg & ~UDC_CSR_NE_CFG_MASK) | | ||
| 2396 | (dev->cfg_data.cur_cfg << UDC_CSR_NE_CFG_SHIFT); | ||
| 2397 | pch_udc_write_csr(dev, reg, UDC_EP0OUT_IDX); | ||
| 2398 | for (i = 0; i < PCH_UDC_USED_EP_NUM * 2; i++) { | ||
| 2399 | /* clear stall bits */ | ||
| 2400 | pch_udc_ep_clear_stall(&(dev->ep[i])); | ||
| 2401 | dev->ep[i].halted = 0; | ||
| 2402 | } | ||
| 2403 | dev->stall = 0; | ||
| 2404 | |||
| 2405 | /* call gadget zero with setup data received */ | ||
| 2406 | spin_unlock(&dev->lock); | ||
| 2407 | ret = dev->driver->setup(&dev->gadget, &dev->setup_data); | ||
| 2408 | spin_lock(&dev->lock); | ||
| 2409 | } | ||
| 2410 | |||
| 2411 | /** | ||
| 2412 | * pch_udc_dev_isr() - This function services device interrupts | ||
| 2413 | * by invoking appropriate routines. | ||
| 2414 | * @dev: Reference to the device structure | ||
| 2415 | * @dev_intr: The Device interrupt status. | ||
| 2416 | */ | ||
| 2417 | static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) | ||
| 2418 | { | ||
| 2419 | /* USB Reset Interrupt */ | ||
| 2420 | if (dev_intr & UDC_DEVINT_UR) | ||
| 2421 | pch_udc_svc_ur_interrupt(dev); | ||
| 2422 | /* Enumeration Done Interrupt */ | ||
| 2423 | if (dev_intr & UDC_DEVINT_ENUM) | ||
| 2424 | pch_udc_svc_enum_interrupt(dev); | ||
| 2425 | /* Set Interface Interrupt */ | ||
| 2426 | if (dev_intr & UDC_DEVINT_SI) | ||
| 2427 | pch_udc_svc_intf_interrupt(dev); | ||
| 2428 | /* Set Config Interrupt */ | ||
| 2429 | if (dev_intr & UDC_DEVINT_SC) | ||
| 2430 | pch_udc_svc_cfg_interrupt(dev); | ||
| 2431 | /* USB Suspend interrupt */ | ||
| 2432 | if (dev_intr & UDC_DEVINT_US) | ||
| 2433 | dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); | ||
| 2434 | /* Clear the SOF interrupt, if enabled */ | ||
| 2435 | if (dev_intr & UDC_DEVINT_SOF) | ||
| 2436 | dev_dbg(&dev->pdev->dev, "SOF\n"); | ||
| 2437 | /* ES interrupt, IDLE > 3ms on the USB */ | ||
| 2438 | if (dev_intr & UDC_DEVINT_ES) | ||
| 2439 | dev_dbg(&dev->pdev->dev, "ES\n"); | ||
| 2440 | /* RWKP interrupt */ | ||
| 2441 | if (dev_intr & UDC_DEVINT_RWKP) | ||
| 2442 | dev_dbg(&dev->pdev->dev, "RWKP\n"); | ||
| 2443 | } | ||
| 2444 | |||
| 2445 | /** | ||
| 2446 | * pch_udc_isr() - This function handles interrupts from the PCH USB Device | ||
| 2447 | * @irq: Interrupt request number | ||
| 2448 | * @dev: Reference to the device structure | ||
| 2449 | */ | ||
| 2450 | static irqreturn_t pch_udc_isr(int irq, void *pdev) | ||
| 2451 | { | ||
| 2452 | struct pch_udc_dev *dev = (struct pch_udc_dev *) pdev; | ||
| 2453 | u32 dev_intr, ep_intr; | ||
| 2454 | int i; | ||
| 2455 | |||
| 2456 | dev_intr = pch_udc_read_device_interrupts(dev); | ||
| 2457 | ep_intr = pch_udc_read_ep_interrupts(dev); | ||
| 2458 | |||
| 2459 | if (dev_intr) | ||
| 2460 | /* Clear device interrupts */ | ||
| 2461 | pch_udc_write_device_interrupts(dev, dev_intr); | ||
| 2462 | if (ep_intr) | ||
| 2463 | /* Clear ep interrupts */ | ||
| 2464 | pch_udc_write_ep_interrupts(dev, ep_intr); | ||
| 2465 | if (!dev_intr && !ep_intr) | ||
| 2466 | return IRQ_NONE; | ||
| 2467 | spin_lock(&dev->lock); | ||
| 2468 | if (dev_intr) | ||
| 2469 | pch_udc_dev_isr(dev, dev_intr); | ||
| 2470 | if (ep_intr) { | ||
| 2471 | pch_udc_read_all_epstatus(dev, ep_intr); | ||
| 2472 | /* Process Control In interrupts, if present */ | ||
| 2473 | if (ep_intr & UDC_EPINT_IN_EP0) { | ||
| 2474 | pch_udc_svc_control_in(dev); | ||
| 2475 | pch_udc_postsvc_epinters(dev, 0); | ||
| 2476 | } | ||
| 2477 | /* Process Control Out interrupts, if present */ | ||
| 2478 | if (ep_intr & UDC_EPINT_OUT_EP0) | ||
| 2479 | pch_udc_svc_control_out(dev); | ||
| 2480 | /* Process data in end point interrupts */ | ||
| 2481 | for (i = 1; i < PCH_UDC_USED_EP_NUM; i++) { | ||
| 2482 | if (ep_intr & (1 << i)) { | ||
| 2483 | pch_udc_svc_data_in(dev, i); | ||
| 2484 | pch_udc_postsvc_epinters(dev, i); | ||
| 2485 | } | ||
| 2486 | } | ||
| 2487 | /* Process data out end point interrupts */ | ||
| 2488 | for (i = UDC_EPINT_OUT_SHIFT + 1; i < (UDC_EPINT_OUT_SHIFT + | ||
| 2489 | PCH_UDC_USED_EP_NUM); i++) | ||
| 2490 | if (ep_intr & (1 << i)) | ||
| 2491 | pch_udc_svc_data_out(dev, i - | ||
| 2492 | UDC_EPINT_OUT_SHIFT); | ||
| 2493 | } | ||
| 2494 | spin_unlock(&dev->lock); | ||
| 2495 | return IRQ_HANDLED; | ||
| 2496 | } | ||
| 2497 | |||
| 2498 | /** | ||
| 2499 | * pch_udc_setup_ep0() - This function enables control endpoint for traffic | ||
| 2500 | * @dev: Reference to the device structure | ||
| 2501 | */ | ||
| 2502 | static void pch_udc_setup_ep0(struct pch_udc_dev *dev) | ||
| 2503 | { | ||
| 2504 | /* enable ep0 interrupts */ | ||
| 2505 | pch_udc_enable_ep_interrupts(dev, UDC_EPINT_IN_EP0 | | ||
| 2506 | UDC_EPINT_OUT_EP0); | ||
| 2507 | /* enable device interrupts */ | ||
| 2508 | pch_udc_enable_interrupts(dev, UDC_DEVINT_UR | UDC_DEVINT_US | | ||
| 2509 | UDC_DEVINT_ES | UDC_DEVINT_ENUM | | ||
| 2510 | UDC_DEVINT_SI | UDC_DEVINT_SC); | ||
| 2511 | } | ||
| 2512 | |||
| 2513 | /** | ||
| 2514 | * gadget_release() - Free the gadget driver private data | ||
| 2515 | * @pdev reference to struct pci_dev | ||
| 2516 | */ | ||
| 2517 | static void gadget_release(struct device *pdev) | ||
| 2518 | { | ||
| 2519 | struct pch_udc_dev *dev = dev_get_drvdata(pdev); | ||
| 2520 | |||
| 2521 | kfree(dev); | ||
| 2522 | } | ||
| 2523 | |||
| 2524 | /** | ||
| 2525 | * pch_udc_pcd_reinit() - This API initializes the endpoint structures | ||
| 2526 | * @dev: Reference to the driver structure | ||
| 2527 | */ | ||
| 2528 | static void pch_udc_pcd_reinit(struct pch_udc_dev *dev) | ||
| 2529 | { | ||
| 2530 | const char *const ep_string[] = { | ||
| 2531 | ep0_string, "ep0out", "ep1in", "ep1out", "ep2in", "ep2out", | ||
| 2532 | "ep3in", "ep3out", "ep4in", "ep4out", "ep5in", "ep5out", | ||
| 2533 | "ep6in", "ep6out", "ep7in", "ep7out", "ep8in", "ep8out", | ||
| 2534 | "ep9in", "ep9out", "ep10in", "ep10out", "ep11in", "ep11out", | ||
| 2535 | "ep12in", "ep12out", "ep13in", "ep13out", "ep14in", "ep14out", | ||
| 2536 | "ep15in", "ep15out", | ||
| 2537 | }; | ||
| 2538 | int i; | ||
| 2539 | |||
| 2540 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 2541 | INIT_LIST_HEAD(&dev->gadget.ep_list); | ||
| 2542 | |||
| 2543 | /* Initialize the endpoints structures */ | ||
| 2544 | memset(dev->ep, 0, sizeof dev->ep); | ||
| 2545 | for (i = 0; i < PCH_UDC_EP_NUM; i++) { | ||
| 2546 | struct pch_udc_ep *ep = &dev->ep[i]; | ||
| 2547 | ep->dev = dev; | ||
| 2548 | ep->halted = 1; | ||
| 2549 | ep->num = i / 2; | ||
| 2550 | ep->in = ~i & 1; | ||
| 2551 | ep->ep.name = ep_string[i]; | ||
| 2552 | ep->ep.ops = &pch_udc_ep_ops; | ||
| 2553 | if (ep->in) | ||
| 2554 | ep->offset_addr = ep->num * UDC_EP_REG_SHIFT; | ||
| 2555 | else | ||
| 2556 | ep->offset_addr = (UDC_EPINT_OUT_SHIFT + ep->num) * | ||
| 2557 | UDC_EP_REG_SHIFT; | ||
| 2558 | /* need to set ep->ep.maxpacket and set Default Configuration?*/ | ||
| 2559 | ep->ep.maxpacket = UDC_BULK_MAX_PKT_SIZE; | ||
| 2560 | list_add_tail(&ep->ep.ep_list, &dev->gadget.ep_list); | ||
| 2561 | INIT_LIST_HEAD(&ep->queue); | ||
| 2562 | } | ||
| 2563 | dev->ep[UDC_EP0IN_IDX].ep.maxpacket = UDC_EP0IN_MAX_PKT_SIZE; | ||
| 2564 | dev->ep[UDC_EP0OUT_IDX].ep.maxpacket = UDC_EP0OUT_MAX_PKT_SIZE; | ||
| 2565 | |||
| 2566 | dev->dma_addr = pci_map_single(dev->pdev, dev->ep0out_buf, 256, | ||
| 2567 | PCI_DMA_FROMDEVICE); | ||
| 2568 | |||
| 2569 | /* remove ep0 in and out from the list. They have own pointer */ | ||
| 2570 | list_del_init(&dev->ep[UDC_EP0IN_IDX].ep.ep_list); | ||
| 2571 | list_del_init(&dev->ep[UDC_EP0OUT_IDX].ep.ep_list); | ||
| 2572 | |||
| 2573 | dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IDX].ep; | ||
| 2574 | INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); | ||
| 2575 | } | ||
| 2576 | |||
| 2577 | /** | ||
| 2578 | * pch_udc_pcd_init() - This API initializes the driver structure | ||
| 2579 | * @dev: Reference to the driver structure | ||
| 2580 | * | ||
| 2581 | * Return codes: | ||
| 2582 | * 0: Success | ||
| 2583 | */ | ||
| 2584 | static int pch_udc_pcd_init(struct pch_udc_dev *dev) | ||
| 2585 | { | ||
| 2586 | pch_udc_init(dev); | ||
| 2587 | pch_udc_pcd_reinit(dev); | ||
| 2588 | return 0; | ||
| 2589 | } | ||
| 2590 | |||
| 2591 | /** | ||
| 2592 | * init_dma_pools() - create dma pools during initialization | ||
| 2593 | * @pdev: reference to struct pci_dev | ||
| 2594 | */ | ||
| 2595 | static int init_dma_pools(struct pch_udc_dev *dev) | ||
| 2596 | { | ||
| 2597 | struct pch_udc_stp_dma_desc *td_stp; | ||
| 2598 | struct pch_udc_data_dma_desc *td_data; | ||
| 2599 | |||
| 2600 | /* DMA setup */ | ||
| 2601 | dev->data_requests = pci_pool_create("data_requests", dev->pdev, | ||
| 2602 | sizeof(struct pch_udc_data_dma_desc), 0, 0); | ||
| 2603 | if (!dev->data_requests) { | ||
| 2604 | dev_err(&dev->pdev->dev, "%s: can't get request data pool\n", | ||
| 2605 | __func__); | ||
| 2606 | return -ENOMEM; | ||
| 2607 | } | ||
| 2608 | |||
| 2609 | /* dma desc for setup data */ | ||
| 2610 | dev->stp_requests = pci_pool_create("setup requests", dev->pdev, | ||
| 2611 | sizeof(struct pch_udc_stp_dma_desc), 0, 0); | ||
| 2612 | if (!dev->stp_requests) { | ||
| 2613 | dev_err(&dev->pdev->dev, "%s: can't get setup request pool\n", | ||
| 2614 | __func__); | ||
| 2615 | return -ENOMEM; | ||
| 2616 | } | ||
| 2617 | /* setup */ | ||
| 2618 | td_stp = pci_pool_alloc(dev->stp_requests, GFP_KERNEL, | ||
| 2619 | &dev->ep[UDC_EP0OUT_IDX].td_stp_phys); | ||
| 2620 | if (!td_stp) { | ||
| 2621 | dev_err(&dev->pdev->dev, | ||
| 2622 | "%s: can't allocate setup dma descriptor\n", __func__); | ||
| 2623 | return -ENOMEM; | ||
| 2624 | } | ||
| 2625 | dev->ep[UDC_EP0OUT_IDX].td_stp = td_stp; | ||
| 2626 | |||
| 2627 | /* data: 0 packets !? */ | ||
| 2628 | td_data = pci_pool_alloc(dev->data_requests, GFP_KERNEL, | ||
| 2629 | &dev->ep[UDC_EP0OUT_IDX].td_data_phys); | ||
| 2630 | if (!td_data) { | ||
| 2631 | dev_err(&dev->pdev->dev, | ||
| 2632 | "%s: can't allocate data dma descriptor\n", __func__); | ||
| 2633 | return -ENOMEM; | ||
| 2634 | } | ||
| 2635 | dev->ep[UDC_EP0OUT_IDX].td_data = td_data; | ||
| 2636 | dev->ep[UDC_EP0IN_IDX].td_stp = NULL; | ||
| 2637 | dev->ep[UDC_EP0IN_IDX].td_stp_phys = 0; | ||
| 2638 | dev->ep[UDC_EP0IN_IDX].td_data = NULL; | ||
| 2639 | dev->ep[UDC_EP0IN_IDX].td_data_phys = 0; | ||
| 2640 | return 0; | ||
| 2641 | } | ||
| 2642 | |||
| 2643 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | ||
| 2644 | int (*bind)(struct usb_gadget *)) | ||
| 2645 | { | ||
| 2646 | struct pch_udc_dev *dev = pch_udc; | ||
| 2647 | int retval; | ||
| 2648 | |||
| 2649 | if (!driver || (driver->speed == USB_SPEED_UNKNOWN) || !bind || | ||
| 2650 | !driver->setup || !driver->unbind || !driver->disconnect) { | ||
| 2651 | dev_err(&dev->pdev->dev, | ||
| 2652 | "%s: invalid driver parameter\n", __func__); | ||
| 2653 | return -EINVAL; | ||
| 2654 | } | ||
| 2655 | |||
| 2656 | if (!dev) | ||
| 2657 | return -ENODEV; | ||
| 2658 | |||
| 2659 | if (dev->driver) { | ||
| 2660 | dev_err(&dev->pdev->dev, "%s: already bound\n", __func__); | ||
| 2661 | return -EBUSY; | ||
| 2662 | } | ||
| 2663 | driver->driver.bus = NULL; | ||
| 2664 | dev->driver = driver; | ||
| 2665 | dev->gadget.dev.driver = &driver->driver; | ||
| 2666 | |||
| 2667 | /* Invoke the bind routine of the gadget driver */ | ||
| 2668 | retval = bind(&dev->gadget); | ||
| 2669 | |||
| 2670 | if (retval) { | ||
| 2671 | dev_err(&dev->pdev->dev, "%s: binding to %s returning %d\n", | ||
| 2672 | __func__, driver->driver.name, retval); | ||
| 2673 | dev->driver = NULL; | ||
| 2674 | dev->gadget.dev.driver = NULL; | ||
| 2675 | return retval; | ||
| 2676 | } | ||
| 2677 | /* get ready for ep0 traffic */ | ||
| 2678 | pch_udc_setup_ep0(dev); | ||
| 2679 | |||
| 2680 | /* clear SD */ | ||
| 2681 | pch_udc_clear_disconnect(dev); | ||
| 2682 | |||
| 2683 | dev->connected = 1; | ||
| 2684 | return 0; | ||
| 2685 | } | ||
| 2686 | EXPORT_SYMBOL(usb_gadget_probe_driver); | ||
| 2687 | |||
| 2688 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
| 2689 | { | ||
| 2690 | struct pch_udc_dev *dev = pch_udc; | ||
| 2691 | |||
| 2692 | if (!dev) | ||
| 2693 | return -ENODEV; | ||
| 2694 | |||
| 2695 | if (!driver || (driver != dev->driver)) { | ||
| 2696 | dev_err(&dev->pdev->dev, | ||
| 2697 | "%s: invalid driver parameter\n", __func__); | ||
| 2698 | return -EINVAL; | ||
| 2699 | } | ||
| 2700 | |||
| 2701 | pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); | ||
| 2702 | |||
| 2703 | /* Assues that there are no pending requets with this driver */ | ||
| 2704 | driver->unbind(&dev->gadget); | ||
| 2705 | dev->gadget.dev.driver = NULL; | ||
| 2706 | dev->driver = NULL; | ||
| 2707 | dev->connected = 0; | ||
| 2708 | |||
| 2709 | /* set SD */ | ||
| 2710 | pch_udc_set_disconnect(dev); | ||
| 2711 | return 0; | ||
| 2712 | } | ||
| 2713 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
| 2714 | |||
| 2715 | static void pch_udc_shutdown(struct pci_dev *pdev) | ||
| 2716 | { | ||
| 2717 | struct pch_udc_dev *dev = pci_get_drvdata(pdev); | ||
| 2718 | |||
| 2719 | pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); | ||
| 2720 | pch_udc_disable_ep_interrupts(dev, UDC_EPINT_MSK_DISABLE_ALL); | ||
| 2721 | |||
| 2722 | /* disable the pullup so the host will think we're gone */ | ||
| 2723 | pch_udc_set_disconnect(dev); | ||
| 2724 | } | ||
| 2725 | |||
| 2726 | static void pch_udc_remove(struct pci_dev *pdev) | ||
| 2727 | { | ||
| 2728 | struct pch_udc_dev *dev = pci_get_drvdata(pdev); | ||
| 2729 | |||
| 2730 | /* gadget driver must not be registered */ | ||
| 2731 | if (dev->driver) | ||
| 2732 | dev_err(&pdev->dev, | ||
| 2733 | "%s: gadget driver still bound!!!\n", __func__); | ||
| 2734 | /* dma pool cleanup */ | ||
| 2735 | if (dev->data_requests) | ||
| 2736 | pci_pool_destroy(dev->data_requests); | ||
| 2737 | |||
| 2738 | if (dev->stp_requests) { | ||
| 2739 | /* cleanup DMA desc's for ep0in */ | ||
| 2740 | if (dev->ep[UDC_EP0OUT_IDX].td_stp) { | ||
| 2741 | pci_pool_free(dev->stp_requests, | ||
| 2742 | dev->ep[UDC_EP0OUT_IDX].td_stp, | ||
| 2743 | dev->ep[UDC_EP0OUT_IDX].td_stp_phys); | ||
| 2744 | } | ||
| 2745 | if (dev->ep[UDC_EP0OUT_IDX].td_data) { | ||
| 2746 | pci_pool_free(dev->stp_requests, | ||
| 2747 | dev->ep[UDC_EP0OUT_IDX].td_data, | ||
| 2748 | dev->ep[UDC_EP0OUT_IDX].td_data_phys); | ||
| 2749 | } | ||
| 2750 | pci_pool_destroy(dev->stp_requests); | ||
| 2751 | } | ||
| 2752 | |||
| 2753 | pch_udc_exit(dev); | ||
| 2754 | |||
| 2755 | if (dev->irq_registered) | ||
| 2756 | free_irq(pdev->irq, dev); | ||
| 2757 | if (dev->base_addr) | ||
| 2758 | iounmap(dev->base_addr); | ||
| 2759 | if (dev->mem_region) | ||
| 2760 | release_mem_region(dev->phys_addr, | ||
| 2761 | pci_resource_len(pdev, PCH_UDC_PCI_BAR)); | ||
| 2762 | if (dev->active) | ||
| 2763 | pci_disable_device(pdev); | ||
| 2764 | if (dev->registered) | ||
| 2765 | device_unregister(&dev->gadget.dev); | ||
| 2766 | kfree(dev); | ||
| 2767 | pci_set_drvdata(pdev, NULL); | ||
| 2768 | } | ||
| 2769 | |||
| 2770 | #ifdef CONFIG_PM | ||
| 2771 | static int pch_udc_suspend(struct pci_dev *pdev, pm_message_t state) | ||
| 2772 | { | ||
| 2773 | struct pch_udc_dev *dev = pci_get_drvdata(pdev); | ||
| 2774 | |||
| 2775 | pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); | ||
| 2776 | pch_udc_disable_ep_interrupts(dev, UDC_EPINT_MSK_DISABLE_ALL); | ||
| 2777 | |||
| 2778 | pci_disable_device(pdev); | ||
| 2779 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
| 2780 | |||
| 2781 | if (pci_save_state(pdev)) { | ||
| 2782 | dev_err(&pdev->dev, | ||
| 2783 | "%s: could not save PCI config state\n", __func__); | ||
| 2784 | return -ENOMEM; | ||
| 2785 | } | ||
| 2786 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
| 2787 | return 0; | ||
| 2788 | } | ||
| 2789 | |||
| 2790 | static int pch_udc_resume(struct pci_dev *pdev) | ||
| 2791 | { | ||
| 2792 | int ret; | ||
| 2793 | |||
| 2794 | pci_set_power_state(pdev, PCI_D0); | ||
| 2795 | ret = pci_restore_state(pdev); | ||
| 2796 | if (ret) { | ||
| 2797 | dev_err(&pdev->dev, "%s: pci_restore_state failed\n", __func__); | ||
| 2798 | return ret; | ||
| 2799 | } | ||
| 2800 | ret = pci_enable_device(pdev); | ||
| 2801 | if (ret) { | ||
| 2802 | dev_err(&pdev->dev, "%s: pci_enable_device failed\n", __func__); | ||
| 2803 | return ret; | ||
| 2804 | } | ||
| 2805 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
| 2806 | return 0; | ||
| 2807 | } | ||
| 2808 | #else | ||
| 2809 | #define pch_udc_suspend NULL | ||
| 2810 | #define pch_udc_resume NULL | ||
| 2811 | #endif /* CONFIG_PM */ | ||
| 2812 | |||
| 2813 | static int pch_udc_probe(struct pci_dev *pdev, | ||
| 2814 | const struct pci_device_id *id) | ||
| 2815 | { | ||
| 2816 | unsigned long resource; | ||
| 2817 | unsigned long len; | ||
| 2818 | int retval; | ||
| 2819 | struct pch_udc_dev *dev; | ||
| 2820 | |||
| 2821 | /* one udc only */ | ||
| 2822 | if (pch_udc) { | ||
| 2823 | pr_err("%s: already probed\n", __func__); | ||
| 2824 | return -EBUSY; | ||
| 2825 | } | ||
| 2826 | /* init */ | ||
| 2827 | dev = kzalloc(sizeof *dev, GFP_KERNEL); | ||
| 2828 | if (!dev) { | ||
| 2829 | pr_err("%s: no memory for device structure\n", __func__); | ||
| 2830 | return -ENOMEM; | ||
| 2831 | } | ||
| 2832 | /* pci setup */ | ||
| 2833 | if (pci_enable_device(pdev) < 0) { | ||
| 2834 | kfree(dev); | ||
| 2835 | pr_err("%s: pci_enable_device failed\n", __func__); | ||
| 2836 | return -ENODEV; | ||
| 2837 | } | ||
| 2838 | dev->active = 1; | ||
| 2839 | pci_set_drvdata(pdev, dev); | ||
| 2840 | |||
| 2841 | /* PCI resource allocation */ | ||
| 2842 | resource = pci_resource_start(pdev, 1); | ||
| 2843 | len = pci_resource_len(pdev, 1); | ||
| 2844 | |||
| 2845 | if (!request_mem_region(resource, len, KBUILD_MODNAME)) { | ||
| 2846 | dev_err(&pdev->dev, "%s: pci device used already\n", __func__); | ||
| 2847 | retval = -EBUSY; | ||
| 2848 | goto finished; | ||
| 2849 | } | ||
| 2850 | dev->phys_addr = resource; | ||
| 2851 | dev->mem_region = 1; | ||
| 2852 | |||
| 2853 | dev->base_addr = ioremap_nocache(resource, len); | ||
| 2854 | if (!dev->base_addr) { | ||
| 2855 | pr_err("%s: device memory cannot be mapped\n", __func__); | ||
| 2856 | retval = -ENOMEM; | ||
| 2857 | goto finished; | ||
| 2858 | } | ||
| 2859 | if (!pdev->irq) { | ||
| 2860 | dev_err(&pdev->dev, "%s: irq not set\n", __func__); | ||
| 2861 | retval = -ENODEV; | ||
| 2862 | goto finished; | ||
| 2863 | } | ||
| 2864 | pch_udc = dev; | ||
| 2865 | /* initialize the hardware */ | ||
| 2866 | if (pch_udc_pcd_init(dev)) | ||
| 2867 | goto finished; | ||
| 2868 | if (request_irq(pdev->irq, pch_udc_isr, IRQF_SHARED, KBUILD_MODNAME, | ||
| 2869 | dev)) { | ||
| 2870 | dev_err(&pdev->dev, "%s: request_irq(%d) fail\n", __func__, | ||
| 2871 | pdev->irq); | ||
| 2872 | retval = -ENODEV; | ||
| 2873 | goto finished; | ||
| 2874 | } | ||
| 2875 | dev->irq = pdev->irq; | ||
| 2876 | dev->irq_registered = 1; | ||
| 2877 | |||
| 2878 | pci_set_master(pdev); | ||
| 2879 | pci_try_set_mwi(pdev); | ||
| 2880 | |||
| 2881 | /* device struct setup */ | ||
| 2882 | spin_lock_init(&dev->lock); | ||
| 2883 | dev->pdev = pdev; | ||
| 2884 | dev->gadget.ops = &pch_udc_ops; | ||
| 2885 | |||
| 2886 | retval = init_dma_pools(dev); | ||
| 2887 | if (retval) | ||
| 2888 | goto finished; | ||
| 2889 | |||
| 2890 | dev_set_name(&dev->gadget.dev, "gadget"); | ||
| 2891 | dev->gadget.dev.parent = &pdev->dev; | ||
| 2892 | dev->gadget.dev.dma_mask = pdev->dev.dma_mask; | ||
| 2893 | dev->gadget.dev.release = gadget_release; | ||
| 2894 | dev->gadget.name = KBUILD_MODNAME; | ||
| 2895 | dev->gadget.is_dualspeed = 1; | ||
| 2896 | |||
| 2897 | retval = device_register(&dev->gadget.dev); | ||
| 2898 | if (retval) | ||
| 2899 | goto finished; | ||
| 2900 | dev->registered = 1; | ||
| 2901 | |||
| 2902 | /* Put the device in disconnected state till a driver is bound */ | ||
| 2903 | pch_udc_set_disconnect(dev); | ||
| 2904 | return 0; | ||
| 2905 | |||
| 2906 | finished: | ||
| 2907 | pch_udc_remove(pdev); | ||
| 2908 | return retval; | ||
| 2909 | } | ||
| 2910 | |||
| 2911 | static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = { | ||
| 2912 | { | ||
| 2913 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EG20T_UDC), | ||
| 2914 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | ||
| 2915 | .class_mask = 0xffffffff, | ||
| 2916 | }, | ||
| 2917 | { 0 }, | ||
| 2918 | }; | ||
| 2919 | |||
| 2920 | MODULE_DEVICE_TABLE(pci, pch_udc_pcidev_id); | ||
| 2921 | |||
| 2922 | |||
| 2923 | static struct pci_driver pch_udc_driver = { | ||
| 2924 | .name = KBUILD_MODNAME, | ||
| 2925 | .id_table = pch_udc_pcidev_id, | ||
| 2926 | .probe = pch_udc_probe, | ||
| 2927 | .remove = pch_udc_remove, | ||
| 2928 | .suspend = pch_udc_suspend, | ||
| 2929 | .resume = pch_udc_resume, | ||
| 2930 | .shutdown = pch_udc_shutdown, | ||
| 2931 | }; | ||
| 2932 | |||
| 2933 | static int __init pch_udc_pci_init(void) | ||
| 2934 | { | ||
| 2935 | return pci_register_driver(&pch_udc_driver); | ||
| 2936 | } | ||
| 2937 | module_init(pch_udc_pci_init); | ||
| 2938 | |||
| 2939 | static void __exit pch_udc_pci_exit(void) | ||
| 2940 | { | ||
| 2941 | pci_unregister_driver(&pch_udc_driver); | ||
| 2942 | } | ||
| 2943 | module_exit(pch_udc_pci_exit); | ||
| 2944 | |||
| 2945 | MODULE_DESCRIPTION("Intel EG20T USB Device Controller"); | ||
| 2946 | MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>"); | ||
| 2947 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/u_audio.c b/drivers/usb/gadget/u_audio.c index 7a86d2c9109c..59ffe1ecf1c9 100644 --- a/drivers/usb/gadget/u_audio.c +++ b/drivers/usb/gadget/u_audio.c | |||
| @@ -255,6 +255,7 @@ static int gaudio_open_snd_dev(struct gaudio *card) | |||
| 255 | ERROR(card, "No such PCM capture device: %s\n", fn_cap); | 255 | ERROR(card, "No such PCM capture device: %s\n", fn_cap); |
| 256 | snd->substream = NULL; | 256 | snd->substream = NULL; |
| 257 | snd->card = NULL; | 257 | snd->card = NULL; |
| 258 | snd->filp = NULL; | ||
| 258 | } else { | 259 | } else { |
| 259 | pcm_file = snd->filp->private_data; | 260 | pcm_file = snd->filp->private_data; |
| 260 | snd->substream = pcm_file->substream; | 261 | snd->substream = pcm_file->substream; |
| @@ -273,17 +274,17 @@ static int gaudio_close_snd_dev(struct gaudio *gau) | |||
| 273 | 274 | ||
| 274 | /* Close control device */ | 275 | /* Close control device */ |
| 275 | snd = &gau->control; | 276 | snd = &gau->control; |
| 276 | if (!IS_ERR(snd->filp)) | 277 | if (snd->filp) |
| 277 | filp_close(snd->filp, current->files); | 278 | filp_close(snd->filp, current->files); |
| 278 | 279 | ||
| 279 | /* Close PCM playback device and setup substream */ | 280 | /* Close PCM playback device and setup substream */ |
| 280 | snd = &gau->playback; | 281 | snd = &gau->playback; |
| 281 | if (!IS_ERR(snd->filp)) | 282 | if (snd->filp) |
| 282 | filp_close(snd->filp, current->files); | 283 | filp_close(snd->filp, current->files); |
| 283 | 284 | ||
| 284 | /* Close PCM capture device and setup substream */ | 285 | /* Close PCM capture device and setup substream */ |
| 285 | snd = &gau->capture; | 286 | snd = &gau->capture; |
| 286 | if (!IS_ERR(snd->filp)) | 287 | if (snd->filp) |
| 287 | filp_close(snd->filp, current->files); | 288 | filp_close(snd->filp, current->files); |
| 288 | 289 | ||
| 289 | return 0; | 290 | return 0; |
| @@ -304,8 +305,7 @@ int __init gaudio_setup(struct gaudio *card) | |||
| 304 | ret = gaudio_open_snd_dev(card); | 305 | ret = gaudio_open_snd_dev(card); |
| 305 | if (ret) | 306 | if (ret) |
| 306 | ERROR(card, "we need at least one control device\n"); | 307 | ERROR(card, "we need at least one control device\n"); |
| 307 | 308 | else if (!the_card) | |
| 308 | if (!the_card) | ||
| 309 | the_card = card; | 309 | the_card = card; |
| 310 | 310 | ||
| 311 | return ret; | 311 | return ret; |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index fbe86ca95802..e3454fe46b47 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
| @@ -240,6 +240,9 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) | |||
| 240 | size += out->maxpacket - 1; | 240 | size += out->maxpacket - 1; |
| 241 | size -= size % out->maxpacket; | 241 | size -= size % out->maxpacket; |
| 242 | 242 | ||
| 243 | if (dev->port_usb->is_fixed) | ||
| 244 | size = max(size, dev->port_usb->fixed_out_len); | ||
| 245 | |||
| 243 | skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); | 246 | skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); |
| 244 | if (skb == NULL) { | 247 | if (skb == NULL) { |
| 245 | DBG(dev, "no rx skb\n"); | 248 | DBG(dev, "no rx skb\n"); |
| @@ -578,12 +581,19 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb, | |||
| 578 | req->context = skb; | 581 | req->context = skb; |
| 579 | req->complete = tx_complete; | 582 | req->complete = tx_complete; |
| 580 | 583 | ||
| 584 | /* NCM requires no zlp if transfer is dwNtbInMaxSize */ | ||
| 585 | if (dev->port_usb->is_fixed && | ||
| 586 | length == dev->port_usb->fixed_in_len && | ||
| 587 | (length % in->maxpacket) == 0) | ||
| 588 | req->zero = 0; | ||
| 589 | else | ||
| 590 | req->zero = 1; | ||
| 591 | |||
| 581 | /* use zlp framing on tx for strict CDC-Ether conformance, | 592 | /* use zlp framing on tx for strict CDC-Ether conformance, |
| 582 | * though any robust network rx path ignores extra padding. | 593 | * though any robust network rx path ignores extra padding. |
| 583 | * and some hardware doesn't like to write zlps. | 594 | * and some hardware doesn't like to write zlps. |
| 584 | */ | 595 | */ |
| 585 | req->zero = 1; | 596 | if (req->zero && !dev->zlp && (length % in->maxpacket) == 0) |
| 586 | if (!dev->zlp && (length % in->maxpacket) == 0) | ||
| 587 | length++; | 597 | length++; |
| 588 | 598 | ||
| 589 | req->length = length; | 599 | req->length = length; |
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h index 3c8c0c9f9d72..b56e1e7d423c 100644 --- a/drivers/usb/gadget/u_ether.h +++ b/drivers/usb/gadget/u_ether.h | |||
| @@ -62,6 +62,10 @@ struct gether { | |||
| 62 | 62 | ||
| 63 | /* hooks for added framing, as needed for RNDIS and EEM. */ | 63 | /* hooks for added framing, as needed for RNDIS and EEM. */ |
| 64 | u32 header_len; | 64 | u32 header_len; |
| 65 | /* NCM requires fixed size bundles */ | ||
| 66 | bool is_fixed; | ||
| 67 | u32 fixed_out_len; | ||
| 68 | u32 fixed_in_len; | ||
| 65 | struct sk_buff *(*wrap)(struct gether *port, | 69 | struct sk_buff *(*wrap)(struct gether *port, |
| 66 | struct sk_buff *skb); | 70 | struct sk_buff *skb); |
| 67 | int (*unwrap)(struct gether *port, | 71 | int (*unwrap)(struct gether *port, |
| @@ -103,6 +107,7 @@ static inline bool can_support_ecm(struct usb_gadget *gadget) | |||
| 103 | /* each configuration may bind one instance of an ethernet link */ | 107 | /* each configuration may bind one instance of an ethernet link */ |
| 104 | int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); | 108 | int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); |
| 105 | int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); | 109 | int ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); |
| 110 | int ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]); | ||
| 106 | int eem_bind_config(struct usb_configuration *c); | 111 | int eem_bind_config(struct usb_configuration *c); |
| 107 | 112 | ||
| 108 | #ifdef USB_ETH_RNDIS | 113 | #ifdef USB_ETH_RNDIS |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 6f4f8e6a40c7..fa3782a30f0a 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
| @@ -133,6 +133,25 @@ config USB_EHCI_MXC | |||
| 133 | ---help--- | 133 | ---help--- |
| 134 | Variation of ARC USB block used in some Freescale chips. | 134 | Variation of ARC USB block used in some Freescale chips. |
| 135 | 135 | ||
| 136 | config USB_EHCI_HCD_OMAP | ||
| 137 | bool "EHCI support for OMAP3 and later chips" | ||
| 138 | depends on USB_EHCI_HCD && ARCH_OMAP | ||
| 139 | default y | ||
| 140 | --- help --- | ||
| 141 | Enables support for the on-chip EHCI controller on | ||
| 142 | OMAP3 and later chips. | ||
| 143 | |||
| 144 | config USB_EHCI_MSM | ||
| 145 | bool "Support for MSM on-chip EHCI USB controller" | ||
| 146 | depends on USB_EHCI_HCD && ARCH_MSM | ||
| 147 | select USB_EHCI_ROOT_HUB_TT | ||
| 148 | select USB_MSM_OTG_72K | ||
| 149 | ---help--- | ||
| 150 | Enables support for the USB Host controller present on the | ||
| 151 | Qualcomm chipsets. Root Hub has inbuilt TT. | ||
| 152 | This driver depends on OTG driver for PHY initialization, | ||
| 153 | clock management, powering up VBUS, and power management. | ||
| 154 | |||
| 136 | config USB_EHCI_HCD_PPC_OF | 155 | config USB_EHCI_HCD_PPC_OF |
| 137 | bool "EHCI support for PPC USB controller on OF platform bus" | 156 | bool "EHCI support for PPC USB controller on OF platform bus" |
| 138 | depends on USB_EHCI_HCD && PPC_OF | 157 | depends on USB_EHCI_HCD && PPC_OF |
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 51bd0edf544f..d6a69d514a84 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c | |||
| @@ -99,6 +99,7 @@ static const struct hc_driver ehci_atmel_hc_driver = { | |||
| 99 | .urb_enqueue = ehci_urb_enqueue, | 99 | .urb_enqueue = ehci_urb_enqueue, |
| 100 | .urb_dequeue = ehci_urb_dequeue, | 100 | .urb_dequeue = ehci_urb_dequeue, |
| 101 | .endpoint_disable = ehci_endpoint_disable, | 101 | .endpoint_disable = ehci_endpoint_disable, |
| 102 | .endpoint_reset = ehci_endpoint_reset, | ||
| 102 | 103 | ||
| 103 | /* scheduling support */ | 104 | /* scheduling support */ |
| 104 | .get_frame_number = ehci_get_frame, | 105 | .get_frame_number = ehci_get_frame, |
| @@ -110,6 +111,8 @@ static const struct hc_driver ehci_atmel_hc_driver = { | |||
| 110 | .bus_resume = ehci_bus_resume, | 111 | .bus_resume = ehci_bus_resume, |
| 111 | .relinquish_port = ehci_relinquish_port, | 112 | .relinquish_port = ehci_relinquish_port, |
| 112 | .port_handed_over = ehci_port_handed_over, | 113 | .port_handed_over = ehci_port_handed_over, |
| 114 | |||
| 115 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 113 | }; | 116 | }; |
| 114 | 117 | ||
| 115 | static int __init ehci_atmel_drv_probe(struct platform_device *pdev) | 118 | static int __init ehci_atmel_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 6e2599661b5b..3be238a24cc5 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
| @@ -879,7 +879,7 @@ static int fill_buffer(struct debug_buffer *buf) | |||
| 879 | int ret = 0; | 879 | int ret = 0; |
| 880 | 880 | ||
| 881 | if (!buf->output_buf) | 881 | if (!buf->output_buf) |
| 882 | buf->output_buf = (char *)vmalloc(buf->alloc_size); | 882 | buf->output_buf = vmalloc(buf->alloc_size); |
| 883 | 883 | ||
| 884 | if (!buf->output_buf) { | 884 | if (!buf->output_buf) { |
| 885 | ret = -ENOMEM; | 885 | ret = -ENOMEM; |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index e9062806d4a2..72732daa3b3e 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
| @@ -114,6 +114,9 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us\n"); | |||
| 114 | 114 | ||
| 115 | #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) | 115 | #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) |
| 116 | 116 | ||
| 117 | /* for ASPM quirk of ISOC on AMD SB800 */ | ||
| 118 | static struct pci_dev *amd_nb_dev; | ||
| 119 | |||
| 117 | /*-------------------------------------------------------------------------*/ | 120 | /*-------------------------------------------------------------------------*/ |
| 118 | 121 | ||
| 119 | #include "ehci.h" | 122 | #include "ehci.h" |
| @@ -529,6 +532,11 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
| 529 | spin_unlock_irq (&ehci->lock); | 532 | spin_unlock_irq (&ehci->lock); |
| 530 | ehci_mem_cleanup (ehci); | 533 | ehci_mem_cleanup (ehci); |
| 531 | 534 | ||
| 535 | if (amd_nb_dev) { | ||
| 536 | pci_dev_put(amd_nb_dev); | ||
| 537 | amd_nb_dev = NULL; | ||
| 538 | } | ||
| 539 | |||
| 532 | #ifdef EHCI_STATS | 540 | #ifdef EHCI_STATS |
| 533 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", | 541 | ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", |
| 534 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, | 542 | ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, |
| @@ -1166,12 +1174,17 @@ MODULE_LICENSE ("GPL"); | |||
| 1166 | #define PLATFORM_DRIVER ehci_mxc_driver | 1174 | #define PLATFORM_DRIVER ehci_mxc_driver |
| 1167 | #endif | 1175 | #endif |
| 1168 | 1176 | ||
| 1177 | #ifdef CONFIG_CPU_SUBTYPE_SH7786 | ||
| 1178 | #include "ehci-sh.c" | ||
| 1179 | #define PLATFORM_DRIVER ehci_hcd_sh_driver | ||
| 1180 | #endif | ||
| 1181 | |||
| 1169 | #ifdef CONFIG_SOC_AU1200 | 1182 | #ifdef CONFIG_SOC_AU1200 |
| 1170 | #include "ehci-au1xxx.c" | 1183 | #include "ehci-au1xxx.c" |
| 1171 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver | 1184 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver |
| 1172 | #endif | 1185 | #endif |
| 1173 | 1186 | ||
| 1174 | #ifdef CONFIG_ARCH_OMAP3 | 1187 | #ifdef CONFIG_USB_EHCI_HCD_OMAP |
| 1175 | #include "ehci-omap.c" | 1188 | #include "ehci-omap.c" |
| 1176 | #define PLATFORM_DRIVER ehci_hcd_omap_driver | 1189 | #define PLATFORM_DRIVER ehci_hcd_omap_driver |
| 1177 | #endif | 1190 | #endif |
| @@ -1216,6 +1229,21 @@ MODULE_LICENSE ("GPL"); | |||
| 1216 | #define PLATFORM_DRIVER ehci_octeon_driver | 1229 | #define PLATFORM_DRIVER ehci_octeon_driver |
| 1217 | #endif | 1230 | #endif |
| 1218 | 1231 | ||
| 1232 | #ifdef CONFIG_ARCH_VT8500 | ||
| 1233 | #include "ehci-vt8500.c" | ||
| 1234 | #define PLATFORM_DRIVER vt8500_ehci_driver | ||
| 1235 | #endif | ||
| 1236 | |||
| 1237 | #ifdef CONFIG_PLAT_SPEAR | ||
| 1238 | #include "ehci-spear.c" | ||
| 1239 | #define PLATFORM_DRIVER spear_ehci_hcd_driver | ||
| 1240 | #endif | ||
| 1241 | |||
| 1242 | #ifdef CONFIG_USB_EHCI_MSM | ||
| 1243 | #include "ehci-msm.c" | ||
| 1244 | #define PLATFORM_DRIVER ehci_msm_driver | ||
| 1245 | #endif | ||
| 1246 | |||
| 1219 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ | 1247 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ |
| 1220 | !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ | 1248 | !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ |
| 1221 | !defined(XILINX_OF_PLATFORM_DRIVER) | 1249 | !defined(XILINX_OF_PLATFORM_DRIVER) |
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c new file mode 100644 index 000000000000..413f4deca532 --- /dev/null +++ b/drivers/usb/host/ehci-msm.c | |||
| @@ -0,0 +1,345 @@ | |||
| 1 | /* ehci-msm.c - HSUSB Host Controller Driver Implementation | ||
| 2 | * | ||
| 3 | * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. | ||
| 4 | * | ||
| 5 | * Partly derived from ehci-fsl.c and ehci-hcd.c | ||
| 6 | * Copyright (c) 2000-2004 by David Brownell | ||
| 7 | * Copyright (c) 2005 MontaVista Software | ||
| 8 | * | ||
| 9 | * All source code in this file is licensed under the following license except | ||
| 10 | * where indicated. | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify it | ||
| 13 | * under the terms of the GNU General Public License version 2 as published | ||
| 14 | * by the Free Software Foundation. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 19 | * | ||
| 20 | * See the GNU General Public License for more details. | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, you can find it at http://www.fsf.org | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/platform_device.h> | ||
| 26 | #include <linux/clk.h> | ||
| 27 | #include <linux/err.h> | ||
| 28 | #include <linux/pm_runtime.h> | ||
| 29 | |||
| 30 | #include <linux/usb/otg.h> | ||
| 31 | #include <linux/usb/msm_hsusb_hw.h> | ||
| 32 | |||
| 33 | #define MSM_USB_BASE (hcd->regs) | ||
| 34 | |||
| 35 | static struct otg_transceiver *otg; | ||
| 36 | |||
| 37 | /* | ||
| 38 | * ehci_run defined in drivers/usb/host/ehci-hcd.c reset the controller and | ||
| 39 | * the configuration settings in ehci_msm_reset vanish after controller is | ||
| 40 | * reset. Resetting the controler in ehci_run seems to be un-necessary | ||
| 41 | * provided HCD reset the controller before calling ehci_run. Most of the HCD | ||
| 42 | * do but some are not. So this function is same as ehci_run but we don't | ||
| 43 | * reset the controller here. | ||
| 44 | */ | ||
| 45 | static int ehci_msm_run(struct usb_hcd *hcd) | ||
| 46 | { | ||
| 47 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 48 | u32 temp; | ||
| 49 | u32 hcc_params; | ||
| 50 | |||
| 51 | hcd->uses_new_polling = 1; | ||
| 52 | |||
| 53 | ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); | ||
| 54 | ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); | ||
| 55 | |||
| 56 | /* | ||
| 57 | * hcc_params controls whether ehci->regs->segment must (!!!) | ||
| 58 | * be used; it constrains QH/ITD/SITD and QTD locations. | ||
| 59 | * pci_pool consistent memory always uses segment zero. | ||
| 60 | * streaming mappings for I/O buffers, like pci_map_single(), | ||
| 61 | * can return segments above 4GB, if the device allows. | ||
| 62 | * | ||
| 63 | * NOTE: the dma mask is visible through dma_supported(), so | ||
| 64 | * drivers can pass this info along ... like NETIF_F_HIGHDMA, | ||
| 65 | * Scsi_Host.highmem_io, and so forth. It's readonly to all | ||
| 66 | * host side drivers though. | ||
| 67 | */ | ||
| 68 | hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); | ||
| 69 | if (HCC_64BIT_ADDR(hcc_params)) | ||
| 70 | ehci_writel(ehci, 0, &ehci->regs->segment); | ||
| 71 | |||
| 72 | /* | ||
| 73 | * Philips, Intel, and maybe others need CMD_RUN before the | ||
| 74 | * root hub will detect new devices (why?); NEC doesn't | ||
| 75 | */ | ||
| 76 | ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); | ||
| 77 | ehci->command |= CMD_RUN; | ||
| 78 | ehci_writel(ehci, ehci->command, &ehci->regs->command); | ||
| 79 | dbg_cmd(ehci, "init", ehci->command); | ||
| 80 | |||
| 81 | /* | ||
| 82 | * Start, enabling full USB 2.0 functionality ... usb 1.1 devices | ||
| 83 | * are explicitly handed to companion controller(s), so no TT is | ||
| 84 | * involved with the root hub. (Except where one is integrated, | ||
| 85 | * and there's no companion controller unless maybe for USB OTG.) | ||
| 86 | * | ||
| 87 | * Turning on the CF flag will transfer ownership of all ports | ||
| 88 | * from the companions to the EHCI controller. If any of the | ||
| 89 | * companions are in the middle of a port reset at the time, it | ||
| 90 | * could cause trouble. Write-locking ehci_cf_port_reset_rwsem | ||
| 91 | * guarantees that no resets are in progress. After we set CF, | ||
| 92 | * a short delay lets the hardware catch up; new resets shouldn't | ||
| 93 | * be started before the port switching actions could complete. | ||
| 94 | */ | ||
| 95 | down_write(&ehci_cf_port_reset_rwsem); | ||
| 96 | hcd->state = HC_STATE_RUNNING; | ||
| 97 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); | ||
| 98 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ | ||
| 99 | usleep_range(5000, 5500); | ||
| 100 | up_write(&ehci_cf_port_reset_rwsem); | ||
| 101 | ehci->last_periodic_enable = ktime_get_real(); | ||
| 102 | |||
| 103 | temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
| 104 | ehci_info(ehci, | ||
| 105 | "USB %x.%x started, EHCI %x.%02x%s\n", | ||
| 106 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), | ||
| 107 | temp >> 8, temp & 0xff, | ||
| 108 | ignore_oc ? ", overcurrent ignored" : ""); | ||
| 109 | |||
| 110 | ehci_writel(ehci, INTR_MASK, | ||
| 111 | &ehci->regs->intr_enable); /* Turn On Interrupts */ | ||
| 112 | |||
| 113 | /* GRR this is run-once init(), being done every time the HC starts. | ||
| 114 | * So long as they're part of class devices, we can't do it init() | ||
| 115 | * since the class device isn't created that early. | ||
| 116 | */ | ||
| 117 | create_debug_files(ehci); | ||
| 118 | create_companion_file(ehci); | ||
| 119 | |||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int ehci_msm_reset(struct usb_hcd *hcd) | ||
| 124 | { | ||
| 125 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 126 | int retval; | ||
| 127 | |||
| 128 | ehci->caps = USB_CAPLENGTH; | ||
| 129 | ehci->regs = USB_CAPLENGTH + | ||
| 130 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
| 131 | |||
| 132 | /* cache the data to minimize the chip reads*/ | ||
| 133 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
| 134 | |||
| 135 | hcd->has_tt = 1; | ||
| 136 | ehci->sbrn = HCD_USB2; | ||
| 137 | |||
| 138 | /* data structure init */ | ||
| 139 | retval = ehci_init(hcd); | ||
| 140 | if (retval) | ||
| 141 | return retval; | ||
| 142 | |||
| 143 | retval = ehci_reset(ehci); | ||
| 144 | if (retval) | ||
| 145 | return retval; | ||
| 146 | |||
| 147 | /* bursts of unspecified length. */ | ||
| 148 | writel(0, USB_AHBBURST); | ||
| 149 | /* Use the AHB transactor */ | ||
| 150 | writel(0, USB_AHBMODE); | ||
| 151 | /* Disable streaming mode and select host mode */ | ||
| 152 | writel(0x13, USB_USBMODE); | ||
| 153 | |||
| 154 | ehci_port_power(ehci, 1); | ||
| 155 | return 0; | ||
| 156 | } | ||
| 157 | |||
| 158 | static struct hc_driver msm_hc_driver = { | ||
| 159 | .description = hcd_name, | ||
| 160 | .product_desc = "Qualcomm On-Chip EHCI Host Controller", | ||
| 161 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
| 162 | |||
| 163 | /* | ||
| 164 | * generic hardware linkage | ||
| 165 | */ | ||
| 166 | .irq = ehci_irq, | ||
| 167 | .flags = HCD_USB2 | HCD_MEMORY, | ||
| 168 | |||
| 169 | .reset = ehci_msm_reset, | ||
| 170 | .start = ehci_msm_run, | ||
| 171 | |||
| 172 | .stop = ehci_stop, | ||
| 173 | .shutdown = ehci_shutdown, | ||
| 174 | |||
| 175 | /* | ||
| 176 | * managing i/o requests and associated device resources | ||
| 177 | */ | ||
| 178 | .urb_enqueue = ehci_urb_enqueue, | ||
| 179 | .urb_dequeue = ehci_urb_dequeue, | ||
| 180 | .endpoint_disable = ehci_endpoint_disable, | ||
| 181 | .endpoint_reset = ehci_endpoint_reset, | ||
| 182 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 183 | |||
| 184 | /* | ||
| 185 | * scheduling support | ||
| 186 | */ | ||
| 187 | .get_frame_number = ehci_get_frame, | ||
| 188 | |||
| 189 | /* | ||
| 190 | * root hub support | ||
| 191 | */ | ||
| 192 | .hub_status_data = ehci_hub_status_data, | ||
| 193 | .hub_control = ehci_hub_control, | ||
| 194 | .relinquish_port = ehci_relinquish_port, | ||
| 195 | .port_handed_over = ehci_port_handed_over, | ||
| 196 | |||
| 197 | /* | ||
| 198 | * PM support | ||
| 199 | */ | ||
| 200 | .bus_suspend = ehci_bus_suspend, | ||
| 201 | .bus_resume = ehci_bus_resume, | ||
| 202 | }; | ||
| 203 | |||
| 204 | static int ehci_msm_probe(struct platform_device *pdev) | ||
| 205 | { | ||
| 206 | struct usb_hcd *hcd; | ||
| 207 | struct resource *res; | ||
| 208 | int ret; | ||
| 209 | |||
| 210 | dev_dbg(&pdev->dev, "ehci_msm proble\n"); | ||
| 211 | |||
| 212 | hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev)); | ||
| 213 | if (!hcd) { | ||
| 214 | dev_err(&pdev->dev, "Unable to create HCD\n"); | ||
| 215 | return -ENOMEM; | ||
| 216 | } | ||
| 217 | |||
| 218 | hcd->irq = platform_get_irq(pdev, 0); | ||
| 219 | if (hcd->irq < 0) { | ||
| 220 | dev_err(&pdev->dev, "Unable to get IRQ resource\n"); | ||
| 221 | ret = hcd->irq; | ||
| 222 | goto put_hcd; | ||
| 223 | } | ||
| 224 | |||
| 225 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 226 | if (!res) { | ||
| 227 | dev_err(&pdev->dev, "Unable to get memory resource\n"); | ||
| 228 | ret = -ENODEV; | ||
| 229 | goto put_hcd; | ||
| 230 | } | ||
| 231 | |||
| 232 | hcd->rsrc_start = res->start; | ||
| 233 | hcd->rsrc_len = resource_size(res); | ||
| 234 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
| 235 | if (!hcd->regs) { | ||
| 236 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
| 237 | ret = -ENOMEM; | ||
| 238 | goto put_hcd; | ||
| 239 | } | ||
| 240 | |||
| 241 | /* | ||
| 242 | * OTG driver takes care of PHY initialization, clock management, | ||
| 243 | * powering up VBUS, mapping of registers address space and power | ||
| 244 | * management. | ||
| 245 | */ | ||
| 246 | otg = otg_get_transceiver(); | ||
| 247 | if (!otg) { | ||
| 248 | dev_err(&pdev->dev, "unable to find transceiver\n"); | ||
| 249 | ret = -ENODEV; | ||
| 250 | goto unmap; | ||
| 251 | } | ||
| 252 | |||
| 253 | ret = otg_set_host(otg, &hcd->self); | ||
| 254 | if (ret < 0) { | ||
| 255 | dev_err(&pdev->dev, "unable to register with transceiver\n"); | ||
| 256 | goto put_transceiver; | ||
| 257 | } | ||
| 258 | |||
| 259 | device_init_wakeup(&pdev->dev, 1); | ||
| 260 | /* | ||
| 261 | * OTG device parent of HCD takes care of putting | ||
| 262 | * hardware into low power mode. | ||
| 263 | */ | ||
| 264 | pm_runtime_no_callbacks(&pdev->dev); | ||
| 265 | pm_runtime_enable(&pdev->dev); | ||
| 266 | |||
| 267 | return 0; | ||
| 268 | |||
| 269 | put_transceiver: | ||
| 270 | otg_put_transceiver(otg); | ||
| 271 | unmap: | ||
| 272 | iounmap(hcd->regs); | ||
| 273 | put_hcd: | ||
| 274 | usb_put_hcd(hcd); | ||
| 275 | |||
| 276 | return ret; | ||
| 277 | } | ||
| 278 | |||
| 279 | static int __devexit ehci_msm_remove(struct platform_device *pdev) | ||
| 280 | { | ||
| 281 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
| 282 | |||
| 283 | device_init_wakeup(&pdev->dev, 0); | ||
| 284 | pm_runtime_disable(&pdev->dev); | ||
| 285 | pm_runtime_set_suspended(&pdev->dev); | ||
| 286 | |||
| 287 | otg_set_host(otg, NULL); | ||
| 288 | otg_put_transceiver(otg); | ||
| 289 | |||
| 290 | usb_put_hcd(hcd); | ||
| 291 | |||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | |||
| 295 | #ifdef CONFIG_PM | ||
| 296 | static int ehci_msm_pm_suspend(struct device *dev) | ||
| 297 | { | ||
| 298 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
| 299 | bool wakeup = device_may_wakeup(dev); | ||
| 300 | |||
| 301 | dev_dbg(dev, "ehci-msm PM suspend\n"); | ||
| 302 | |||
| 303 | /* | ||
| 304 | * EHCI helper function has also the same check before manipulating | ||
| 305 | * port wakeup flags. We do check here the same condition before | ||
| 306 | * calling the same helper function to avoid bringing hardware | ||
| 307 | * from Low power mode when there is no need for adjusting port | ||
| 308 | * wakeup flags. | ||
| 309 | */ | ||
| 310 | if (hcd->self.root_hub->do_remote_wakeup && !wakeup) { | ||
| 311 | pm_runtime_resume(dev); | ||
| 312 | ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd), | ||
| 313 | wakeup); | ||
| 314 | } | ||
| 315 | |||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | |||
| 319 | static int ehci_msm_pm_resume(struct device *dev) | ||
| 320 | { | ||
| 321 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
| 322 | |||
| 323 | dev_dbg(dev, "ehci-msm PM resume\n"); | ||
| 324 | ehci_prepare_ports_for_controller_resume(hcd_to_ehci(hcd)); | ||
| 325 | |||
| 326 | return 0; | ||
| 327 | } | ||
| 328 | #else | ||
| 329 | #define ehci_msm_pm_suspend NULL | ||
| 330 | #define ehci_msm_pm_resume NULL | ||
| 331 | #endif | ||
| 332 | |||
| 333 | static const struct dev_pm_ops ehci_msm_dev_pm_ops = { | ||
| 334 | .suspend = ehci_msm_pm_suspend, | ||
| 335 | .resume = ehci_msm_pm_resume, | ||
| 336 | }; | ||
| 337 | |||
| 338 | static struct platform_driver ehci_msm_driver = { | ||
| 339 | .probe = ehci_msm_probe, | ||
| 340 | .remove = __devexit_p(ehci_msm_remove), | ||
| 341 | .driver = { | ||
| 342 | .name = "msm_hsusb_host", | ||
| 343 | .pm = &ehci_msm_dev_pm_ops, | ||
| 344 | }, | ||
| 345 | }; | ||
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index bce85055019a..f6e5d44c06b6 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c | |||
| @@ -100,6 +100,7 @@ static const struct hc_driver ehci_mxc_hc_driver = { | |||
| 100 | .urb_enqueue = ehci_urb_enqueue, | 100 | .urb_enqueue = ehci_urb_enqueue, |
| 101 | .urb_dequeue = ehci_urb_dequeue, | 101 | .urb_dequeue = ehci_urb_dequeue, |
| 102 | .endpoint_disable = ehci_endpoint_disable, | 102 | .endpoint_disable = ehci_endpoint_disable, |
| 103 | .endpoint_reset = ehci_endpoint_reset, | ||
| 103 | 104 | ||
| 104 | /* | 105 | /* |
| 105 | * scheduling support | 106 | * scheduling support |
| @@ -115,6 +116,8 @@ static const struct hc_driver ehci_mxc_hc_driver = { | |||
| 115 | .bus_resume = ehci_bus_resume, | 116 | .bus_resume = ehci_bus_resume, |
| 116 | .relinquish_port = ehci_relinquish_port, | 117 | .relinquish_port = ehci_relinquish_port, |
| 117 | .port_handed_over = ehci_port_handed_over, | 118 | .port_handed_over = ehci_port_handed_over, |
| 119 | |||
| 120 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 118 | }; | 121 | }; |
| 119 | 122 | ||
| 120 | static int ehci_mxc_drv_probe(struct platform_device *pdev) | 123 | static int ehci_mxc_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 116ae280053a..0374eb47f09b 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * ehci-omap.c - driver for USBHOST on OMAP 34xx processor | 2 | * ehci-omap.c - driver for USBHOST on OMAP3/4 processors |
| 3 | * | 3 | * |
| 4 | * Bus Glue for OMAP34xx USBHOST 3 port EHCI controller | 4 | * Bus Glue for the EHCI controllers in OMAP3/4 |
| 5 | * Tested on OMAP3430 ES2.0 SDP | 5 | * Tested on several OMAP3 boards, and OMAP4 Pandaboard |
| 6 | * | 6 | * |
| 7 | * Copyright (C) 2007-2008 Texas Instruments, Inc. | 7 | * Copyright (C) 2007-2010 Texas Instruments, Inc. |
| 8 | * Author: Vikram Pandita <vikram.pandita@ti.com> | 8 | * Author: Vikram Pandita <vikram.pandita@ti.com> |
| 9 | * Author: Anand Gadiyar <gadiyar@ti.com> | ||
| 9 | * | 10 | * |
| 10 | * Copyright (C) 2009 Nokia Corporation | 11 | * Copyright (C) 2009 Nokia Corporation |
| 11 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> | 12 | * Contact: Felipe Balbi <felipe.balbi@nokia.com> |
| @@ -26,11 +27,14 @@ | |||
| 26 | * along with this program; if not, write to the Free Software | 27 | * along with this program; if not, write to the Free Software |
| 27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 28 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 28 | * | 29 | * |
| 29 | * TODO (last updated Feb 12, 2010): | 30 | * TODO (last updated Nov 21, 2010): |
| 30 | * - add kernel-doc | 31 | * - add kernel-doc |
| 31 | * - enable AUTOIDLE | 32 | * - enable AUTOIDLE |
| 32 | * - add suspend/resume | 33 | * - add suspend/resume |
| 33 | * - move workarounds to board-files | 34 | * - move workarounds to board-files |
| 35 | * - factor out code common to OHCI | ||
| 36 | * - add HSIC and TLL support | ||
| 37 | * - convert to use hwmod and runtime PM | ||
| 34 | */ | 38 | */ |
| 35 | 39 | ||
| 36 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
| @@ -114,6 +118,23 @@ | |||
| 114 | #define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) | 118 | #define OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS (1 << 9) |
| 115 | #define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) | 119 | #define OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS (1 << 10) |
| 116 | 120 | ||
| 121 | /* OMAP4-specific defines */ | ||
| 122 | #define OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR (3 << 2) | ||
| 123 | #define OMAP4_UHH_SYSCONFIG_NOIDLE (1 << 2) | ||
| 124 | |||
| 125 | #define OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR (3 << 4) | ||
| 126 | #define OMAP4_UHH_SYSCONFIG_NOSTDBY (1 << 4) | ||
| 127 | #define OMAP4_UHH_SYSCONFIG_SOFTRESET (1 << 0) | ||
| 128 | |||
| 129 | #define OMAP4_P1_MODE_CLEAR (3 << 16) | ||
| 130 | #define OMAP4_P1_MODE_TLL (1 << 16) | ||
| 131 | #define OMAP4_P1_MODE_HSIC (3 << 16) | ||
| 132 | #define OMAP4_P2_MODE_CLEAR (3 << 18) | ||
| 133 | #define OMAP4_P2_MODE_TLL (1 << 18) | ||
| 134 | #define OMAP4_P2_MODE_HSIC (3 << 18) | ||
| 135 | |||
| 136 | #define OMAP_REV2_TLL_CHANNEL_COUNT 2 | ||
| 137 | |||
| 117 | #define OMAP_UHH_DEBUG_CSR (0x44) | 138 | #define OMAP_UHH_DEBUG_CSR (0x44) |
| 118 | 139 | ||
| 119 | /* EHCI Register Set */ | 140 | /* EHCI Register Set */ |
| @@ -127,6 +148,17 @@ | |||
| 127 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 | 148 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 |
| 128 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 | 149 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 |
| 129 | 150 | ||
| 151 | /* Values of UHH_REVISION - Note: these are not given in the TRM */ | ||
| 152 | #define OMAP_EHCI_REV1 0x00000010 /* OMAP3 */ | ||
| 153 | #define OMAP_EHCI_REV2 0x50700100 /* OMAP4 */ | ||
| 154 | |||
| 155 | #define is_omap_ehci_rev1(x) (x->omap_ehci_rev == OMAP_EHCI_REV1) | ||
| 156 | #define is_omap_ehci_rev2(x) (x->omap_ehci_rev == OMAP_EHCI_REV2) | ||
| 157 | |||
| 158 | #define is_ehci_phy_mode(x) (x == EHCI_HCD_OMAP_MODE_PHY) | ||
| 159 | #define is_ehci_tll_mode(x) (x == EHCI_HCD_OMAP_MODE_TLL) | ||
| 160 | #define is_ehci_hsic_mode(x) (x == EHCI_HCD_OMAP_MODE_HSIC) | ||
| 161 | |||
| 130 | /*-------------------------------------------------------------------------*/ | 162 | /*-------------------------------------------------------------------------*/ |
| 131 | 163 | ||
| 132 | static inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val) | 164 | static inline void ehci_omap_writel(void __iomem *base, u32 reg, u32 val) |
| @@ -156,10 +188,14 @@ struct ehci_hcd_omap { | |||
| 156 | struct device *dev; | 188 | struct device *dev; |
| 157 | 189 | ||
| 158 | struct clk *usbhost_ick; | 190 | struct clk *usbhost_ick; |
| 159 | struct clk *usbhost2_120m_fck; | 191 | struct clk *usbhost_hs_fck; |
| 160 | struct clk *usbhost1_48m_fck; | 192 | struct clk *usbhost_fs_fck; |
| 161 | struct clk *usbtll_fck; | 193 | struct clk *usbtll_fck; |
| 162 | struct clk *usbtll_ick; | 194 | struct clk *usbtll_ick; |
| 195 | struct clk *xclk60mhsp1_ck; | ||
| 196 | struct clk *xclk60mhsp2_ck; | ||
| 197 | struct clk *utmi_p1_fck; | ||
| 198 | struct clk *utmi_p2_fck; | ||
| 163 | 199 | ||
| 164 | /* FIXME the following two workarounds are | 200 | /* FIXME the following two workarounds are |
| 165 | * board specific not silicon-specific so these | 201 | * board specific not silicon-specific so these |
| @@ -176,6 +212,9 @@ struct ehci_hcd_omap { | |||
| 176 | /* phy reset workaround */ | 212 | /* phy reset workaround */ |
| 177 | int phy_reset; | 213 | int phy_reset; |
| 178 | 214 | ||
| 215 | /* IP revision */ | ||
| 216 | u32 omap_ehci_rev; | ||
| 217 | |||
| 179 | /* desired phy_mode: TLL, PHY */ | 218 | /* desired phy_mode: TLL, PHY */ |
| 180 | enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; | 219 | enum ehci_hcd_omap_mode port_mode[OMAP3_HS_USB_PORTS]; |
| 181 | 220 | ||
| @@ -191,13 +230,14 @@ struct ehci_hcd_omap { | |||
| 191 | 230 | ||
| 192 | /*-------------------------------------------------------------------------*/ | 231 | /*-------------------------------------------------------------------------*/ |
| 193 | 232 | ||
| 194 | static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask) | 233 | static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask, |
| 234 | u8 tll_channel_count) | ||
| 195 | { | 235 | { |
| 196 | unsigned reg; | 236 | unsigned reg; |
| 197 | int i; | 237 | int i; |
| 198 | 238 | ||
| 199 | /* Program the 3 TLL channels upfront */ | 239 | /* Program the 3 TLL channels upfront */ |
| 200 | for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { | 240 | for (i = 0; i < tll_channel_count; i++) { |
| 201 | reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); | 241 | reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); |
| 202 | 242 | ||
| 203 | /* Disable AutoIdle, BitStuffing and use SDR Mode */ | 243 | /* Disable AutoIdle, BitStuffing and use SDR Mode */ |
| @@ -217,7 +257,7 @@ static void omap_usb_utmi_init(struct ehci_hcd_omap *omap, u8 tll_channel_mask) | |||
| 217 | ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); | 257 | ehci_omap_writel(omap->tll_base, OMAP_TLL_SHARED_CONF, reg); |
| 218 | 258 | ||
| 219 | /* Enable channels now */ | 259 | /* Enable channels now */ |
| 220 | for (i = 0; i < OMAP_TLL_CHANNEL_COUNT; i++) { | 260 | for (i = 0; i < tll_channel_count; i++) { |
| 221 | reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); | 261 | reg = ehci_omap_readl(omap->tll_base, OMAP_TLL_CHANNEL_CONF(i)); |
| 222 | 262 | ||
| 223 | /* Enable only the reg that is needed */ | 263 | /* Enable only the reg that is needed */ |
| @@ -286,19 +326,19 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
| 286 | } | 326 | } |
| 287 | clk_enable(omap->usbhost_ick); | 327 | clk_enable(omap->usbhost_ick); |
| 288 | 328 | ||
| 289 | omap->usbhost2_120m_fck = clk_get(omap->dev, "usbhost_120m_fck"); | 329 | omap->usbhost_hs_fck = clk_get(omap->dev, "hs_fck"); |
| 290 | if (IS_ERR(omap->usbhost2_120m_fck)) { | 330 | if (IS_ERR(omap->usbhost_hs_fck)) { |
| 291 | ret = PTR_ERR(omap->usbhost2_120m_fck); | 331 | ret = PTR_ERR(omap->usbhost_hs_fck); |
| 292 | goto err_host_120m_fck; | 332 | goto err_host_120m_fck; |
| 293 | } | 333 | } |
| 294 | clk_enable(omap->usbhost2_120m_fck); | 334 | clk_enable(omap->usbhost_hs_fck); |
| 295 | 335 | ||
| 296 | omap->usbhost1_48m_fck = clk_get(omap->dev, "usbhost_48m_fck"); | 336 | omap->usbhost_fs_fck = clk_get(omap->dev, "fs_fck"); |
| 297 | if (IS_ERR(omap->usbhost1_48m_fck)) { | 337 | if (IS_ERR(omap->usbhost_fs_fck)) { |
| 298 | ret = PTR_ERR(omap->usbhost1_48m_fck); | 338 | ret = PTR_ERR(omap->usbhost_fs_fck); |
| 299 | goto err_host_48m_fck; | 339 | goto err_host_48m_fck; |
| 300 | } | 340 | } |
| 301 | clk_enable(omap->usbhost1_48m_fck); | 341 | clk_enable(omap->usbhost_fs_fck); |
| 302 | 342 | ||
| 303 | if (omap->phy_reset) { | 343 | if (omap->phy_reset) { |
| 304 | /* Refer: ISSUE1 */ | 344 | /* Refer: ISSUE1 */ |
| @@ -333,6 +373,80 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
| 333 | } | 373 | } |
| 334 | clk_enable(omap->usbtll_ick); | 374 | clk_enable(omap->usbtll_ick); |
| 335 | 375 | ||
| 376 | omap->omap_ehci_rev = ehci_omap_readl(omap->uhh_base, | ||
| 377 | OMAP_UHH_REVISION); | ||
| 378 | dev_dbg(omap->dev, "OMAP UHH_REVISION 0x%x\n", | ||
| 379 | omap->omap_ehci_rev); | ||
| 380 | |||
| 381 | /* | ||
| 382 | * Enable per-port clocks as needed (newer controllers only). | ||
| 383 | * - External ULPI clock for PHY mode | ||
| 384 | * - Internal clocks for TLL and HSIC modes (TODO) | ||
| 385 | */ | ||
| 386 | if (is_omap_ehci_rev2(omap)) { | ||
| 387 | switch (omap->port_mode[0]) { | ||
| 388 | case EHCI_HCD_OMAP_MODE_PHY: | ||
| 389 | omap->xclk60mhsp1_ck = clk_get(omap->dev, | ||
| 390 | "xclk60mhsp1_ck"); | ||
| 391 | if (IS_ERR(omap->xclk60mhsp1_ck)) { | ||
| 392 | ret = PTR_ERR(omap->xclk60mhsp1_ck); | ||
| 393 | dev_err(omap->dev, | ||
| 394 | "Unable to get Port1 ULPI clock\n"); | ||
| 395 | } | ||
| 396 | |||
| 397 | omap->utmi_p1_fck = clk_get(omap->dev, | ||
| 398 | "utmi_p1_gfclk"); | ||
| 399 | if (IS_ERR(omap->utmi_p1_fck)) { | ||
| 400 | ret = PTR_ERR(omap->utmi_p1_fck); | ||
| 401 | dev_err(omap->dev, | ||
| 402 | "Unable to get utmi_p1_fck\n"); | ||
| 403 | } | ||
| 404 | |||
| 405 | ret = clk_set_parent(omap->utmi_p1_fck, | ||
| 406 | omap->xclk60mhsp1_ck); | ||
| 407 | if (ret != 0) { | ||
| 408 | dev_err(omap->dev, | ||
| 409 | "Unable to set P1 f-clock\n"); | ||
| 410 | } | ||
| 411 | break; | ||
| 412 | case EHCI_HCD_OMAP_MODE_TLL: | ||
| 413 | /* TODO */ | ||
| 414 | default: | ||
| 415 | break; | ||
| 416 | } | ||
| 417 | switch (omap->port_mode[1]) { | ||
| 418 | case EHCI_HCD_OMAP_MODE_PHY: | ||
| 419 | omap->xclk60mhsp2_ck = clk_get(omap->dev, | ||
| 420 | "xclk60mhsp2_ck"); | ||
| 421 | if (IS_ERR(omap->xclk60mhsp2_ck)) { | ||
| 422 | ret = PTR_ERR(omap->xclk60mhsp2_ck); | ||
| 423 | dev_err(omap->dev, | ||
| 424 | "Unable to get Port2 ULPI clock\n"); | ||
| 425 | } | ||
| 426 | |||
| 427 | omap->utmi_p2_fck = clk_get(omap->dev, | ||
| 428 | "utmi_p2_gfclk"); | ||
| 429 | if (IS_ERR(omap->utmi_p2_fck)) { | ||
| 430 | ret = PTR_ERR(omap->utmi_p2_fck); | ||
| 431 | dev_err(omap->dev, | ||
| 432 | "Unable to get utmi_p2_fck\n"); | ||
| 433 | } | ||
| 434 | |||
| 435 | ret = clk_set_parent(omap->utmi_p2_fck, | ||
| 436 | omap->xclk60mhsp2_ck); | ||
| 437 | if (ret != 0) { | ||
| 438 | dev_err(omap->dev, | ||
| 439 | "Unable to set P2 f-clock\n"); | ||
| 440 | } | ||
| 441 | break; | ||
| 442 | case EHCI_HCD_OMAP_MODE_TLL: | ||
| 443 | /* TODO */ | ||
| 444 | default: | ||
| 445 | break; | ||
| 446 | } | ||
| 447 | } | ||
| 448 | |||
| 449 | |||
| 336 | /* perform TLL soft reset, and wait until reset is complete */ | 450 | /* perform TLL soft reset, and wait until reset is complete */ |
| 337 | ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, | 451 | ehci_omap_writel(omap->tll_base, OMAP_USBTLL_SYSCONFIG, |
| 338 | OMAP_USBTLL_SYSCONFIG_SOFTRESET); | 452 | OMAP_USBTLL_SYSCONFIG_SOFTRESET); |
| @@ -360,12 +474,20 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
| 360 | 474 | ||
| 361 | /* Put UHH in NoIdle/NoStandby mode */ | 475 | /* Put UHH in NoIdle/NoStandby mode */ |
| 362 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); | 476 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSCONFIG); |
| 363 | reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP | 477 | if (is_omap_ehci_rev1(omap)) { |
| 364 | | OMAP_UHH_SYSCONFIG_SIDLEMODE | 478 | reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP |
| 365 | | OMAP_UHH_SYSCONFIG_CACTIVITY | 479 | | OMAP_UHH_SYSCONFIG_SIDLEMODE |
| 366 | | OMAP_UHH_SYSCONFIG_MIDLEMODE); | 480 | | OMAP_UHH_SYSCONFIG_CACTIVITY |
| 367 | reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; | 481 | | OMAP_UHH_SYSCONFIG_MIDLEMODE); |
| 482 | reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; | ||
| 483 | |||
| 368 | 484 | ||
| 485 | } else if (is_omap_ehci_rev2(omap)) { | ||
| 486 | reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; | ||
| 487 | reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; | ||
| 488 | reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; | ||
| 489 | reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; | ||
| 490 | } | ||
| 369 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); | 491 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); |
| 370 | 492 | ||
| 371 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); | 493 | reg = ehci_omap_readl(omap->uhh_base, OMAP_UHH_HOSTCONFIG); |
| @@ -376,40 +498,56 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
| 376 | | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); | 498 | | OMAP_UHH_HOSTCONFIG_INCR16_BURST_EN); |
| 377 | reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; | 499 | reg &= ~OMAP_UHH_HOSTCONFIG_INCRX_ALIGN_EN; |
| 378 | 500 | ||
| 379 | if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) | 501 | if (is_omap_ehci_rev1(omap)) { |
| 380 | reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; | 502 | if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_UNKNOWN) |
| 381 | if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) | 503 | reg &= ~OMAP_UHH_HOSTCONFIG_P1_CONNECT_STATUS; |
| 382 | reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; | 504 | if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_UNKNOWN) |
| 383 | if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) | 505 | reg &= ~OMAP_UHH_HOSTCONFIG_P2_CONNECT_STATUS; |
| 384 | reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; | 506 | if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_UNKNOWN) |
| 385 | 507 | reg &= ~OMAP_UHH_HOSTCONFIG_P3_CONNECT_STATUS; | |
| 386 | /* Bypass the TLL module for PHY mode operation */ | 508 | |
| 387 | if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { | 509 | /* Bypass the TLL module for PHY mode operation */ |
| 388 | dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); | 510 | if (cpu_is_omap3430() && (omap_rev() <= OMAP3430_REV_ES2_1)) { |
| 389 | if ((omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) || | 511 | dev_dbg(omap->dev, "OMAP3 ES version <= ES2.1\n"); |
| 390 | (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) || | 512 | if (is_ehci_phy_mode(omap->port_mode[0]) || |
| 391 | (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY)) | 513 | is_ehci_phy_mode(omap->port_mode[1]) || |
| 392 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; | 514 | is_ehci_phy_mode(omap->port_mode[2])) |
| 393 | else | 515 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; |
| 394 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; | 516 | else |
| 395 | } else { | 517 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; |
| 396 | dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); | 518 | } else { |
| 397 | if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_PHY) | 519 | dev_dbg(omap->dev, "OMAP3 ES version > ES2.1\n"); |
| 398 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; | 520 | if (is_ehci_phy_mode(omap->port_mode[0])) |
| 399 | else if (omap->port_mode[0] == EHCI_HCD_OMAP_MODE_TLL) | 521 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; |
| 400 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; | 522 | else if (is_ehci_tll_mode(omap->port_mode[0])) |
| 401 | 523 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P1_BYPASS; | |
| 402 | if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_PHY) | 524 | |
| 403 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; | 525 | if (is_ehci_phy_mode(omap->port_mode[1])) |
| 404 | else if (omap->port_mode[1] == EHCI_HCD_OMAP_MODE_TLL) | 526 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; |
| 405 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; | 527 | else if (is_ehci_tll_mode(omap->port_mode[1])) |
| 406 | 528 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P2_BYPASS; | |
| 407 | if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_PHY) | 529 | |
| 408 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; | 530 | if (is_ehci_phy_mode(omap->port_mode[2])) |
| 409 | else if (omap->port_mode[2] == EHCI_HCD_OMAP_MODE_TLL) | 531 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; |
| 410 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; | 532 | else if (is_ehci_tll_mode(omap->port_mode[2])) |
| 533 | reg |= OMAP_UHH_HOSTCONFIG_ULPI_P3_BYPASS; | ||
| 534 | } | ||
| 535 | } else if (is_omap_ehci_rev2(omap)) { | ||
| 536 | /* Clear port mode fields for PHY mode*/ | ||
| 537 | reg &= ~OMAP4_P1_MODE_CLEAR; | ||
| 538 | reg &= ~OMAP4_P2_MODE_CLEAR; | ||
| 539 | |||
| 540 | if (is_ehci_tll_mode(omap->port_mode[0])) | ||
| 541 | reg |= OMAP4_P1_MODE_TLL; | ||
| 542 | else if (is_ehci_hsic_mode(omap->port_mode[0])) | ||
| 543 | reg |= OMAP4_P1_MODE_HSIC; | ||
| 411 | 544 | ||
| 545 | if (is_ehci_tll_mode(omap->port_mode[1])) | ||
| 546 | reg |= OMAP4_P2_MODE_TLL; | ||
| 547 | else if (is_ehci_hsic_mode(omap->port_mode[1])) | ||
| 548 | reg |= OMAP4_P2_MODE_HSIC; | ||
| 412 | } | 549 | } |
| 550 | |||
| 413 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); | 551 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); |
| 414 | dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); | 552 | dev_dbg(omap->dev, "UHH setup done, uhh_hostconfig=%x\n", reg); |
| 415 | 553 | ||
| @@ -438,7 +576,7 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
| 438 | tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; | 576 | tll_ch_mask |= OMAP_TLL_CHANNEL_3_EN_MASK; |
| 439 | 577 | ||
| 440 | /* Enable UTMI mode for required TLL channels */ | 578 | /* Enable UTMI mode for required TLL channels */ |
| 441 | omap_usb_utmi_init(omap, tll_ch_mask); | 579 | omap_usb_utmi_init(omap, tll_ch_mask, OMAP_TLL_CHANNEL_COUNT); |
| 442 | } | 580 | } |
| 443 | 581 | ||
| 444 | if (omap->phy_reset) { | 582 | if (omap->phy_reset) { |
| @@ -464,6 +602,14 @@ static int omap_start_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
| 464 | return 0; | 602 | return 0; |
| 465 | 603 | ||
| 466 | err_sys_status: | 604 | err_sys_status: |
| 605 | clk_disable(omap->utmi_p2_fck); | ||
| 606 | clk_put(omap->utmi_p2_fck); | ||
| 607 | clk_disable(omap->xclk60mhsp2_ck); | ||
| 608 | clk_put(omap->xclk60mhsp2_ck); | ||
| 609 | clk_disable(omap->utmi_p1_fck); | ||
| 610 | clk_put(omap->utmi_p1_fck); | ||
| 611 | clk_disable(omap->xclk60mhsp1_ck); | ||
| 612 | clk_put(omap->xclk60mhsp1_ck); | ||
| 467 | clk_disable(omap->usbtll_ick); | 613 | clk_disable(omap->usbtll_ick); |
| 468 | clk_put(omap->usbtll_ick); | 614 | clk_put(omap->usbtll_ick); |
| 469 | 615 | ||
| @@ -472,8 +618,8 @@ err_tll_ick: | |||
| 472 | clk_put(omap->usbtll_fck); | 618 | clk_put(omap->usbtll_fck); |
| 473 | 619 | ||
| 474 | err_tll_fck: | 620 | err_tll_fck: |
| 475 | clk_disable(omap->usbhost1_48m_fck); | 621 | clk_disable(omap->usbhost_fs_fck); |
| 476 | clk_put(omap->usbhost1_48m_fck); | 622 | clk_put(omap->usbhost_fs_fck); |
| 477 | 623 | ||
| 478 | if (omap->phy_reset) { | 624 | if (omap->phy_reset) { |
| 479 | if (gpio_is_valid(omap->reset_gpio_port[0])) | 625 | if (gpio_is_valid(omap->reset_gpio_port[0])) |
| @@ -484,8 +630,8 @@ err_tll_fck: | |||
| 484 | } | 630 | } |
| 485 | 631 | ||
| 486 | err_host_48m_fck: | 632 | err_host_48m_fck: |
| 487 | clk_disable(omap->usbhost2_120m_fck); | 633 | clk_disable(omap->usbhost_hs_fck); |
| 488 | clk_put(omap->usbhost2_120m_fck); | 634 | clk_put(omap->usbhost_hs_fck); |
| 489 | 635 | ||
| 490 | err_host_120m_fck: | 636 | err_host_120m_fck: |
| 491 | clk_disable(omap->usbhost_ick); | 637 | clk_disable(omap->usbhost_ick); |
| @@ -503,6 +649,8 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
| 503 | 649 | ||
| 504 | /* Reset OMAP modules for insmod/rmmod to work */ | 650 | /* Reset OMAP modules for insmod/rmmod to work */ |
| 505 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, | 651 | ehci_omap_writel(omap->uhh_base, OMAP_UHH_SYSCONFIG, |
| 652 | is_omap_ehci_rev2(omap) ? | ||
| 653 | OMAP4_UHH_SYSCONFIG_SOFTRESET : | ||
| 506 | OMAP_UHH_SYSCONFIG_SOFTRESET); | 654 | OMAP_UHH_SYSCONFIG_SOFTRESET); |
| 507 | while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) | 655 | while (!(ehci_omap_readl(omap->uhh_base, OMAP_UHH_SYSSTATUS) |
| 508 | & (1 << 0))) { | 656 | & (1 << 0))) { |
| @@ -550,16 +698,16 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
| 550 | omap->usbhost_ick = NULL; | 698 | omap->usbhost_ick = NULL; |
| 551 | } | 699 | } |
| 552 | 700 | ||
| 553 | if (omap->usbhost1_48m_fck != NULL) { | 701 | if (omap->usbhost_fs_fck != NULL) { |
| 554 | clk_disable(omap->usbhost1_48m_fck); | 702 | clk_disable(omap->usbhost_fs_fck); |
| 555 | clk_put(omap->usbhost1_48m_fck); | 703 | clk_put(omap->usbhost_fs_fck); |
| 556 | omap->usbhost1_48m_fck = NULL; | 704 | omap->usbhost_fs_fck = NULL; |
| 557 | } | 705 | } |
| 558 | 706 | ||
| 559 | if (omap->usbhost2_120m_fck != NULL) { | 707 | if (omap->usbhost_hs_fck != NULL) { |
| 560 | clk_disable(omap->usbhost2_120m_fck); | 708 | clk_disable(omap->usbhost_hs_fck); |
| 561 | clk_put(omap->usbhost2_120m_fck); | 709 | clk_put(omap->usbhost_hs_fck); |
| 562 | omap->usbhost2_120m_fck = NULL; | 710 | omap->usbhost_hs_fck = NULL; |
| 563 | } | 711 | } |
| 564 | 712 | ||
| 565 | if (omap->usbtll_ick != NULL) { | 713 | if (omap->usbtll_ick != NULL) { |
| @@ -568,6 +716,32 @@ static void omap_stop_ehc(struct ehci_hcd_omap *omap, struct usb_hcd *hcd) | |||
| 568 | omap->usbtll_ick = NULL; | 716 | omap->usbtll_ick = NULL; |
| 569 | } | 717 | } |
| 570 | 718 | ||
| 719 | if (is_omap_ehci_rev2(omap)) { | ||
| 720 | if (omap->xclk60mhsp1_ck != NULL) { | ||
| 721 | clk_disable(omap->xclk60mhsp1_ck); | ||
| 722 | clk_put(omap->xclk60mhsp1_ck); | ||
| 723 | omap->xclk60mhsp1_ck = NULL; | ||
| 724 | } | ||
| 725 | |||
| 726 | if (omap->utmi_p1_fck != NULL) { | ||
| 727 | clk_disable(omap->utmi_p1_fck); | ||
| 728 | clk_put(omap->utmi_p1_fck); | ||
| 729 | omap->utmi_p1_fck = NULL; | ||
| 730 | } | ||
| 731 | |||
| 732 | if (omap->xclk60mhsp2_ck != NULL) { | ||
| 733 | clk_disable(omap->xclk60mhsp2_ck); | ||
| 734 | clk_put(omap->xclk60mhsp2_ck); | ||
| 735 | omap->xclk60mhsp2_ck = NULL; | ||
| 736 | } | ||
| 737 | |||
| 738 | if (omap->utmi_p2_fck != NULL) { | ||
| 739 | clk_disable(omap->utmi_p2_fck); | ||
| 740 | clk_put(omap->utmi_p2_fck); | ||
| 741 | omap->utmi_p2_fck = NULL; | ||
| 742 | } | ||
| 743 | } | ||
| 744 | |||
| 571 | if (omap->phy_reset) { | 745 | if (omap->phy_reset) { |
| 572 | if (gpio_is_valid(omap->reset_gpio_port[0])) | 746 | if (gpio_is_valid(omap->reset_gpio_port[0])) |
| 573 | gpio_free(omap->reset_gpio_port[0]); | 747 | gpio_free(omap->reset_gpio_port[0]); |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 655f3c9f88bf..76179c39c0e3 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
| @@ -22,6 +22,9 @@ | |||
| 22 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." | 22 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." |
| 23 | #endif | 23 | #endif |
| 24 | 24 | ||
| 25 | /* defined here to avoid adding to pci_ids.h for single instance use */ | ||
| 26 | #define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70 | ||
| 27 | |||
| 25 | /*-------------------------------------------------------------------------*/ | 28 | /*-------------------------------------------------------------------------*/ |
| 26 | 29 | ||
| 27 | /* called after powerup, by probe or system-pm "wakeup" */ | 30 | /* called after powerup, by probe or system-pm "wakeup" */ |
| @@ -41,6 +44,35 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | |||
| 41 | return 0; | 44 | return 0; |
| 42 | } | 45 | } |
| 43 | 46 | ||
| 47 | static int ehci_quirk_amd_SB800(struct ehci_hcd *ehci) | ||
| 48 | { | ||
| 49 | struct pci_dev *amd_smbus_dev; | ||
| 50 | u8 rev = 0; | ||
| 51 | |||
| 52 | amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); | ||
| 53 | if (!amd_smbus_dev) | ||
| 54 | return 0; | ||
| 55 | |||
| 56 | pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); | ||
| 57 | if (rev < 0x40) { | ||
| 58 | pci_dev_put(amd_smbus_dev); | ||
| 59 | amd_smbus_dev = NULL; | ||
| 60 | return 0; | ||
| 61 | } | ||
| 62 | |||
| 63 | if (!amd_nb_dev) | ||
| 64 | amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL); | ||
| 65 | if (!amd_nb_dev) | ||
| 66 | ehci_err(ehci, "QUIRK: unable to get AMD NB device\n"); | ||
| 67 | |||
| 68 | ehci_info(ehci, "QUIRK: Enable AMD SB800 L1 fix\n"); | ||
| 69 | |||
| 70 | pci_dev_put(amd_smbus_dev); | ||
| 71 | amd_smbus_dev = NULL; | ||
| 72 | |||
| 73 | return 1; | ||
| 74 | } | ||
| 75 | |||
| 44 | /* called during probe() after chip reset completes */ | 76 | /* called during probe() after chip reset completes */ |
| 45 | static int ehci_pci_setup(struct usb_hcd *hcd) | 77 | static int ehci_pci_setup(struct usb_hcd *hcd) |
| 46 | { | 78 | { |
| @@ -99,6 +131,9 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
| 99 | /* cache this readonly data; minimize chip reads */ | 131 | /* cache this readonly data; minimize chip reads */ |
| 100 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | 132 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
| 101 | 133 | ||
| 134 | if (ehci_quirk_amd_SB800(ehci)) | ||
| 135 | ehci->amd_l1_fix = 1; | ||
| 136 | |||
| 102 | retval = ehci_halt(ehci); | 137 | retval = ehci_halt(ehci); |
| 103 | if (retval) | 138 | if (retval) |
| 104 | return retval; | 139 | return retval; |
| @@ -137,6 +172,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
| 137 | ehci_info(ehci, "disable lpm for langwell/penwell\n"); | 172 | ehci_info(ehci, "disable lpm for langwell/penwell\n"); |
| 138 | ehci->has_lpm = 0; | 173 | ehci->has_lpm = 0; |
| 139 | } | 174 | } |
| 175 | if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) { | ||
| 176 | hcd->has_tt = 1; | ||
| 177 | tdi_reset(ehci); | ||
| 178 | } | ||
| 140 | break; | 179 | break; |
| 141 | case PCI_VENDOR_ID_TDI: | 180 | case PCI_VENDOR_ID_TDI: |
| 142 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { | 181 | if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index d9f78eb26572..aa46f57f9ec8 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
| @@ -1590,6 +1590,63 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) | |||
| 1590 | *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); | 1590 | *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); |
| 1591 | } | 1591 | } |
| 1592 | 1592 | ||
| 1593 | #define AB_REG_BAR_LOW 0xe0 | ||
| 1594 | #define AB_REG_BAR_HIGH 0xe1 | ||
| 1595 | #define AB_INDX(addr) ((addr) + 0x00) | ||
| 1596 | #define AB_DATA(addr) ((addr) + 0x04) | ||
| 1597 | #define NB_PCIE_INDX_ADDR 0xe0 | ||
| 1598 | #define NB_PCIE_INDX_DATA 0xe4 | ||
| 1599 | #define NB_PIF0_PWRDOWN_0 0x01100012 | ||
| 1600 | #define NB_PIF0_PWRDOWN_1 0x01100013 | ||
| 1601 | |||
| 1602 | static void ehci_quirk_amd_L1(struct ehci_hcd *ehci, int disable) | ||
| 1603 | { | ||
| 1604 | u32 addr, addr_low, addr_high, val; | ||
| 1605 | |||
| 1606 | outb_p(AB_REG_BAR_LOW, 0xcd6); | ||
| 1607 | addr_low = inb_p(0xcd7); | ||
| 1608 | outb_p(AB_REG_BAR_HIGH, 0xcd6); | ||
| 1609 | addr_high = inb_p(0xcd7); | ||
| 1610 | addr = addr_high << 8 | addr_low; | ||
| 1611 | outl_p(0x30, AB_INDX(addr)); | ||
| 1612 | outl_p(0x40, AB_DATA(addr)); | ||
| 1613 | outl_p(0x34, AB_INDX(addr)); | ||
| 1614 | val = inl_p(AB_DATA(addr)); | ||
| 1615 | |||
| 1616 | if (disable) { | ||
| 1617 | val &= ~0x8; | ||
| 1618 | val |= (1 << 4) | (1 << 9); | ||
| 1619 | } else { | ||
| 1620 | val |= 0x8; | ||
| 1621 | val &= ~((1 << 4) | (1 << 9)); | ||
| 1622 | } | ||
| 1623 | outl_p(val, AB_DATA(addr)); | ||
| 1624 | |||
| 1625 | if (amd_nb_dev) { | ||
| 1626 | addr = NB_PIF0_PWRDOWN_0; | ||
| 1627 | pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); | ||
| 1628 | pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); | ||
| 1629 | if (disable) | ||
| 1630 | val &= ~(0x3f << 7); | ||
| 1631 | else | ||
| 1632 | val |= 0x3f << 7; | ||
| 1633 | |||
| 1634 | pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); | ||
| 1635 | |||
| 1636 | addr = NB_PIF0_PWRDOWN_1; | ||
| 1637 | pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_ADDR, addr); | ||
| 1638 | pci_read_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, &val); | ||
| 1639 | if (disable) | ||
| 1640 | val &= ~(0x3f << 7); | ||
| 1641 | else | ||
| 1642 | val |= 0x3f << 7; | ||
| 1643 | |||
| 1644 | pci_write_config_dword(amd_nb_dev, NB_PCIE_INDX_DATA, val); | ||
| 1645 | } | ||
| 1646 | |||
| 1647 | return; | ||
| 1648 | } | ||
| 1649 | |||
| 1593 | /* fit urb's itds into the selected schedule slot; activate as needed */ | 1650 | /* fit urb's itds into the selected schedule slot; activate as needed */ |
| 1594 | static int | 1651 | static int |
| 1595 | itd_link_urb ( | 1652 | itd_link_urb ( |
| @@ -1616,6 +1673,12 @@ itd_link_urb ( | |||
| 1616 | urb->interval, | 1673 | urb->interval, |
| 1617 | next_uframe >> 3, next_uframe & 0x7); | 1674 | next_uframe >> 3, next_uframe & 0x7); |
| 1618 | } | 1675 | } |
| 1676 | |||
| 1677 | if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { | ||
| 1678 | if (ehci->amd_l1_fix == 1) | ||
| 1679 | ehci_quirk_amd_L1(ehci, 1); | ||
| 1680 | } | ||
| 1681 | |||
| 1619 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; | 1682 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; |
| 1620 | 1683 | ||
| 1621 | /* fill iTDs uframe by uframe */ | 1684 | /* fill iTDs uframe by uframe */ |
| @@ -1740,6 +1803,11 @@ itd_complete ( | |||
| 1740 | (void) disable_periodic(ehci); | 1803 | (void) disable_periodic(ehci); |
| 1741 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; | 1804 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; |
| 1742 | 1805 | ||
| 1806 | if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { | ||
| 1807 | if (ehci->amd_l1_fix == 1) | ||
| 1808 | ehci_quirk_amd_L1(ehci, 0); | ||
| 1809 | } | ||
| 1810 | |||
| 1743 | if (unlikely(list_is_singular(&stream->td_list))) { | 1811 | if (unlikely(list_is_singular(&stream->td_list))) { |
| 1744 | ehci_to_hcd(ehci)->self.bandwidth_allocated | 1812 | ehci_to_hcd(ehci)->self.bandwidth_allocated |
| 1745 | -= stream->bandwidth; | 1813 | -= stream->bandwidth; |
| @@ -2025,6 +2093,12 @@ sitd_link_urb ( | |||
| 2025 | (next_uframe >> 3) & (ehci->periodic_size - 1), | 2093 | (next_uframe >> 3) & (ehci->periodic_size - 1), |
| 2026 | stream->interval, hc32_to_cpu(ehci, stream->splits)); | 2094 | stream->interval, hc32_to_cpu(ehci, stream->splits)); |
| 2027 | } | 2095 | } |
| 2096 | |||
| 2097 | if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { | ||
| 2098 | if (ehci->amd_l1_fix == 1) | ||
| 2099 | ehci_quirk_amd_L1(ehci, 1); | ||
| 2100 | } | ||
| 2101 | |||
| 2028 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; | 2102 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; |
| 2029 | 2103 | ||
| 2030 | /* fill sITDs frame by frame */ | 2104 | /* fill sITDs frame by frame */ |
| @@ -2125,6 +2199,11 @@ sitd_complete ( | |||
| 2125 | (void) disable_periodic(ehci); | 2199 | (void) disable_periodic(ehci); |
| 2126 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; | 2200 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; |
| 2127 | 2201 | ||
| 2202 | if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { | ||
| 2203 | if (ehci->amd_l1_fix == 1) | ||
| 2204 | ehci_quirk_amd_L1(ehci, 0); | ||
| 2205 | } | ||
| 2206 | |||
| 2128 | if (list_is_singular(&stream->td_list)) { | 2207 | if (list_is_singular(&stream->td_list)) { |
| 2129 | ehci_to_hcd(ehci)->self.bandwidth_allocated | 2208 | ehci_to_hcd(ehci)->self.bandwidth_allocated |
| 2130 | -= stream->bandwidth; | 2209 | -= stream->bandwidth; |
diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c new file mode 100644 index 000000000000..595f70f42b52 --- /dev/null +++ b/drivers/usb/host/ehci-sh.c | |||
| @@ -0,0 +1,243 @@ | |||
| 1 | /* | ||
| 2 | * SuperH EHCI host controller driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Paul Mundt | ||
| 5 | * | ||
| 6 | * Based on ohci-sh.c and ehci-atmel.c. | ||
| 7 | * | ||
| 8 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 9 | * License. See the file "COPYING" in the main directory of this archive | ||
| 10 | * for more details. | ||
| 11 | */ | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/clk.h> | ||
| 14 | |||
| 15 | struct ehci_sh_priv { | ||
| 16 | struct clk *iclk, *fclk; | ||
| 17 | struct usb_hcd *hcd; | ||
| 18 | }; | ||
| 19 | |||
| 20 | static int ehci_sh_reset(struct usb_hcd *hcd) | ||
| 21 | { | ||
| 22 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 23 | int ret; | ||
| 24 | |||
| 25 | ehci->caps = hcd->regs; | ||
| 26 | ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, | ||
| 27 | &ehci->caps->hc_capbase)); | ||
| 28 | |||
| 29 | dbg_hcs_params(ehci, "reset"); | ||
| 30 | dbg_hcc_params(ehci, "reset"); | ||
| 31 | |||
| 32 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
| 33 | |||
| 34 | ret = ehci_halt(ehci); | ||
| 35 | if (unlikely(ret)) | ||
| 36 | return ret; | ||
| 37 | |||
| 38 | ret = ehci_init(hcd); | ||
| 39 | if (unlikely(ret)) | ||
| 40 | return ret; | ||
| 41 | |||
| 42 | ehci->sbrn = 0x20; | ||
| 43 | |||
| 44 | ehci_reset(ehci); | ||
| 45 | ehci_port_power(ehci, 0); | ||
| 46 | |||
| 47 | return ret; | ||
| 48 | } | ||
| 49 | |||
| 50 | static const struct hc_driver ehci_sh_hc_driver = { | ||
| 51 | .description = hcd_name, | ||
| 52 | .product_desc = "SuperH EHCI", | ||
| 53 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
| 54 | |||
| 55 | /* | ||
| 56 | * generic hardware linkage | ||
| 57 | */ | ||
| 58 | .irq = ehci_irq, | ||
| 59 | .flags = HCD_USB2 | HCD_MEMORY, | ||
| 60 | |||
| 61 | /* | ||
| 62 | * basic lifecycle operations | ||
| 63 | */ | ||
| 64 | .reset = ehci_sh_reset, | ||
| 65 | .start = ehci_run, | ||
| 66 | .stop = ehci_stop, | ||
| 67 | .shutdown = ehci_shutdown, | ||
| 68 | |||
| 69 | /* | ||
| 70 | * managing i/o requests and associated device resources | ||
| 71 | */ | ||
| 72 | .urb_enqueue = ehci_urb_enqueue, | ||
| 73 | .urb_dequeue = ehci_urb_dequeue, | ||
| 74 | .endpoint_disable = ehci_endpoint_disable, | ||
| 75 | .endpoint_reset = ehci_endpoint_reset, | ||
| 76 | |||
| 77 | /* | ||
| 78 | * scheduling support | ||
| 79 | */ | ||
| 80 | .get_frame_number = ehci_get_frame, | ||
| 81 | |||
| 82 | /* | ||
| 83 | * root hub support | ||
| 84 | */ | ||
| 85 | .hub_status_data = ehci_hub_status_data, | ||
| 86 | .hub_control = ehci_hub_control, | ||
| 87 | |||
| 88 | #ifdef CONFIG_PM | ||
| 89 | .bus_suspend = ehci_bus_suspend, | ||
| 90 | .bus_resume = ehci_bus_resume, | ||
| 91 | #endif | ||
| 92 | |||
| 93 | .relinquish_port = ehci_relinquish_port, | ||
| 94 | .port_handed_over = ehci_port_handed_over, | ||
| 95 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 96 | }; | ||
| 97 | |||
| 98 | static int ehci_hcd_sh_probe(struct platform_device *pdev) | ||
| 99 | { | ||
| 100 | const struct hc_driver *driver = &ehci_sh_hc_driver; | ||
| 101 | struct resource *res; | ||
| 102 | struct ehci_sh_priv *priv; | ||
| 103 | struct usb_hcd *hcd; | ||
| 104 | int irq, ret; | ||
| 105 | |||
| 106 | if (usb_disabled()) | ||
| 107 | return -ENODEV; | ||
| 108 | |||
| 109 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 110 | if (!res) { | ||
| 111 | dev_err(&pdev->dev, | ||
| 112 | "Found HC with no register addr. Check %s setup!\n", | ||
| 113 | dev_name(&pdev->dev)); | ||
| 114 | ret = -ENODEV; | ||
| 115 | goto fail_create_hcd; | ||
| 116 | } | ||
| 117 | |||
| 118 | irq = platform_get_irq(pdev, 0); | ||
| 119 | if (irq <= 0) { | ||
| 120 | dev_err(&pdev->dev, | ||
| 121 | "Found HC with no IRQ. Check %s setup!\n", | ||
| 122 | dev_name(&pdev->dev)); | ||
| 123 | ret = -ENODEV; | ||
| 124 | goto fail_create_hcd; | ||
| 125 | } | ||
| 126 | |||
| 127 | /* initialize hcd */ | ||
| 128 | hcd = usb_create_hcd(&ehci_sh_hc_driver, &pdev->dev, | ||
| 129 | dev_name(&pdev->dev)); | ||
| 130 | if (!hcd) { | ||
| 131 | ret = -ENOMEM; | ||
| 132 | goto fail_create_hcd; | ||
| 133 | } | ||
| 134 | |||
| 135 | hcd->rsrc_start = res->start; | ||
| 136 | hcd->rsrc_len = resource_size(res); | ||
| 137 | |||
| 138 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
| 139 | driver->description)) { | ||
| 140 | dev_dbg(&pdev->dev, "controller already in use\n"); | ||
| 141 | ret = -EBUSY; | ||
| 142 | goto fail_request_resource; | ||
| 143 | } | ||
| 144 | |||
| 145 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | ||
| 146 | if (hcd->regs == NULL) { | ||
| 147 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
| 148 | ret = -ENXIO; | ||
| 149 | goto fail_ioremap; | ||
| 150 | } | ||
| 151 | |||
| 152 | priv = kmalloc(sizeof(struct ehci_sh_priv), GFP_KERNEL); | ||
| 153 | if (!priv) { | ||
| 154 | dev_dbg(&pdev->dev, "error allocating priv data\n"); | ||
| 155 | ret = -ENOMEM; | ||
| 156 | goto fail_alloc; | ||
| 157 | } | ||
| 158 | |||
| 159 | /* These are optional, we don't care if they fail */ | ||
| 160 | priv->fclk = clk_get(&pdev->dev, "usb_fck"); | ||
| 161 | if (IS_ERR(priv->fclk)) | ||
| 162 | priv->fclk = NULL; | ||
| 163 | |||
| 164 | priv->iclk = clk_get(&pdev->dev, "usb_ick"); | ||
| 165 | if (IS_ERR(priv->iclk)) | ||
| 166 | priv->iclk = NULL; | ||
| 167 | |||
| 168 | clk_enable(priv->fclk); | ||
| 169 | clk_enable(priv->iclk); | ||
| 170 | |||
| 171 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); | ||
| 172 | if (ret != 0) { | ||
| 173 | dev_err(&pdev->dev, "Failed to add hcd"); | ||
| 174 | goto fail_add_hcd; | ||
| 175 | } | ||
| 176 | |||
| 177 | priv->hcd = hcd; | ||
| 178 | platform_set_drvdata(pdev, priv); | ||
| 179 | |||
| 180 | return ret; | ||
| 181 | |||
| 182 | fail_add_hcd: | ||
| 183 | clk_disable(priv->iclk); | ||
| 184 | clk_disable(priv->fclk); | ||
| 185 | |||
| 186 | clk_put(priv->iclk); | ||
| 187 | clk_put(priv->fclk); | ||
| 188 | |||
| 189 | kfree(priv); | ||
| 190 | fail_alloc: | ||
| 191 | iounmap(hcd->regs); | ||
| 192 | fail_ioremap: | ||
| 193 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 194 | fail_request_resource: | ||
| 195 | usb_put_hcd(hcd); | ||
| 196 | fail_create_hcd: | ||
| 197 | dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), ret); | ||
| 198 | |||
| 199 | return ret; | ||
| 200 | } | ||
| 201 | |||
| 202 | static int __exit ehci_hcd_sh_remove(struct platform_device *pdev) | ||
| 203 | { | ||
| 204 | struct ehci_sh_priv *priv = platform_get_drvdata(pdev); | ||
| 205 | struct usb_hcd *hcd = priv->hcd; | ||
| 206 | |||
| 207 | usb_remove_hcd(hcd); | ||
| 208 | iounmap(hcd->regs); | ||
| 209 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 210 | usb_put_hcd(hcd); | ||
| 211 | platform_set_drvdata(pdev, NULL); | ||
| 212 | |||
| 213 | clk_disable(priv->fclk); | ||
| 214 | clk_disable(priv->iclk); | ||
| 215 | |||
| 216 | clk_put(priv->fclk); | ||
| 217 | clk_put(priv->iclk); | ||
| 218 | |||
| 219 | kfree(priv); | ||
| 220 | |||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | static void ehci_hcd_sh_shutdown(struct platform_device *pdev) | ||
| 225 | { | ||
| 226 | struct ehci_sh_priv *priv = platform_get_drvdata(pdev); | ||
| 227 | struct usb_hcd *hcd = priv->hcd; | ||
| 228 | |||
| 229 | if (hcd->driver->shutdown) | ||
| 230 | hcd->driver->shutdown(hcd); | ||
| 231 | } | ||
| 232 | |||
| 233 | static struct platform_driver ehci_hcd_sh_driver = { | ||
| 234 | .probe = ehci_hcd_sh_probe, | ||
| 235 | .remove = __exit_p(ehci_hcd_sh_remove), | ||
| 236 | .shutdown = ehci_hcd_sh_shutdown, | ||
| 237 | .driver = { | ||
| 238 | .name = "sh_ehci", | ||
| 239 | .owner = THIS_MODULE, | ||
| 240 | }, | ||
| 241 | }; | ||
| 242 | |||
| 243 | MODULE_ALIAS("platform:sh_ehci"); | ||
diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c new file mode 100644 index 000000000000..75c00873443d --- /dev/null +++ b/drivers/usb/host/ehci-spear.c | |||
| @@ -0,0 +1,212 @@ | |||
| 1 | /* | ||
| 2 | * Driver for EHCI HCD on SPEAR SOC | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 ST Micro Electronics, | ||
| 5 | * Deepak Sikri <deepak.sikri@st.com> | ||
| 6 | * | ||
| 7 | * Based on various ehci-*.c drivers | ||
| 8 | * | ||
| 9 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 10 | * License. See the file COPYING in the main directory of this archive for | ||
| 11 | * more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/clk.h> | ||
| 16 | |||
| 17 | struct spear_ehci { | ||
| 18 | struct ehci_hcd ehci; | ||
| 19 | struct clk *clk; | ||
| 20 | }; | ||
| 21 | |||
| 22 | #define to_spear_ehci(hcd) (struct spear_ehci *)hcd_to_ehci(hcd) | ||
| 23 | |||
| 24 | static void spear_start_ehci(struct spear_ehci *ehci) | ||
| 25 | { | ||
| 26 | clk_enable(ehci->clk); | ||
| 27 | } | ||
| 28 | |||
| 29 | static void spear_stop_ehci(struct spear_ehci *ehci) | ||
| 30 | { | ||
| 31 | clk_disable(ehci->clk); | ||
| 32 | } | ||
| 33 | |||
| 34 | static int ehci_spear_setup(struct usb_hcd *hcd) | ||
| 35 | { | ||
| 36 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 37 | int retval = 0; | ||
| 38 | |||
| 39 | /* registers start at offset 0x0 */ | ||
| 40 | ehci->caps = hcd->regs; | ||
| 41 | ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, | ||
| 42 | &ehci->caps->hc_capbase)); | ||
| 43 | /* cache this readonly data; minimize chip reads */ | ||
| 44 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
| 45 | retval = ehci_halt(ehci); | ||
| 46 | if (retval) | ||
| 47 | return retval; | ||
| 48 | |||
| 49 | retval = ehci_init(hcd); | ||
| 50 | if (retval) | ||
| 51 | return retval; | ||
| 52 | |||
| 53 | ehci_reset(ehci); | ||
| 54 | ehci_port_power(ehci, 0); | ||
| 55 | |||
| 56 | return retval; | ||
| 57 | } | ||
| 58 | |||
| 59 | static const struct hc_driver ehci_spear_hc_driver = { | ||
| 60 | .description = hcd_name, | ||
| 61 | .product_desc = "SPEAr EHCI", | ||
| 62 | .hcd_priv_size = sizeof(struct spear_ehci), | ||
| 63 | |||
| 64 | /* generic hardware linkage */ | ||
| 65 | .irq = ehci_irq, | ||
| 66 | .flags = HCD_MEMORY | HCD_USB2, | ||
| 67 | |||
| 68 | /* basic lifecycle operations */ | ||
| 69 | .reset = ehci_spear_setup, | ||
| 70 | .start = ehci_run, | ||
| 71 | .stop = ehci_stop, | ||
| 72 | .shutdown = ehci_shutdown, | ||
| 73 | |||
| 74 | /* managing i/o requests and associated device resources */ | ||
| 75 | .urb_enqueue = ehci_urb_enqueue, | ||
| 76 | .urb_dequeue = ehci_urb_dequeue, | ||
| 77 | .endpoint_disable = ehci_endpoint_disable, | ||
| 78 | .endpoint_reset = ehci_endpoint_reset, | ||
| 79 | |||
| 80 | /* scheduling support */ | ||
| 81 | .get_frame_number = ehci_get_frame, | ||
| 82 | |||
| 83 | /* root hub support */ | ||
| 84 | .hub_status_data = ehci_hub_status_data, | ||
| 85 | .hub_control = ehci_hub_control, | ||
| 86 | .bus_suspend = ehci_bus_suspend, | ||
| 87 | .bus_resume = ehci_bus_resume, | ||
| 88 | .relinquish_port = ehci_relinquish_port, | ||
| 89 | .port_handed_over = ehci_port_handed_over, | ||
| 90 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 91 | }; | ||
| 92 | |||
| 93 | static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) | ||
| 94 | { | ||
| 95 | struct usb_hcd *hcd ; | ||
| 96 | struct spear_ehci *ehci; | ||
| 97 | struct resource *res; | ||
| 98 | struct clk *usbh_clk; | ||
| 99 | const struct hc_driver *driver = &ehci_spear_hc_driver; | ||
| 100 | int *pdata = pdev->dev.platform_data; | ||
| 101 | int irq, retval; | ||
| 102 | char clk_name[20] = "usbh_clk"; | ||
| 103 | |||
| 104 | if (pdata == NULL) | ||
| 105 | return -EFAULT; | ||
| 106 | |||
| 107 | if (usb_disabled()) | ||
| 108 | return -ENODEV; | ||
| 109 | |||
| 110 | irq = platform_get_irq(pdev, 0); | ||
| 111 | if (irq < 0) { | ||
| 112 | retval = irq; | ||
| 113 | goto fail_irq_get; | ||
| 114 | } | ||
| 115 | |||
| 116 | if (*pdata >= 0) | ||
| 117 | sprintf(clk_name, "usbh.%01d_clk", *pdata); | ||
| 118 | |||
| 119 | usbh_clk = clk_get(NULL, clk_name); | ||
| 120 | if (IS_ERR(usbh_clk)) { | ||
| 121 | dev_err(&pdev->dev, "Error getting interface clock\n"); | ||
| 122 | retval = PTR_ERR(usbh_clk); | ||
| 123 | goto fail_get_usbh_clk; | ||
| 124 | } | ||
| 125 | |||
| 126 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | ||
| 127 | if (!hcd) { | ||
| 128 | retval = -ENOMEM; | ||
| 129 | goto fail_create_hcd; | ||
| 130 | } | ||
| 131 | |||
| 132 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 133 | if (!res) { | ||
| 134 | retval = -ENODEV; | ||
| 135 | goto fail_request_resource; | ||
| 136 | } | ||
| 137 | |||
| 138 | hcd->rsrc_start = res->start; | ||
| 139 | hcd->rsrc_len = resource_size(res); | ||
| 140 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, | ||
| 141 | driver->description)) { | ||
| 142 | retval = -EBUSY; | ||
| 143 | goto fail_request_resource; | ||
| 144 | } | ||
| 145 | |||
| 146 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
| 147 | if (hcd->regs == NULL) { | ||
| 148 | dev_dbg(&pdev->dev, "error mapping memory\n"); | ||
| 149 | retval = -ENOMEM; | ||
| 150 | goto fail_ioremap; | ||
| 151 | } | ||
| 152 | |||
| 153 | ehci = (struct spear_ehci *)hcd_to_ehci(hcd); | ||
| 154 | ehci->clk = usbh_clk; | ||
| 155 | |||
| 156 | spear_start_ehci(ehci); | ||
| 157 | retval = usb_add_hcd(hcd, irq, IRQF_SHARED | IRQF_DISABLED); | ||
| 158 | if (retval) | ||
| 159 | goto fail_add_hcd; | ||
| 160 | |||
| 161 | return retval; | ||
| 162 | |||
| 163 | fail_add_hcd: | ||
| 164 | spear_stop_ehci(ehci); | ||
| 165 | iounmap(hcd->regs); | ||
| 166 | fail_ioremap: | ||
| 167 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 168 | fail_request_resource: | ||
| 169 | usb_put_hcd(hcd); | ||
| 170 | fail_create_hcd: | ||
| 171 | clk_put(usbh_clk); | ||
| 172 | fail_get_usbh_clk: | ||
| 173 | fail_irq_get: | ||
| 174 | dev_err(&pdev->dev, "init fail, %d\n", retval); | ||
| 175 | |||
| 176 | return retval ; | ||
| 177 | } | ||
| 178 | |||
| 179 | static int spear_ehci_hcd_drv_remove(struct platform_device *pdev) | ||
| 180 | { | ||
| 181 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
| 182 | struct spear_ehci *ehci_p = to_spear_ehci(hcd); | ||
| 183 | |||
| 184 | if (!hcd) | ||
| 185 | return 0; | ||
| 186 | if (in_interrupt()) | ||
| 187 | BUG(); | ||
| 188 | usb_remove_hcd(hcd); | ||
| 189 | |||
| 190 | if (ehci_p->clk) | ||
| 191 | spear_stop_ehci(ehci_p); | ||
| 192 | iounmap(hcd->regs); | ||
| 193 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 194 | usb_put_hcd(hcd); | ||
| 195 | |||
| 196 | if (ehci_p->clk) | ||
| 197 | clk_put(ehci_p->clk); | ||
| 198 | |||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | static struct platform_driver spear_ehci_hcd_driver = { | ||
| 203 | .probe = spear_ehci_hcd_drv_probe, | ||
| 204 | .remove = spear_ehci_hcd_drv_remove, | ||
| 205 | .shutdown = usb_hcd_platform_shutdown, | ||
| 206 | .driver = { | ||
| 207 | .name = "spear-ehci", | ||
| 208 | .bus = &platform_bus_type | ||
| 209 | } | ||
| 210 | }; | ||
| 211 | |||
| 212 | MODULE_ALIAS("platform:spear-ehci"); | ||
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c new file mode 100644 index 000000000000..20168062035a --- /dev/null +++ b/drivers/usb/host/ehci-vt8500.c | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | /* | ||
| 2 | * drivers/usb/host/ehci-vt8500.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com> | ||
| 5 | * | ||
| 6 | * Based on ehci-au1xxx.c | ||
| 7 | * | ||
| 8 | * This software is licensed under the terms of the GNU General Public | ||
| 9 | * License version 2, as published by the Free Software Foundation, and | ||
| 10 | * may be copied, distributed, and modified under those terms. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/platform_device.h> | ||
| 20 | |||
| 21 | static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev) | ||
| 22 | { | ||
| 23 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
| 24 | int rc = 0; | ||
| 25 | |||
| 26 | if (!udev->parent) /* udev is root hub itself, impossible */ | ||
| 27 | rc = -1; | ||
| 28 | /* we only support lpm device connected to root hub yet */ | ||
| 29 | if (ehci->has_lpm && !udev->parent->parent) { | ||
| 30 | rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum); | ||
| 31 | if (!rc) | ||
| 32 | rc = ehci_lpm_check(ehci, udev->portnum); | ||
| 33 | } | ||
| 34 | return rc; | ||
| 35 | } | ||
| 36 | |||
| 37 | static const struct hc_driver vt8500_ehci_hc_driver = { | ||
| 38 | .description = hcd_name, | ||
| 39 | .product_desc = "VT8500 EHCI", | ||
| 40 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
| 41 | |||
| 42 | /* | ||
| 43 | * generic hardware linkage | ||
| 44 | */ | ||
| 45 | .irq = ehci_irq, | ||
| 46 | .flags = HCD_MEMORY | HCD_USB2, | ||
| 47 | |||
| 48 | /* | ||
| 49 | * basic lifecycle operations | ||
| 50 | */ | ||
| 51 | .reset = ehci_init, | ||
| 52 | .start = ehci_run, | ||
| 53 | .stop = ehci_stop, | ||
| 54 | .shutdown = ehci_shutdown, | ||
| 55 | |||
| 56 | /* | ||
| 57 | * managing i/o requests and associated device resources | ||
| 58 | */ | ||
| 59 | .urb_enqueue = ehci_urb_enqueue, | ||
| 60 | .urb_dequeue = ehci_urb_dequeue, | ||
| 61 | .endpoint_disable = ehci_endpoint_disable, | ||
| 62 | .endpoint_reset = ehci_endpoint_reset, | ||
| 63 | |||
| 64 | /* | ||
| 65 | * scheduling support | ||
| 66 | */ | ||
| 67 | .get_frame_number = ehci_get_frame, | ||
| 68 | |||
| 69 | /* | ||
| 70 | * root hub support | ||
| 71 | */ | ||
| 72 | .hub_status_data = ehci_hub_status_data, | ||
| 73 | .hub_control = ehci_hub_control, | ||
| 74 | .bus_suspend = ehci_bus_suspend, | ||
| 75 | .bus_resume = ehci_bus_resume, | ||
| 76 | .relinquish_port = ehci_relinquish_port, | ||
| 77 | .port_handed_over = ehci_port_handed_over, | ||
| 78 | |||
| 79 | /* | ||
| 80 | * call back when device connected and addressed | ||
| 81 | */ | ||
| 82 | .update_device = ehci_update_device, | ||
| 83 | |||
| 84 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static int vt8500_ehci_drv_probe(struct platform_device *pdev) | ||
| 88 | { | ||
| 89 | struct usb_hcd *hcd; | ||
| 90 | struct ehci_hcd *ehci; | ||
| 91 | struct resource *res; | ||
| 92 | int ret; | ||
| 93 | |||
| 94 | if (usb_disabled()) | ||
| 95 | return -ENODEV; | ||
| 96 | |||
| 97 | if (pdev->resource[1].flags != IORESOURCE_IRQ) { | ||
| 98 | pr_debug("resource[1] is not IORESOURCE_IRQ"); | ||
| 99 | return -ENOMEM; | ||
| 100 | } | ||
| 101 | hcd = usb_create_hcd(&vt8500_ehci_hc_driver, &pdev->dev, "VT8500"); | ||
| 102 | if (!hcd) | ||
| 103 | return -ENOMEM; | ||
| 104 | |||
| 105 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 106 | hcd->rsrc_start = res->start; | ||
| 107 | hcd->rsrc_len = resource_size(res); | ||
| 108 | |||
| 109 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
| 110 | pr_debug("request_mem_region failed"); | ||
| 111 | ret = -EBUSY; | ||
| 112 | goto err1; | ||
| 113 | } | ||
| 114 | |||
| 115 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
| 116 | if (!hcd->regs) { | ||
| 117 | pr_debug("ioremap failed"); | ||
| 118 | ret = -ENOMEM; | ||
| 119 | goto err2; | ||
| 120 | } | ||
| 121 | |||
| 122 | ehci = hcd_to_ehci(hcd); | ||
| 123 | ehci->caps = hcd->regs; | ||
| 124 | ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); | ||
| 125 | |||
| 126 | dbg_hcs_params(ehci, "reset"); | ||
| 127 | dbg_hcc_params(ehci, "reset"); | ||
| 128 | |||
| 129 | /* cache this readonly data; minimize chip reads */ | ||
| 130 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | ||
| 131 | |||
| 132 | ehci_port_power(ehci, 1); | ||
| 133 | |||
| 134 | ret = usb_add_hcd(hcd, pdev->resource[1].start, | ||
| 135 | IRQF_DISABLED | IRQF_SHARED); | ||
| 136 | if (ret == 0) { | ||
| 137 | platform_set_drvdata(pdev, hcd); | ||
| 138 | return ret; | ||
| 139 | } | ||
| 140 | |||
| 141 | iounmap(hcd->regs); | ||
| 142 | err2: | ||
| 143 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 144 | err1: | ||
| 145 | usb_put_hcd(hcd); | ||
| 146 | return ret; | ||
| 147 | } | ||
| 148 | |||
| 149 | static int vt8500_ehci_drv_remove(struct platform_device *pdev) | ||
| 150 | { | ||
| 151 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
| 152 | |||
| 153 | usb_remove_hcd(hcd); | ||
| 154 | iounmap(hcd->regs); | ||
| 155 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 156 | usb_put_hcd(hcd); | ||
| 157 | platform_set_drvdata(pdev, NULL); | ||
| 158 | |||
| 159 | return 0; | ||
| 160 | } | ||
| 161 | |||
| 162 | static struct platform_driver vt8500_ehci_driver = { | ||
| 163 | .probe = vt8500_ehci_drv_probe, | ||
| 164 | .remove = vt8500_ehci_drv_remove, | ||
| 165 | .shutdown = usb_hcd_platform_shutdown, | ||
| 166 | .driver = { | ||
| 167 | .name = "vt8500-ehci", | ||
| 168 | .owner = THIS_MODULE, | ||
| 169 | } | ||
| 170 | }; | ||
| 171 | |||
| 172 | MODULE_ALIAS("platform:vt8500-ehci"); | ||
diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index cfa21ea20f82..6bc35809a5c6 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c | |||
| @@ -130,6 +130,7 @@ static const struct hc_driver ehci_w90x900_hc_driver = { | |||
| 130 | .urb_enqueue = ehci_urb_enqueue, | 130 | .urb_enqueue = ehci_urb_enqueue, |
| 131 | .urb_dequeue = ehci_urb_dequeue, | 131 | .urb_dequeue = ehci_urb_dequeue, |
| 132 | .endpoint_disable = ehci_endpoint_disable, | 132 | .endpoint_disable = ehci_endpoint_disable, |
| 133 | .endpoint_reset = ehci_endpoint_reset, | ||
| 133 | 134 | ||
| 134 | /* | 135 | /* |
| 135 | * scheduling support | 136 | * scheduling support |
| @@ -147,6 +148,8 @@ static const struct hc_driver ehci_w90x900_hc_driver = { | |||
| 147 | #endif | 148 | #endif |
| 148 | .relinquish_port = ehci_relinquish_port, | 149 | .relinquish_port = ehci_relinquish_port, |
| 149 | .port_handed_over = ehci_port_handed_over, | 150 | .port_handed_over = ehci_port_handed_over, |
| 151 | |||
| 152 | .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, | ||
| 150 | }; | 153 | }; |
| 151 | 154 | ||
| 152 | static int __devinit ehci_w90x900_probe(struct platform_device *pdev) | 155 | static int __devinit ehci_w90x900_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index 6c8076ad821d..e8f4f36fdf0b 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c | |||
| @@ -117,6 +117,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = { | |||
| 117 | .urb_enqueue = ehci_urb_enqueue, | 117 | .urb_enqueue = ehci_urb_enqueue, |
| 118 | .urb_dequeue = ehci_urb_dequeue, | 118 | .urb_dequeue = ehci_urb_dequeue, |
| 119 | .endpoint_disable = ehci_endpoint_disable, | 119 | .endpoint_disable = ehci_endpoint_disable, |
| 120 | .endpoint_reset = ehci_endpoint_reset, | ||
| 120 | 121 | ||
| 121 | /* | 122 | /* |
| 122 | * scheduling support | 123 | * scheduling support |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index ba8eab366b82..799ac16a54b4 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
| @@ -131,6 +131,7 @@ struct ehci_hcd { /* one per controller */ | |||
| 131 | unsigned has_amcc_usb23:1; | 131 | unsigned has_amcc_usb23:1; |
| 132 | unsigned need_io_watchdog:1; | 132 | unsigned need_io_watchdog:1; |
| 133 | unsigned broken_periodic:1; | 133 | unsigned broken_periodic:1; |
| 134 | unsigned amd_l1_fix:1; | ||
| 134 | unsigned fs_i_thresh:1; /* Intel iso scheduling */ | 135 | unsigned fs_i_thresh:1; /* Intel iso scheduling */ |
| 135 | unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ | 136 | unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ |
| 136 | 137 | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 5179acb7aa2f..4a4a4f025385 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
| @@ -1081,6 +1081,11 @@ MODULE_LICENSE ("GPL"); | |||
| 1081 | #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver | 1081 | #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver |
| 1082 | #endif | 1082 | #endif |
| 1083 | 1083 | ||
| 1084 | #ifdef CONFIG_PLAT_SPEAR | ||
| 1085 | #include "ohci-spear.c" | ||
| 1086 | #define PLATFORM_DRIVER spear_ohci_hcd_driver | ||
| 1087 | #endif | ||
| 1088 | |||
| 1084 | #ifdef CONFIG_PPC_PS3 | 1089 | #ifdef CONFIG_PPC_PS3 |
| 1085 | #include "ohci-ps3.c" | 1090 | #include "ohci-ps3.c" |
| 1086 | #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver | 1091 | #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver |
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c index 0b35d22cc70e..f47867ff78c7 100644 --- a/drivers/usb/host/ohci-sh.c +++ b/drivers/usb/host/ohci-sh.c | |||
| @@ -109,7 +109,7 @@ static int ohci_hcd_sh_probe(struct platform_device *pdev) | |||
| 109 | hcd->regs = (void __iomem *)res->start; | 109 | hcd->regs = (void __iomem *)res->start; |
| 110 | hcd->rsrc_start = res->start; | 110 | hcd->rsrc_start = res->start; |
| 111 | hcd->rsrc_len = resource_size(res); | 111 | hcd->rsrc_len = resource_size(res); |
| 112 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 112 | ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); |
| 113 | if (ret != 0) { | 113 | if (ret != 0) { |
| 114 | err("Failed to add hcd"); | 114 | err("Failed to add hcd"); |
| 115 | usb_put_hcd(hcd); | 115 | usb_put_hcd(hcd); |
diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c new file mode 100644 index 000000000000..4fd4bea9ac7a --- /dev/null +++ b/drivers/usb/host/ohci-spear.c | |||
| @@ -0,0 +1,240 @@ | |||
| 1 | /* | ||
| 2 | * OHCI HCD (Host Controller Driver) for USB. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 ST Microelectronics. | ||
| 5 | * Deepak Sikri<deepak.sikri@st.com> | ||
| 6 | * | ||
| 7 | * Based on various ohci-*.c drivers | ||
| 8 | * | ||
| 9 | * This file is licensed under the terms of the GNU General Public | ||
| 10 | * License version 2. This program is licensed "as is" without any | ||
| 11 | * warranty of any kind, whether express or implied. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/signal.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/clk.h> | ||
| 17 | |||
| 18 | struct spear_ohci { | ||
| 19 | struct ohci_hcd ohci; | ||
| 20 | struct clk *clk; | ||
| 21 | }; | ||
| 22 | |||
| 23 | #define to_spear_ohci(hcd) (struct spear_ohci *)hcd_to_ohci(hcd) | ||
| 24 | |||
| 25 | static void spear_start_ohci(struct spear_ohci *ohci) | ||
| 26 | { | ||
| 27 | clk_enable(ohci->clk); | ||
| 28 | } | ||
| 29 | |||
| 30 | static void spear_stop_ohci(struct spear_ohci *ohci) | ||
| 31 | { | ||
| 32 | clk_disable(ohci->clk); | ||
| 33 | } | ||
| 34 | |||
| 35 | static int __devinit ohci_spear_start(struct usb_hcd *hcd) | ||
| 36 | { | ||
| 37 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
| 38 | int ret; | ||
| 39 | |||
| 40 | ret = ohci_init(ohci); | ||
| 41 | if (ret < 0) | ||
| 42 | return ret; | ||
| 43 | ohci->regs = hcd->regs; | ||
| 44 | |||
| 45 | ret = ohci_run(ohci); | ||
| 46 | if (ret < 0) { | ||
| 47 | dev_err(hcd->self.controller, "can't start\n"); | ||
| 48 | ohci_stop(hcd); | ||
| 49 | return ret; | ||
| 50 | } | ||
| 51 | |||
| 52 | create_debug_files(ohci); | ||
| 53 | |||
| 54 | #ifdef DEBUG | ||
| 55 | ohci_dump(ohci, 1); | ||
| 56 | #endif | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | static const struct hc_driver ohci_spear_hc_driver = { | ||
| 61 | .description = hcd_name, | ||
| 62 | .product_desc = "SPEAr OHCI", | ||
| 63 | .hcd_priv_size = sizeof(struct spear_ohci), | ||
| 64 | |||
| 65 | /* generic hardware linkage */ | ||
| 66 | .irq = ohci_irq, | ||
| 67 | .flags = HCD_USB11 | HCD_MEMORY, | ||
| 68 | |||
| 69 | /* basic lifecycle operations */ | ||
| 70 | .start = ohci_spear_start, | ||
| 71 | .stop = ohci_stop, | ||
| 72 | .shutdown = ohci_shutdown, | ||
| 73 | #ifdef CONFIG_PM | ||
| 74 | .bus_suspend = ohci_bus_suspend, | ||
| 75 | .bus_resume = ohci_bus_resume, | ||
| 76 | #endif | ||
| 77 | |||
| 78 | /* managing i/o requests and associated device resources */ | ||
| 79 | .urb_enqueue = ohci_urb_enqueue, | ||
| 80 | .urb_dequeue = ohci_urb_dequeue, | ||
| 81 | .endpoint_disable = ohci_endpoint_disable, | ||
| 82 | |||
| 83 | /* scheduling support */ | ||
| 84 | .get_frame_number = ohci_get_frame, | ||
| 85 | |||
| 86 | /* root hub support */ | ||
| 87 | .hub_status_data = ohci_hub_status_data, | ||
| 88 | .hub_control = ohci_hub_control, | ||
| 89 | |||
| 90 | .start_port_reset = ohci_start_port_reset, | ||
| 91 | }; | ||
| 92 | |||
| 93 | static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) | ||
| 94 | { | ||
| 95 | const struct hc_driver *driver = &ohci_spear_hc_driver; | ||
| 96 | struct usb_hcd *hcd = NULL; | ||
| 97 | struct clk *usbh_clk; | ||
| 98 | struct spear_ohci *ohci_p; | ||
| 99 | struct resource *res; | ||
| 100 | int retval, irq; | ||
| 101 | int *pdata = pdev->dev.platform_data; | ||
| 102 | char clk_name[20] = "usbh_clk"; | ||
| 103 | |||
| 104 | if (pdata == NULL) | ||
| 105 | return -EFAULT; | ||
| 106 | |||
| 107 | irq = platform_get_irq(pdev, 0); | ||
| 108 | if (irq < 0) { | ||
| 109 | retval = irq; | ||
| 110 | goto fail_irq_get; | ||
| 111 | } | ||
| 112 | |||
| 113 | if (*pdata >= 0) | ||
| 114 | sprintf(clk_name, "usbh.%01d_clk", *pdata); | ||
| 115 | |||
| 116 | usbh_clk = clk_get(NULL, clk_name); | ||
| 117 | if (IS_ERR(usbh_clk)) { | ||
| 118 | dev_err(&pdev->dev, "Error getting interface clock\n"); | ||
| 119 | retval = PTR_ERR(usbh_clk); | ||
| 120 | goto fail_get_usbh_clk; | ||
| 121 | } | ||
| 122 | |||
| 123 | hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); | ||
| 124 | if (!hcd) { | ||
| 125 | retval = -ENOMEM; | ||
| 126 | goto fail_create_hcd; | ||
| 127 | } | ||
| 128 | |||
| 129 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 130 | if (!res) { | ||
| 131 | retval = -ENODEV; | ||
| 132 | goto fail_request_resource; | ||
| 133 | } | ||
| 134 | |||
| 135 | hcd->rsrc_start = pdev->resource[0].start; | ||
| 136 | hcd->rsrc_len = resource_size(res); | ||
| 137 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
| 138 | dev_dbg(&pdev->dev, "request_mem_region failed\n"); | ||
| 139 | retval = -EBUSY; | ||
| 140 | goto fail_request_resource; | ||
| 141 | } | ||
| 142 | |||
| 143 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
| 144 | if (!hcd->regs) { | ||
| 145 | dev_dbg(&pdev->dev, "ioremap failed\n"); | ||
| 146 | retval = -ENOMEM; | ||
| 147 | goto fail_ioremap; | ||
| 148 | } | ||
| 149 | |||
| 150 | ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd); | ||
| 151 | ohci_p->clk = usbh_clk; | ||
| 152 | spear_start_ohci(ohci_p); | ||
| 153 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
| 154 | |||
| 155 | retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), IRQF_DISABLED); | ||
| 156 | if (retval == 0) | ||
| 157 | return retval; | ||
| 158 | |||
| 159 | spear_stop_ohci(ohci_p); | ||
| 160 | iounmap(hcd->regs); | ||
| 161 | fail_ioremap: | ||
| 162 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 163 | fail_request_resource: | ||
| 164 | usb_put_hcd(hcd); | ||
| 165 | fail_create_hcd: | ||
| 166 | clk_put(usbh_clk); | ||
| 167 | fail_get_usbh_clk: | ||
| 168 | fail_irq_get: | ||
| 169 | dev_err(&pdev->dev, "init fail, %d\n", retval); | ||
| 170 | |||
| 171 | return retval; | ||
| 172 | } | ||
| 173 | |||
| 174 | static int spear_ohci_hcd_drv_remove(struct platform_device *pdev) | ||
| 175 | { | ||
| 176 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
| 177 | struct spear_ohci *ohci_p = to_spear_ohci(hcd); | ||
| 178 | |||
| 179 | usb_remove_hcd(hcd); | ||
| 180 | if (ohci_p->clk) | ||
| 181 | spear_stop_ohci(ohci_p); | ||
| 182 | |||
| 183 | iounmap(hcd->regs); | ||
| 184 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
| 185 | usb_put_hcd(hcd); | ||
| 186 | |||
| 187 | if (ohci_p->clk) | ||
| 188 | clk_put(ohci_p->clk); | ||
| 189 | platform_set_drvdata(pdev, NULL); | ||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | |||
| 193 | #if defined(CONFIG_PM) | ||
| 194 | static int spear_ohci_hcd_drv_suspend(struct platform_device *dev, | ||
| 195 | pm_message_t message) | ||
| 196 | { | ||
| 197 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
| 198 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
| 199 | struct spear_ohci *ohci_p = to_spear_ohci(hcd); | ||
| 200 | |||
| 201 | if (time_before(jiffies, ohci->next_statechange)) | ||
| 202 | msleep(5); | ||
| 203 | ohci->next_statechange = jiffies; | ||
| 204 | |||
| 205 | spear_stop_ohci(ohci_p); | ||
| 206 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | ||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | static int spear_ohci_hcd_drv_resume(struct platform_device *dev) | ||
| 211 | { | ||
| 212 | struct usb_hcd *hcd = platform_get_drvdata(dev); | ||
| 213 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
| 214 | struct spear_ohci *ohci_p = to_spear_ohci(hcd); | ||
| 215 | |||
| 216 | if (time_before(jiffies, ohci->next_statechange)) | ||
| 217 | msleep(5); | ||
| 218 | ohci->next_statechange = jiffies; | ||
| 219 | |||
| 220 | spear_start_ohci(ohci_p); | ||
| 221 | ohci_finish_controller_resume(hcd); | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | #endif | ||
| 225 | |||
| 226 | /* Driver definition to register with the platform bus */ | ||
| 227 | static struct platform_driver spear_ohci_hcd_driver = { | ||
| 228 | .probe = spear_ohci_hcd_drv_probe, | ||
| 229 | .remove = spear_ohci_hcd_drv_remove, | ||
| 230 | #ifdef CONFIG_PM | ||
| 231 | .suspend = spear_ohci_hcd_drv_suspend, | ||
| 232 | .resume = spear_ohci_hcd_drv_resume, | ||
| 233 | #endif | ||
| 234 | .driver = { | ||
| 235 | .owner = THIS_MODULE, | ||
| 236 | .name = "spear-ohci", | ||
| 237 | }, | ||
| 238 | }; | ||
| 239 | |||
| 240 | MODULE_ALIAS("platform:spear-ohci"); | ||
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index f52d04db28f4..cee867829ec9 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
| @@ -569,7 +569,7 @@ static int uhci_init(struct usb_hcd *hcd) | |||
| 569 | */ | 569 | */ |
| 570 | static void uhci_shutdown(struct pci_dev *pdev) | 570 | static void uhci_shutdown(struct pci_dev *pdev) |
| 571 | { | 571 | { |
| 572 | struct usb_hcd *hcd = (struct usb_hcd *) pci_get_drvdata(pdev); | 572 | struct usb_hcd *hcd = pci_get_drvdata(pdev); |
| 573 | 573 | ||
| 574 | uhci_hc_died(hcd_to_uhci(hcd)); | 574 | uhci_hc_died(hcd_to_uhci(hcd)); |
| 575 | } | 575 | } |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 2090b45eb606..af77abb5c68b 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
| @@ -29,7 +29,7 @@ static void uhci_set_next_interrupt(struct uhci_hcd *uhci) | |||
| 29 | { | 29 | { |
| 30 | if (uhci->is_stopped) | 30 | if (uhci->is_stopped) |
| 31 | mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); | 31 | mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); |
| 32 | uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); | 32 | uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) | 35 | static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) |
| @@ -195,7 +195,9 @@ static inline void uhci_remove_td_from_frame_list(struct uhci_hcd *uhci, | |||
| 195 | } else { | 195 | } else { |
| 196 | struct uhci_td *ntd; | 196 | struct uhci_td *ntd; |
| 197 | 197 | ||
| 198 | ntd = list_entry(td->fl_list.next, struct uhci_td, fl_list); | 198 | ntd = list_entry(td->fl_list.next, |
| 199 | struct uhci_td, | ||
| 200 | fl_list); | ||
| 199 | uhci->frame[td->frame] = LINK_TO_TD(ntd); | 201 | uhci->frame[td->frame] = LINK_TO_TD(ntd); |
| 200 | uhci->frame_cpu[td->frame] = ntd; | 202 | uhci->frame_cpu[td->frame] = ntd; |
| 201 | } | 203 | } |
| @@ -728,7 +730,7 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, | |||
| 728 | 730 | ||
| 729 | urbp->urb = urb; | 731 | urbp->urb = urb; |
| 730 | urb->hcpriv = urbp; | 732 | urb->hcpriv = urbp; |
| 731 | 733 | ||
| 732 | INIT_LIST_HEAD(&urbp->node); | 734 | INIT_LIST_HEAD(&urbp->node); |
| 733 | INIT_LIST_HEAD(&urbp->td_list); | 735 | INIT_LIST_HEAD(&urbp->td_list); |
| 734 | 736 | ||
| @@ -846,7 +848,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
| 846 | 848 | ||
| 847 | /* Alternate Data0/1 (start with Data1) */ | 849 | /* Alternate Data0/1 (start with Data1) */ |
| 848 | destination ^= TD_TOKEN_TOGGLE; | 850 | destination ^= TD_TOKEN_TOGGLE; |
| 849 | 851 | ||
| 850 | uhci_add_td_to_urbp(td, urbp); | 852 | uhci_add_td_to_urbp(td, urbp); |
| 851 | uhci_fill_td(td, status, destination | uhci_explen(pktsze), | 853 | uhci_fill_td(td, status, destination | uhci_explen(pktsze), |
| 852 | data); | 854 | data); |
| @@ -857,7 +859,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
| 857 | } | 859 | } |
| 858 | 860 | ||
| 859 | /* | 861 | /* |
| 860 | * Build the final TD for control status | 862 | * Build the final TD for control status |
| 861 | */ | 863 | */ |
| 862 | td = uhci_alloc_td(uhci); | 864 | td = uhci_alloc_td(uhci); |
| 863 | if (!td) | 865 | if (!td) |
diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index 72b6892fda67..9546f6cd01f0 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c | |||
| @@ -356,7 +356,7 @@ static void __exit whci_hc_driver_exit(void) | |||
| 356 | module_exit(whci_hc_driver_exit); | 356 | module_exit(whci_hc_driver_exit); |
| 357 | 357 | ||
| 358 | /* PCI device ID's that we handle (so it gets loaded) */ | 358 | /* PCI device ID's that we handle (so it gets loaded) */ |
| 359 | static struct pci_device_id whci_hcd_id_table[] = { | 359 | static struct pci_device_id __used whci_hcd_id_table[] = { |
| 360 | { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) }, | 360 | { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) }, |
| 361 | { /* empty last entry */ } | 361 | { /* empty last entry */ } |
| 362 | }; | 362 | }; |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index c436e1e2c3b6..a09dbd243eb3 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
| @@ -436,6 +436,28 @@ static unsigned int mon_bin_get_data(const struct mon_reader_bin *rp, | |||
| 436 | return length; | 436 | return length; |
| 437 | } | 437 | } |
| 438 | 438 | ||
| 439 | /* | ||
| 440 | * This is the look-ahead pass in case of 'C Zi', when actual_length cannot | ||
| 441 | * be used to determine the length of the whole contiguous buffer. | ||
| 442 | */ | ||
| 443 | static unsigned int mon_bin_collate_isodesc(const struct mon_reader_bin *rp, | ||
| 444 | struct urb *urb, unsigned int ndesc) | ||
| 445 | { | ||
| 446 | struct usb_iso_packet_descriptor *fp; | ||
| 447 | unsigned int length; | ||
| 448 | |||
| 449 | length = 0; | ||
| 450 | fp = urb->iso_frame_desc; | ||
| 451 | while (ndesc-- != 0) { | ||
| 452 | if (fp->actual_length != 0) { | ||
| 453 | if (fp->offset + fp->actual_length > length) | ||
| 454 | length = fp->offset + fp->actual_length; | ||
| 455 | } | ||
| 456 | fp++; | ||
| 457 | } | ||
| 458 | return length; | ||
| 459 | } | ||
| 460 | |||
| 439 | static void mon_bin_get_isodesc(const struct mon_reader_bin *rp, | 461 | static void mon_bin_get_isodesc(const struct mon_reader_bin *rp, |
| 440 | unsigned int offset, struct urb *urb, char ev_type, unsigned int ndesc) | 462 | unsigned int offset, struct urb *urb, char ev_type, unsigned int ndesc) |
| 441 | { | 463 | { |
| @@ -478,6 +500,10 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
| 478 | /* | 500 | /* |
| 479 | * Find the maximum allowable length, then allocate space. | 501 | * Find the maximum allowable length, then allocate space. |
| 480 | */ | 502 | */ |
| 503 | urb_length = (ev_type == 'S') ? | ||
| 504 | urb->transfer_buffer_length : urb->actual_length; | ||
| 505 | length = urb_length; | ||
| 506 | |||
| 481 | if (usb_endpoint_xfer_isoc(epd)) { | 507 | if (usb_endpoint_xfer_isoc(epd)) { |
| 482 | if (urb->number_of_packets < 0) { | 508 | if (urb->number_of_packets < 0) { |
| 483 | ndesc = 0; | 509 | ndesc = 0; |
| @@ -486,14 +512,16 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
| 486 | } else { | 512 | } else { |
| 487 | ndesc = urb->number_of_packets; | 513 | ndesc = urb->number_of_packets; |
| 488 | } | 514 | } |
| 515 | if (ev_type == 'C' && usb_urb_dir_in(urb)) | ||
| 516 | length = mon_bin_collate_isodesc(rp, urb, ndesc); | ||
| 489 | } else { | 517 | } else { |
| 490 | ndesc = 0; | 518 | ndesc = 0; |
| 491 | } | 519 | } |
| 492 | lendesc = ndesc*sizeof(struct mon_bin_isodesc); | 520 | lendesc = ndesc*sizeof(struct mon_bin_isodesc); |
| 493 | 521 | ||
| 494 | urb_length = (ev_type == 'S') ? | 522 | /* not an issue unless there's a subtle bug in a HCD somewhere */ |
| 495 | urb->transfer_buffer_length : urb->actual_length; | 523 | if (length >= urb->transfer_buffer_length) |
| 496 | length = urb_length; | 524 | length = urb->transfer_buffer_length; |
| 497 | 525 | ||
| 498 | if (length >= rp->b_size/5) | 526 | if (length >= rp->b_size/5) |
| 499 | length = rp->b_size/5; | 527 | length = rp->b_size/5; |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 341a37a469bd..4cbb7e4b368d 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
| @@ -12,6 +12,7 @@ config USB_MUSB_HDRC | |||
| 12 | depends on (ARM || (BF54x && !BF544) || (BF52x && !BF522 && !BF523)) | 12 | depends on (ARM || (BF54x && !BF544) || (BF52x && !BF522 && !BF523)) |
| 13 | select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) | 13 | select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) |
| 14 | select TWL4030_USB if MACH_OMAP_3430SDP | 14 | select TWL4030_USB if MACH_OMAP_3430SDP |
| 15 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA | ||
| 15 | select USB_OTG_UTILS | 16 | select USB_OTG_UTILS |
| 16 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' | 17 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' |
| 17 | help | 18 | help |
| @@ -30,57 +31,41 @@ config USB_MUSB_HDRC | |||
| 30 | If you do not know what this is, please say N. | 31 | If you do not know what this is, please say N. |
| 31 | 32 | ||
| 32 | To compile this driver as a module, choose M here; the | 33 | To compile this driver as a module, choose M here; the |
| 33 | module will be called "musb_hdrc". | 34 | module will be called "musb-hdrc". |
| 34 | 35 | ||
| 35 | config USB_MUSB_SOC | 36 | choice |
| 36 | boolean | 37 | prompt "Platform Glue Layer" |
| 37 | depends on USB_MUSB_HDRC | 38 | depends on USB_MUSB_HDRC |
| 38 | default y if ARCH_DAVINCI | ||
| 39 | default y if ARCH_OMAP2430 | ||
| 40 | default y if ARCH_OMAP3 | ||
| 41 | default y if ARCH_OMAP4 | ||
| 42 | default y if (BF54x && !BF544) | ||
| 43 | default y if (BF52x && !BF522 && !BF523) | ||
| 44 | 39 | ||
| 45 | comment "DaVinci 35x and 644x USB support" | 40 | config USB_MUSB_DAVINCI |
| 46 | depends on USB_MUSB_HDRC && ARCH_DAVINCI_DMx | 41 | bool "DaVinci" |
| 42 | depends on ARCH_DAVINCI_DMx | ||
| 47 | 43 | ||
| 48 | comment "DA8xx/OMAP-L1x USB support" | 44 | config USB_MUSB_DA8XX |
| 49 | depends on USB_MUSB_HDRC && ARCH_DAVINCI_DA8XX | 45 | bool "DA8xx/OMAP-L1x" |
| 46 | depends on ARCH_DAVINCI_DA8XX | ||
| 50 | 47 | ||
| 51 | comment "OMAP 243x high speed USB support" | 48 | config USB_MUSB_TUSB6010 |
| 52 | depends on USB_MUSB_HDRC && ARCH_OMAP2430 | 49 | bool "TUSB6010" |
| 50 | depends on ARCH_OMAP | ||
| 53 | 51 | ||
| 54 | comment "OMAP 343x high speed USB support" | 52 | config USB_MUSB_OMAP2PLUS |
| 55 | depends on USB_MUSB_HDRC && ARCH_OMAP3 | 53 | bool "OMAP2430 and onwards" |
| 54 | depends on ARCH_OMAP2PLUS | ||
| 56 | 55 | ||
| 57 | comment "OMAP 44xx high speed USB support" | 56 | config USB_MUSB_AM35X |
| 58 | depends on USB_MUSB_HDRC && ARCH_OMAP4 | 57 | bool "AM35x" |
| 58 | depends on ARCH_OMAP | ||
| 59 | 59 | ||
| 60 | comment "Blackfin high speed USB Support" | 60 | config USB_MUSB_BLACKFIN |
| 61 | depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523)) | 61 | bool "Blackfin" |
| 62 | depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523) | ||
| 62 | 63 | ||
| 63 | config USB_MUSB_AM35X | 64 | config USB_MUSB_UX500 |
| 64 | bool | 65 | bool "U8500 and U5500" |
| 65 | depends on USB_MUSB_HDRC && !ARCH_OMAP2430 && !ARCH_OMAP4 | 66 | depends on (ARCH_U8500 && AB8500_USB) || (ARCH_U5500) |
| 66 | select NOP_USB_XCEIV | 67 | |
| 67 | default MACH_OMAP3517EVM | 68 | endchoice |
| 68 | help | ||
| 69 | Select this option if your platform is based on AM35x. As | ||
| 70 | AM35x has an updated MUSB with CPPI4.1 DMA so this config | ||
| 71 | is introduced to differentiate musb ip between OMAP3x and | ||
| 72 | AM35x platforms. | ||
| 73 | |||
| 74 | config USB_TUSB6010 | ||
| 75 | boolean "TUSB 6010 support" | ||
| 76 | depends on USB_MUSB_HDRC && !USB_MUSB_SOC | ||
| 77 | select NOP_USB_XCEIV | ||
| 78 | default y | ||
| 79 | help | ||
| 80 | The TUSB 6010 chip, from Texas Instruments, connects a discrete | ||
| 81 | HDRC core using a 16-bit parallel bus (NOR flash style) or VLYNQ | ||
| 82 | (a high speed serial link). It can use system-specific external | ||
| 83 | DMA controllers. | ||
| 84 | 69 | ||
| 85 | choice | 70 | choice |
| 86 | prompt "Driver Mode" | 71 | prompt "Driver Mode" |
| @@ -158,7 +143,7 @@ config USB_MUSB_HDRC_HCD | |||
| 158 | config MUSB_PIO_ONLY | 143 | config MUSB_PIO_ONLY |
| 159 | bool 'Disable DMA (always use PIO)' | 144 | bool 'Disable DMA (always use PIO)' |
| 160 | depends on USB_MUSB_HDRC | 145 | depends on USB_MUSB_HDRC |
| 161 | default USB_TUSB6010 || ARCH_DAVINCI_DA8XX || USB_MUSB_AM35X | 146 | default USB_MUSB_TUSB6010 || USB_MUSB_DA8XX || USB_MUSB_AM35X |
| 162 | help | 147 | help |
| 163 | All data is copied between memory and FIFO by the CPU. | 148 | All data is copied between memory and FIFO by the CPU. |
| 164 | DMA controllers are ignored. | 149 | DMA controllers are ignored. |
| @@ -171,21 +156,21 @@ config MUSB_PIO_ONLY | |||
| 171 | config USB_INVENTRA_DMA | 156 | config USB_INVENTRA_DMA |
| 172 | bool | 157 | bool |
| 173 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY | 158 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY |
| 174 | default ARCH_OMAP2430 || ARCH_OMAP3 || BLACKFIN || ARCH_OMAP4 | 159 | default USB_MUSB_OMAP2PLUS || USB_MUSB_BLACKFIN |
| 175 | help | 160 | help |
| 176 | Enable DMA transfers using Mentor's engine. | 161 | Enable DMA transfers using Mentor's engine. |
| 177 | 162 | ||
| 178 | config USB_TI_CPPI_DMA | 163 | config USB_TI_CPPI_DMA |
| 179 | bool | 164 | bool |
| 180 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY | 165 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY |
| 181 | default ARCH_DAVINCI | 166 | default USB_MUSB_DAVINCI |
| 182 | help | 167 | help |
| 183 | Enable DMA transfers when TI CPPI DMA is available. | 168 | Enable DMA transfers when TI CPPI DMA is available. |
| 184 | 169 | ||
| 185 | config USB_TUSB_OMAP_DMA | 170 | config USB_TUSB_OMAP_DMA |
| 186 | bool | 171 | bool |
| 187 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY | 172 | depends on USB_MUSB_HDRC && !MUSB_PIO_ONLY |
| 188 | depends on USB_TUSB6010 | 173 | depends on USB_MUSB_TUSB6010 |
| 189 | depends on ARCH_OMAP | 174 | depends on ARCH_OMAP |
| 190 | default y | 175 | default y |
| 191 | help | 176 | help |
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile index ce164e8998d8..74df5284894f 100644 --- a/drivers/usb/musb/Makefile +++ b/drivers/usb/musb/Makefile | |||
| @@ -8,22 +8,19 @@ obj-$(CONFIG_USB_MUSB_HDRC) += musb_hdrc.o | |||
| 8 | 8 | ||
| 9 | musb_hdrc-y := musb_core.o | 9 | musb_hdrc-y := musb_core.o |
| 10 | 10 | ||
| 11 | musb_hdrc-$(CONFIG_ARCH_DAVINCI_DMx) += davinci.o | ||
| 12 | musb_hdrc-$(CONFIG_ARCH_DAVINCI_DA8XX) += da8xx.o | ||
| 13 | musb_hdrc-$(CONFIG_USB_TUSB6010) += tusb6010.o | ||
| 14 | musb_hdrc-$(CONFIG_ARCH_OMAP2430) += omap2430.o | ||
| 15 | ifeq ($(CONFIG_USB_MUSB_AM35X),y) | ||
| 16 | musb_hdrc-$(CONFIG_ARCH_OMAP3430) += am35x.o | ||
| 17 | else | ||
| 18 | musb_hdrc-$(CONFIG_ARCH_OMAP3430) += omap2430.o | ||
| 19 | endif | ||
| 20 | musb_hdrc-$(CONFIG_ARCH_OMAP4) += omap2430.o | ||
| 21 | musb_hdrc-$(CONFIG_BF54x) += blackfin.o | ||
| 22 | musb_hdrc-$(CONFIG_BF52x) += blackfin.o | ||
| 23 | musb_hdrc-$(CONFIG_USB_GADGET_MUSB_HDRC) += musb_gadget_ep0.o musb_gadget.o | 11 | musb_hdrc-$(CONFIG_USB_GADGET_MUSB_HDRC) += musb_gadget_ep0.o musb_gadget.o |
| 24 | musb_hdrc-$(CONFIG_USB_MUSB_HDRC_HCD) += musb_virthub.o musb_host.o | 12 | musb_hdrc-$(CONFIG_USB_MUSB_HDRC_HCD) += musb_virthub.o musb_host.o |
| 25 | musb_hdrc-$(CONFIG_DEBUG_FS) += musb_debugfs.o | 13 | musb_hdrc-$(CONFIG_DEBUG_FS) += musb_debugfs.o |
| 26 | 14 | ||
| 15 | # Hardware Glue Layer | ||
| 16 | obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o | ||
| 17 | obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o | ||
| 18 | obj-$(CONFIG_USB_MUSB_TUSB6010) += tusb6010.o | ||
| 19 | obj-$(CONFIG_USB_MUSB_DAVINCI) += davinci.o | ||
| 20 | obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o | ||
| 21 | obj-$(CONFIG_USB_MUSB_BLACKFIN) += blackfin.o | ||
| 22 | obj-$(CONFIG_USB_MUSB_UX500) += ux500.o | ||
| 23 | |||
| 27 | # the kconfig must guarantee that only one of the | 24 | # the kconfig must guarantee that only one of the |
| 28 | # possible I/O schemes will be enabled at a time ... | 25 | # possible I/O schemes will be enabled at a time ... |
| 29 | # PIO only, or DMA (several potential schemes). | 26 | # PIO only, or DMA (several potential schemes). |
diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index b0aabf3a606f..d5a3da37c90c 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c | |||
| @@ -29,8 +29,9 @@ | |||
| 29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
| 30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
| 31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
| 32 | #include <linux/platform_device.h> | ||
| 33 | #include <linux/dma-mapping.h> | ||
| 32 | 34 | ||
| 33 | #include <plat/control.h> | ||
| 34 | #include <plat/usb.h> | 35 | #include <plat/usb.h> |
| 35 | 36 | ||
| 36 | #include "musb_core.h" | 37 | #include "musb_core.h" |
| @@ -80,51 +81,18 @@ | |||
| 80 | 81 | ||
| 81 | #define USB_MENTOR_CORE_OFFSET 0x400 | 82 | #define USB_MENTOR_CORE_OFFSET 0x400 |
| 82 | 83 | ||
| 83 | static inline void phy_on(void) | 84 | struct am35x_glue { |
| 84 | { | 85 | struct device *dev; |
| 85 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | 86 | struct platform_device *musb; |
| 86 | u32 devconf2; | 87 | struct clk *phy_clk; |
| 87 | 88 | struct clk *clk; | |
| 88 | /* | 89 | }; |
| 89 | * Start the on-chip PHY and its PLL. | 90 | #define glue_to_musb(g) platform_get_drvdata(g->musb) |
| 90 | */ | ||
| 91 | devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); | ||
| 92 | |||
| 93 | devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN); | ||
| 94 | devconf2 |= CONF2_PHY_PLLON; | ||
| 95 | |||
| 96 | omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); | ||
| 97 | |||
| 98 | DBG(1, "Waiting for PHY clock good...\n"); | ||
| 99 | while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2) | ||
| 100 | & CONF2_PHYCLKGD)) { | ||
| 101 | cpu_relax(); | ||
| 102 | |||
| 103 | if (time_after(jiffies, timeout)) { | ||
| 104 | DBG(1, "musb PHY clock good timed out\n"); | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | static inline void phy_off(void) | ||
| 111 | { | ||
| 112 | u32 devconf2; | ||
| 113 | |||
| 114 | /* | ||
| 115 | * Power down the on-chip PHY. | ||
| 116 | */ | ||
| 117 | devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); | ||
| 118 | |||
| 119 | devconf2 &= ~CONF2_PHY_PLLON; | ||
| 120 | devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN; | ||
| 121 | omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); | ||
| 122 | } | ||
| 123 | 91 | ||
| 124 | /* | 92 | /* |
| 125 | * musb_platform_enable - enable interrupts | 93 | * am35x_musb_enable - enable interrupts |
| 126 | */ | 94 | */ |
| 127 | void musb_platform_enable(struct musb *musb) | 95 | static void am35x_musb_enable(struct musb *musb) |
| 128 | { | 96 | { |
| 129 | void __iomem *reg_base = musb->ctrl_base; | 97 | void __iomem *reg_base = musb->ctrl_base; |
| 130 | u32 epmask; | 98 | u32 epmask; |
| @@ -143,9 +111,9 @@ void musb_platform_enable(struct musb *musb) | |||
| 143 | } | 111 | } |
| 144 | 112 | ||
| 145 | /* | 113 | /* |
| 146 | * musb_platform_disable - disable HDRC and flush interrupts | 114 | * am35x_musb_disable - disable HDRC and flush interrupts |
| 147 | */ | 115 | */ |
| 148 | void musb_platform_disable(struct musb *musb) | 116 | static void am35x_musb_disable(struct musb *musb) |
| 149 | { | 117 | { |
| 150 | void __iomem *reg_base = musb->ctrl_base; | 118 | void __iomem *reg_base = musb->ctrl_base; |
| 151 | 119 | ||
| @@ -162,7 +130,7 @@ void musb_platform_disable(struct musb *musb) | |||
| 162 | #define portstate(stmt) | 130 | #define portstate(stmt) |
| 163 | #endif | 131 | #endif |
| 164 | 132 | ||
| 165 | static void am35x_set_vbus(struct musb *musb, int is_on) | 133 | static void am35x_musb_set_vbus(struct musb *musb, int is_on) |
| 166 | { | 134 | { |
| 167 | WARN_ON(is_on && is_peripheral_active(musb)); | 135 | WARN_ON(is_on && is_peripheral_active(musb)); |
| 168 | } | 136 | } |
| @@ -221,7 +189,7 @@ static void otg_timer(unsigned long _musb) | |||
| 221 | spin_unlock_irqrestore(&musb->lock, flags); | 189 | spin_unlock_irqrestore(&musb->lock, flags); |
| 222 | } | 190 | } |
| 223 | 191 | ||
| 224 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | 192 | static void am35x_musb_try_idle(struct musb *musb, unsigned long timeout) |
| 225 | { | 193 | { |
| 226 | static unsigned long last_timer; | 194 | static unsigned long last_timer; |
| 227 | 195 | ||
| @@ -251,13 +219,16 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | |||
| 251 | mod_timer(&otg_workaround, timeout); | 219 | mod_timer(&otg_workaround, timeout); |
| 252 | } | 220 | } |
| 253 | 221 | ||
| 254 | static irqreturn_t am35x_interrupt(int irq, void *hci) | 222 | static irqreturn_t am35x_musb_interrupt(int irq, void *hci) |
| 255 | { | 223 | { |
| 256 | struct musb *musb = hci; | 224 | struct musb *musb = hci; |
| 257 | void __iomem *reg_base = musb->ctrl_base; | 225 | void __iomem *reg_base = musb->ctrl_base; |
| 226 | struct device *dev = musb->controller; | ||
| 227 | struct musb_hdrc_platform_data *plat = dev->platform_data; | ||
| 228 | struct omap_musb_board_data *data = plat->board_data; | ||
| 258 | unsigned long flags; | 229 | unsigned long flags; |
| 259 | irqreturn_t ret = IRQ_NONE; | 230 | irqreturn_t ret = IRQ_NONE; |
| 260 | u32 epintr, usbintr, lvl_intr; | 231 | u32 epintr, usbintr; |
| 261 | 232 | ||
| 262 | spin_lock_irqsave(&musb->lock, flags); | 233 | spin_lock_irqsave(&musb->lock, flags); |
| 263 | 234 | ||
| @@ -346,9 +317,8 @@ eoi: | |||
| 346 | /* EOI needs to be written for the IRQ to be re-asserted. */ | 317 | /* EOI needs to be written for the IRQ to be re-asserted. */ |
| 347 | if (ret == IRQ_HANDLED || epintr || usbintr) { | 318 | if (ret == IRQ_HANDLED || epintr || usbintr) { |
| 348 | /* clear level interrupt */ | 319 | /* clear level interrupt */ |
| 349 | lvl_intr = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); | 320 | if (data->clear_irq) |
| 350 | lvl_intr |= AM35XX_USBOTGSS_INT_CLR; | 321 | data->clear_irq(); |
| 351 | omap_ctrl_writel(lvl_intr, AM35XX_CONTROL_LVL_INTR_CLEAR); | ||
| 352 | /* write EOI */ | 322 | /* write EOI */ |
| 353 | musb_writel(reg_base, USB_END_OF_INTR_REG, 0); | 323 | musb_writel(reg_base, USB_END_OF_INTR_REG, 0); |
| 354 | } | 324 | } |
| @@ -362,137 +332,85 @@ eoi: | |||
| 362 | return ret; | 332 | return ret; |
| 363 | } | 333 | } |
| 364 | 334 | ||
| 365 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 335 | static int am35x_musb_set_mode(struct musb *musb, u8 musb_mode) |
| 366 | { | 336 | { |
| 367 | u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); | 337 | struct device *dev = musb->controller; |
| 338 | struct musb_hdrc_platform_data *plat = dev->platform_data; | ||
| 339 | struct omap_musb_board_data *data = plat->board_data; | ||
| 340 | int retval = 0; | ||
| 368 | 341 | ||
| 369 | devconf2 &= ~CONF2_OTGMODE; | 342 | if (data->set_mode) |
| 370 | switch (musb_mode) { | 343 | data->set_mode(musb_mode); |
| 371 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 344 | else |
| 372 | case MUSB_HOST: /* Force VBUS valid, ID = 0 */ | 345 | retval = -EIO; |
| 373 | devconf2 |= CONF2_FORCE_HOST; | ||
| 374 | break; | ||
| 375 | #endif | ||
| 376 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
| 377 | case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ | ||
| 378 | devconf2 |= CONF2_FORCE_DEVICE; | ||
| 379 | break; | ||
| 380 | #endif | ||
| 381 | #ifdef CONFIG_USB_MUSB_OTG | ||
| 382 | case MUSB_OTG: /* Don't override the VBUS/ID comparators */ | ||
| 383 | devconf2 |= CONF2_NO_OVERRIDE; | ||
| 384 | break; | ||
| 385 | #endif | ||
| 386 | default: | ||
| 387 | DBG(2, "Trying to set unsupported mode %u\n", musb_mode); | ||
| 388 | } | ||
| 389 | 346 | ||
| 390 | omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); | 347 | return retval; |
| 391 | return 0; | ||
| 392 | } | 348 | } |
| 393 | 349 | ||
| 394 | int __init musb_platform_init(struct musb *musb, void *board_data) | 350 | static int am35x_musb_init(struct musb *musb) |
| 395 | { | 351 | { |
| 352 | struct device *dev = musb->controller; | ||
| 353 | struct musb_hdrc_platform_data *plat = dev->platform_data; | ||
| 354 | struct omap_musb_board_data *data = plat->board_data; | ||
| 396 | void __iomem *reg_base = musb->ctrl_base; | 355 | void __iomem *reg_base = musb->ctrl_base; |
| 397 | u32 rev, lvl_intr, sw_reset; | 356 | u32 rev; |
| 398 | int status; | ||
| 399 | 357 | ||
| 400 | musb->mregs += USB_MENTOR_CORE_OFFSET; | 358 | musb->mregs += USB_MENTOR_CORE_OFFSET; |
| 401 | 359 | ||
| 402 | clk_enable(musb->clock); | ||
| 403 | DBG(2, "musb->clock=%lud\n", clk_get_rate(musb->clock)); | ||
| 404 | |||
| 405 | musb->phy_clock = clk_get(musb->controller, "fck"); | ||
| 406 | if (IS_ERR(musb->phy_clock)) { | ||
| 407 | status = PTR_ERR(musb->phy_clock); | ||
| 408 | goto exit0; | ||
| 409 | } | ||
| 410 | clk_enable(musb->phy_clock); | ||
| 411 | DBG(2, "musb->phy_clock=%lud\n", clk_get_rate(musb->phy_clock)); | ||
| 412 | |||
| 413 | /* Returns zero if e.g. not clocked */ | 360 | /* Returns zero if e.g. not clocked */ |
| 414 | rev = musb_readl(reg_base, USB_REVISION_REG); | 361 | rev = musb_readl(reg_base, USB_REVISION_REG); |
| 415 | if (!rev) { | 362 | if (!rev) |
| 416 | status = -ENODEV; | 363 | return -ENODEV; |
| 417 | goto exit1; | ||
| 418 | } | ||
| 419 | 364 | ||
| 420 | usb_nop_xceiv_register(); | 365 | usb_nop_xceiv_register(); |
| 421 | musb->xceiv = otg_get_transceiver(); | 366 | musb->xceiv = otg_get_transceiver(); |
| 422 | if (!musb->xceiv) { | 367 | if (!musb->xceiv) |
| 423 | status = -ENODEV; | 368 | return -ENODEV; |
| 424 | goto exit1; | ||
| 425 | } | ||
| 426 | 369 | ||
| 427 | if (is_host_enabled(musb)) | 370 | if (is_host_enabled(musb)) |
| 428 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); | 371 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); |
| 429 | 372 | ||
| 430 | musb->board_set_vbus = am35x_set_vbus; | 373 | /* Reset the musb */ |
| 431 | 374 | if (data->reset) | |
| 432 | /* Global reset */ | 375 | data->reset(); |
| 433 | sw_reset = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); | ||
| 434 | |||
| 435 | sw_reset |= AM35XX_USBOTGSS_SW_RST; | ||
| 436 | omap_ctrl_writel(sw_reset, AM35XX_CONTROL_IP_SW_RESET); | ||
| 437 | |||
| 438 | sw_reset &= ~AM35XX_USBOTGSS_SW_RST; | ||
| 439 | omap_ctrl_writel(sw_reset, AM35XX_CONTROL_IP_SW_RESET); | ||
| 440 | 376 | ||
| 441 | /* Reset the controller */ | 377 | /* Reset the controller */ |
| 442 | musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK); | 378 | musb_writel(reg_base, USB_CTRL_REG, AM35X_SOFT_RESET_MASK); |
| 443 | 379 | ||
| 444 | /* Start the on-chip PHY and its PLL. */ | 380 | /* Start the on-chip PHY and its PLL. */ |
| 445 | phy_on(); | 381 | if (data->set_phy_power) |
| 382 | data->set_phy_power(1); | ||
| 446 | 383 | ||
| 447 | msleep(5); | 384 | msleep(5); |
| 448 | 385 | ||
| 449 | musb->isr = am35x_interrupt; | 386 | musb->isr = am35x_musb_interrupt; |
| 450 | 387 | ||
| 451 | /* clear level interrupt */ | 388 | /* clear level interrupt */ |
| 452 | lvl_intr = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); | 389 | if (data->clear_irq) |
| 453 | lvl_intr |= AM35XX_USBOTGSS_INT_CLR; | 390 | data->clear_irq(); |
| 454 | omap_ctrl_writel(lvl_intr, AM35XX_CONTROL_LVL_INTR_CLEAR); | 391 | |
| 455 | return 0; | 392 | return 0; |
| 456 | exit1: | ||
| 457 | clk_disable(musb->phy_clock); | ||
| 458 | clk_put(musb->phy_clock); | ||
| 459 | exit0: | ||
| 460 | clk_disable(musb->clock); | ||
| 461 | return status; | ||
| 462 | } | 393 | } |
| 463 | 394 | ||
| 464 | int musb_platform_exit(struct musb *musb) | 395 | static int am35x_musb_exit(struct musb *musb) |
| 465 | { | 396 | { |
| 397 | struct device *dev = musb->controller; | ||
| 398 | struct musb_hdrc_platform_data *plat = dev->platform_data; | ||
| 399 | struct omap_musb_board_data *data = plat->board_data; | ||
| 400 | |||
| 466 | if (is_host_enabled(musb)) | 401 | if (is_host_enabled(musb)) |
| 467 | del_timer_sync(&otg_workaround); | 402 | del_timer_sync(&otg_workaround); |
| 468 | 403 | ||
| 469 | phy_off(); | 404 | /* Shutdown the on-chip PHY and its PLL. */ |
| 405 | if (data->set_phy_power) | ||
| 406 | data->set_phy_power(0); | ||
| 470 | 407 | ||
| 471 | otg_put_transceiver(musb->xceiv); | 408 | otg_put_transceiver(musb->xceiv); |
| 472 | usb_nop_xceiv_unregister(); | 409 | usb_nop_xceiv_unregister(); |
| 473 | 410 | ||
| 474 | clk_disable(musb->clock); | ||
| 475 | |||
| 476 | clk_disable(musb->phy_clock); | ||
| 477 | clk_put(musb->phy_clock); | ||
| 478 | |||
| 479 | return 0; | 411 | return 0; |
| 480 | } | 412 | } |
| 481 | 413 | ||
| 482 | #ifdef CONFIG_PM | ||
| 483 | void musb_platform_save_context(struct musb *musb, | ||
| 484 | struct musb_context_registers *musb_context) | ||
| 485 | { | ||
| 486 | phy_off(); | ||
| 487 | } | ||
| 488 | |||
| 489 | void musb_platform_restore_context(struct musb *musb, | ||
| 490 | struct musb_context_registers *musb_context) | ||
| 491 | { | ||
| 492 | phy_on(); | ||
| 493 | } | ||
| 494 | #endif | ||
| 495 | |||
| 496 | /* AM35x supports only 32bit read operation */ | 414 | /* AM35x supports only 32bit read operation */ |
| 497 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | 415 | void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) |
| 498 | { | 416 | { |
| @@ -522,3 +440,215 @@ void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | |||
| 522 | memcpy(dst, &val, len); | 440 | memcpy(dst, &val, len); |
| 523 | } | 441 | } |
| 524 | } | 442 | } |
| 443 | |||
| 444 | static const struct musb_platform_ops am35x_ops = { | ||
| 445 | .init = am35x_musb_init, | ||
| 446 | .exit = am35x_musb_exit, | ||
| 447 | |||
| 448 | .enable = am35x_musb_enable, | ||
| 449 | .disable = am35x_musb_disable, | ||
| 450 | |||
| 451 | .set_mode = am35x_musb_set_mode, | ||
| 452 | .try_idle = am35x_musb_try_idle, | ||
| 453 | |||
| 454 | .set_vbus = am35x_musb_set_vbus, | ||
| 455 | }; | ||
| 456 | |||
| 457 | static u64 am35x_dmamask = DMA_BIT_MASK(32); | ||
| 458 | |||
| 459 | static int __init am35x_probe(struct platform_device *pdev) | ||
| 460 | { | ||
| 461 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | ||
| 462 | struct platform_device *musb; | ||
| 463 | struct am35x_glue *glue; | ||
| 464 | |||
| 465 | struct clk *phy_clk; | ||
| 466 | struct clk *clk; | ||
| 467 | |||
| 468 | int ret = -ENOMEM; | ||
| 469 | |||
| 470 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | ||
| 471 | if (!glue) { | ||
| 472 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
| 473 | goto err0; | ||
| 474 | } | ||
| 475 | |||
| 476 | musb = platform_device_alloc("musb-hdrc", -1); | ||
| 477 | if (!musb) { | ||
| 478 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | ||
| 479 | goto err1; | ||
| 480 | } | ||
| 481 | |||
| 482 | phy_clk = clk_get(&pdev->dev, "fck"); | ||
| 483 | if (IS_ERR(phy_clk)) { | ||
| 484 | dev_err(&pdev->dev, "failed to get PHY clock\n"); | ||
| 485 | ret = PTR_ERR(phy_clk); | ||
| 486 | goto err2; | ||
| 487 | } | ||
| 488 | |||
| 489 | clk = clk_get(&pdev->dev, "ick"); | ||
| 490 | if (IS_ERR(clk)) { | ||
| 491 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
| 492 | ret = PTR_ERR(clk); | ||
| 493 | goto err3; | ||
| 494 | } | ||
| 495 | |||
| 496 | ret = clk_enable(phy_clk); | ||
| 497 | if (ret) { | ||
| 498 | dev_err(&pdev->dev, "failed to enable PHY clock\n"); | ||
| 499 | goto err4; | ||
| 500 | } | ||
| 501 | |||
| 502 | ret = clk_enable(clk); | ||
| 503 | if (ret) { | ||
| 504 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
| 505 | goto err5; | ||
| 506 | } | ||
| 507 | |||
| 508 | musb->dev.parent = &pdev->dev; | ||
| 509 | musb->dev.dma_mask = &am35x_dmamask; | ||
| 510 | musb->dev.coherent_dma_mask = am35x_dmamask; | ||
| 511 | |||
| 512 | glue->dev = &pdev->dev; | ||
| 513 | glue->musb = musb; | ||
| 514 | glue->phy_clk = phy_clk; | ||
| 515 | glue->clk = clk; | ||
| 516 | |||
| 517 | pdata->platform_ops = &am35x_ops; | ||
| 518 | |||
| 519 | platform_set_drvdata(pdev, glue); | ||
| 520 | |||
| 521 | ret = platform_device_add_resources(musb, pdev->resource, | ||
| 522 | pdev->num_resources); | ||
| 523 | if (ret) { | ||
| 524 | dev_err(&pdev->dev, "failed to add resources\n"); | ||
| 525 | goto err6; | ||
| 526 | } | ||
| 527 | |||
| 528 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | ||
| 529 | if (ret) { | ||
| 530 | dev_err(&pdev->dev, "failed to add platform_data\n"); | ||
| 531 | goto err6; | ||
| 532 | } | ||
| 533 | |||
| 534 | ret = platform_device_add(musb); | ||
| 535 | if (ret) { | ||
| 536 | dev_err(&pdev->dev, "failed to register musb device\n"); | ||
| 537 | goto err6; | ||
| 538 | } | ||
| 539 | |||
| 540 | return 0; | ||
| 541 | |||
| 542 | err6: | ||
| 543 | clk_disable(clk); | ||
| 544 | |||
| 545 | err5: | ||
| 546 | clk_disable(phy_clk); | ||
| 547 | |||
| 548 | err4: | ||
| 549 | clk_put(clk); | ||
| 550 | |||
| 551 | err3: | ||
| 552 | clk_put(phy_clk); | ||
| 553 | |||
| 554 | err2: | ||
| 555 | platform_device_put(musb); | ||
| 556 | |||
| 557 | err1: | ||
| 558 | kfree(glue); | ||
| 559 | |||
| 560 | err0: | ||
| 561 | return ret; | ||
| 562 | } | ||
| 563 | |||
| 564 | static int __exit am35x_remove(struct platform_device *pdev) | ||
| 565 | { | ||
| 566 | struct am35x_glue *glue = platform_get_drvdata(pdev); | ||
| 567 | |||
| 568 | platform_device_del(glue->musb); | ||
| 569 | platform_device_put(glue->musb); | ||
| 570 | clk_disable(glue->clk); | ||
| 571 | clk_disable(glue->phy_clk); | ||
| 572 | clk_put(glue->clk); | ||
| 573 | clk_put(glue->phy_clk); | ||
| 574 | kfree(glue); | ||
| 575 | |||
| 576 | return 0; | ||
| 577 | } | ||
| 578 | |||
| 579 | #ifdef CONFIG_PM | ||
| 580 | static int am35x_suspend(struct device *dev) | ||
| 581 | { | ||
| 582 | struct am35x_glue *glue = dev_get_drvdata(dev); | ||
| 583 | struct musb_hdrc_platform_data *plat = dev->platform_data; | ||
| 584 | struct omap_musb_board_data *data = plat->board_data; | ||
| 585 | |||
| 586 | /* Shutdown the on-chip PHY and its PLL. */ | ||
| 587 | if (data->set_phy_power) | ||
| 588 | data->set_phy_power(0); | ||
| 589 | |||
| 590 | clk_disable(glue->phy_clk); | ||
| 591 | clk_disable(glue->clk); | ||
| 592 | |||
| 593 | return 0; | ||
| 594 | } | ||
| 595 | |||
| 596 | static int am35x_resume(struct device *dev) | ||
| 597 | { | ||
| 598 | struct am35x_glue *glue = dev_get_drvdata(dev); | ||
| 599 | struct musb_hdrc_platform_data *plat = dev->platform_data; | ||
| 600 | struct omap_musb_board_data *data = plat->board_data; | ||
| 601 | int ret; | ||
| 602 | |||
| 603 | /* Start the on-chip PHY and its PLL. */ | ||
| 604 | if (data->set_phy_power) | ||
| 605 | data->set_phy_power(1); | ||
| 606 | |||
| 607 | ret = clk_enable(glue->phy_clk); | ||
| 608 | if (ret) { | ||
| 609 | dev_err(dev, "failed to enable PHY clock\n"); | ||
| 610 | return ret; | ||
| 611 | } | ||
| 612 | |||
| 613 | ret = clk_enable(glue->clk); | ||
| 614 | if (ret) { | ||
| 615 | dev_err(dev, "failed to enable clock\n"); | ||
| 616 | return ret; | ||
| 617 | } | ||
| 618 | |||
| 619 | return 0; | ||
| 620 | } | ||
| 621 | |||
| 622 | static struct dev_pm_ops am35x_pm_ops = { | ||
| 623 | .suspend = am35x_suspend, | ||
| 624 | .resume = am35x_resume, | ||
| 625 | }; | ||
| 626 | |||
| 627 | #define DEV_PM_OPS &am35x_pm_ops | ||
| 628 | #else | ||
| 629 | #define DEV_PM_OPS NULL | ||
| 630 | #endif | ||
| 631 | |||
| 632 | static struct platform_driver am35x_driver = { | ||
| 633 | .remove = __exit_p(am35x_remove), | ||
| 634 | .driver = { | ||
| 635 | .name = "musb-am35x", | ||
| 636 | .pm = DEV_PM_OPS, | ||
| 637 | }, | ||
| 638 | }; | ||
| 639 | |||
| 640 | MODULE_DESCRIPTION("AM35x MUSB Glue Layer"); | ||
| 641 | MODULE_AUTHOR("Ajay Kumar Gupta <ajay.gupta@ti.com>"); | ||
| 642 | MODULE_LICENSE("GPL v2"); | ||
| 643 | |||
| 644 | static int __init am35x_init(void) | ||
| 645 | { | ||
| 646 | return platform_driver_probe(&am35x_driver, am35x_probe); | ||
| 647 | } | ||
| 648 | subsys_initcall(am35x_init); | ||
| 649 | |||
| 650 | static void __exit am35x_exit(void) | ||
| 651 | { | ||
| 652 | platform_driver_unregister(&am35x_driver); | ||
| 653 | } | ||
| 654 | module_exit(am35x_exit); | ||
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 930a2611fe3e..eeba228eb2af 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
| @@ -15,12 +15,20 @@ | |||
| 15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
| 16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
| 17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <linux/dma-mapping.h> | ||
| 18 | 20 | ||
| 19 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
| 20 | 22 | ||
| 21 | #include "musb_core.h" | 23 | #include "musb_core.h" |
| 22 | #include "blackfin.h" | 24 | #include "blackfin.h" |
| 23 | 25 | ||
| 26 | struct bfin_glue { | ||
| 27 | struct device *dev; | ||
| 28 | struct platform_device *musb; | ||
| 29 | }; | ||
| 30 | #define glue_to_musb(g) platform_get_drvdata(g->musb) | ||
| 31 | |||
| 24 | /* | 32 | /* |
| 25 | * Load an endpoint's FIFO | 33 | * Load an endpoint's FIFO |
| 26 | */ | 34 | */ |
| @@ -278,7 +286,7 @@ static void musb_conn_timer_handler(unsigned long _musb) | |||
| 278 | DBG(4, "state is %s\n", otg_state_string(musb)); | 286 | DBG(4, "state is %s\n", otg_state_string(musb)); |
| 279 | } | 287 | } |
| 280 | 288 | ||
| 281 | void musb_platform_enable(struct musb *musb) | 289 | static void bfin_musb_enable(struct musb *musb) |
| 282 | { | 290 | { |
| 283 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) { | 291 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) { |
| 284 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | 292 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); |
| @@ -286,11 +294,11 @@ void musb_platform_enable(struct musb *musb) | |||
| 286 | } | 294 | } |
| 287 | } | 295 | } |
| 288 | 296 | ||
| 289 | void musb_platform_disable(struct musb *musb) | 297 | static void bfin_musb_disable(struct musb *musb) |
| 290 | { | 298 | { |
| 291 | } | 299 | } |
| 292 | 300 | ||
| 293 | static void bfin_set_vbus(struct musb *musb, int is_on) | 301 | static void bfin_musb_set_vbus(struct musb *musb, int is_on) |
| 294 | { | 302 | { |
| 295 | int value = musb->config->gpio_vrsel_active; | 303 | int value = musb->config->gpio_vrsel_active; |
| 296 | if (!is_on) | 304 | if (!is_on) |
| @@ -303,51 +311,29 @@ static void bfin_set_vbus(struct musb *musb, int is_on) | |||
| 303 | musb_readb(musb->mregs, MUSB_DEVCTL)); | 311 | musb_readb(musb->mregs, MUSB_DEVCTL)); |
| 304 | } | 312 | } |
| 305 | 313 | ||
| 306 | static int bfin_set_power(struct otg_transceiver *x, unsigned mA) | 314 | static int bfin_musb_set_power(struct otg_transceiver *x, unsigned mA) |
| 307 | { | 315 | { |
| 308 | return 0; | 316 | return 0; |
| 309 | } | 317 | } |
| 310 | 318 | ||
| 311 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | 319 | static void bfin_musb_try_idle(struct musb *musb, unsigned long timeout) |
| 312 | { | 320 | { |
| 313 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) | 321 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) |
| 314 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); | 322 | mod_timer(&musb_conn_timer, jiffies + TIMER_DELAY); |
| 315 | } | 323 | } |
| 316 | 324 | ||
| 317 | int musb_platform_get_vbus_status(struct musb *musb) | 325 | static int bfin_musb_get_vbus_status(struct musb *musb) |
| 318 | { | 326 | { |
| 319 | return 0; | 327 | return 0; |
| 320 | } | 328 | } |
| 321 | 329 | ||
| 322 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 330 | static int bfin_musb_set_mode(struct musb *musb, u8 musb_mode) |
| 323 | { | 331 | { |
| 324 | return -EIO; | 332 | return -EIO; |
| 325 | } | 333 | } |
| 326 | 334 | ||
| 327 | int __init musb_platform_init(struct musb *musb, void *board_data) | 335 | static void bfin_musb_reg_init(struct musb *musb) |
| 328 | { | 336 | { |
| 329 | |||
| 330 | /* | ||
| 331 | * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE | ||
| 332 | * and OTG HOST modes, while rev 1.1 and greater require PE7 to | ||
| 333 | * be low for DEVICE mode and high for HOST mode. We set it high | ||
| 334 | * here because we are in host mode | ||
| 335 | */ | ||
| 336 | |||
| 337 | if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { | ||
| 338 | printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d \n", | ||
| 339 | musb->config->gpio_vrsel); | ||
| 340 | return -ENODEV; | ||
| 341 | } | ||
| 342 | gpio_direction_output(musb->config->gpio_vrsel, 0); | ||
| 343 | |||
| 344 | usb_nop_xceiv_register(); | ||
| 345 | musb->xceiv = otg_get_transceiver(); | ||
| 346 | if (!musb->xceiv) { | ||
| 347 | gpio_free(musb->config->gpio_vrsel); | ||
| 348 | return -ENODEV; | ||
| 349 | } | ||
| 350 | |||
| 351 | if (ANOMALY_05000346) { | 337 | if (ANOMALY_05000346) { |
| 352 | bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); | 338 | bfin_write_USB_APHY_CALIB(ANOMALY_05000346_value); |
| 353 | SSYNC(); | 339 | SSYNC(); |
| @@ -382,21 +368,47 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
| 382 | EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA | | 368 | EP2_RX_ENA | EP3_RX_ENA | EP4_RX_ENA | |
| 383 | EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA); | 369 | EP5_RX_ENA | EP6_RX_ENA | EP7_RX_ENA); |
| 384 | SSYNC(); | 370 | SSYNC(); |
| 371 | } | ||
| 372 | |||
| 373 | static int bfin_musb_init(struct musb *musb) | ||
| 374 | { | ||
| 375 | |||
| 376 | /* | ||
| 377 | * Rev 1.0 BF549 EZ-KITs require PE7 to be high for both DEVICE | ||
| 378 | * and OTG HOST modes, while rev 1.1 and greater require PE7 to | ||
| 379 | * be low for DEVICE mode and high for HOST mode. We set it high | ||
| 380 | * here because we are in host mode | ||
| 381 | */ | ||
| 382 | |||
| 383 | if (gpio_request(musb->config->gpio_vrsel, "USB_VRSEL")) { | ||
| 384 | printk(KERN_ERR "Failed ro request USB_VRSEL GPIO_%d\n", | ||
| 385 | musb->config->gpio_vrsel); | ||
| 386 | return -ENODEV; | ||
| 387 | } | ||
| 388 | gpio_direction_output(musb->config->gpio_vrsel, 0); | ||
| 389 | |||
| 390 | usb_nop_xceiv_register(); | ||
| 391 | musb->xceiv = otg_get_transceiver(); | ||
| 392 | if (!musb->xceiv) { | ||
| 393 | gpio_free(musb->config->gpio_vrsel); | ||
| 394 | return -ENODEV; | ||
| 395 | } | ||
| 396 | |||
| 397 | bfin_musb_reg_init(musb); | ||
| 385 | 398 | ||
| 386 | if (is_host_enabled(musb)) { | 399 | if (is_host_enabled(musb)) { |
| 387 | musb->board_set_vbus = bfin_set_vbus; | ||
| 388 | setup_timer(&musb_conn_timer, | 400 | setup_timer(&musb_conn_timer, |
| 389 | musb_conn_timer_handler, (unsigned long) musb); | 401 | musb_conn_timer_handler, (unsigned long) musb); |
| 390 | } | 402 | } |
| 391 | if (is_peripheral_enabled(musb)) | 403 | if (is_peripheral_enabled(musb)) |
| 392 | musb->xceiv->set_power = bfin_set_power; | 404 | musb->xceiv->set_power = bfin_musb_set_power; |
| 393 | 405 | ||
| 394 | musb->isr = blackfin_interrupt; | 406 | musb->isr = blackfin_interrupt; |
| 395 | 407 | ||
| 396 | return 0; | 408 | return 0; |
| 397 | } | 409 | } |
| 398 | 410 | ||
| 399 | int musb_platform_exit(struct musb *musb) | 411 | static int bfin_musb_exit(struct musb *musb) |
| 400 | { | 412 | { |
| 401 | gpio_free(musb->config->gpio_vrsel); | 413 | gpio_free(musb->config->gpio_vrsel); |
| 402 | 414 | ||
| @@ -404,3 +416,154 @@ int musb_platform_exit(struct musb *musb) | |||
| 404 | usb_nop_xceiv_unregister(); | 416 | usb_nop_xceiv_unregister(); |
| 405 | return 0; | 417 | return 0; |
| 406 | } | 418 | } |
| 419 | |||
| 420 | static const struct musb_platform_ops bfin_ops = { | ||
| 421 | .init = bfin_musb_init, | ||
| 422 | .exit = bfin_musb_exit, | ||
| 423 | |||
| 424 | .enable = bfin_musb_enable, | ||
| 425 | .disable = bfin_musb_disable, | ||
| 426 | |||
| 427 | .set_mode = bfin_musb_set_mode, | ||
| 428 | .try_idle = bfin_musb_try_idle, | ||
| 429 | |||
| 430 | .vbus_status = bfin_musb_vbus_status, | ||
| 431 | .set_vbus = bfin_musb_set_vbus, | ||
| 432 | }; | ||
| 433 | |||
| 434 | static u64 bfin_dmamask = DMA_BIT_MASK(32); | ||
| 435 | |||
| 436 | static int __init bfin_probe(struct platform_device *pdev) | ||
| 437 | { | ||
| 438 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | ||
| 439 | struct platform_device *musb; | ||
| 440 | struct bfin_glue *glue; | ||
| 441 | |||
| 442 | int ret = -ENOMEM; | ||
| 443 | |||
| 444 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | ||
| 445 | if (!glue) { | ||
| 446 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
| 447 | goto err0; | ||
| 448 | } | ||
| 449 | |||
| 450 | musb = platform_device_alloc("musb-hdrc", -1); | ||
| 451 | if (!musb) { | ||
| 452 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | ||
| 453 | goto err1; | ||
| 454 | } | ||
| 455 | |||
| 456 | musb->dev.parent = &pdev->dev; | ||
| 457 | musb->dev.dma_mask = &bfin_dmamask; | ||
| 458 | musb->dev.coherent_dma_mask = bfin_dmamask; | ||
| 459 | |||
| 460 | glue->dev = &pdev->dev; | ||
| 461 | glue->musb = musb; | ||
| 462 | |||
| 463 | pdata->platform_ops = &bfin_ops; | ||
| 464 | |||
| 465 | platform_set_drvdata(pdev, glue); | ||
| 466 | |||
| 467 | ret = platform_device_add_resources(musb, pdev->resource, | ||
| 468 | pdev->num_resources); | ||
| 469 | if (ret) { | ||
| 470 | dev_err(&pdev->dev, "failed to add resources\n"); | ||
| 471 | goto err2; | ||
| 472 | } | ||
| 473 | |||
| 474 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | ||
| 475 | if (ret) { | ||
| 476 | dev_err(&pdev->dev, "failed to add platform_data\n"); | ||
| 477 | goto err2; | ||
| 478 | } | ||
| 479 | |||
| 480 | ret = platform_device_add(musb); | ||
| 481 | if (ret) { | ||
| 482 | dev_err(&pdev->dev, "failed to register musb device\n"); | ||
| 483 | goto err2; | ||
| 484 | } | ||
| 485 | |||
| 486 | return 0; | ||
| 487 | |||
| 488 | err2: | ||
| 489 | platform_device_put(musb); | ||
| 490 | |||
| 491 | err1: | ||
| 492 | kfree(glue); | ||
| 493 | |||
| 494 | err0: | ||
| 495 | return ret; | ||
| 496 | } | ||
| 497 | |||
| 498 | static int __exit bfin_remove(struct platform_device *pdev) | ||
| 499 | { | ||
| 500 | struct bfin_glue *glue = platform_get_drvdata(pdev); | ||
| 501 | |||
| 502 | platform_device_del(glue->musb); | ||
| 503 | platform_device_put(glue->musb); | ||
| 504 | kfree(glue); | ||
| 505 | |||
| 506 | return 0; | ||
| 507 | } | ||
| 508 | |||
| 509 | #ifdef CONFIG_PM | ||
| 510 | static int bfin_suspend(struct device *dev) | ||
| 511 | { | ||
| 512 | struct bfin_glue *glue = dev_get_drvdata(dev); | ||
| 513 | struct musb *musb = glue_to_musb(glue); | ||
| 514 | |||
| 515 | if (is_host_active(musb)) | ||
| 516 | /* | ||
| 517 | * During hibernate gpio_vrsel will change from high to low | ||
| 518 | * low which will generate wakeup event resume the system | ||
| 519 | * immediately. Set it to 0 before hibernate to avoid this | ||
| 520 | * wakeup event. | ||
| 521 | */ | ||
| 522 | gpio_set_value(musb->config->gpio_vrsel, 0); | ||
| 523 | |||
| 524 | return 0; | ||
| 525 | } | ||
| 526 | |||
| 527 | static int bfin_resume(struct device *dev) | ||
| 528 | { | ||
| 529 | struct bfin_glue *glue = dev_get_drvdata(dev); | ||
| 530 | struct musb *musb = glue_to_musb(glue); | ||
| 531 | |||
| 532 | bfin_musb_reg_init(musb); | ||
| 533 | |||
| 534 | return 0; | ||
| 535 | } | ||
| 536 | |||
| 537 | static struct dev_pm_ops bfin_pm_ops = { | ||
| 538 | .suspend = bfin_suspend, | ||
| 539 | .resume = bfin_resume, | ||
| 540 | }; | ||
| 541 | |||
| 542 | #define DEV_PM_OPS &bfin_pm_op, | ||
| 543 | #else | ||
| 544 | #define DEV_PM_OPS NULL | ||
| 545 | #endif | ||
| 546 | |||
| 547 | static struct platform_driver bfin_driver = { | ||
| 548 | .remove = __exit_p(bfin_remove), | ||
| 549 | .driver = { | ||
| 550 | .name = "musb-bfin", | ||
| 551 | .pm = DEV_PM_OPS, | ||
| 552 | }, | ||
| 553 | }; | ||
| 554 | |||
| 555 | MODULE_DESCRIPTION("Blackfin MUSB Glue Layer"); | ||
| 556 | MODULE_AUTHOR("Bryan Wy <cooloney@kernel.org>"); | ||
| 557 | MODULE_LICENSE("GPL v2"); | ||
| 558 | |||
| 559 | static int __init bfin_init(void) | ||
| 560 | { | ||
| 561 | return platform_driver_probe(&bfin_driver, bfin_probe); | ||
| 562 | } | ||
| 563 | subsys_initcall(bfin_init); | ||
| 564 | |||
| 565 | static void __exit bfin_exit(void) | ||
| 566 | { | ||
| 567 | platform_driver_unregister(&bfin_driver); | ||
| 568 | } | ||
| 569 | module_exit(bfin_exit); | ||
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index f5a65ff0ac2b..de55a3c3259a 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
| @@ -1308,7 +1308,7 @@ dma_controller_create(struct musb *musb, void __iomem *mregs) | |||
| 1308 | struct cppi *controller; | 1308 | struct cppi *controller; |
| 1309 | struct device *dev = musb->controller; | 1309 | struct device *dev = musb->controller; |
| 1310 | struct platform_device *pdev = to_platform_device(dev); | 1310 | struct platform_device *pdev = to_platform_device(dev); |
| 1311 | int irq = platform_get_irq(pdev, 1); | 1311 | int irq = platform_get_irq_byname(pdev, "dma"); |
| 1312 | 1312 | ||
| 1313 | controller = kzalloc(sizeof *controller, GFP_KERNEL); | 1313 | controller = kzalloc(sizeof *controller, GFP_KERNEL); |
| 1314 | if (!controller) | 1314 | if (!controller) |
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 84427bebbf62..69a0da3c8f09 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
| 30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
| 31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
| 32 | #include <linux/platform_device.h> | ||
| 33 | #include <linux/dma-mapping.h> | ||
| 32 | 34 | ||
| 33 | #include <mach/da8xx.h> | 35 | #include <mach/da8xx.h> |
| 34 | #include <mach/usb.h> | 36 | #include <mach/usb.h> |
| @@ -78,6 +80,12 @@ | |||
| 78 | 80 | ||
| 79 | #define CFGCHIP2 IO_ADDRESS(DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP2_REG) | 81 | #define CFGCHIP2 IO_ADDRESS(DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP2_REG) |
| 80 | 82 | ||
| 83 | struct da8xx_glue { | ||
| 84 | struct device *dev; | ||
| 85 | struct platform_device *musb; | ||
| 86 | struct clk *clk; | ||
| 87 | }; | ||
| 88 | |||
| 81 | /* | 89 | /* |
| 82 | * REVISIT (PM): we should be able to keep the PHY in low power mode most | 90 | * REVISIT (PM): we should be able to keep the PHY in low power mode most |
| 83 | * of the time (24 MHz oscillator and PLL off, etc.) by setting POWER.D0 | 91 | * of the time (24 MHz oscillator and PLL off, etc.) by setting POWER.D0 |
| @@ -131,9 +139,9 @@ static inline void phy_off(void) | |||
| 131 | */ | 139 | */ |
| 132 | 140 | ||
| 133 | /** | 141 | /** |
| 134 | * musb_platform_enable - enable interrupts | 142 | * da8xx_musb_enable - enable interrupts |
| 135 | */ | 143 | */ |
| 136 | void musb_platform_enable(struct musb *musb) | 144 | static void da8xx_musb_enable(struct musb *musb) |
| 137 | { | 145 | { |
| 138 | void __iomem *reg_base = musb->ctrl_base; | 146 | void __iomem *reg_base = musb->ctrl_base; |
| 139 | u32 mask; | 147 | u32 mask; |
| @@ -151,9 +159,9 @@ void musb_platform_enable(struct musb *musb) | |||
| 151 | } | 159 | } |
| 152 | 160 | ||
| 153 | /** | 161 | /** |
| 154 | * musb_platform_disable - disable HDRC and flush interrupts | 162 | * da8xx_musb_disable - disable HDRC and flush interrupts |
| 155 | */ | 163 | */ |
| 156 | void musb_platform_disable(struct musb *musb) | 164 | static void da8xx_musb_disable(struct musb *musb) |
| 157 | { | 165 | { |
| 158 | void __iomem *reg_base = musb->ctrl_base; | 166 | void __iomem *reg_base = musb->ctrl_base; |
| 159 | 167 | ||
| @@ -170,7 +178,7 @@ void musb_platform_disable(struct musb *musb) | |||
| 170 | #define portstate(stmt) | 178 | #define portstate(stmt) |
| 171 | #endif | 179 | #endif |
| 172 | 180 | ||
| 173 | static void da8xx_set_vbus(struct musb *musb, int is_on) | 181 | static void da8xx_musb_set_vbus(struct musb *musb, int is_on) |
| 174 | { | 182 | { |
| 175 | WARN_ON(is_on && is_peripheral_active(musb)); | 183 | WARN_ON(is_on && is_peripheral_active(musb)); |
| 176 | } | 184 | } |
| @@ -252,7 +260,7 @@ static void otg_timer(unsigned long _musb) | |||
| 252 | spin_unlock_irqrestore(&musb->lock, flags); | 260 | spin_unlock_irqrestore(&musb->lock, flags); |
| 253 | } | 261 | } |
| 254 | 262 | ||
| 255 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | 263 | static void da8xx_musb_try_idle(struct musb *musb, unsigned long timeout) |
| 256 | { | 264 | { |
| 257 | static unsigned long last_timer; | 265 | static unsigned long last_timer; |
| 258 | 266 | ||
| @@ -282,7 +290,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | |||
| 282 | mod_timer(&otg_workaround, timeout); | 290 | mod_timer(&otg_workaround, timeout); |
| 283 | } | 291 | } |
| 284 | 292 | ||
| 285 | static irqreturn_t da8xx_interrupt(int irq, void *hci) | 293 | static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) |
| 286 | { | 294 | { |
| 287 | struct musb *musb = hci; | 295 | struct musb *musb = hci; |
| 288 | void __iomem *reg_base = musb->ctrl_base; | 296 | void __iomem *reg_base = musb->ctrl_base; |
| @@ -380,7 +388,7 @@ static irqreturn_t da8xx_interrupt(int irq, void *hci) | |||
| 380 | return ret; | 388 | return ret; |
| 381 | } | 389 | } |
| 382 | 390 | ||
| 383 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 391 | static int da8xx_musb_set_mode(struct musb *musb, u8 musb_mode) |
| 384 | { | 392 | { |
| 385 | u32 cfgchip2 = __raw_readl(CFGCHIP2); | 393 | u32 cfgchip2 = __raw_readl(CFGCHIP2); |
| 386 | 394 | ||
| @@ -409,15 +417,13 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
| 409 | return 0; | 417 | return 0; |
| 410 | } | 418 | } |
| 411 | 419 | ||
| 412 | int __init musb_platform_init(struct musb *musb, void *board_data) | 420 | static int da8xx_musb_init(struct musb *musb) |
| 413 | { | 421 | { |
| 414 | void __iomem *reg_base = musb->ctrl_base; | 422 | void __iomem *reg_base = musb->ctrl_base; |
| 415 | u32 rev; | 423 | u32 rev; |
| 416 | 424 | ||
| 417 | musb->mregs += DA8XX_MENTOR_CORE_OFFSET; | 425 | musb->mregs += DA8XX_MENTOR_CORE_OFFSET; |
| 418 | 426 | ||
| 419 | clk_enable(musb->clock); | ||
| 420 | |||
| 421 | /* Returns zero if e.g. not clocked */ | 427 | /* Returns zero if e.g. not clocked */ |
| 422 | rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG); | 428 | rev = musb_readl(reg_base, DA8XX_USB_REVISION_REG); |
| 423 | if (!rev) | 429 | if (!rev) |
| @@ -431,8 +437,6 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
| 431 | if (is_host_enabled(musb)) | 437 | if (is_host_enabled(musb)) |
| 432 | setup_timer(&otg_workaround, otg_timer, (unsigned long)musb); | 438 | setup_timer(&otg_workaround, otg_timer, (unsigned long)musb); |
| 433 | 439 | ||
| 434 | musb->board_set_vbus = da8xx_set_vbus; | ||
| 435 | |||
| 436 | /* Reset the controller */ | 440 | /* Reset the controller */ |
| 437 | musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK); | 441 | musb_writel(reg_base, DA8XX_USB_CTRL_REG, DA8XX_SOFT_RESET_MASK); |
| 438 | 442 | ||
| @@ -446,14 +450,13 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
| 446 | rev, __raw_readl(CFGCHIP2), | 450 | rev, __raw_readl(CFGCHIP2), |
| 447 | musb_readb(reg_base, DA8XX_USB_CTRL_REG)); | 451 | musb_readb(reg_base, DA8XX_USB_CTRL_REG)); |
| 448 | 452 | ||
| 449 | musb->isr = da8xx_interrupt; | 453 | musb->isr = da8xx_musb_interrupt; |
| 450 | return 0; | 454 | return 0; |
| 451 | fail: | 455 | fail: |
| 452 | clk_disable(musb->clock); | ||
| 453 | return -ENODEV; | 456 | return -ENODEV; |
| 454 | } | 457 | } |
| 455 | 458 | ||
| 456 | int musb_platform_exit(struct musb *musb) | 459 | static int da8xx_musb_exit(struct musb *musb) |
| 457 | { | 460 | { |
| 458 | if (is_host_enabled(musb)) | 461 | if (is_host_enabled(musb)) |
| 459 | del_timer_sync(&otg_workaround); | 462 | del_timer_sync(&otg_workaround); |
| @@ -463,7 +466,140 @@ int musb_platform_exit(struct musb *musb) | |||
| 463 | otg_put_transceiver(musb->xceiv); | 466 | otg_put_transceiver(musb->xceiv); |
| 464 | usb_nop_xceiv_unregister(); | 467 | usb_nop_xceiv_unregister(); |
| 465 | 468 | ||
| 466 | clk_disable(musb->clock); | 469 | return 0; |
| 470 | } | ||
| 471 | |||
| 472 | static const struct musb_platform_ops da8xx_ops = { | ||
| 473 | .init = da8xx_musb_init, | ||
| 474 | .exit = da8xx_musb_exit, | ||
| 475 | |||
| 476 | .enable = da8xx_musb_enable, | ||
| 477 | .disable = da8xx_musb_disable, | ||
| 478 | |||
| 479 | .set_mode = da8xx_musb_set_mode, | ||
| 480 | .try_idle = da8xx_musb_try_idle, | ||
| 481 | |||
| 482 | .set_vbus = da8xx_musb_set_vbus, | ||
| 483 | }; | ||
| 484 | |||
| 485 | static u64 da8xx_dmamask = DMA_BIT_MASK(32); | ||
| 486 | |||
| 487 | static int __init da8xx_probe(struct platform_device *pdev) | ||
| 488 | { | ||
| 489 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | ||
| 490 | struct platform_device *musb; | ||
| 491 | struct da8xx_glue *glue; | ||
| 492 | |||
| 493 | struct clk *clk; | ||
| 494 | |||
| 495 | int ret = -ENOMEM; | ||
| 496 | |||
| 497 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | ||
| 498 | if (!glue) { | ||
| 499 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
| 500 | goto err0; | ||
| 501 | } | ||
| 502 | |||
| 503 | musb = platform_device_alloc("musb-hdrc", -1); | ||
| 504 | if (!musb) { | ||
| 505 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | ||
| 506 | goto err1; | ||
| 507 | } | ||
| 508 | |||
| 509 | clk = clk_get(&pdev->dev, "usb20"); | ||
| 510 | if (IS_ERR(clk)) { | ||
| 511 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
| 512 | ret = PTR_ERR(clk); | ||
| 513 | goto err2; | ||
| 514 | } | ||
| 515 | |||
| 516 | ret = clk_enable(clk); | ||
| 517 | if (ret) { | ||
| 518 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
| 519 | goto err3; | ||
| 520 | } | ||
| 521 | |||
| 522 | musb->dev.parent = &pdev->dev; | ||
| 523 | musb->dev.dma_mask = &da8xx_dmamask; | ||
| 524 | musb->dev.coherent_dma_mask = da8xx_dmamask; | ||
| 525 | |||
| 526 | glue->dev = &pdev->dev; | ||
| 527 | glue->musb = musb; | ||
| 528 | glue->clk = clk; | ||
| 529 | |||
| 530 | pdata->platform_ops = &da8xx_ops; | ||
| 531 | |||
| 532 | platform_set_drvdata(pdev, glue); | ||
| 533 | |||
| 534 | ret = platform_device_add_resources(musb, pdev->resource, | ||
| 535 | pdev->num_resources); | ||
| 536 | if (ret) { | ||
| 537 | dev_err(&pdev->dev, "failed to add resources\n"); | ||
| 538 | goto err4; | ||
| 539 | } | ||
| 540 | |||
| 541 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | ||
| 542 | if (ret) { | ||
| 543 | dev_err(&pdev->dev, "failed to add platform_data\n"); | ||
| 544 | goto err4; | ||
| 545 | } | ||
| 546 | |||
| 547 | ret = platform_device_add(musb); | ||
| 548 | if (ret) { | ||
| 549 | dev_err(&pdev->dev, "failed to register musb device\n"); | ||
| 550 | goto err4; | ||
| 551 | } | ||
| 552 | |||
| 553 | return 0; | ||
| 554 | |||
| 555 | err4: | ||
| 556 | clk_disable(clk); | ||
| 557 | |||
| 558 | err3: | ||
| 559 | clk_put(clk); | ||
| 560 | |||
| 561 | err2: | ||
| 562 | platform_device_put(musb); | ||
| 563 | |||
| 564 | err1: | ||
| 565 | kfree(glue); | ||
| 566 | |||
| 567 | err0: | ||
| 568 | return ret; | ||
| 569 | } | ||
| 570 | |||
| 571 | static int __exit da8xx_remove(struct platform_device *pdev) | ||
| 572 | { | ||
| 573 | struct da8xx_glue *glue = platform_get_drvdata(pdev); | ||
| 574 | |||
| 575 | platform_device_del(glue->musb); | ||
| 576 | platform_device_put(glue->musb); | ||
| 577 | clk_disable(glue->clk); | ||
| 578 | clk_put(glue->clk); | ||
| 579 | kfree(glue); | ||
| 467 | 580 | ||
| 468 | return 0; | 581 | return 0; |
| 469 | } | 582 | } |
| 583 | |||
| 584 | static struct platform_driver da8xx_driver = { | ||
| 585 | .remove = __exit_p(da8xx_remove), | ||
| 586 | .driver = { | ||
| 587 | .name = "musb-da8xx", | ||
| 588 | }, | ||
| 589 | }; | ||
| 590 | |||
| 591 | MODULE_DESCRIPTION("DA8xx/OMAP-L1x MUSB Glue Layer"); | ||
| 592 | MODULE_AUTHOR("Sergei Shtylyov <sshtylyov@ru.mvista.com>"); | ||
| 593 | MODULE_LICENSE("GPL v2"); | ||
| 594 | |||
| 595 | static int __init da8xx_init(void) | ||
| 596 | { | ||
| 597 | return platform_driver_probe(&da8xx_driver, da8xx_probe); | ||
| 598 | } | ||
| 599 | subsys_initcall(da8xx_init); | ||
| 600 | |||
| 601 | static void __exit da8xx_exit(void) | ||
| 602 | { | ||
| 603 | platform_driver_unregister(&da8xx_driver); | ||
| 604 | } | ||
| 605 | module_exit(da8xx_exit); | ||
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 6e67629f50cc..e6de097fb7e8 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
| @@ -30,6 +30,8 @@ | |||
| 30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
| 31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
| 32 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
| 33 | #include <linux/platform_device.h> | ||
| 34 | #include <linux/dma-mapping.h> | ||
| 33 | 35 | ||
| 34 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
| 35 | #include <mach/memory.h> | 37 | #include <mach/memory.h> |
| @@ -51,6 +53,12 @@ | |||
| 51 | #define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR) | 53 | #define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR) |
| 52 | #define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR) | 54 | #define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR) |
| 53 | 55 | ||
| 56 | struct davinci_glue { | ||
| 57 | struct device *dev; | ||
| 58 | struct platform_device *musb; | ||
| 59 | struct clk *clk; | ||
| 60 | }; | ||
| 61 | |||
| 54 | /* REVISIT (PM) we should be able to keep the PHY in low power mode most | 62 | /* REVISIT (PM) we should be able to keep the PHY in low power mode most |
| 55 | * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 | 63 | * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 |
| 56 | * and, when in host mode, autosuspending idle root ports... PHYPLLON | 64 | * and, when in host mode, autosuspending idle root ports... PHYPLLON |
| @@ -83,7 +91,7 @@ static inline void phy_off(void) | |||
| 83 | 91 | ||
| 84 | static int dma_off = 1; | 92 | static int dma_off = 1; |
| 85 | 93 | ||
| 86 | void musb_platform_enable(struct musb *musb) | 94 | static void davinci_musb_enable(struct musb *musb) |
| 87 | { | 95 | { |
| 88 | u32 tmp, old, val; | 96 | u32 tmp, old, val; |
| 89 | 97 | ||
| @@ -116,7 +124,7 @@ void musb_platform_enable(struct musb *musb) | |||
| 116 | /* | 124 | /* |
| 117 | * Disable the HDRC and flush interrupts | 125 | * Disable the HDRC and flush interrupts |
| 118 | */ | 126 | */ |
| 119 | void musb_platform_disable(struct musb *musb) | 127 | static void davinci_musb_disable(struct musb *musb) |
| 120 | { | 128 | { |
| 121 | /* because we don't set CTRLR.UINT, "important" to: | 129 | /* because we don't set CTRLR.UINT, "important" to: |
| 122 | * - not read/write INTRUSB/INTRUSBE | 130 | * - not read/write INTRUSB/INTRUSBE |
| @@ -167,7 +175,7 @@ static void evm_deferred_drvvbus(struct work_struct *ignored) | |||
| 167 | 175 | ||
| 168 | #endif /* EVM */ | 176 | #endif /* EVM */ |
| 169 | 177 | ||
| 170 | static void davinci_source_power(struct musb *musb, int is_on, int immediate) | 178 | static void davinci_musb_source_power(struct musb *musb, int is_on, int immediate) |
| 171 | { | 179 | { |
| 172 | #ifdef CONFIG_MACH_DAVINCI_EVM | 180 | #ifdef CONFIG_MACH_DAVINCI_EVM |
| 173 | if (is_on) | 181 | if (is_on) |
| @@ -190,10 +198,10 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate) | |||
| 190 | #endif | 198 | #endif |
| 191 | } | 199 | } |
| 192 | 200 | ||
| 193 | static void davinci_set_vbus(struct musb *musb, int is_on) | 201 | static void davinci_musb_set_vbus(struct musb *musb, int is_on) |
| 194 | { | 202 | { |
| 195 | WARN_ON(is_on && is_peripheral_active(musb)); | 203 | WARN_ON(is_on && is_peripheral_active(musb)); |
| 196 | davinci_source_power(musb, is_on, 0); | 204 | davinci_musb_source_power(musb, is_on, 0); |
| 197 | } | 205 | } |
| 198 | 206 | ||
| 199 | 207 | ||
| @@ -259,7 +267,7 @@ static void otg_timer(unsigned long _musb) | |||
| 259 | spin_unlock_irqrestore(&musb->lock, flags); | 267 | spin_unlock_irqrestore(&musb->lock, flags); |
| 260 | } | 268 | } |
| 261 | 269 | ||
| 262 | static irqreturn_t davinci_interrupt(int irq, void *__hci) | 270 | static irqreturn_t davinci_musb_interrupt(int irq, void *__hci) |
| 263 | { | 271 | { |
| 264 | unsigned long flags; | 272 | unsigned long flags; |
| 265 | irqreturn_t retval = IRQ_NONE; | 273 | irqreturn_t retval = IRQ_NONE; |
| @@ -345,7 +353,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
| 345 | /* NOTE: this must complete poweron within 100 msec | 353 | /* NOTE: this must complete poweron within 100 msec |
| 346 | * (OTG_TIME_A_WAIT_VRISE) but we don't check for that. | 354 | * (OTG_TIME_A_WAIT_VRISE) but we don't check for that. |
| 347 | */ | 355 | */ |
| 348 | davinci_source_power(musb, drvvbus, 0); | 356 | davinci_musb_source_power(musb, drvvbus, 0); |
| 349 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", | 357 | DBG(2, "VBUS %s (%s)%s, devctl %02x\n", |
| 350 | drvvbus ? "on" : "off", | 358 | drvvbus ? "on" : "off", |
| 351 | otg_state_string(musb), | 359 | otg_state_string(musb), |
| @@ -370,13 +378,13 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci) | |||
| 370 | return retval; | 378 | return retval; |
| 371 | } | 379 | } |
| 372 | 380 | ||
| 373 | int musb_platform_set_mode(struct musb *musb, u8 mode) | 381 | static int davinci_musb_set_mode(struct musb *musb, u8 mode) |
| 374 | { | 382 | { |
| 375 | /* EVM can't do this (right?) */ | 383 | /* EVM can't do this (right?) */ |
| 376 | return -EIO; | 384 | return -EIO; |
| 377 | } | 385 | } |
| 378 | 386 | ||
| 379 | int __init musb_platform_init(struct musb *musb, void *board_data) | 387 | static int davinci_musb_init(struct musb *musb) |
| 380 | { | 388 | { |
| 381 | void __iomem *tibase = musb->ctrl_base; | 389 | void __iomem *tibase = musb->ctrl_base; |
| 382 | u32 revision; | 390 | u32 revision; |
| @@ -388,8 +396,6 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
| 388 | 396 | ||
| 389 | musb->mregs += DAVINCI_BASE_OFFSET; | 397 | musb->mregs += DAVINCI_BASE_OFFSET; |
| 390 | 398 | ||
| 391 | clk_enable(musb->clock); | ||
| 392 | |||
| 393 | /* returns zero if e.g. not clocked */ | 399 | /* returns zero if e.g. not clocked */ |
| 394 | revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); | 400 | revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); |
| 395 | if (revision == 0) | 401 | if (revision == 0) |
| @@ -398,8 +404,7 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
| 398 | if (is_host_enabled(musb)) | 404 | if (is_host_enabled(musb)) |
| 399 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); | 405 | setup_timer(&otg_workaround, otg_timer, (unsigned long) musb); |
| 400 | 406 | ||
| 401 | musb->board_set_vbus = davinci_set_vbus; | 407 | davinci_musb_source_power(musb, 0, 1); |
| 402 | davinci_source_power(musb, 0, 1); | ||
| 403 | 408 | ||
| 404 | /* dm355 EVM swaps D+/D- for signal integrity, and | 409 | /* dm355 EVM swaps D+/D- for signal integrity, and |
| 405 | * is clocked from the main 24 MHz crystal. | 410 | * is clocked from the main 24 MHz crystal. |
| @@ -440,18 +445,16 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
| 440 | revision, __raw_readl(USB_PHY_CTRL), | 445 | revision, __raw_readl(USB_PHY_CTRL), |
| 441 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); | 446 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); |
| 442 | 447 | ||
| 443 | musb->isr = davinci_interrupt; | 448 | musb->isr = davinci_musb_interrupt; |
| 444 | return 0; | 449 | return 0; |
| 445 | 450 | ||
| 446 | fail: | 451 | fail: |
| 447 | clk_disable(musb->clock); | ||
| 448 | |||
| 449 | otg_put_transceiver(musb->xceiv); | 452 | otg_put_transceiver(musb->xceiv); |
| 450 | usb_nop_xceiv_unregister(); | 453 | usb_nop_xceiv_unregister(); |
| 451 | return -ENODEV; | 454 | return -ENODEV; |
| 452 | } | 455 | } |
| 453 | 456 | ||
| 454 | int musb_platform_exit(struct musb *musb) | 457 | static int davinci_musb_exit(struct musb *musb) |
| 455 | { | 458 | { |
| 456 | if (is_host_enabled(musb)) | 459 | if (is_host_enabled(musb)) |
| 457 | del_timer_sync(&otg_workaround); | 460 | del_timer_sync(&otg_workaround); |
| @@ -465,7 +468,7 @@ int musb_platform_exit(struct musb *musb) | |||
| 465 | __raw_writel(deepsleep, DM355_DEEPSLEEP); | 468 | __raw_writel(deepsleep, DM355_DEEPSLEEP); |
| 466 | } | 469 | } |
| 467 | 470 | ||
| 468 | davinci_source_power(musb, 0 /*off*/, 1); | 471 | davinci_musb_source_power(musb, 0 /*off*/, 1); |
| 469 | 472 | ||
| 470 | /* delay, to avoid problems with module reload */ | 473 | /* delay, to avoid problems with module reload */ |
| 471 | if (is_host_enabled(musb) && musb->xceiv->default_a) { | 474 | if (is_host_enabled(musb) && musb->xceiv->default_a) { |
| @@ -495,10 +498,141 @@ int musb_platform_exit(struct musb *musb) | |||
| 495 | 498 | ||
| 496 | phy_off(); | 499 | phy_off(); |
| 497 | 500 | ||
| 498 | clk_disable(musb->clock); | ||
| 499 | |||
| 500 | otg_put_transceiver(musb->xceiv); | 501 | otg_put_transceiver(musb->xceiv); |
| 501 | usb_nop_xceiv_unregister(); | 502 | usb_nop_xceiv_unregister(); |
| 502 | 503 | ||
| 503 | return 0; | 504 | return 0; |
| 504 | } | 505 | } |
| 506 | |||
| 507 | static const struct musb_platform_ops davinci_ops = { | ||
| 508 | .init = davinci_musb_init, | ||
| 509 | .exit = davinci_musb_exit, | ||
| 510 | |||
| 511 | .enable = davinci_musb_enable, | ||
| 512 | .disable = davinci_musb_disable, | ||
| 513 | |||
| 514 | .set_mode = davinci_musb_set_mode, | ||
| 515 | |||
| 516 | .set_vbus = davinci_musb_set_vbus, | ||
| 517 | }; | ||
| 518 | |||
| 519 | static u64 davinci_dmamask = DMA_BIT_MASK(32); | ||
| 520 | |||
| 521 | static int __init davinci_probe(struct platform_device *pdev) | ||
| 522 | { | ||
| 523 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | ||
| 524 | struct platform_device *musb; | ||
| 525 | struct davinci_glue *glue; | ||
| 526 | struct clk *clk; | ||
| 527 | |||
| 528 | int ret = -ENOMEM; | ||
| 529 | |||
| 530 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | ||
| 531 | if (!glue) { | ||
| 532 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
| 533 | goto err0; | ||
| 534 | } | ||
| 535 | |||
| 536 | musb = platform_device_alloc("musb-hdrc", -1); | ||
| 537 | if (!musb) { | ||
| 538 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | ||
| 539 | goto err1; | ||
| 540 | } | ||
| 541 | |||
| 542 | clk = clk_get(&pdev->dev, "usb"); | ||
| 543 | if (IS_ERR(clk)) { | ||
| 544 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
| 545 | ret = PTR_ERR(clk); | ||
| 546 | goto err2; | ||
| 547 | } | ||
| 548 | |||
| 549 | ret = clk_enable(clk); | ||
| 550 | if (ret) { | ||
| 551 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
| 552 | goto err3; | ||
| 553 | } | ||
| 554 | |||
| 555 | musb->dev.parent = &pdev->dev; | ||
| 556 | musb->dev.dma_mask = &davinci_dmamask; | ||
| 557 | musb->dev.coherent_dma_mask = davinci_dmamask; | ||
| 558 | |||
| 559 | glue->dev = &pdev->dev; | ||
| 560 | glue->musb = musb; | ||
| 561 | glue->clk = clk; | ||
| 562 | |||
| 563 | pdata->platform_ops = &davinci_ops; | ||
| 564 | |||
| 565 | platform_set_drvdata(pdev, glue); | ||
| 566 | |||
| 567 | ret = platform_device_add_resources(musb, pdev->resource, | ||
| 568 | pdev->num_resources); | ||
| 569 | if (ret) { | ||
| 570 | dev_err(&pdev->dev, "failed to add resources\n"); | ||
| 571 | goto err4; | ||
| 572 | } | ||
| 573 | |||
| 574 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | ||
| 575 | if (ret) { | ||
| 576 | dev_err(&pdev->dev, "failed to add platform_data\n"); | ||
| 577 | goto err4; | ||
| 578 | } | ||
| 579 | |||
| 580 | ret = platform_device_add(musb); | ||
| 581 | if (ret) { | ||
| 582 | dev_err(&pdev->dev, "failed to register musb device\n"); | ||
| 583 | goto err4; | ||
| 584 | } | ||
| 585 | |||
| 586 | return 0; | ||
| 587 | |||
| 588 | err4: | ||
| 589 | clk_disable(clk); | ||
| 590 | |||
| 591 | err3: | ||
| 592 | clk_put(clk); | ||
| 593 | |||
| 594 | err2: | ||
| 595 | platform_device_put(musb); | ||
| 596 | |||
| 597 | err1: | ||
| 598 | kfree(glue); | ||
| 599 | |||
| 600 | err0: | ||
| 601 | return ret; | ||
| 602 | } | ||
| 603 | |||
| 604 | static int __exit davinci_remove(struct platform_device *pdev) | ||
| 605 | { | ||
| 606 | struct davinci_glue *glue = platform_get_drvdata(pdev); | ||
| 607 | |||
| 608 | platform_device_del(glue->musb); | ||
| 609 | platform_device_put(glue->musb); | ||
| 610 | clk_disable(glue->clk); | ||
| 611 | clk_put(glue->clk); | ||
| 612 | kfree(glue); | ||
| 613 | |||
| 614 | return 0; | ||
| 615 | } | ||
| 616 | |||
| 617 | static struct platform_driver davinci_driver = { | ||
| 618 | .remove = __exit_p(davinci_remove), | ||
| 619 | .driver = { | ||
| 620 | .name = "musb-davinci", | ||
| 621 | }, | ||
| 622 | }; | ||
| 623 | |||
| 624 | MODULE_DESCRIPTION("DaVinci MUSB Glue Layer"); | ||
| 625 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | ||
| 626 | MODULE_LICENSE("GPL v2"); | ||
| 627 | |||
| 628 | static int __init davinci_init(void) | ||
| 629 | { | ||
| 630 | return platform_driver_probe(&davinci_driver, davinci_probe); | ||
| 631 | } | ||
| 632 | subsys_initcall(davinci_init); | ||
| 633 | |||
| 634 | static void __exit davinci_exit(void) | ||
| 635 | { | ||
| 636 | platform_driver_unregister(&davinci_driver); | ||
| 637 | } | ||
| 638 | module_exit(davinci_exit); | ||
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 365a4fab5c64..07cf394e491b 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -99,19 +99,8 @@ | |||
| 99 | #include <linux/platform_device.h> | 99 | #include <linux/platform_device.h> |
| 100 | #include <linux/io.h> | 100 | #include <linux/io.h> |
| 101 | 101 | ||
| 102 | #ifdef CONFIG_ARM | ||
| 103 | #include <mach/hardware.h> | ||
| 104 | #include <mach/memory.h> | ||
| 105 | #include <asm/mach-types.h> | ||
| 106 | #endif | ||
| 107 | |||
| 108 | #include "musb_core.h" | 102 | #include "musb_core.h" |
| 109 | 103 | ||
| 110 | |||
| 111 | #ifdef CONFIG_ARCH_DAVINCI | ||
| 112 | #include "davinci.h" | ||
| 113 | #endif | ||
| 114 | |||
| 115 | #define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON) | 104 | #define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON) |
| 116 | 105 | ||
| 117 | 106 | ||
| @@ -126,7 +115,7 @@ MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); | |||
| 126 | 115 | ||
| 127 | #define DRIVER_INFO DRIVER_DESC ", v" MUSB_VERSION | 116 | #define DRIVER_INFO DRIVER_DESC ", v" MUSB_VERSION |
| 128 | 117 | ||
| 129 | #define MUSB_DRIVER_NAME "musb_hdrc" | 118 | #define MUSB_DRIVER_NAME "musb-hdrc" |
| 130 | const char musb_driver_name[] = MUSB_DRIVER_NAME; | 119 | const char musb_driver_name[] = MUSB_DRIVER_NAME; |
| 131 | 120 | ||
| 132 | MODULE_DESCRIPTION(DRIVER_INFO); | 121 | MODULE_DESCRIPTION(DRIVER_INFO); |
| @@ -230,7 +219,7 @@ static struct otg_io_access_ops musb_ulpi_access = { | |||
| 230 | 219 | ||
| 231 | /*-------------------------------------------------------------------------*/ | 220 | /*-------------------------------------------------------------------------*/ |
| 232 | 221 | ||
| 233 | #if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN) | 222 | #if !defined(CONFIG_USB_MUSB_TUSB6010) && !defined(CONFIG_USB_MUSB_BLACKFIN) |
| 234 | 223 | ||
| 235 | /* | 224 | /* |
| 236 | * Load an endpoint's FIFO | 225 | * Load an endpoint's FIFO |
| @@ -390,7 +379,7 @@ void musb_otg_timer_func(unsigned long data) | |||
| 390 | case OTG_STATE_A_SUSPEND: | 379 | case OTG_STATE_A_SUSPEND: |
| 391 | case OTG_STATE_A_WAIT_BCON: | 380 | case OTG_STATE_A_WAIT_BCON: |
| 392 | DBG(1, "HNP: %s timeout\n", otg_state_string(musb)); | 381 | DBG(1, "HNP: %s timeout\n", otg_state_string(musb)); |
| 393 | musb_set_vbus(musb, 0); | 382 | musb_platform_set_vbus(musb, 0); |
| 394 | musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; | 383 | musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; |
| 395 | break; | 384 | break; |
| 396 | default: | 385 | default: |
| @@ -571,7 +560,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
| 571 | musb->ep0_stage = MUSB_EP0_START; | 560 | musb->ep0_stage = MUSB_EP0_START; |
| 572 | musb->xceiv->state = OTG_STATE_A_IDLE; | 561 | musb->xceiv->state = OTG_STATE_A_IDLE; |
| 573 | MUSB_HST_MODE(musb); | 562 | MUSB_HST_MODE(musb); |
| 574 | musb_set_vbus(musb, 1); | 563 | musb_platform_set_vbus(musb, 1); |
| 575 | 564 | ||
| 576 | handled = IRQ_HANDLED; | 565 | handled = IRQ_HANDLED; |
| 577 | } | 566 | } |
| @@ -642,7 +631,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, | |||
| 642 | 631 | ||
| 643 | /* go through A_WAIT_VFALL then start a new session */ | 632 | /* go through A_WAIT_VFALL then start a new session */ |
| 644 | if (!ignore) | 633 | if (!ignore) |
| 645 | musb_set_vbus(musb, 0); | 634 | musb_platform_set_vbus(musb, 0); |
| 646 | handled = IRQ_HANDLED; | 635 | handled = IRQ_HANDLED; |
| 647 | } | 636 | } |
| 648 | 637 | ||
| @@ -1049,8 +1038,6 @@ static void musb_shutdown(struct platform_device *pdev) | |||
| 1049 | spin_lock_irqsave(&musb->lock, flags); | 1038 | spin_lock_irqsave(&musb->lock, flags); |
| 1050 | musb_platform_disable(musb); | 1039 | musb_platform_disable(musb); |
| 1051 | musb_generic_disable(musb); | 1040 | musb_generic_disable(musb); |
| 1052 | if (musb->clock) | ||
| 1053 | clk_put(musb->clock); | ||
| 1054 | spin_unlock_irqrestore(&musb->lock, flags); | 1041 | spin_unlock_irqrestore(&musb->lock, flags); |
| 1055 | 1042 | ||
| 1056 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) | 1043 | if (!is_otg_enabled(musb) && is_host_enabled(musb)) |
| @@ -1074,10 +1061,11 @@ static void musb_shutdown(struct platform_device *pdev) | |||
| 1074 | * We don't currently use dynamic fifo setup capability to do anything | 1061 | * We don't currently use dynamic fifo setup capability to do anything |
| 1075 | * more than selecting one of a bunch of predefined configurations. | 1062 | * more than selecting one of a bunch of predefined configurations. |
| 1076 | */ | 1063 | */ |
| 1077 | #if defined(CONFIG_USB_TUSB6010) || \ | 1064 | #if defined(CONFIG_USB_MUSB_TUSB6010) || defined(CONFIG_USB_MUSB_OMAP2PLUS) \ |
| 1078 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \ | 1065 | || defined(CONFIG_USB_MUSB_AM35X) |
| 1079 | || defined(CONFIG_ARCH_OMAP4) | ||
| 1080 | static ushort __initdata fifo_mode = 4; | 1066 | static ushort __initdata fifo_mode = 4; |
| 1067 | #elif defined(CONFIG_USB_MUSB_UX500) | ||
| 1068 | static ushort __initdata fifo_mode = 5; | ||
| 1081 | #else | 1069 | #else |
| 1082 | static ushort __initdata fifo_mode = 2; | 1070 | static ushort __initdata fifo_mode = 2; |
| 1083 | #endif | 1071 | #endif |
| @@ -1501,7 +1489,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
| 1501 | struct musb_hw_ep *hw_ep = musb->endpoints + i; | 1489 | struct musb_hw_ep *hw_ep = musb->endpoints + i; |
| 1502 | 1490 | ||
| 1503 | hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase; | 1491 | hw_ep->fifo = MUSB_FIFO_OFFSET(i) + mbase; |
| 1504 | #ifdef CONFIG_USB_TUSB6010 | 1492 | #ifdef CONFIG_USB_MUSB_TUSB6010 |
| 1505 | hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i); | 1493 | hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i); |
| 1506 | hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i); | 1494 | hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i); |
| 1507 | hw_ep->fifo_sync_va = | 1495 | hw_ep->fifo_sync_va = |
| @@ -1548,7 +1536,8 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) | |||
| 1548 | /*-------------------------------------------------------------------------*/ | 1536 | /*-------------------------------------------------------------------------*/ |
| 1549 | 1537 | ||
| 1550 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) || \ | 1538 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) || \ |
| 1551 | defined(CONFIG_ARCH_OMAP4) | 1539 | defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) || \ |
| 1540 | defined(CONFIG_ARCH_U5500) | ||
| 1552 | 1541 | ||
| 1553 | static irqreturn_t generic_interrupt(int irq, void *__hci) | 1542 | static irqreturn_t generic_interrupt(int irq, void *__hci) |
| 1554 | { | 1543 | { |
| @@ -1904,6 +1893,7 @@ allocate_instance(struct device *dev, | |||
| 1904 | } | 1893 | } |
| 1905 | 1894 | ||
| 1906 | musb->controller = dev; | 1895 | musb->controller = dev; |
| 1896 | |||
| 1907 | return musb; | 1897 | return musb; |
| 1908 | } | 1898 | } |
| 1909 | 1899 | ||
| @@ -2000,30 +1990,14 @@ bad_config: | |||
| 2000 | spin_lock_init(&musb->lock); | 1990 | spin_lock_init(&musb->lock); |
| 2001 | musb->board_mode = plat->mode; | 1991 | musb->board_mode = plat->mode; |
| 2002 | musb->board_set_power = plat->set_power; | 1992 | musb->board_set_power = plat->set_power; |
| 2003 | musb->set_clock = plat->set_clock; | ||
| 2004 | musb->min_power = plat->min_power; | 1993 | musb->min_power = plat->min_power; |
| 2005 | 1994 | musb->ops = plat->platform_ops; | |
| 2006 | /* Clock usage is chip-specific ... functional clock (DaVinci, | ||
| 2007 | * OMAP2430), or PHY ref (some TUSB6010 boards). All this core | ||
| 2008 | * code does is make sure a clock handle is available; platform | ||
| 2009 | * code manages it during start/stop and suspend/resume. | ||
| 2010 | */ | ||
| 2011 | if (plat->clock) { | ||
| 2012 | musb->clock = clk_get(dev, plat->clock); | ||
| 2013 | if (IS_ERR(musb->clock)) { | ||
| 2014 | status = PTR_ERR(musb->clock); | ||
| 2015 | musb->clock = NULL; | ||
| 2016 | goto fail1; | ||
| 2017 | } | ||
| 2018 | } | ||
| 2019 | 1995 | ||
| 2020 | /* The musb_platform_init() call: | 1996 | /* The musb_platform_init() call: |
| 2021 | * - adjusts musb->mregs and musb->isr if needed, | 1997 | * - adjusts musb->mregs and musb->isr if needed, |
| 2022 | * - may initialize an integrated tranceiver | 1998 | * - may initialize an integrated tranceiver |
| 2023 | * - initializes musb->xceiv, usually by otg_get_transceiver() | 1999 | * - initializes musb->xceiv, usually by otg_get_transceiver() |
| 2024 | * - activates clocks. | ||
| 2025 | * - stops powering VBUS | 2000 | * - stops powering VBUS |
| 2026 | * - assigns musb->board_set_vbus if host mode is enabled | ||
| 2027 | * | 2001 | * |
| 2028 | * There are various transciever configurations. Blackfin, | 2002 | * There are various transciever configurations. Blackfin, |
| 2029 | * DaVinci, TUSB60x0, and others integrate them. OMAP3 uses | 2003 | * DaVinci, TUSB60x0, and others integrate them. OMAP3 uses |
| @@ -2031,9 +2005,9 @@ bad_config: | |||
| 2031 | * isp1504, non-OTG, etc) mostly hooking up through ULPI. | 2005 | * isp1504, non-OTG, etc) mostly hooking up through ULPI. |
| 2032 | */ | 2006 | */ |
| 2033 | musb->isr = generic_interrupt; | 2007 | musb->isr = generic_interrupt; |
| 2034 | status = musb_platform_init(musb, plat->board_data); | 2008 | status = musb_platform_init(musb); |
| 2035 | if (status < 0) | 2009 | if (status < 0) |
| 2036 | goto fail2; | 2010 | goto fail1; |
| 2037 | 2011 | ||
| 2038 | if (!musb->isr) { | 2012 | if (!musb->isr) { |
| 2039 | status = -ENODEV; | 2013 | status = -ENODEV; |
| @@ -2186,10 +2160,6 @@ fail3: | |||
| 2186 | device_init_wakeup(dev, 0); | 2160 | device_init_wakeup(dev, 0); |
| 2187 | musb_platform_exit(musb); | 2161 | musb_platform_exit(musb); |
| 2188 | 2162 | ||
| 2189 | fail2: | ||
| 2190 | if (musb->clock) | ||
| 2191 | clk_put(musb->clock); | ||
| 2192 | |||
| 2193 | fail1: | 2163 | fail1: |
| 2194 | dev_err(musb->controller, | 2164 | dev_err(musb->controller, |
| 2195 | "musb_init_controller failed with status %d\n", status); | 2165 | "musb_init_controller failed with status %d\n", status); |
| @@ -2215,7 +2185,7 @@ static u64 *orig_dma_mask; | |||
| 2215 | static int __init musb_probe(struct platform_device *pdev) | 2185 | static int __init musb_probe(struct platform_device *pdev) |
| 2216 | { | 2186 | { |
| 2217 | struct device *dev = &pdev->dev; | 2187 | struct device *dev = &pdev->dev; |
| 2218 | int irq = platform_get_irq(pdev, 0); | 2188 | int irq = platform_get_irq_byname(pdev, "mc"); |
| 2219 | int status; | 2189 | int status; |
| 2220 | struct resource *iomem; | 2190 | struct resource *iomem; |
| 2221 | void __iomem *base; | 2191 | void __iomem *base; |
| @@ -2265,144 +2235,138 @@ static int __exit musb_remove(struct platform_device *pdev) | |||
| 2265 | 2235 | ||
| 2266 | #ifdef CONFIG_PM | 2236 | #ifdef CONFIG_PM |
| 2267 | 2237 | ||
| 2268 | static struct musb_context_registers musb_context; | 2238 | static void musb_save_context(struct musb *musb) |
| 2269 | |||
| 2270 | void musb_save_context(struct musb *musb) | ||
| 2271 | { | 2239 | { |
| 2272 | int i; | 2240 | int i; |
| 2273 | void __iomem *musb_base = musb->mregs; | 2241 | void __iomem *musb_base = musb->mregs; |
| 2274 | void __iomem *epio; | 2242 | void __iomem *epio; |
| 2275 | 2243 | ||
| 2276 | if (is_host_enabled(musb)) { | 2244 | if (is_host_enabled(musb)) { |
| 2277 | musb_context.frame = musb_readw(musb_base, MUSB_FRAME); | 2245 | musb->context.frame = musb_readw(musb_base, MUSB_FRAME); |
| 2278 | musb_context.testmode = musb_readb(musb_base, MUSB_TESTMODE); | 2246 | musb->context.testmode = musb_readb(musb_base, MUSB_TESTMODE); |
| 2279 | musb_context.busctl = musb_read_ulpi_buscontrol(musb->mregs); | 2247 | musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs); |
| 2280 | } | 2248 | } |
| 2281 | musb_context.power = musb_readb(musb_base, MUSB_POWER); | 2249 | musb->context.power = musb_readb(musb_base, MUSB_POWER); |
| 2282 | musb_context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); | 2250 | musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); |
| 2283 | musb_context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE); | 2251 | musb->context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE); |
| 2284 | musb_context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); | 2252 | musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); |
| 2285 | musb_context.index = musb_readb(musb_base, MUSB_INDEX); | 2253 | musb->context.index = musb_readb(musb_base, MUSB_INDEX); |
| 2286 | musb_context.devctl = musb_readb(musb_base, MUSB_DEVCTL); | 2254 | musb->context.devctl = musb_readb(musb_base, MUSB_DEVCTL); |
| 2287 | 2255 | ||
| 2288 | for (i = 0; i < musb->config->num_eps; ++i) { | 2256 | for (i = 0; i < musb->config->num_eps; ++i) { |
| 2289 | epio = musb->endpoints[i].regs; | 2257 | epio = musb->endpoints[i].regs; |
| 2290 | musb_context.index_regs[i].txmaxp = | 2258 | musb->context.index_regs[i].txmaxp = |
| 2291 | musb_readw(epio, MUSB_TXMAXP); | 2259 | musb_readw(epio, MUSB_TXMAXP); |
| 2292 | musb_context.index_regs[i].txcsr = | 2260 | musb->context.index_regs[i].txcsr = |
| 2293 | musb_readw(epio, MUSB_TXCSR); | 2261 | musb_readw(epio, MUSB_TXCSR); |
| 2294 | musb_context.index_regs[i].rxmaxp = | 2262 | musb->context.index_regs[i].rxmaxp = |
| 2295 | musb_readw(epio, MUSB_RXMAXP); | 2263 | musb_readw(epio, MUSB_RXMAXP); |
| 2296 | musb_context.index_regs[i].rxcsr = | 2264 | musb->context.index_regs[i].rxcsr = |
| 2297 | musb_readw(epio, MUSB_RXCSR); | 2265 | musb_readw(epio, MUSB_RXCSR); |
| 2298 | 2266 | ||
| 2299 | if (musb->dyn_fifo) { | 2267 | if (musb->dyn_fifo) { |
| 2300 | musb_context.index_regs[i].txfifoadd = | 2268 | musb->context.index_regs[i].txfifoadd = |
| 2301 | musb_read_txfifoadd(musb_base); | 2269 | musb_read_txfifoadd(musb_base); |
| 2302 | musb_context.index_regs[i].rxfifoadd = | 2270 | musb->context.index_regs[i].rxfifoadd = |
| 2303 | musb_read_rxfifoadd(musb_base); | 2271 | musb_read_rxfifoadd(musb_base); |
| 2304 | musb_context.index_regs[i].txfifosz = | 2272 | musb->context.index_regs[i].txfifosz = |
| 2305 | musb_read_txfifosz(musb_base); | 2273 | musb_read_txfifosz(musb_base); |
| 2306 | musb_context.index_regs[i].rxfifosz = | 2274 | musb->context.index_regs[i].rxfifosz = |
| 2307 | musb_read_rxfifosz(musb_base); | 2275 | musb_read_rxfifosz(musb_base); |
| 2308 | } | 2276 | } |
| 2309 | if (is_host_enabled(musb)) { | 2277 | if (is_host_enabled(musb)) { |
| 2310 | musb_context.index_regs[i].txtype = | 2278 | musb->context.index_regs[i].txtype = |
| 2311 | musb_readb(epio, MUSB_TXTYPE); | 2279 | musb_readb(epio, MUSB_TXTYPE); |
| 2312 | musb_context.index_regs[i].txinterval = | 2280 | musb->context.index_regs[i].txinterval = |
| 2313 | musb_readb(epio, MUSB_TXINTERVAL); | 2281 | musb_readb(epio, MUSB_TXINTERVAL); |
| 2314 | musb_context.index_regs[i].rxtype = | 2282 | musb->context.index_regs[i].rxtype = |
| 2315 | musb_readb(epio, MUSB_RXTYPE); | 2283 | musb_readb(epio, MUSB_RXTYPE); |
| 2316 | musb_context.index_regs[i].rxinterval = | 2284 | musb->context.index_regs[i].rxinterval = |
| 2317 | musb_readb(epio, MUSB_RXINTERVAL); | 2285 | musb_readb(epio, MUSB_RXINTERVAL); |
| 2318 | 2286 | ||
| 2319 | musb_context.index_regs[i].txfunaddr = | 2287 | musb->context.index_regs[i].txfunaddr = |
| 2320 | musb_read_txfunaddr(musb_base, i); | 2288 | musb_read_txfunaddr(musb_base, i); |
| 2321 | musb_context.index_regs[i].txhubaddr = | 2289 | musb->context.index_regs[i].txhubaddr = |
| 2322 | musb_read_txhubaddr(musb_base, i); | 2290 | musb_read_txhubaddr(musb_base, i); |
| 2323 | musb_context.index_regs[i].txhubport = | 2291 | musb->context.index_regs[i].txhubport = |
| 2324 | musb_read_txhubport(musb_base, i); | 2292 | musb_read_txhubport(musb_base, i); |
| 2325 | 2293 | ||
| 2326 | musb_context.index_regs[i].rxfunaddr = | 2294 | musb->context.index_regs[i].rxfunaddr = |
| 2327 | musb_read_rxfunaddr(musb_base, i); | 2295 | musb_read_rxfunaddr(musb_base, i); |
| 2328 | musb_context.index_regs[i].rxhubaddr = | 2296 | musb->context.index_regs[i].rxhubaddr = |
| 2329 | musb_read_rxhubaddr(musb_base, i); | 2297 | musb_read_rxhubaddr(musb_base, i); |
| 2330 | musb_context.index_regs[i].rxhubport = | 2298 | musb->context.index_regs[i].rxhubport = |
| 2331 | musb_read_rxhubport(musb_base, i); | 2299 | musb_read_rxhubport(musb_base, i); |
| 2332 | } | 2300 | } |
| 2333 | } | 2301 | } |
| 2334 | |||
| 2335 | musb_platform_save_context(musb, &musb_context); | ||
| 2336 | } | 2302 | } |
| 2337 | 2303 | ||
| 2338 | void musb_restore_context(struct musb *musb) | 2304 | static void musb_restore_context(struct musb *musb) |
| 2339 | { | 2305 | { |
| 2340 | int i; | 2306 | int i; |
| 2341 | void __iomem *musb_base = musb->mregs; | 2307 | void __iomem *musb_base = musb->mregs; |
| 2342 | void __iomem *ep_target_regs; | 2308 | void __iomem *ep_target_regs; |
| 2343 | void __iomem *epio; | 2309 | void __iomem *epio; |
| 2344 | 2310 | ||
| 2345 | musb_platform_restore_context(musb, &musb_context); | ||
| 2346 | |||
| 2347 | if (is_host_enabled(musb)) { | 2311 | if (is_host_enabled(musb)) { |
| 2348 | musb_writew(musb_base, MUSB_FRAME, musb_context.frame); | 2312 | musb_writew(musb_base, MUSB_FRAME, musb->context.frame); |
| 2349 | musb_writeb(musb_base, MUSB_TESTMODE, musb_context.testmode); | 2313 | musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode); |
| 2350 | musb_write_ulpi_buscontrol(musb->mregs, musb_context.busctl); | 2314 | musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); |
| 2351 | } | 2315 | } |
| 2352 | musb_writeb(musb_base, MUSB_POWER, musb_context.power); | 2316 | musb_writeb(musb_base, MUSB_POWER, musb->context.power); |
| 2353 | musb_writew(musb_base, MUSB_INTRTXE, musb_context.intrtxe); | 2317 | musb_writew(musb_base, MUSB_INTRTXE, musb->context.intrtxe); |
| 2354 | musb_writew(musb_base, MUSB_INTRRXE, musb_context.intrrxe); | 2318 | musb_writew(musb_base, MUSB_INTRRXE, musb->context.intrrxe); |
| 2355 | musb_writeb(musb_base, MUSB_INTRUSBE, musb_context.intrusbe); | 2319 | musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); |
| 2356 | musb_writeb(musb_base, MUSB_DEVCTL, musb_context.devctl); | 2320 | musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); |
| 2357 | 2321 | ||
| 2358 | for (i = 0; i < musb->config->num_eps; ++i) { | 2322 | for (i = 0; i < musb->config->num_eps; ++i) { |
| 2359 | epio = musb->endpoints[i].regs; | 2323 | epio = musb->endpoints[i].regs; |
| 2360 | musb_writew(epio, MUSB_TXMAXP, | 2324 | musb_writew(epio, MUSB_TXMAXP, |
| 2361 | musb_context.index_regs[i].txmaxp); | 2325 | musb->context.index_regs[i].txmaxp); |
| 2362 | musb_writew(epio, MUSB_TXCSR, | 2326 | musb_writew(epio, MUSB_TXCSR, |
| 2363 | musb_context.index_regs[i].txcsr); | 2327 | musb->context.index_regs[i].txcsr); |
| 2364 | musb_writew(epio, MUSB_RXMAXP, | 2328 | musb_writew(epio, MUSB_RXMAXP, |
| 2365 | musb_context.index_regs[i].rxmaxp); | 2329 | musb->context.index_regs[i].rxmaxp); |
| 2366 | musb_writew(epio, MUSB_RXCSR, | 2330 | musb_writew(epio, MUSB_RXCSR, |
| 2367 | musb_context.index_regs[i].rxcsr); | 2331 | musb->context.index_regs[i].rxcsr); |
| 2368 | 2332 | ||
| 2369 | if (musb->dyn_fifo) { | 2333 | if (musb->dyn_fifo) { |
| 2370 | musb_write_txfifosz(musb_base, | 2334 | musb_write_txfifosz(musb_base, |
| 2371 | musb_context.index_regs[i].txfifosz); | 2335 | musb->context.index_regs[i].txfifosz); |
| 2372 | musb_write_rxfifosz(musb_base, | 2336 | musb_write_rxfifosz(musb_base, |
| 2373 | musb_context.index_regs[i].rxfifosz); | 2337 | musb->context.index_regs[i].rxfifosz); |
| 2374 | musb_write_txfifoadd(musb_base, | 2338 | musb_write_txfifoadd(musb_base, |
| 2375 | musb_context.index_regs[i].txfifoadd); | 2339 | musb->context.index_regs[i].txfifoadd); |
| 2376 | musb_write_rxfifoadd(musb_base, | 2340 | musb_write_rxfifoadd(musb_base, |
| 2377 | musb_context.index_regs[i].rxfifoadd); | 2341 | musb->context.index_regs[i].rxfifoadd); |
| 2378 | } | 2342 | } |
| 2379 | 2343 | ||
| 2380 | if (is_host_enabled(musb)) { | 2344 | if (is_host_enabled(musb)) { |
| 2381 | musb_writeb(epio, MUSB_TXTYPE, | 2345 | musb_writeb(epio, MUSB_TXTYPE, |
| 2382 | musb_context.index_regs[i].txtype); | 2346 | musb->context.index_regs[i].txtype); |
| 2383 | musb_writeb(epio, MUSB_TXINTERVAL, | 2347 | musb_writeb(epio, MUSB_TXINTERVAL, |
| 2384 | musb_context.index_regs[i].txinterval); | 2348 | musb->context.index_regs[i].txinterval); |
| 2385 | musb_writeb(epio, MUSB_RXTYPE, | 2349 | musb_writeb(epio, MUSB_RXTYPE, |
| 2386 | musb_context.index_regs[i].rxtype); | 2350 | musb->context.index_regs[i].rxtype); |
| 2387 | musb_writeb(epio, MUSB_RXINTERVAL, | 2351 | musb_writeb(epio, MUSB_RXINTERVAL, |
| 2388 | 2352 | ||
| 2389 | musb_context.index_regs[i].rxinterval); | 2353 | musb->context.index_regs[i].rxinterval); |
| 2390 | musb_write_txfunaddr(musb_base, i, | 2354 | musb_write_txfunaddr(musb_base, i, |
| 2391 | musb_context.index_regs[i].txfunaddr); | 2355 | musb->context.index_regs[i].txfunaddr); |
| 2392 | musb_write_txhubaddr(musb_base, i, | 2356 | musb_write_txhubaddr(musb_base, i, |
| 2393 | musb_context.index_regs[i].txhubaddr); | 2357 | musb->context.index_regs[i].txhubaddr); |
| 2394 | musb_write_txhubport(musb_base, i, | 2358 | musb_write_txhubport(musb_base, i, |
| 2395 | musb_context.index_regs[i].txhubport); | 2359 | musb->context.index_regs[i].txhubport); |
| 2396 | 2360 | ||
| 2397 | ep_target_regs = | 2361 | ep_target_regs = |
| 2398 | musb_read_target_reg_base(i, musb_base); | 2362 | musb_read_target_reg_base(i, musb_base); |
| 2399 | 2363 | ||
| 2400 | musb_write_rxfunaddr(ep_target_regs, | 2364 | musb_write_rxfunaddr(ep_target_regs, |
| 2401 | musb_context.index_regs[i].rxfunaddr); | 2365 | musb->context.index_regs[i].rxfunaddr); |
| 2402 | musb_write_rxhubaddr(ep_target_regs, | 2366 | musb_write_rxhubaddr(ep_target_regs, |
| 2403 | musb_context.index_regs[i].rxhubaddr); | 2367 | musb->context.index_regs[i].rxhubaddr); |
| 2404 | musb_write_rxhubport(ep_target_regs, | 2368 | musb_write_rxhubport(ep_target_regs, |
| 2405 | musb_context.index_regs[i].rxhubport); | 2369 | musb->context.index_regs[i].rxhubport); |
| 2406 | } | 2370 | } |
| 2407 | } | 2371 | } |
| 2408 | } | 2372 | } |
| @@ -2413,9 +2377,6 @@ static int musb_suspend(struct device *dev) | |||
| 2413 | unsigned long flags; | 2377 | unsigned long flags; |
| 2414 | struct musb *musb = dev_to_musb(&pdev->dev); | 2378 | struct musb *musb = dev_to_musb(&pdev->dev); |
| 2415 | 2379 | ||
| 2416 | if (!musb->clock) | ||
| 2417 | return 0; | ||
| 2418 | |||
| 2419 | spin_lock_irqsave(&musb->lock, flags); | 2380 | spin_lock_irqsave(&musb->lock, flags); |
| 2420 | 2381 | ||
| 2421 | if (is_peripheral_active(musb)) { | 2382 | if (is_peripheral_active(musb)) { |
| @@ -2430,10 +2391,6 @@ static int musb_suspend(struct device *dev) | |||
| 2430 | 2391 | ||
| 2431 | musb_save_context(musb); | 2392 | musb_save_context(musb); |
| 2432 | 2393 | ||
| 2433 | if (musb->set_clock) | ||
| 2434 | musb->set_clock(musb->clock, 0); | ||
| 2435 | else | ||
| 2436 | clk_disable(musb->clock); | ||
| 2437 | spin_unlock_irqrestore(&musb->lock, flags); | 2394 | spin_unlock_irqrestore(&musb->lock, flags); |
| 2438 | return 0; | 2395 | return 0; |
| 2439 | } | 2396 | } |
| @@ -2443,14 +2400,6 @@ static int musb_resume_noirq(struct device *dev) | |||
| 2443 | struct platform_device *pdev = to_platform_device(dev); | 2400 | struct platform_device *pdev = to_platform_device(dev); |
| 2444 | struct musb *musb = dev_to_musb(&pdev->dev); | 2401 | struct musb *musb = dev_to_musb(&pdev->dev); |
| 2445 | 2402 | ||
| 2446 | if (!musb->clock) | ||
| 2447 | return 0; | ||
| 2448 | |||
| 2449 | if (musb->set_clock) | ||
| 2450 | musb->set_clock(musb->clock, 1); | ||
| 2451 | else | ||
| 2452 | clk_enable(musb->clock); | ||
| 2453 | |||
| 2454 | musb_restore_context(musb); | 2403 | musb_restore_context(musb); |
| 2455 | 2404 | ||
| 2456 | /* for static cmos like DaVinci, register values were preserved | 2405 | /* for static cmos like DaVinci, register values were preserved |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 69797e5b46a7..d0c236f8e191 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
| @@ -222,7 +222,7 @@ enum musb_g_ep0_state { | |||
| 222 | #endif | 222 | #endif |
| 223 | 223 | ||
| 224 | /* TUSB mapping: "flat" plus ep0 special cases */ | 224 | /* TUSB mapping: "flat" plus ep0 special cases */ |
| 225 | #if defined(CONFIG_USB_TUSB6010) | 225 | #if defined(CONFIG_USB_MUSB_TUSB6010) |
| 226 | #define musb_ep_select(_mbase, _epnum) \ | 226 | #define musb_ep_select(_mbase, _epnum) \ |
| 227 | musb_writeb((_mbase), MUSB_INDEX, (_epnum)) | 227 | musb_writeb((_mbase), MUSB_INDEX, (_epnum)) |
| 228 | #define MUSB_EP_OFFSET MUSB_TUSB_OFFSET | 228 | #define MUSB_EP_OFFSET MUSB_TUSB_OFFSET |
| @@ -253,6 +253,29 @@ enum musb_g_ep0_state { | |||
| 253 | 253 | ||
| 254 | /******************************** TYPES *************************************/ | 254 | /******************************** TYPES *************************************/ |
| 255 | 255 | ||
| 256 | /** | ||
| 257 | * struct musb_platform_ops - Operations passed to musb_core by HW glue layer | ||
| 258 | * @init: turns on clocks, sets up platform-specific registers, etc | ||
| 259 | * @exit: undoes @init | ||
| 260 | * @set_mode: forcefully changes operating mode | ||
| 261 | * @try_ilde: tries to idle the IP | ||
| 262 | * @vbus_status: returns vbus status if possible | ||
| 263 | * @set_vbus: forces vbus status | ||
| 264 | */ | ||
| 265 | struct musb_platform_ops { | ||
| 266 | int (*init)(struct musb *musb); | ||
| 267 | int (*exit)(struct musb *musb); | ||
| 268 | |||
| 269 | void (*enable)(struct musb *musb); | ||
| 270 | void (*disable)(struct musb *musb); | ||
| 271 | |||
| 272 | int (*set_mode)(struct musb *musb, u8 mode); | ||
| 273 | void (*try_idle)(struct musb *musb, unsigned long timeout); | ||
| 274 | |||
| 275 | int (*vbus_status)(struct musb *musb); | ||
| 276 | void (*set_vbus)(struct musb *musb, int on); | ||
| 277 | }; | ||
| 278 | |||
| 256 | /* | 279 | /* |
| 257 | * struct musb_hw_ep - endpoint hardware (bidirectional) | 280 | * struct musb_hw_ep - endpoint hardware (bidirectional) |
| 258 | * | 281 | * |
| @@ -263,7 +286,7 @@ struct musb_hw_ep { | |||
| 263 | void __iomem *fifo; | 286 | void __iomem *fifo; |
| 264 | void __iomem *regs; | 287 | void __iomem *regs; |
| 265 | 288 | ||
| 266 | #ifdef CONFIG_USB_TUSB6010 | 289 | #ifdef CONFIG_USB_MUSB_TUSB6010 |
| 267 | void __iomem *conf; | 290 | void __iomem *conf; |
| 268 | #endif | 291 | #endif |
| 269 | 292 | ||
| @@ -280,7 +303,7 @@ struct musb_hw_ep { | |||
| 280 | struct dma_channel *tx_channel; | 303 | struct dma_channel *tx_channel; |
| 281 | struct dma_channel *rx_channel; | 304 | struct dma_channel *rx_channel; |
| 282 | 305 | ||
| 283 | #ifdef CONFIG_USB_TUSB6010 | 306 | #ifdef CONFIG_USB_MUSB_TUSB6010 |
| 284 | /* TUSB has "asynchronous" and "synchronous" dma modes */ | 307 | /* TUSB has "asynchronous" and "synchronous" dma modes */ |
| 285 | dma_addr_t fifo_async; | 308 | dma_addr_t fifo_async; |
| 286 | dma_addr_t fifo_sync; | 309 | dma_addr_t fifo_sync; |
| @@ -323,14 +346,43 @@ static inline struct usb_request *next_out_request(struct musb_hw_ep *hw_ep) | |||
| 323 | #endif | 346 | #endif |
| 324 | } | 347 | } |
| 325 | 348 | ||
| 349 | struct musb_csr_regs { | ||
| 350 | /* FIFO registers */ | ||
| 351 | u16 txmaxp, txcsr, rxmaxp, rxcsr; | ||
| 352 | u16 rxfifoadd, txfifoadd; | ||
| 353 | u8 txtype, txinterval, rxtype, rxinterval; | ||
| 354 | u8 rxfifosz, txfifosz; | ||
| 355 | u8 txfunaddr, txhubaddr, txhubport; | ||
| 356 | u8 rxfunaddr, rxhubaddr, rxhubport; | ||
| 357 | }; | ||
| 358 | |||
| 359 | struct musb_context_registers { | ||
| 360 | |||
| 361 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ | ||
| 362 | defined(CONFIG_ARCH_OMAP4) | ||
| 363 | u32 otg_sysconfig, otg_forcestandby; | ||
| 364 | #endif | ||
| 365 | u8 power; | ||
| 366 | u16 intrtxe, intrrxe; | ||
| 367 | u8 intrusbe; | ||
| 368 | u16 frame; | ||
| 369 | u8 index, testmode; | ||
| 370 | |||
| 371 | u8 devctl, busctl, misc; | ||
| 372 | |||
| 373 | struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; | ||
| 374 | }; | ||
| 375 | |||
| 326 | /* | 376 | /* |
| 327 | * struct musb - Driver instance data. | 377 | * struct musb - Driver instance data. |
| 328 | */ | 378 | */ |
| 329 | struct musb { | 379 | struct musb { |
| 330 | /* device lock */ | 380 | /* device lock */ |
| 331 | spinlock_t lock; | 381 | spinlock_t lock; |
| 332 | struct clk *clock; | 382 | |
| 333 | struct clk *phy_clock; | 383 | const struct musb_platform_ops *ops; |
| 384 | struct musb_context_registers context; | ||
| 385 | |||
| 334 | irqreturn_t (*isr)(int, void *); | 386 | irqreturn_t (*isr)(int, void *); |
| 335 | struct work_struct irq_work; | 387 | struct work_struct irq_work; |
| 336 | u16 hwvers; | 388 | u16 hwvers; |
| @@ -359,11 +411,7 @@ struct musb { | |||
| 359 | 411 | ||
| 360 | struct timer_list otg_timer; | 412 | struct timer_list otg_timer; |
| 361 | #endif | 413 | #endif |
| 362 | 414 | struct notifier_block nb; | |
| 363 | /* called with IRQs blocked; ON/nonzero implies starting a session, | ||
| 364 | * and waiting at least a_wait_vrise_tmout. | ||
| 365 | */ | ||
| 366 | void (*board_set_vbus)(struct musb *, int is_on); | ||
| 367 | 415 | ||
| 368 | struct dma_controller *dma_controller; | 416 | struct dma_controller *dma_controller; |
| 369 | 417 | ||
| @@ -371,7 +419,7 @@ struct musb { | |||
| 371 | void __iomem *ctrl_base; | 419 | void __iomem *ctrl_base; |
| 372 | void __iomem *mregs; | 420 | void __iomem *mregs; |
| 373 | 421 | ||
| 374 | #ifdef CONFIG_USB_TUSB6010 | 422 | #ifdef CONFIG_USB_MUSB_TUSB6010 |
| 375 | dma_addr_t async; | 423 | dma_addr_t async; |
| 376 | dma_addr_t sync; | 424 | dma_addr_t sync; |
| 377 | void __iomem *sync_va; | 425 | void __iomem *sync_va; |
| @@ -398,8 +446,6 @@ struct musb { | |||
| 398 | u8 board_mode; /* enum musb_mode */ | 446 | u8 board_mode; /* enum musb_mode */ |
| 399 | int (*board_set_power)(int state); | 447 | int (*board_set_power)(int state); |
| 400 | 448 | ||
| 401 | int (*set_clock)(struct clk *clk, int is_active); | ||
| 402 | |||
| 403 | u8 min_power; /* vbus for periph, in mA/2 */ | 449 | u8 min_power; /* vbus for periph, in mA/2 */ |
| 404 | 450 | ||
| 405 | bool is_host; | 451 | bool is_host; |
| @@ -458,52 +504,6 @@ struct musb { | |||
| 458 | #endif | 504 | #endif |
| 459 | }; | 505 | }; |
| 460 | 506 | ||
| 461 | #ifdef CONFIG_PM | ||
| 462 | struct musb_csr_regs { | ||
| 463 | /* FIFO registers */ | ||
| 464 | u16 txmaxp, txcsr, rxmaxp, rxcsr; | ||
| 465 | u16 rxfifoadd, txfifoadd; | ||
| 466 | u8 txtype, txinterval, rxtype, rxinterval; | ||
| 467 | u8 rxfifosz, txfifosz; | ||
| 468 | u8 txfunaddr, txhubaddr, txhubport; | ||
| 469 | u8 rxfunaddr, rxhubaddr, rxhubport; | ||
| 470 | }; | ||
| 471 | |||
| 472 | struct musb_context_registers { | ||
| 473 | |||
| 474 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ | ||
| 475 | defined(CONFIG_ARCH_OMAP4) | ||
| 476 | u32 otg_sysconfig, otg_forcestandby; | ||
| 477 | #endif | ||
| 478 | u8 power; | ||
| 479 | u16 intrtxe, intrrxe; | ||
| 480 | u8 intrusbe; | ||
| 481 | u16 frame; | ||
| 482 | u8 index, testmode; | ||
| 483 | |||
| 484 | u8 devctl, busctl, misc; | ||
| 485 | |||
| 486 | struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; | ||
| 487 | }; | ||
| 488 | |||
| 489 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ | ||
| 490 | defined(CONFIG_ARCH_OMAP4) | ||
| 491 | extern void musb_platform_save_context(struct musb *musb, | ||
| 492 | struct musb_context_registers *musb_context); | ||
| 493 | extern void musb_platform_restore_context(struct musb *musb, | ||
| 494 | struct musb_context_registers *musb_context); | ||
| 495 | #else | ||
| 496 | #define musb_platform_save_context(m, x) do {} while (0) | ||
| 497 | #define musb_platform_restore_context(m, x) do {} while (0) | ||
| 498 | #endif | ||
| 499 | |||
| 500 | #endif | ||
| 501 | |||
| 502 | static inline void musb_set_vbus(struct musb *musb, int is_on) | ||
| 503 | { | ||
| 504 | musb->board_set_vbus(musb, is_on); | ||
| 505 | } | ||
| 506 | |||
| 507 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | 507 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
| 508 | static inline struct musb *gadget_to_musb(struct usb_gadget *g) | 508 | static inline struct musb *gadget_to_musb(struct usb_gadget *g) |
| 509 | { | 509 | { |
| @@ -592,29 +592,63 @@ extern void musb_load_testpacket(struct musb *); | |||
| 592 | 592 | ||
| 593 | extern irqreturn_t musb_interrupt(struct musb *); | 593 | extern irqreturn_t musb_interrupt(struct musb *); |
| 594 | 594 | ||
| 595 | extern void musb_platform_enable(struct musb *musb); | ||
| 596 | extern void musb_platform_disable(struct musb *musb); | ||
| 597 | |||
| 598 | extern void musb_hnp_stop(struct musb *musb); | 595 | extern void musb_hnp_stop(struct musb *musb); |
| 599 | 596 | ||
| 600 | extern int musb_platform_set_mode(struct musb *musb, u8 musb_mode); | 597 | static inline void musb_platform_set_vbus(struct musb *musb, int is_on) |
| 598 | { | ||
| 599 | if (musb->ops->set_vbus) | ||
| 600 | musb->ops->set_vbus(musb, is_on); | ||
| 601 | } | ||
| 601 | 602 | ||
| 602 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) || \ | 603 | static inline void musb_platform_enable(struct musb *musb) |
| 603 | defined(CONFIG_ARCH_DAVINCI_DA8XX) || \ | 604 | { |
| 604 | defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ | 605 | if (musb->ops->enable) |
| 605 | defined(CONFIG_ARCH_OMAP4) | 606 | musb->ops->enable(musb); |
| 606 | extern void musb_platform_try_idle(struct musb *musb, unsigned long timeout); | 607 | } |
| 607 | #else | ||
| 608 | #define musb_platform_try_idle(x, y) do {} while (0) | ||
| 609 | #endif | ||
| 610 | 608 | ||
| 611 | #if defined(CONFIG_USB_TUSB6010) || defined(CONFIG_BLACKFIN) | 609 | static inline void musb_platform_disable(struct musb *musb) |
| 612 | extern int musb_platform_get_vbus_status(struct musb *musb); | 610 | { |
| 613 | #else | 611 | if (musb->ops->disable) |
| 614 | #define musb_platform_get_vbus_status(x) 0 | 612 | musb->ops->disable(musb); |
| 615 | #endif | 613 | } |
| 614 | |||
| 615 | static inline int musb_platform_set_mode(struct musb *musb, u8 mode) | ||
| 616 | { | ||
| 617 | if (!musb->ops->set_mode) | ||
| 618 | return 0; | ||
| 619 | |||
| 620 | return musb->ops->set_mode(musb, mode); | ||
| 621 | } | ||
| 622 | |||
| 623 | static inline void musb_platform_try_idle(struct musb *musb, | ||
| 624 | unsigned long timeout) | ||
| 625 | { | ||
| 626 | if (musb->ops->try_idle) | ||
| 627 | musb->ops->try_idle(musb, timeout); | ||
| 628 | } | ||
| 629 | |||
| 630 | static inline int musb_platform_get_vbus_status(struct musb *musb) | ||
| 631 | { | ||
| 632 | if (!musb->ops->vbus_status) | ||
| 633 | return 0; | ||
| 616 | 634 | ||
| 617 | extern int __init musb_platform_init(struct musb *musb, void *board_data); | 635 | return musb->ops->vbus_status(musb); |
| 618 | extern int musb_platform_exit(struct musb *musb); | 636 | } |
| 637 | |||
| 638 | static inline int musb_platform_init(struct musb *musb) | ||
| 639 | { | ||
| 640 | if (!musb->ops->init) | ||
| 641 | return -EINVAL; | ||
| 642 | |||
| 643 | return musb->ops->init(musb); | ||
| 644 | } | ||
| 645 | |||
| 646 | static inline int musb_platform_exit(struct musb *musb) | ||
| 647 | { | ||
| 648 | if (!musb->ops->exit) | ||
| 649 | return -EINVAL; | ||
| 650 | |||
| 651 | return musb->ops->exit(musb); | ||
| 652 | } | ||
| 619 | 653 | ||
| 620 | #endif /* __MUSB_CORE_H__ */ | 654 | #endif /* __MUSB_CORE_H__ */ |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 9d6ade82b9f2..9b162dfaa4fb 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
| @@ -1136,13 +1136,16 @@ struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) | |||
| 1136 | struct musb_request *request = NULL; | 1136 | struct musb_request *request = NULL; |
| 1137 | 1137 | ||
| 1138 | request = kzalloc(sizeof *request, gfp_flags); | 1138 | request = kzalloc(sizeof *request, gfp_flags); |
| 1139 | if (request) { | 1139 | if (!request) { |
| 1140 | INIT_LIST_HEAD(&request->request.list); | 1140 | DBG(4, "not enough memory\n"); |
| 1141 | request->request.dma = DMA_ADDR_INVALID; | 1141 | return NULL; |
| 1142 | request->epnum = musb_ep->current_epnum; | ||
| 1143 | request->ep = musb_ep; | ||
| 1144 | } | 1142 | } |
| 1145 | 1143 | ||
| 1144 | INIT_LIST_HEAD(&request->request.list); | ||
| 1145 | request->request.dma = DMA_ADDR_INVALID; | ||
| 1146 | request->epnum = musb_ep->current_epnum; | ||
| 1147 | request->ep = musb_ep; | ||
| 1148 | |||
| 1146 | return &request->request; | 1149 | return &request->request; |
| 1147 | } | 1150 | } |
| 1148 | 1151 | ||
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h index b06e9ef00cfc..03c6ccdbb3be 100644 --- a/drivers/usb/musb/musb_io.h +++ b/drivers/usb/musb/musb_io.h | |||
| @@ -74,7 +74,7 @@ static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data) | |||
| 74 | { __raw_writel(data, addr + offset); } | 74 | { __raw_writel(data, addr + offset); } |
| 75 | 75 | ||
| 76 | 76 | ||
| 77 | #ifdef CONFIG_USB_TUSB6010 | 77 | #ifdef CONFIG_USB_MUSB_TUSB6010 |
| 78 | 78 | ||
| 79 | /* | 79 | /* |
| 80 | * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum. | 80 | * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum. |
| @@ -114,7 +114,7 @@ static inline u8 musb_readb(const void __iomem *addr, unsigned offset) | |||
| 114 | static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) | 114 | static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) |
| 115 | { __raw_writeb(data, addr + offset); } | 115 | { __raw_writeb(data, addr + offset); } |
| 116 | 116 | ||
| 117 | #endif /* CONFIG_USB_TUSB6010 */ | 117 | #endif /* CONFIG_USB_MUSB_TUSB6010 */ |
| 118 | 118 | ||
| 119 | #else | 119 | #else |
| 120 | 120 | ||
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h index 5a727c5b8676..82410703dcd3 100644 --- a/drivers/usb/musb/musb_regs.h +++ b/drivers/usb/musb/musb_regs.h | |||
| @@ -234,7 +234,7 @@ | |||
| 234 | #define MUSB_TESTMODE 0x0F /* 8 bit */ | 234 | #define MUSB_TESTMODE 0x0F /* 8 bit */ |
| 235 | 235 | ||
| 236 | /* Get offset for a given FIFO from musb->mregs */ | 236 | /* Get offset for a given FIFO from musb->mregs */ |
| 237 | #ifdef CONFIG_USB_TUSB6010 | 237 | #ifdef CONFIG_USB_MUSB_TUSB6010 |
| 238 | #define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) | 238 | #define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) |
| 239 | #else | 239 | #else |
| 240 | #define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4)) | 240 | #define MUSB_FIFO_OFFSET(epnum) (0x20 + ((epnum) * 4)) |
| @@ -295,7 +295,7 @@ | |||
| 295 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ | 295 | #define MUSB_FLAT_OFFSET(_epnum, _offset) \ |
| 296 | (0x100 + (0x10*(_epnum)) + (_offset)) | 296 | (0x100 + (0x10*(_epnum)) + (_offset)) |
| 297 | 297 | ||
| 298 | #ifdef CONFIG_USB_TUSB6010 | 298 | #ifdef CONFIG_USB_MUSB_TUSB6010 |
| 299 | /* TUSB6010 EP0 configuration register is special */ | 299 | /* TUSB6010 EP0 configuration register is special */ |
| 300 | #define MUSB_TUSB_OFFSET(_epnum, _offset) \ | 300 | #define MUSB_TUSB_OFFSET(_epnum, _offset) \ |
| 301 | (0x10 + _offset) | 301 | (0x10 + _offset) |
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index 43233c397b6e..b46d1877e28e 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
| @@ -276,7 +276,7 @@ int musb_hub_control( | |||
| 276 | break; | 276 | break; |
| 277 | case USB_PORT_FEAT_POWER: | 277 | case USB_PORT_FEAT_POWER: |
| 278 | if (!(is_otg_enabled(musb) && hcd->self.is_b_host)) | 278 | if (!(is_otg_enabled(musb) && hcd->self.is_b_host)) |
| 279 | musb_set_vbus(musb, 0); | 279 | musb_platform_set_vbus(musb, 0); |
| 280 | break; | 280 | break; |
| 281 | case USB_PORT_FEAT_C_CONNECTION: | 281 | case USB_PORT_FEAT_C_CONNECTION: |
| 282 | case USB_PORT_FEAT_C_ENABLE: | 282 | case USB_PORT_FEAT_C_ENABLE: |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 563114d613d6..0144a2d481fd 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
| @@ -377,7 +377,7 @@ dma_controller_create(struct musb *musb, void __iomem *base) | |||
| 377 | struct musb_dma_controller *controller; | 377 | struct musb_dma_controller *controller; |
| 378 | struct device *dev = musb->controller; | 378 | struct device *dev = musb->controller; |
| 379 | struct platform_device *pdev = to_platform_device(dev); | 379 | struct platform_device *pdev = to_platform_device(dev); |
| 380 | int irq = platform_get_irq(pdev, 1); | 380 | int irq = platform_get_irq_byname(pdev, "dma"); |
| 381 | 381 | ||
| 382 | if (irq == 0) { | 382 | if (irq == 0) { |
| 383 | dev_err(dev, "No DMA interrupt line!\n"); | 383 | dev_err(dev, "No DMA interrupt line!\n"); |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index ed618bde1eec..a3f12333fc41 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
| @@ -31,10 +31,18 @@ | |||
| 31 | #include <linux/list.h> | 31 | #include <linux/list.h> |
| 32 | #include <linux/clk.h> | 32 | #include <linux/clk.h> |
| 33 | #include <linux/io.h> | 33 | #include <linux/io.h> |
| 34 | #include <linux/platform_device.h> | ||
| 35 | #include <linux/dma-mapping.h> | ||
| 34 | 36 | ||
| 35 | #include "musb_core.h" | 37 | #include "musb_core.h" |
| 36 | #include "omap2430.h" | 38 | #include "omap2430.h" |
| 37 | 39 | ||
| 40 | struct omap2430_glue { | ||
| 41 | struct device *dev; | ||
| 42 | struct platform_device *musb; | ||
| 43 | struct clk *clk; | ||
| 44 | }; | ||
| 45 | #define glue_to_musb(g) platform_get_drvdata(g->musb) | ||
| 38 | 46 | ||
| 39 | static struct timer_list musb_idle_timer; | 47 | static struct timer_list musb_idle_timer; |
| 40 | 48 | ||
| @@ -49,12 +57,8 @@ static void musb_do_idle(unsigned long _musb) | |||
| 49 | 57 | ||
| 50 | spin_lock_irqsave(&musb->lock, flags); | 58 | spin_lock_irqsave(&musb->lock, flags); |
| 51 | 59 | ||
| 52 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | ||
| 53 | |||
| 54 | switch (musb->xceiv->state) { | 60 | switch (musb->xceiv->state) { |
| 55 | case OTG_STATE_A_WAIT_BCON: | 61 | case OTG_STATE_A_WAIT_BCON: |
| 56 | devctl &= ~MUSB_DEVCTL_SESSION; | ||
| 57 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); | ||
| 58 | 62 | ||
| 59 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 63 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
| 60 | if (devctl & MUSB_DEVCTL_BDEVICE) { | 64 | if (devctl & MUSB_DEVCTL_BDEVICE) { |
| @@ -98,7 +102,7 @@ static void musb_do_idle(unsigned long _musb) | |||
| 98 | } | 102 | } |
| 99 | 103 | ||
| 100 | 104 | ||
| 101 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | 105 | static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout) |
| 102 | { | 106 | { |
| 103 | unsigned long default_timeout = jiffies + msecs_to_jiffies(3); | 107 | unsigned long default_timeout = jiffies + msecs_to_jiffies(3); |
| 104 | static unsigned long last_timer; | 108 | static unsigned long last_timer; |
| @@ -131,15 +135,11 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | |||
| 131 | mod_timer(&musb_idle_timer, timeout); | 135 | mod_timer(&musb_idle_timer, timeout); |
| 132 | } | 136 | } |
| 133 | 137 | ||
| 134 | void musb_platform_enable(struct musb *musb) | 138 | static void omap2430_musb_set_vbus(struct musb *musb, int is_on) |
| 135 | { | ||
| 136 | } | ||
| 137 | void musb_platform_disable(struct musb *musb) | ||
| 138 | { | ||
| 139 | } | ||
| 140 | static void omap_set_vbus(struct musb *musb, int is_on) | ||
| 141 | { | 139 | { |
| 142 | u8 devctl; | 140 | u8 devctl; |
| 141 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | ||
| 142 | int ret = 1; | ||
| 143 | /* HDRC controls CPEN, but beware current surges during device | 143 | /* HDRC controls CPEN, but beware current surges during device |
| 144 | * connect. They can trigger transient overcurrent conditions | 144 | * connect. They can trigger transient overcurrent conditions |
| 145 | * that must be ignored. | 145 | * that must be ignored. |
| @@ -148,12 +148,35 @@ static void omap_set_vbus(struct musb *musb, int is_on) | |||
| 148 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 148 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
| 149 | 149 | ||
| 150 | if (is_on) { | 150 | if (is_on) { |
| 151 | musb->is_active = 1; | 151 | if (musb->xceiv->state == OTG_STATE_A_IDLE) { |
| 152 | musb->xceiv->default_a = 1; | 152 | /* start the session */ |
| 153 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | 153 | devctl |= MUSB_DEVCTL_SESSION; |
| 154 | devctl |= MUSB_DEVCTL_SESSION; | 154 | musb_writeb(musb->mregs, MUSB_DEVCTL, devctl); |
| 155 | 155 | /* | |
| 156 | MUSB_HST_MODE(musb); | 156 | * Wait for the musb to set as A device to enable the |
| 157 | * VBUS | ||
| 158 | */ | ||
| 159 | while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) { | ||
| 160 | |||
| 161 | cpu_relax(); | ||
| 162 | |||
| 163 | if (time_after(jiffies, timeout)) { | ||
| 164 | dev_err(musb->controller, | ||
| 165 | "configured as A device timeout"); | ||
| 166 | ret = -EINVAL; | ||
| 167 | break; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | if (ret && musb->xceiv->set_vbus) | ||
| 172 | otg_set_vbus(musb->xceiv, 1); | ||
| 173 | } else { | ||
| 174 | musb->is_active = 1; | ||
| 175 | musb->xceiv->default_a = 1; | ||
| 176 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | ||
| 177 | devctl |= MUSB_DEVCTL_SESSION; | ||
| 178 | MUSB_HST_MODE(musb); | ||
| 179 | } | ||
| 157 | } else { | 180 | } else { |
| 158 | musb->is_active = 0; | 181 | musb->is_active = 0; |
| 159 | 182 | ||
| @@ -175,9 +198,7 @@ static void omap_set_vbus(struct musb *musb, int is_on) | |||
| 175 | musb_readb(musb->mregs, MUSB_DEVCTL)); | 198 | musb_readb(musb->mregs, MUSB_DEVCTL)); |
| 176 | } | 199 | } |
| 177 | 200 | ||
| 178 | static int musb_platform_resume(struct musb *musb); | 201 | static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode) |
| 179 | |||
| 180 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | ||
| 181 | { | 202 | { |
| 182 | u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 203 | u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
| 183 | 204 | ||
| @@ -187,10 +208,94 @@ int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | |||
| 187 | return 0; | 208 | return 0; |
| 188 | } | 209 | } |
| 189 | 210 | ||
| 190 | int __init musb_platform_init(struct musb *musb, void *board_data) | 211 | static inline void omap2430_low_level_exit(struct musb *musb) |
| 191 | { | 212 | { |
| 192 | u32 l; | 213 | u32 l; |
| 193 | struct omap_musb_board_data *data = board_data; | 214 | |
| 215 | /* in any role */ | ||
| 216 | l = musb_readl(musb->mregs, OTG_FORCESTDBY); | ||
| 217 | l |= ENABLEFORCE; /* enable MSTANDBY */ | ||
| 218 | musb_writel(musb->mregs, OTG_FORCESTDBY, l); | ||
| 219 | |||
| 220 | l = musb_readl(musb->mregs, OTG_SYSCONFIG); | ||
| 221 | l |= ENABLEWAKEUP; /* enable wakeup */ | ||
| 222 | musb_writel(musb->mregs, OTG_SYSCONFIG, l); | ||
| 223 | } | ||
| 224 | |||
| 225 | static inline void omap2430_low_level_init(struct musb *musb) | ||
| 226 | { | ||
| 227 | u32 l; | ||
| 228 | |||
| 229 | l = musb_readl(musb->mregs, OTG_SYSCONFIG); | ||
| 230 | l &= ~ENABLEWAKEUP; /* disable wakeup */ | ||
| 231 | musb_writel(musb->mregs, OTG_SYSCONFIG, l); | ||
| 232 | |||
| 233 | l = musb_readl(musb->mregs, OTG_FORCESTDBY); | ||
| 234 | l &= ~ENABLEFORCE; /* disable MSTANDBY */ | ||
| 235 | musb_writel(musb->mregs, OTG_FORCESTDBY, l); | ||
| 236 | } | ||
| 237 | |||
| 238 | /* blocking notifier support */ | ||
| 239 | static int musb_otg_notifications(struct notifier_block *nb, | ||
| 240 | unsigned long event, void *unused) | ||
| 241 | { | ||
| 242 | struct musb *musb = container_of(nb, struct musb, nb); | ||
| 243 | struct device *dev = musb->controller; | ||
| 244 | struct musb_hdrc_platform_data *pdata = dev->platform_data; | ||
| 245 | struct omap_musb_board_data *data = pdata->board_data; | ||
| 246 | |||
| 247 | switch (event) { | ||
| 248 | case USB_EVENT_ID: | ||
| 249 | DBG(4, "ID GND\n"); | ||
| 250 | |||
| 251 | if (is_otg_enabled(musb)) { | ||
| 252 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
| 253 | if (musb->gadget_driver) { | ||
| 254 | otg_init(musb->xceiv); | ||
| 255 | |||
| 256 | if (data->interface_type == | ||
| 257 | MUSB_INTERFACE_UTMI) | ||
| 258 | omap2430_musb_set_vbus(musb, 1); | ||
| 259 | |||
| 260 | } | ||
| 261 | #endif | ||
| 262 | } else { | ||
| 263 | otg_init(musb->xceiv); | ||
| 264 | if (data->interface_type == | ||
| 265 | MUSB_INTERFACE_UTMI) | ||
| 266 | omap2430_musb_set_vbus(musb, 1); | ||
| 267 | } | ||
| 268 | break; | ||
| 269 | |||
| 270 | case USB_EVENT_VBUS: | ||
| 271 | DBG(4, "VBUS Connect\n"); | ||
| 272 | |||
| 273 | otg_init(musb->xceiv); | ||
| 274 | break; | ||
| 275 | |||
| 276 | case USB_EVENT_NONE: | ||
| 277 | DBG(4, "VBUS Disconnect\n"); | ||
| 278 | |||
| 279 | if (data->interface_type == MUSB_INTERFACE_UTMI) { | ||
| 280 | if (musb->xceiv->set_vbus) | ||
| 281 | otg_set_vbus(musb->xceiv, 0); | ||
| 282 | } | ||
| 283 | otg_shutdown(musb->xceiv); | ||
| 284 | break; | ||
| 285 | default: | ||
| 286 | DBG(4, "ID float\n"); | ||
| 287 | return NOTIFY_DONE; | ||
| 288 | } | ||
| 289 | |||
| 290 | return NOTIFY_OK; | ||
| 291 | } | ||
| 292 | |||
| 293 | static int omap2430_musb_init(struct musb *musb) | ||
| 294 | { | ||
| 295 | u32 l, status = 0; | ||
| 296 | struct device *dev = musb->controller; | ||
| 297 | struct musb_hdrc_platform_data *plat = dev->platform_data; | ||
| 298 | struct omap_musb_board_data *data = plat->board_data; | ||
| 194 | 299 | ||
| 195 | /* We require some kind of external transceiver, hooked | 300 | /* We require some kind of external transceiver, hooked |
| 196 | * up through ULPI. TWL4030-family PMICs include one, | 301 | * up through ULPI. TWL4030-family PMICs include one, |
| @@ -202,7 +307,7 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
| 202 | return -ENODEV; | 307 | return -ENODEV; |
| 203 | } | 308 | } |
| 204 | 309 | ||
| 205 | musb_platform_resume(musb); | 310 | omap2430_low_level_init(musb); |
| 206 | 311 | ||
| 207 | l = musb_readl(musb->mregs, OTG_SYSCONFIG); | 312 | l = musb_readl(musb->mregs, OTG_SYSCONFIG); |
| 208 | l &= ~ENABLEWAKEUP; /* disable wakeup */ | 313 | l &= ~ENABLEWAKEUP; /* disable wakeup */ |
| @@ -239,87 +344,214 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
| 239 | musb_readl(musb->mregs, OTG_INTERFSEL), | 344 | musb_readl(musb->mregs, OTG_INTERFSEL), |
| 240 | musb_readl(musb->mregs, OTG_SIMENABLE)); | 345 | musb_readl(musb->mregs, OTG_SIMENABLE)); |
| 241 | 346 | ||
| 242 | if (is_host_enabled(musb)) | 347 | musb->nb.notifier_call = musb_otg_notifications; |
| 243 | musb->board_set_vbus = omap_set_vbus; | 348 | status = otg_register_notifier(musb->xceiv, &musb->nb); |
| 349 | |||
| 350 | if (status) | ||
| 351 | DBG(1, "notification register failed\n"); | ||
| 352 | |||
| 353 | /* check whether cable is already connected */ | ||
| 354 | if (musb->xceiv->state ==OTG_STATE_B_IDLE) | ||
| 355 | musb_otg_notifications(&musb->nb, 1, | ||
| 356 | musb->xceiv->gadget); | ||
| 244 | 357 | ||
| 245 | setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); | 358 | setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); |
| 246 | 359 | ||
| 247 | return 0; | 360 | return 0; |
| 248 | } | 361 | } |
| 249 | 362 | ||
| 250 | #ifdef CONFIG_PM | 363 | static int omap2430_musb_exit(struct musb *musb) |
| 251 | void musb_platform_save_context(struct musb *musb, | ||
| 252 | struct musb_context_registers *musb_context) | ||
| 253 | { | 364 | { |
| 254 | musb_context->otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG); | ||
| 255 | musb_context->otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY); | ||
| 256 | } | ||
| 257 | 365 | ||
| 258 | void musb_platform_restore_context(struct musb *musb, | 366 | omap2430_low_level_exit(musb); |
| 259 | struct musb_context_registers *musb_context) | 367 | otg_put_transceiver(musb->xceiv); |
| 260 | { | 368 | |
| 261 | musb_writel(musb->mregs, OTG_SYSCONFIG, musb_context->otg_sysconfig); | 369 | return 0; |
| 262 | musb_writel(musb->mregs, OTG_FORCESTDBY, musb_context->otg_forcestandby); | ||
| 263 | } | 370 | } |
| 264 | #endif | ||
| 265 | 371 | ||
| 266 | static int musb_platform_suspend(struct musb *musb) | 372 | static const struct musb_platform_ops omap2430_ops = { |
| 373 | .init = omap2430_musb_init, | ||
| 374 | .exit = omap2430_musb_exit, | ||
| 375 | |||
| 376 | .set_mode = omap2430_musb_set_mode, | ||
| 377 | .try_idle = omap2430_musb_try_idle, | ||
| 378 | |||
| 379 | .set_vbus = omap2430_musb_set_vbus, | ||
| 380 | }; | ||
| 381 | |||
| 382 | static u64 omap2430_dmamask = DMA_BIT_MASK(32); | ||
| 383 | |||
| 384 | static int __init omap2430_probe(struct platform_device *pdev) | ||
| 267 | { | 385 | { |
| 268 | u32 l; | 386 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; |
| 387 | struct platform_device *musb; | ||
| 388 | struct omap2430_glue *glue; | ||
| 389 | struct clk *clk; | ||
| 269 | 390 | ||
| 270 | if (!musb->clock) | 391 | int ret = -ENOMEM; |
| 271 | return 0; | ||
| 272 | 392 | ||
| 273 | /* in any role */ | 393 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); |
| 274 | l = musb_readl(musb->mregs, OTG_FORCESTDBY); | 394 | if (!glue) { |
| 275 | l |= ENABLEFORCE; /* enable MSTANDBY */ | 395 | dev_err(&pdev->dev, "failed to allocate glue context\n"); |
| 276 | musb_writel(musb->mregs, OTG_FORCESTDBY, l); | 396 | goto err0; |
| 397 | } | ||
| 277 | 398 | ||
| 278 | l = musb_readl(musb->mregs, OTG_SYSCONFIG); | 399 | musb = platform_device_alloc("musb-hdrc", -1); |
| 279 | l |= ENABLEWAKEUP; /* enable wakeup */ | 400 | if (!musb) { |
| 280 | musb_writel(musb->mregs, OTG_SYSCONFIG, l); | 401 | dev_err(&pdev->dev, "failed to allocate musb device\n"); |
| 402 | goto err1; | ||
| 403 | } | ||
| 281 | 404 | ||
| 282 | otg_set_suspend(musb->xceiv, 1); | 405 | clk = clk_get(&pdev->dev, "ick"); |
| 406 | if (IS_ERR(clk)) { | ||
| 407 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
| 408 | ret = PTR_ERR(clk); | ||
| 409 | goto err2; | ||
| 410 | } | ||
| 283 | 411 | ||
| 284 | if (musb->set_clock) | 412 | ret = clk_enable(clk); |
| 285 | musb->set_clock(musb->clock, 0); | 413 | if (ret) { |
| 286 | else | 414 | dev_err(&pdev->dev, "failed to enable clock\n"); |
| 287 | clk_disable(musb->clock); | 415 | goto err3; |
| 416 | } | ||
| 417 | |||
| 418 | musb->dev.parent = &pdev->dev; | ||
| 419 | musb->dev.dma_mask = &omap2430_dmamask; | ||
| 420 | musb->dev.coherent_dma_mask = omap2430_dmamask; | ||
| 421 | |||
| 422 | glue->dev = &pdev->dev; | ||
| 423 | glue->musb = musb; | ||
| 424 | glue->clk = clk; | ||
| 425 | |||
| 426 | pdata->platform_ops = &omap2430_ops; | ||
| 427 | |||
| 428 | platform_set_drvdata(pdev, glue); | ||
| 429 | |||
| 430 | ret = platform_device_add_resources(musb, pdev->resource, | ||
| 431 | pdev->num_resources); | ||
| 432 | if (ret) { | ||
| 433 | dev_err(&pdev->dev, "failed to add resources\n"); | ||
| 434 | goto err4; | ||
| 435 | } | ||
| 436 | |||
| 437 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | ||
| 438 | if (ret) { | ||
| 439 | dev_err(&pdev->dev, "failed to add platform_data\n"); | ||
| 440 | goto err4; | ||
| 441 | } | ||
| 442 | |||
| 443 | ret = platform_device_add(musb); | ||
| 444 | if (ret) { | ||
| 445 | dev_err(&pdev->dev, "failed to register musb device\n"); | ||
| 446 | goto err4; | ||
| 447 | } | ||
| 288 | 448 | ||
| 289 | return 0; | 449 | return 0; |
| 450 | |||
| 451 | err4: | ||
| 452 | clk_disable(clk); | ||
| 453 | |||
| 454 | err3: | ||
| 455 | clk_put(clk); | ||
| 456 | |||
| 457 | err2: | ||
| 458 | platform_device_put(musb); | ||
| 459 | |||
| 460 | err1: | ||
| 461 | kfree(glue); | ||
| 462 | |||
| 463 | err0: | ||
| 464 | return ret; | ||
| 290 | } | 465 | } |
| 291 | 466 | ||
| 292 | static int musb_platform_resume(struct musb *musb) | 467 | static int __exit omap2430_remove(struct platform_device *pdev) |
| 293 | { | 468 | { |
| 294 | u32 l; | 469 | struct omap2430_glue *glue = platform_get_drvdata(pdev); |
| 295 | 470 | ||
| 296 | if (!musb->clock) | 471 | platform_device_del(glue->musb); |
| 297 | return 0; | 472 | platform_device_put(glue->musb); |
| 473 | clk_disable(glue->clk); | ||
| 474 | clk_put(glue->clk); | ||
| 475 | kfree(glue); | ||
| 298 | 476 | ||
| 299 | otg_set_suspend(musb->xceiv, 0); | 477 | return 0; |
| 478 | } | ||
| 300 | 479 | ||
| 301 | if (musb->set_clock) | 480 | #ifdef CONFIG_PM |
| 302 | musb->set_clock(musb->clock, 1); | 481 | static void omap2430_save_context(struct musb *musb) |
| 303 | else | 482 | { |
| 304 | clk_enable(musb->clock); | 483 | musb->context.otg_sysconfig = musb_readl(musb->mregs, OTG_SYSCONFIG); |
| 484 | musb->context.otg_forcestandby = musb_readl(musb->mregs, OTG_FORCESTDBY); | ||
| 485 | } | ||
| 305 | 486 | ||
| 306 | l = musb_readl(musb->mregs, OTG_SYSCONFIG); | 487 | static void omap2430_restore_context(struct musb *musb) |
| 307 | l &= ~ENABLEWAKEUP; /* disable wakeup */ | 488 | { |
| 308 | musb_writel(musb->mregs, OTG_SYSCONFIG, l); | 489 | musb_writel(musb->mregs, OTG_SYSCONFIG, musb->context.otg_sysconfig); |
| 490 | musb_writel(musb->mregs, OTG_FORCESTDBY, musb->context.otg_forcestandby); | ||
| 491 | } | ||
| 309 | 492 | ||
| 310 | l = musb_readl(musb->mregs, OTG_FORCESTDBY); | 493 | static int omap2430_suspend(struct device *dev) |
| 311 | l &= ~ENABLEFORCE; /* disable MSTANDBY */ | 494 | { |
| 312 | musb_writel(musb->mregs, OTG_FORCESTDBY, l); | 495 | struct omap2430_glue *glue = dev_get_drvdata(dev); |
| 496 | struct musb *musb = glue_to_musb(glue); | ||
| 497 | |||
| 498 | omap2430_low_level_exit(musb); | ||
| 499 | otg_set_suspend(musb->xceiv, 1); | ||
| 500 | omap2430_save_context(musb); | ||
| 501 | clk_disable(glue->clk); | ||
| 313 | 502 | ||
| 314 | return 0; | 503 | return 0; |
| 315 | } | 504 | } |
| 316 | 505 | ||
| 317 | 506 | static int omap2430_resume(struct device *dev) | |
| 318 | int musb_platform_exit(struct musb *musb) | ||
| 319 | { | 507 | { |
| 508 | struct omap2430_glue *glue = dev_get_drvdata(dev); | ||
| 509 | struct musb *musb = glue_to_musb(glue); | ||
| 510 | int ret; | ||
| 511 | |||
| 512 | ret = clk_enable(glue->clk); | ||
| 513 | if (ret) { | ||
| 514 | dev_err(dev, "faled to enable clock\n"); | ||
| 515 | return ret; | ||
| 516 | } | ||
| 320 | 517 | ||
| 321 | musb_platform_suspend(musb); | 518 | omap2430_low_level_init(musb); |
| 519 | omap2430_restore_context(musb); | ||
| 520 | otg_set_suspend(musb->xceiv, 0); | ||
| 322 | 521 | ||
| 323 | otg_put_transceiver(musb->xceiv); | ||
| 324 | return 0; | 522 | return 0; |
| 325 | } | 523 | } |
| 524 | |||
| 525 | static struct dev_pm_ops omap2430_pm_ops = { | ||
| 526 | .suspend = omap2430_suspend, | ||
| 527 | .resume = omap2430_resume, | ||
| 528 | }; | ||
| 529 | |||
| 530 | #define DEV_PM_OPS (&omap2430_pm_ops) | ||
| 531 | #else | ||
| 532 | #define DEV_PM_OPS NULL | ||
| 533 | #endif | ||
| 534 | |||
| 535 | static struct platform_driver omap2430_driver = { | ||
| 536 | .remove = __exit_p(omap2430_remove), | ||
| 537 | .driver = { | ||
| 538 | .name = "musb-omap2430", | ||
| 539 | .pm = DEV_PM_OPS, | ||
| 540 | }, | ||
| 541 | }; | ||
| 542 | |||
| 543 | MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer"); | ||
| 544 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | ||
| 545 | MODULE_LICENSE("GPL v2"); | ||
| 546 | |||
| 547 | static int __init omap2430_init(void) | ||
| 548 | { | ||
| 549 | return platform_driver_probe(&omap2430_driver, omap2430_probe); | ||
| 550 | } | ||
| 551 | subsys_initcall(omap2430_init); | ||
| 552 | |||
| 553 | static void __exit omap2430_exit(void) | ||
| 554 | { | ||
| 555 | platform_driver_unregister(&omap2430_driver); | ||
| 556 | } | ||
| 557 | module_exit(omap2430_exit); | ||
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index bde40efc7046..2ba3b070ed0b 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
| @@ -21,10 +21,16 @@ | |||
| 21 | #include <linux/usb.h> | 21 | #include <linux/usb.h> |
| 22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
| 23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/dma-mapping.h> | ||
| 24 | 25 | ||
| 25 | #include "musb_core.h" | 26 | #include "musb_core.h" |
| 26 | 27 | ||
| 27 | static void tusb_source_power(struct musb *musb, int is_on); | 28 | struct tusb6010_glue { |
| 29 | struct device *dev; | ||
| 30 | struct platform_device *musb; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static void tusb_musb_set_vbus(struct musb *musb, int is_on); | ||
| 28 | 34 | ||
| 29 | #define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf) | 35 | #define TUSB_REV_MAJOR(reg_val) ((reg_val >> 4) & 0xf) |
| 30 | #define TUSB_REV_MINOR(reg_val) (reg_val & 0xf) | 36 | #define TUSB_REV_MINOR(reg_val) (reg_val & 0xf) |
| @@ -50,7 +56,7 @@ u8 tusb_get_revision(struct musb *musb) | |||
| 50 | return rev; | 56 | return rev; |
| 51 | } | 57 | } |
| 52 | 58 | ||
| 53 | static int __init tusb_print_revision(struct musb *musb) | 59 | static int tusb_print_revision(struct musb *musb) |
| 54 | { | 60 | { |
| 55 | void __iomem *tbase = musb->ctrl_base; | 61 | void __iomem *tbase = musb->ctrl_base; |
| 56 | u8 rev; | 62 | u8 rev; |
| @@ -275,17 +281,6 @@ static int tusb_draw_power(struct otg_transceiver *x, unsigned mA) | |||
| 275 | void __iomem *tbase = musb->ctrl_base; | 281 | void __iomem *tbase = musb->ctrl_base; |
| 276 | u32 reg; | 282 | u32 reg; |
| 277 | 283 | ||
| 278 | /* | ||
| 279 | * Keep clock active when enabled. Note that this is not tied to | ||
| 280 | * drawing VBUS, as with OTG mA can be less than musb->min_power. | ||
| 281 | */ | ||
| 282 | if (musb->set_clock) { | ||
| 283 | if (mA) | ||
| 284 | musb->set_clock(musb->clock, 1); | ||
| 285 | else | ||
| 286 | musb->set_clock(musb->clock, 0); | ||
| 287 | } | ||
| 288 | |||
| 289 | /* tps65030 seems to consume max 100mA, with maybe 60mA available | 284 | /* tps65030 seems to consume max 100mA, with maybe 60mA available |
| 290 | * (measured on one board) for things other than tps and tusb. | 285 | * (measured on one board) for things other than tps and tusb. |
| 291 | * | 286 | * |
| @@ -348,7 +343,7 @@ static void tusb_set_clock_source(struct musb *musb, unsigned mode) | |||
| 348 | * USB link is not suspended ... and tells us the relevant wakeup | 343 | * USB link is not suspended ... and tells us the relevant wakeup |
| 349 | * events. SW_EN for voltage is handled separately. | 344 | * events. SW_EN for voltage is handled separately. |
| 350 | */ | 345 | */ |
| 351 | void tusb_allow_idle(struct musb *musb, u32 wakeup_enables) | 346 | static void tusb_allow_idle(struct musb *musb, u32 wakeup_enables) |
| 352 | { | 347 | { |
| 353 | void __iomem *tbase = musb->ctrl_base; | 348 | void __iomem *tbase = musb->ctrl_base; |
| 354 | u32 reg; | 349 | u32 reg; |
| @@ -385,7 +380,7 @@ void tusb_allow_idle(struct musb *musb, u32 wakeup_enables) | |||
| 385 | /* | 380 | /* |
| 386 | * Updates cable VBUS status. Caller must take care of locking. | 381 | * Updates cable VBUS status. Caller must take care of locking. |
| 387 | */ | 382 | */ |
| 388 | int musb_platform_get_vbus_status(struct musb *musb) | 383 | static int tusb_musb_vbus_status(struct musb *musb) |
| 389 | { | 384 | { |
| 390 | void __iomem *tbase = musb->ctrl_base; | 385 | void __iomem *tbase = musb->ctrl_base; |
| 391 | u32 otg_stat, prcm_mngmt; | 386 | u32 otg_stat, prcm_mngmt; |
| @@ -431,7 +426,7 @@ static void musb_do_idle(unsigned long _musb) | |||
| 431 | } | 426 | } |
| 432 | /* FALLTHROUGH */ | 427 | /* FALLTHROUGH */ |
| 433 | case OTG_STATE_A_IDLE: | 428 | case OTG_STATE_A_IDLE: |
| 434 | tusb_source_power(musb, 0); | 429 | tusb_musb_set_vbus(musb, 0); |
| 435 | default: | 430 | default: |
| 436 | break; | 431 | break; |
| 437 | } | 432 | } |
| @@ -475,7 +470,7 @@ done: | |||
| 475 | * we don't want to treat that full speed J as a wakeup event. | 470 | * we don't want to treat that full speed J as a wakeup event. |
| 476 | * ... peripherals must draw only suspend current after 10 msec. | 471 | * ... peripherals must draw only suspend current after 10 msec. |
| 477 | */ | 472 | */ |
| 478 | void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | 473 | static void tusb_musb_try_idle(struct musb *musb, unsigned long timeout) |
| 479 | { | 474 | { |
| 480 | unsigned long default_timeout = jiffies + msecs_to_jiffies(3); | 475 | unsigned long default_timeout = jiffies + msecs_to_jiffies(3); |
| 481 | static unsigned long last_timer; | 476 | static unsigned long last_timer; |
| @@ -515,7 +510,7 @@ void musb_platform_try_idle(struct musb *musb, unsigned long timeout) | |||
| 515 | | TUSB_DEV_OTG_TIMER_ENABLE) \ | 510 | | TUSB_DEV_OTG_TIMER_ENABLE) \ |
| 516 | : 0) | 511 | : 0) |
| 517 | 512 | ||
| 518 | static void tusb_source_power(struct musb *musb, int is_on) | 513 | static void tusb_musb_set_vbus(struct musb *musb, int is_on) |
| 519 | { | 514 | { |
| 520 | void __iomem *tbase = musb->ctrl_base; | 515 | void __iomem *tbase = musb->ctrl_base; |
| 521 | u32 conf, prcm, timer; | 516 | u32 conf, prcm, timer; |
| @@ -531,8 +526,6 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
| 531 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); | 526 | devctl = musb_readb(musb->mregs, MUSB_DEVCTL); |
| 532 | 527 | ||
| 533 | if (is_on) { | 528 | if (is_on) { |
| 534 | if (musb->set_clock) | ||
| 535 | musb->set_clock(musb->clock, 1); | ||
| 536 | timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); | 529 | timer = OTG_TIMER_MS(OTG_TIME_A_WAIT_VRISE); |
| 537 | musb->xceiv->default_a = 1; | 530 | musb->xceiv->default_a = 1; |
| 538 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; | 531 | musb->xceiv->state = OTG_STATE_A_WAIT_VRISE; |
| @@ -571,8 +564,6 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
| 571 | 564 | ||
| 572 | devctl &= ~MUSB_DEVCTL_SESSION; | 565 | devctl &= ~MUSB_DEVCTL_SESSION; |
| 573 | conf &= ~TUSB_DEV_CONF_USB_HOST_MODE; | 566 | conf &= ~TUSB_DEV_CONF_USB_HOST_MODE; |
| 574 | if (musb->set_clock) | ||
| 575 | musb->set_clock(musb->clock, 0); | ||
| 576 | } | 567 | } |
| 577 | prcm &= ~(TUSB_PRCM_MNGMT_15_SW_EN | TUSB_PRCM_MNGMT_33_SW_EN); | 568 | prcm &= ~(TUSB_PRCM_MNGMT_15_SW_EN | TUSB_PRCM_MNGMT_33_SW_EN); |
| 578 | 569 | ||
| @@ -599,7 +590,7 @@ static void tusb_source_power(struct musb *musb, int is_on) | |||
| 599 | * and peripheral modes in non-OTG configurations by reconfiguring hardware | 590 | * and peripheral modes in non-OTG configurations by reconfiguring hardware |
| 600 | * and then setting musb->board_mode. For now, only support OTG mode. | 591 | * and then setting musb->board_mode. For now, only support OTG mode. |
| 601 | */ | 592 | */ |
| 602 | int musb_platform_set_mode(struct musb *musb, u8 musb_mode) | 593 | static int tusb_musb_set_mode(struct musb *musb, u8 musb_mode) |
| 603 | { | 594 | { |
| 604 | void __iomem *tbase = musb->ctrl_base; | 595 | void __iomem *tbase = musb->ctrl_base; |
| 605 | u32 otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf; | 596 | u32 otg_stat, phy_otg_ctrl, phy_otg_ena, dev_conf; |
| @@ -677,7 +668,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
| 677 | default_a = is_host_enabled(musb); | 668 | default_a = is_host_enabled(musb); |
| 678 | DBG(2, "Default-%c\n", default_a ? 'A' : 'B'); | 669 | DBG(2, "Default-%c\n", default_a ? 'A' : 'B'); |
| 679 | musb->xceiv->default_a = default_a; | 670 | musb->xceiv->default_a = default_a; |
| 680 | tusb_source_power(musb, default_a); | 671 | tusb_musb_set_vbus(musb, default_a); |
| 681 | 672 | ||
| 682 | /* Don't allow idling immediately */ | 673 | /* Don't allow idling immediately */ |
| 683 | if (default_a) | 674 | if (default_a) |
| @@ -722,7 +713,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
| 722 | switch (musb->xceiv->state) { | 713 | switch (musb->xceiv->state) { |
| 723 | case OTG_STATE_A_IDLE: | 714 | case OTG_STATE_A_IDLE: |
| 724 | DBG(2, "Got SRP, turning on VBUS\n"); | 715 | DBG(2, "Got SRP, turning on VBUS\n"); |
| 725 | musb_set_vbus(musb, 1); | 716 | musb_platform_set_vbus(musb, 1); |
| 726 | 717 | ||
| 727 | /* CONNECT can wake if a_wait_bcon is set */ | 718 | /* CONNECT can wake if a_wait_bcon is set */ |
| 728 | if (musb->a_wait_bcon != 0) | 719 | if (musb->a_wait_bcon != 0) |
| @@ -748,11 +739,11 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
| 748 | */ | 739 | */ |
| 749 | if (musb->vbuserr_retry) { | 740 | if (musb->vbuserr_retry) { |
| 750 | musb->vbuserr_retry--; | 741 | musb->vbuserr_retry--; |
| 751 | tusb_source_power(musb, 1); | 742 | tusb_musb_set_vbus(musb, 1); |
| 752 | } else { | 743 | } else { |
| 753 | musb->vbuserr_retry | 744 | musb->vbuserr_retry |
| 754 | = VBUSERR_RETRY_COUNT; | 745 | = VBUSERR_RETRY_COUNT; |
| 755 | tusb_source_power(musb, 0); | 746 | tusb_musb_set_vbus(musb, 0); |
| 756 | } | 747 | } |
| 757 | break; | 748 | break; |
| 758 | default: | 749 | default: |
| @@ -786,7 +777,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
| 786 | } else { | 777 | } else { |
| 787 | /* REVISIT report overcurrent to hub? */ | 778 | /* REVISIT report overcurrent to hub? */ |
| 788 | ERR("vbus too slow, devctl %02x\n", devctl); | 779 | ERR("vbus too slow, devctl %02x\n", devctl); |
| 789 | tusb_source_power(musb, 0); | 780 | tusb_musb_set_vbus(musb, 0); |
| 790 | } | 781 | } |
| 791 | break; | 782 | break; |
| 792 | case OTG_STATE_A_WAIT_BCON: | 783 | case OTG_STATE_A_WAIT_BCON: |
| @@ -807,7 +798,7 @@ tusb_otg_ints(struct musb *musb, u32 int_src, void __iomem *tbase) | |||
| 807 | return idle_timeout; | 798 | return idle_timeout; |
| 808 | } | 799 | } |
| 809 | 800 | ||
| 810 | static irqreturn_t tusb_interrupt(int irq, void *__hci) | 801 | static irqreturn_t tusb_musb_interrupt(int irq, void *__hci) |
| 811 | { | 802 | { |
| 812 | struct musb *musb = __hci; | 803 | struct musb *musb = __hci; |
| 813 | void __iomem *tbase = musb->ctrl_base; | 804 | void __iomem *tbase = musb->ctrl_base; |
| @@ -911,7 +902,7 @@ static irqreturn_t tusb_interrupt(int irq, void *__hci) | |||
| 911 | musb_writel(tbase, TUSB_INT_SRC_CLEAR, | 902 | musb_writel(tbase, TUSB_INT_SRC_CLEAR, |
| 912 | int_src & ~TUSB_INT_MASK_RESERVED_BITS); | 903 | int_src & ~TUSB_INT_MASK_RESERVED_BITS); |
| 913 | 904 | ||
| 914 | musb_platform_try_idle(musb, idle_timeout); | 905 | tusb_musb_try_idle(musb, idle_timeout); |
| 915 | 906 | ||
| 916 | musb_writel(tbase, TUSB_INT_MASK, int_mask); | 907 | musb_writel(tbase, TUSB_INT_MASK, int_mask); |
| 917 | spin_unlock_irqrestore(&musb->lock, flags); | 908 | spin_unlock_irqrestore(&musb->lock, flags); |
| @@ -926,7 +917,7 @@ static int dma_off; | |||
| 926 | * REVISIT: | 917 | * REVISIT: |
| 927 | * - Check what is unnecessary in MGC_HdrcStart() | 918 | * - Check what is unnecessary in MGC_HdrcStart() |
| 928 | */ | 919 | */ |
| 929 | void musb_platform_enable(struct musb *musb) | 920 | static void tusb_musb_enable(struct musb *musb) |
| 930 | { | 921 | { |
| 931 | void __iomem *tbase = musb->ctrl_base; | 922 | void __iomem *tbase = musb->ctrl_base; |
| 932 | 923 | ||
| @@ -970,7 +961,7 @@ void musb_platform_enable(struct musb *musb) | |||
| 970 | /* | 961 | /* |
| 971 | * Disables TUSB6010. Caller must take care of locking. | 962 | * Disables TUSB6010. Caller must take care of locking. |
| 972 | */ | 963 | */ |
| 973 | void musb_platform_disable(struct musb *musb) | 964 | static void tusb_musb_disable(struct musb *musb) |
| 974 | { | 965 | { |
| 975 | void __iomem *tbase = musb->ctrl_base; | 966 | void __iomem *tbase = musb->ctrl_base; |
| 976 | 967 | ||
| @@ -995,7 +986,7 @@ void musb_platform_disable(struct musb *musb) | |||
| 995 | * Sets up TUSB6010 CPU interface specific signals and registers | 986 | * Sets up TUSB6010 CPU interface specific signals and registers |
| 996 | * Note: Settings optimized for OMAP24xx | 987 | * Note: Settings optimized for OMAP24xx |
| 997 | */ | 988 | */ |
| 998 | static void __init tusb_setup_cpu_interface(struct musb *musb) | 989 | static void tusb_setup_cpu_interface(struct musb *musb) |
| 999 | { | 990 | { |
| 1000 | void __iomem *tbase = musb->ctrl_base; | 991 | void __iomem *tbase = musb->ctrl_base; |
| 1001 | 992 | ||
| @@ -1022,7 +1013,7 @@ static void __init tusb_setup_cpu_interface(struct musb *musb) | |||
| 1022 | musb_writel(tbase, TUSB_WAIT_COUNT, 1); | 1013 | musb_writel(tbase, TUSB_WAIT_COUNT, 1); |
| 1023 | } | 1014 | } |
| 1024 | 1015 | ||
| 1025 | static int __init tusb_start(struct musb *musb) | 1016 | static int tusb_musb_start(struct musb *musb) |
| 1026 | { | 1017 | { |
| 1027 | void __iomem *tbase = musb->ctrl_base; | 1018 | void __iomem *tbase = musb->ctrl_base; |
| 1028 | int ret = 0; | 1019 | int ret = 0; |
| @@ -1091,7 +1082,7 @@ err: | |||
| 1091 | return -ENODEV; | 1082 | return -ENODEV; |
| 1092 | } | 1083 | } |
| 1093 | 1084 | ||
| 1094 | int __init musb_platform_init(struct musb *musb, void *board_data) | 1085 | static int tusb_musb_init(struct musb *musb) |
| 1095 | { | 1086 | { |
| 1096 | struct platform_device *pdev; | 1087 | struct platform_device *pdev; |
| 1097 | struct resource *mem; | 1088 | struct resource *mem; |
| @@ -1131,16 +1122,14 @@ int __init musb_platform_init(struct musb *musb, void *board_data) | |||
| 1131 | */ | 1122 | */ |
| 1132 | musb->mregs += TUSB_BASE_OFFSET; | 1123 | musb->mregs += TUSB_BASE_OFFSET; |
| 1133 | 1124 | ||
| 1134 | ret = tusb_start(musb); | 1125 | ret = tusb_musb_start(musb); |
| 1135 | if (ret) { | 1126 | if (ret) { |
| 1136 | printk(KERN_ERR "Could not start tusb6010 (%d)\n", | 1127 | printk(KERN_ERR "Could not start tusb6010 (%d)\n", |
| 1137 | ret); | 1128 | ret); |
| 1138 | goto done; | 1129 | goto done; |
| 1139 | } | 1130 | } |
| 1140 | musb->isr = tusb_interrupt; | 1131 | musb->isr = tusb_musb_interrupt; |
| 1141 | 1132 | ||
| 1142 | if (is_host_enabled(musb)) | ||
| 1143 | musb->board_set_vbus = tusb_source_power; | ||
| 1144 | if (is_peripheral_enabled(musb)) { | 1133 | if (is_peripheral_enabled(musb)) { |
| 1145 | musb->xceiv->set_power = tusb_draw_power; | 1134 | musb->xceiv->set_power = tusb_draw_power; |
| 1146 | the_musb = musb; | 1135 | the_musb = musb; |
| @@ -1159,7 +1148,7 @@ done: | |||
| 1159 | return ret; | 1148 | return ret; |
| 1160 | } | 1149 | } |
| 1161 | 1150 | ||
| 1162 | int musb_platform_exit(struct musb *musb) | 1151 | static int tusb_musb_exit(struct musb *musb) |
| 1163 | { | 1152 | { |
| 1164 | del_timer_sync(&musb_idle_timer); | 1153 | del_timer_sync(&musb_idle_timer); |
| 1165 | the_musb = NULL; | 1154 | the_musb = NULL; |
| @@ -1173,3 +1162,115 @@ int musb_platform_exit(struct musb *musb) | |||
| 1173 | usb_nop_xceiv_unregister(); | 1162 | usb_nop_xceiv_unregister(); |
| 1174 | return 0; | 1163 | return 0; |
| 1175 | } | 1164 | } |
| 1165 | |||
| 1166 | static const struct musb_platform_ops tusb_ops = { | ||
| 1167 | .init = tusb_musb_init, | ||
| 1168 | .exit = tusb_musb_exit, | ||
| 1169 | |||
| 1170 | .enable = tusb_musb_enable, | ||
| 1171 | .disable = tusb_musb_disable, | ||
| 1172 | |||
| 1173 | .set_mode = tusb_musb_set_mode, | ||
| 1174 | .try_idle = tusb_musb_try_idle, | ||
| 1175 | |||
| 1176 | .vbus_status = tusb_musb_vbus_status, | ||
| 1177 | .set_vbus = tusb_musb_set_vbus, | ||
| 1178 | }; | ||
| 1179 | |||
| 1180 | static u64 tusb_dmamask = DMA_BIT_MASK(32); | ||
| 1181 | |||
| 1182 | static int __init tusb_probe(struct platform_device *pdev) | ||
| 1183 | { | ||
| 1184 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | ||
| 1185 | struct platform_device *musb; | ||
| 1186 | struct tusb6010_glue *glue; | ||
| 1187 | |||
| 1188 | int ret = -ENOMEM; | ||
| 1189 | |||
| 1190 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | ||
| 1191 | if (!glue) { | ||
| 1192 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
| 1193 | goto err0; | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | musb = platform_device_alloc("musb-hdrc", -1); | ||
| 1197 | if (!musb) { | ||
| 1198 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | ||
| 1199 | goto err1; | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | musb->dev.parent = &pdev->dev; | ||
| 1203 | musb->dev.dma_mask = &tusb_dmamask; | ||
| 1204 | musb->dev.coherent_dma_mask = tusb_dmamask; | ||
| 1205 | |||
| 1206 | glue->dev = &pdev->dev; | ||
| 1207 | glue->musb = musb; | ||
| 1208 | |||
| 1209 | pdata->platform_ops = &tusb_ops; | ||
| 1210 | |||
| 1211 | platform_set_drvdata(pdev, glue); | ||
| 1212 | |||
| 1213 | ret = platform_device_add_resources(musb, pdev->resource, | ||
| 1214 | pdev->num_resources); | ||
| 1215 | if (ret) { | ||
| 1216 | dev_err(&pdev->dev, "failed to add resources\n"); | ||
| 1217 | goto err2; | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | ||
| 1221 | if (ret) { | ||
| 1222 | dev_err(&pdev->dev, "failed to add platform_data\n"); | ||
| 1223 | goto err2; | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | ret = platform_device_add(musb); | ||
| 1227 | if (ret) { | ||
| 1228 | dev_err(&pdev->dev, "failed to register musb device\n"); | ||
| 1229 | goto err1; | ||
| 1230 | } | ||
| 1231 | |||
| 1232 | return 0; | ||
| 1233 | |||
| 1234 | err2: | ||
| 1235 | platform_device_put(musb); | ||
| 1236 | |||
| 1237 | err1: | ||
| 1238 | kfree(glue); | ||
| 1239 | |||
| 1240 | err0: | ||
| 1241 | return ret; | ||
| 1242 | } | ||
| 1243 | |||
| 1244 | static int __exit tusb_remove(struct platform_device *pdev) | ||
| 1245 | { | ||
| 1246 | struct tusb6010_glue *glue = platform_get_drvdata(pdev); | ||
| 1247 | |||
| 1248 | platform_device_del(glue->musb); | ||
| 1249 | platform_device_put(glue->musb); | ||
| 1250 | kfree(glue); | ||
| 1251 | |||
| 1252 | return 0; | ||
| 1253 | } | ||
| 1254 | |||
| 1255 | static struct platform_driver tusb_driver = { | ||
| 1256 | .remove = __exit_p(tusb_remove), | ||
| 1257 | .driver = { | ||
| 1258 | .name = "musb-tusb", | ||
| 1259 | }, | ||
| 1260 | }; | ||
| 1261 | |||
| 1262 | MODULE_DESCRIPTION("TUSB6010 MUSB Glue Layer"); | ||
| 1263 | MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>"); | ||
| 1264 | MODULE_LICENSE("GPL v2"); | ||
| 1265 | |||
| 1266 | static int __init tusb_init(void) | ||
| 1267 | { | ||
| 1268 | return platform_driver_probe(&tusb_driver, tusb_probe); | ||
| 1269 | } | ||
| 1270 | subsys_initcall(tusb_init); | ||
| 1271 | |||
| 1272 | static void __exit tusb_exit(void) | ||
| 1273 | { | ||
| 1274 | platform_driver_unregister(&tusb_driver); | ||
| 1275 | } | ||
| 1276 | module_exit(tusb_exit); | ||
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c new file mode 100644 index 000000000000..d6384e4aeef9 --- /dev/null +++ b/drivers/usb/musb/ux500.c | |||
| @@ -0,0 +1,216 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2010 ST-Ericsson AB | ||
| 3 | * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | ||
| 4 | * | ||
| 5 | * Based on omap2430.c | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 20 | */ | ||
| 21 | |||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/kernel.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/clk.h> | ||
| 26 | #include <linux/io.h> | ||
| 27 | #include <linux/platform_device.h> | ||
| 28 | |||
| 29 | #include "musb_core.h" | ||
| 30 | |||
| 31 | struct ux500_glue { | ||
| 32 | struct device *dev; | ||
| 33 | struct platform_device *musb; | ||
| 34 | struct clk *clk; | ||
| 35 | }; | ||
| 36 | #define glue_to_musb(g) platform_get_drvdata(g->musb) | ||
| 37 | |||
| 38 | static int ux500_musb_init(struct musb *musb) | ||
| 39 | { | ||
| 40 | musb->xceiv = otg_get_transceiver(); | ||
| 41 | if (!musb->xceiv) { | ||
| 42 | pr_err("HS USB OTG: no transceiver configured\n"); | ||
| 43 | return -ENODEV; | ||
| 44 | } | ||
| 45 | |||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | static int ux500_musb_exit(struct musb *musb) | ||
| 50 | { | ||
| 51 | otg_put_transceiver(musb->xceiv); | ||
| 52 | |||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | static const struct musb_platform_ops ux500_ops = { | ||
| 57 | .init = ux500_musb_init, | ||
| 58 | .exit = ux500_musb_exit, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static int __init ux500_probe(struct platform_device *pdev) | ||
| 62 | { | ||
| 63 | struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; | ||
| 64 | struct platform_device *musb; | ||
| 65 | struct ux500_glue *glue; | ||
| 66 | struct clk *clk; | ||
| 67 | |||
| 68 | int ret = -ENOMEM; | ||
| 69 | |||
| 70 | glue = kzalloc(sizeof(*glue), GFP_KERNEL); | ||
| 71 | if (!glue) { | ||
| 72 | dev_err(&pdev->dev, "failed to allocate glue context\n"); | ||
| 73 | goto err0; | ||
| 74 | } | ||
| 75 | |||
| 76 | musb = platform_device_alloc("musb-hdrc", -1); | ||
| 77 | if (!musb) { | ||
| 78 | dev_err(&pdev->dev, "failed to allocate musb device\n"); | ||
| 79 | goto err1; | ||
| 80 | } | ||
| 81 | |||
| 82 | clk = clk_get(&pdev->dev, "usb"); | ||
| 83 | if (IS_ERR(clk)) { | ||
| 84 | dev_err(&pdev->dev, "failed to get clock\n"); | ||
| 85 | ret = PTR_ERR(clk); | ||
| 86 | goto err2; | ||
| 87 | } | ||
| 88 | |||
| 89 | ret = clk_enable(clk); | ||
| 90 | if (ret) { | ||
| 91 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
| 92 | goto err3; | ||
| 93 | } | ||
| 94 | |||
| 95 | musb->dev.parent = &pdev->dev; | ||
| 96 | |||
| 97 | glue->dev = &pdev->dev; | ||
| 98 | glue->musb = musb; | ||
| 99 | glue->clk = clk; | ||
| 100 | |||
| 101 | pdata->platform_ops = &ux500_ops; | ||
| 102 | |||
| 103 | platform_set_drvdata(pdev, glue); | ||
| 104 | |||
| 105 | ret = platform_device_add_resources(musb, pdev->resource, | ||
| 106 | pdev->num_resources); | ||
| 107 | if (ret) { | ||
| 108 | dev_err(&pdev->dev, "failed to add resources\n"); | ||
| 109 | goto err4; | ||
| 110 | } | ||
| 111 | |||
| 112 | ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); | ||
| 113 | if (ret) { | ||
| 114 | dev_err(&pdev->dev, "failed to add platform_data\n"); | ||
| 115 | goto err4; | ||
| 116 | } | ||
| 117 | |||
| 118 | ret = platform_device_add(musb); | ||
| 119 | if (ret) { | ||
| 120 | dev_err(&pdev->dev, "failed to register musb device\n"); | ||
| 121 | goto err4; | ||
| 122 | } | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | |||
| 126 | err4: | ||
| 127 | clk_disable(clk); | ||
| 128 | |||
| 129 | err3: | ||
| 130 | clk_put(clk); | ||
| 131 | |||
| 132 | err2: | ||
| 133 | platform_device_put(musb); | ||
| 134 | |||
| 135 | err1: | ||
| 136 | kfree(glue); | ||
| 137 | |||
| 138 | err0: | ||
| 139 | return ret; | ||
| 140 | } | ||
| 141 | |||
| 142 | static int __exit ux500_remove(struct platform_device *pdev) | ||
| 143 | { | ||
| 144 | struct ux500_glue *glue = platform_get_drvdata(pdev); | ||
| 145 | |||
| 146 | platform_device_del(glue->musb); | ||
| 147 | platform_device_put(glue->musb); | ||
| 148 | clk_disable(glue->clk); | ||
| 149 | clk_put(glue->clk); | ||
| 150 | kfree(glue); | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | #ifdef CONFIG_PM | ||
| 156 | static int ux500_suspend(struct device *dev) | ||
| 157 | { | ||
| 158 | struct ux500_glue *glue = dev_get_drvdata(dev); | ||
| 159 | struct musb *musb = glue_to_musb(glue); | ||
| 160 | |||
| 161 | otg_set_suspend(musb->xceiv, 1); | ||
| 162 | clk_disable(glue->clk); | ||
| 163 | |||
| 164 | return 0; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int ux500_resume(struct device *dev) | ||
| 168 | { | ||
| 169 | struct ux500_glue *glue = dev_get_drvdata(dev); | ||
| 170 | struct musb *musb = glue_to_musb(glue); | ||
| 171 | int ret; | ||
| 172 | |||
| 173 | ret = clk_enable(glue->clk); | ||
| 174 | if (ret) { | ||
| 175 | dev_err(dev, "failed to enable clock\n"); | ||
| 176 | return ret; | ||
| 177 | } | ||
| 178 | |||
| 179 | otg_set_suspend(musb->xceiv, 0); | ||
| 180 | |||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | |||
| 184 | static const struct dev_pm_ops ux500_pm_ops = { | ||
| 185 | .suspend = ux500_suspend, | ||
| 186 | .resume = ux500_resume, | ||
| 187 | }; | ||
| 188 | |||
| 189 | #define DEV_PM_OPS (&ux500_pm_ops) | ||
| 190 | #else | ||
| 191 | #define DEV_PM_OPS NULL | ||
| 192 | #endif | ||
| 193 | |||
| 194 | static struct platform_driver ux500_driver = { | ||
| 195 | .remove = __exit_p(ux500_remove), | ||
| 196 | .driver = { | ||
| 197 | .name = "musb-ux500", | ||
| 198 | .pm = DEV_PM_OPS, | ||
| 199 | }, | ||
| 200 | }; | ||
| 201 | |||
| 202 | MODULE_DESCRIPTION("UX500 MUSB Glue Layer"); | ||
| 203 | MODULE_AUTHOR("Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>"); | ||
| 204 | MODULE_LICENSE("GPL v2"); | ||
| 205 | |||
| 206 | static int __init ux500_init(void) | ||
| 207 | { | ||
| 208 | return platform_driver_probe(&ux500_driver, ux500_probe); | ||
| 209 | } | ||
| 210 | subsys_initcall(ux500_init); | ||
| 211 | |||
| 212 | static void __exit ux500_exit(void) | ||
| 213 | { | ||
| 214 | platform_driver_unregister(&ux500_driver); | ||
| 215 | } | ||
| 216 | module_exit(ux500_exit); | ||
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index 5ce07528cd0c..9fb875d5f09c 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
| @@ -59,6 +59,18 @@ config TWL4030_USB | |||
| 59 | This transceiver supports high and full speed devices plus, | 59 | This transceiver supports high and full speed devices plus, |
| 60 | in host mode, low speed. | 60 | in host mode, low speed. |
| 61 | 61 | ||
| 62 | config TWL6030_USB | ||
| 63 | tristate "TWL6030 USB Transceiver Driver" | ||
| 64 | depends on TWL4030_CORE | ||
| 65 | select USB_OTG_UTILS | ||
| 66 | help | ||
| 67 | Enable this to support the USB OTG transceiver on TWL6030 | ||
| 68 | family chips. This TWL6030 transceiver has the VBUS and ID GND | ||
| 69 | and OTG SRP events capabilities. For all other transceiver functionality | ||
| 70 | UTMI PHY is embedded in OMAP4430. The internal PHY configurations APIs | ||
| 71 | are hooked to this driver through platform_data structure. | ||
| 72 | The definition of internal PHY APIs are in the mach-omap2 layer. | ||
| 73 | |||
| 62 | config NOP_USB_XCEIV | 74 | config NOP_USB_XCEIV |
| 63 | tristate "NOP USB Transceiver Driver" | 75 | tristate "NOP USB Transceiver Driver" |
| 64 | select USB_OTG_UTILS | 76 | select USB_OTG_UTILS |
| @@ -81,4 +93,24 @@ config USB_LANGWELL_OTG | |||
| 81 | To compile this driver as a module, choose M here: the | 93 | To compile this driver as a module, choose M here: the |
| 82 | module will be called langwell_otg. | 94 | module will be called langwell_otg. |
| 83 | 95 | ||
| 96 | config USB_MSM_OTG_72K | ||
| 97 | tristate "OTG support for Qualcomm on-chip USB controller" | ||
| 98 | depends on (USB || USB_GADGET) && ARCH_MSM | ||
| 99 | select USB_OTG_UTILS | ||
| 100 | help | ||
| 101 | Enable this to support the USB OTG transceiver on MSM chips. It | ||
| 102 | handles PHY initialization, clock management, and workarounds | ||
| 103 | required after resetting the hardware and power management. | ||
| 104 | This driver is required even for peripheral only or host only | ||
| 105 | mode configurations. | ||
| 106 | |||
| 107 | config AB8500_USB | ||
| 108 | tristate "AB8500 USB Transceiver Driver" | ||
| 109 | depends on AB8500_CORE | ||
| 110 | select USB_OTG_UTILS | ||
| 111 | help | ||
| 112 | Enable this to support the USB OTG transceiver in AB8500 chip. | ||
| 113 | This transceiver supports high and full speed devices plus, | ||
| 114 | in host mode, low speed. | ||
| 115 | |||
| 84 | endif # USB || OTG | 116 | endif # USB || OTG |
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index 66f1b83e4fa7..a520e715cfd6 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile | |||
| @@ -12,6 +12,9 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o | |||
| 12 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o | 12 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o |
| 13 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o | 13 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o |
| 14 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o | 14 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o |
| 15 | obj-$(CONFIG_TWL6030_USB) += twl6030-usb.o | ||
| 15 | obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o | 16 | obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o |
| 16 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o | 17 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o |
| 17 | obj-$(CONFIG_USB_ULPI) += ulpi.o | 18 | obj-$(CONFIG_USB_ULPI) += ulpi.o |
| 19 | obj-$(CONFIG_USB_MSM_OTG_72K) += msm72k_otg.o | ||
| 20 | obj-$(CONFIG_AB8500_USB) += ab8500-usb.o | ||
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c new file mode 100644 index 000000000000..d14736b3107b --- /dev/null +++ b/drivers/usb/otg/ab8500-usb.c | |||
| @@ -0,0 +1,585 @@ | |||
| 1 | /* | ||
| 2 | * drivers/usb/otg/ab8500_usb.c | ||
| 3 | * | ||
| 4 | * USB transceiver driver for AB8500 chip | ||
| 5 | * | ||
| 6 | * Copyright (C) 2010 ST-Ericsson AB | ||
| 7 | * Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | * | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/platform_device.h> | ||
| 27 | #include <linux/usb/otg.h> | ||
| 28 | #include <linux/slab.h> | ||
| 29 | #include <linux/notifier.h> | ||
| 30 | #include <linux/interrupt.h> | ||
| 31 | #include <linux/delay.h> | ||
| 32 | #include <linux/mfd/abx500.h> | ||
| 33 | #include <linux/mfd/ab8500.h> | ||
| 34 | |||
| 35 | #define AB8500_MAIN_WD_CTRL_REG 0x01 | ||
| 36 | #define AB8500_USB_LINE_STAT_REG 0x80 | ||
| 37 | #define AB8500_USB_PHY_CTRL_REG 0x8A | ||
| 38 | |||
| 39 | #define AB8500_BIT_OTG_STAT_ID (1 << 0) | ||
| 40 | #define AB8500_BIT_PHY_CTRL_HOST_EN (1 << 0) | ||
| 41 | #define AB8500_BIT_PHY_CTRL_DEVICE_EN (1 << 1) | ||
| 42 | #define AB8500_BIT_WD_CTRL_ENABLE (1 << 0) | ||
| 43 | #define AB8500_BIT_WD_CTRL_KICK (1 << 1) | ||
| 44 | |||
| 45 | #define AB8500_V1x_LINK_STAT_WAIT (HZ/10) | ||
| 46 | #define AB8500_WD_KICK_DELAY_US 100 /* usec */ | ||
| 47 | #define AB8500_WD_V11_DISABLE_DELAY_US 100 /* usec */ | ||
| 48 | #define AB8500_WD_V10_DISABLE_DELAY_MS 100 /* ms */ | ||
| 49 | |||
| 50 | /* Usb line status register */ | ||
| 51 | enum ab8500_usb_link_status { | ||
| 52 | USB_LINK_NOT_CONFIGURED = 0, | ||
| 53 | USB_LINK_STD_HOST_NC, | ||
| 54 | USB_LINK_STD_HOST_C_NS, | ||
| 55 | USB_LINK_STD_HOST_C_S, | ||
| 56 | USB_LINK_HOST_CHG_NM, | ||
| 57 | USB_LINK_HOST_CHG_HS, | ||
| 58 | USB_LINK_HOST_CHG_HS_CHIRP, | ||
| 59 | USB_LINK_DEDICATED_CHG, | ||
| 60 | USB_LINK_ACA_RID_A, | ||
| 61 | USB_LINK_ACA_RID_B, | ||
| 62 | USB_LINK_ACA_RID_C_NM, | ||
| 63 | USB_LINK_ACA_RID_C_HS, | ||
| 64 | USB_LINK_ACA_RID_C_HS_CHIRP, | ||
| 65 | USB_LINK_HM_IDGND, | ||
| 66 | USB_LINK_RESERVED, | ||
| 67 | USB_LINK_NOT_VALID_LINK | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct ab8500_usb { | ||
| 71 | struct otg_transceiver otg; | ||
| 72 | struct device *dev; | ||
| 73 | int irq_num_id_rise; | ||
| 74 | int irq_num_id_fall; | ||
| 75 | int irq_num_vbus_rise; | ||
| 76 | int irq_num_vbus_fall; | ||
| 77 | int irq_num_link_status; | ||
| 78 | unsigned vbus_draw; | ||
| 79 | struct delayed_work dwork; | ||
| 80 | struct work_struct phy_dis_work; | ||
| 81 | unsigned long link_status_wait; | ||
| 82 | int rev; | ||
| 83 | }; | ||
| 84 | |||
| 85 | static inline struct ab8500_usb *xceiv_to_ab(struct otg_transceiver *x) | ||
| 86 | { | ||
| 87 | return container_of(x, struct ab8500_usb, otg); | ||
| 88 | } | ||
| 89 | |||
| 90 | static void ab8500_usb_wd_workaround(struct ab8500_usb *ab) | ||
| 91 | { | ||
| 92 | abx500_set_register_interruptible(ab->dev, | ||
| 93 | AB8500_SYS_CTRL2_BLOCK, | ||
| 94 | AB8500_MAIN_WD_CTRL_REG, | ||
| 95 | AB8500_BIT_WD_CTRL_ENABLE); | ||
| 96 | |||
| 97 | udelay(AB8500_WD_KICK_DELAY_US); | ||
| 98 | |||
| 99 | abx500_set_register_interruptible(ab->dev, | ||
| 100 | AB8500_SYS_CTRL2_BLOCK, | ||
| 101 | AB8500_MAIN_WD_CTRL_REG, | ||
| 102 | (AB8500_BIT_WD_CTRL_ENABLE | ||
| 103 | | AB8500_BIT_WD_CTRL_KICK)); | ||
| 104 | |||
| 105 | if (ab->rev > 0x10) /* v1.1 v2.0 */ | ||
| 106 | udelay(AB8500_WD_V11_DISABLE_DELAY_US); | ||
| 107 | else /* v1.0 */ | ||
| 108 | msleep(AB8500_WD_V10_DISABLE_DELAY_MS); | ||
| 109 | |||
| 110 | abx500_set_register_interruptible(ab->dev, | ||
| 111 | AB8500_SYS_CTRL2_BLOCK, | ||
| 112 | AB8500_MAIN_WD_CTRL_REG, | ||
| 113 | 0); | ||
| 114 | } | ||
| 115 | |||
| 116 | static void ab8500_usb_phy_ctrl(struct ab8500_usb *ab, bool sel_host, | ||
| 117 | bool enable) | ||
| 118 | { | ||
| 119 | u8 ctrl_reg; | ||
| 120 | abx500_get_register_interruptible(ab->dev, | ||
| 121 | AB8500_USB, | ||
| 122 | AB8500_USB_PHY_CTRL_REG, | ||
| 123 | &ctrl_reg); | ||
| 124 | if (sel_host) { | ||
| 125 | if (enable) | ||
| 126 | ctrl_reg |= AB8500_BIT_PHY_CTRL_HOST_EN; | ||
| 127 | else | ||
| 128 | ctrl_reg &= ~AB8500_BIT_PHY_CTRL_HOST_EN; | ||
| 129 | } else { | ||
| 130 | if (enable) | ||
| 131 | ctrl_reg |= AB8500_BIT_PHY_CTRL_DEVICE_EN; | ||
| 132 | else | ||
| 133 | ctrl_reg &= ~AB8500_BIT_PHY_CTRL_DEVICE_EN; | ||
| 134 | } | ||
| 135 | |||
| 136 | abx500_set_register_interruptible(ab->dev, | ||
| 137 | AB8500_USB, | ||
| 138 | AB8500_USB_PHY_CTRL_REG, | ||
| 139 | ctrl_reg); | ||
| 140 | |||
| 141 | /* Needed to enable the phy.*/ | ||
| 142 | if (enable) | ||
| 143 | ab8500_usb_wd_workaround(ab); | ||
| 144 | } | ||
| 145 | |||
| 146 | #define ab8500_usb_host_phy_en(ab) ab8500_usb_phy_ctrl(ab, true, true) | ||
| 147 | #define ab8500_usb_host_phy_dis(ab) ab8500_usb_phy_ctrl(ab, true, false) | ||
| 148 | #define ab8500_usb_peri_phy_en(ab) ab8500_usb_phy_ctrl(ab, false, true) | ||
| 149 | #define ab8500_usb_peri_phy_dis(ab) ab8500_usb_phy_ctrl(ab, false, false) | ||
| 150 | |||
| 151 | static int ab8500_usb_link_status_update(struct ab8500_usb *ab) | ||
| 152 | { | ||
| 153 | u8 reg; | ||
| 154 | enum ab8500_usb_link_status lsts; | ||
| 155 | void *v = NULL; | ||
| 156 | enum usb_xceiv_events event; | ||
| 157 | |||
| 158 | abx500_get_register_interruptible(ab->dev, | ||
| 159 | AB8500_USB, | ||
| 160 | AB8500_USB_LINE_STAT_REG, | ||
| 161 | ®); | ||
| 162 | |||
| 163 | lsts = (reg >> 3) & 0x0F; | ||
| 164 | |||
| 165 | switch (lsts) { | ||
| 166 | case USB_LINK_NOT_CONFIGURED: | ||
| 167 | case USB_LINK_RESERVED: | ||
| 168 | case USB_LINK_NOT_VALID_LINK: | ||
| 169 | /* TODO: Disable regulators. */ | ||
| 170 | ab8500_usb_host_phy_dis(ab); | ||
| 171 | ab8500_usb_peri_phy_dis(ab); | ||
| 172 | ab->otg.state = OTG_STATE_B_IDLE; | ||
| 173 | ab->otg.default_a = false; | ||
| 174 | ab->vbus_draw = 0; | ||
| 175 | event = USB_EVENT_NONE; | ||
| 176 | break; | ||
| 177 | |||
| 178 | case USB_LINK_STD_HOST_NC: | ||
| 179 | case USB_LINK_STD_HOST_C_NS: | ||
| 180 | case USB_LINK_STD_HOST_C_S: | ||
| 181 | case USB_LINK_HOST_CHG_NM: | ||
| 182 | case USB_LINK_HOST_CHG_HS: | ||
| 183 | case USB_LINK_HOST_CHG_HS_CHIRP: | ||
| 184 | if (ab->otg.gadget) { | ||
| 185 | /* TODO: Enable regulators. */ | ||
| 186 | ab8500_usb_peri_phy_en(ab); | ||
| 187 | v = ab->otg.gadget; | ||
| 188 | } | ||
| 189 | event = USB_EVENT_VBUS; | ||
| 190 | break; | ||
| 191 | |||
| 192 | case USB_LINK_HM_IDGND: | ||
| 193 | if (ab->otg.host) { | ||
| 194 | /* TODO: Enable regulators. */ | ||
| 195 | ab8500_usb_host_phy_en(ab); | ||
| 196 | v = ab->otg.host; | ||
| 197 | } | ||
| 198 | ab->otg.state = OTG_STATE_A_IDLE; | ||
| 199 | ab->otg.default_a = true; | ||
| 200 | event = USB_EVENT_ID; | ||
| 201 | break; | ||
| 202 | |||
| 203 | case USB_LINK_ACA_RID_A: | ||
| 204 | case USB_LINK_ACA_RID_B: | ||
| 205 | /* TODO */ | ||
| 206 | case USB_LINK_ACA_RID_C_NM: | ||
| 207 | case USB_LINK_ACA_RID_C_HS: | ||
| 208 | case USB_LINK_ACA_RID_C_HS_CHIRP: | ||
| 209 | case USB_LINK_DEDICATED_CHG: | ||
| 210 | /* TODO: vbus_draw */ | ||
| 211 | event = USB_EVENT_CHARGER; | ||
| 212 | break; | ||
| 213 | } | ||
| 214 | |||
| 215 | blocking_notifier_call_chain(&ab->otg.notifier, event, v); | ||
| 216 | |||
| 217 | return 0; | ||
| 218 | } | ||
| 219 | |||
| 220 | static void ab8500_usb_delayed_work(struct work_struct *work) | ||
| 221 | { | ||
| 222 | struct ab8500_usb *ab = container_of(work, struct ab8500_usb, | ||
| 223 | dwork.work); | ||
| 224 | |||
| 225 | ab8500_usb_link_status_update(ab); | ||
| 226 | } | ||
| 227 | |||
| 228 | static irqreturn_t ab8500_usb_v1x_common_irq(int irq, void *data) | ||
| 229 | { | ||
| 230 | struct ab8500_usb *ab = (struct ab8500_usb *) data; | ||
| 231 | |||
| 232 | /* Wait for link status to become stable. */ | ||
| 233 | schedule_delayed_work(&ab->dwork, ab->link_status_wait); | ||
| 234 | |||
| 235 | return IRQ_HANDLED; | ||
| 236 | } | ||
| 237 | |||
| 238 | static irqreturn_t ab8500_usb_v1x_vbus_fall_irq(int irq, void *data) | ||
| 239 | { | ||
| 240 | struct ab8500_usb *ab = (struct ab8500_usb *) data; | ||
| 241 | |||
| 242 | /* Link status will not be updated till phy is disabled. */ | ||
| 243 | ab8500_usb_peri_phy_dis(ab); | ||
| 244 | |||
| 245 | /* Wait for link status to become stable. */ | ||
| 246 | schedule_delayed_work(&ab->dwork, ab->link_status_wait); | ||
| 247 | |||
| 248 | return IRQ_HANDLED; | ||
| 249 | } | ||
| 250 | |||
| 251 | static irqreturn_t ab8500_usb_v20_irq(int irq, void *data) | ||
| 252 | { | ||
| 253 | struct ab8500_usb *ab = (struct ab8500_usb *) data; | ||
| 254 | |||
| 255 | ab8500_usb_link_status_update(ab); | ||
| 256 | |||
| 257 | return IRQ_HANDLED; | ||
| 258 | } | ||
| 259 | |||
| 260 | static void ab8500_usb_phy_disable_work(struct work_struct *work) | ||
| 261 | { | ||
| 262 | struct ab8500_usb *ab = container_of(work, struct ab8500_usb, | ||
| 263 | phy_dis_work); | ||
| 264 | |||
| 265 | if (!ab->otg.host) | ||
| 266 | ab8500_usb_host_phy_dis(ab); | ||
| 267 | |||
| 268 | if (!ab->otg.gadget) | ||
| 269 | ab8500_usb_peri_phy_dis(ab); | ||
| 270 | } | ||
| 271 | |||
| 272 | static int ab8500_usb_set_power(struct otg_transceiver *otg, unsigned mA) | ||
| 273 | { | ||
| 274 | struct ab8500_usb *ab; | ||
| 275 | |||
| 276 | if (!otg) | ||
| 277 | return -ENODEV; | ||
| 278 | |||
| 279 | ab = xceiv_to_ab(otg); | ||
| 280 | |||
| 281 | ab->vbus_draw = mA; | ||
| 282 | |||
| 283 | if (mA) | ||
| 284 | blocking_notifier_call_chain(&ab->otg.notifier, | ||
| 285 | USB_EVENT_ENUMERATED, ab->otg.gadget); | ||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 289 | /* TODO: Implement some way for charging or other drivers to read | ||
| 290 | * ab->vbus_draw. | ||
| 291 | */ | ||
| 292 | |||
| 293 | static int ab8500_usb_set_suspend(struct otg_transceiver *x, int suspend) | ||
| 294 | { | ||
| 295 | /* TODO */ | ||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | |||
| 299 | static int ab8500_usb_set_peripheral(struct otg_transceiver *otg, | ||
| 300 | struct usb_gadget *gadget) | ||
| 301 | { | ||
| 302 | struct ab8500_usb *ab; | ||
| 303 | |||
| 304 | if (!otg) | ||
| 305 | return -ENODEV; | ||
| 306 | |||
| 307 | ab = xceiv_to_ab(otg); | ||
| 308 | |||
| 309 | /* Some drivers call this function in atomic context. | ||
| 310 | * Do not update ab8500 registers directly till this | ||
| 311 | * is fixed. | ||
| 312 | */ | ||
| 313 | |||
| 314 | if (!gadget) { | ||
| 315 | /* TODO: Disable regulators. */ | ||
| 316 | ab->otg.gadget = NULL; | ||
| 317 | schedule_work(&ab->phy_dis_work); | ||
| 318 | } else { | ||
| 319 | ab->otg.gadget = gadget; | ||
| 320 | ab->otg.state = OTG_STATE_B_IDLE; | ||
| 321 | |||
| 322 | /* Phy will not be enabled if cable is already | ||
| 323 | * plugged-in. Schedule to enable phy. | ||
| 324 | * Use same delay to avoid any race condition. | ||
| 325 | */ | ||
| 326 | schedule_delayed_work(&ab->dwork, ab->link_status_wait); | ||
| 327 | } | ||
| 328 | |||
| 329 | return 0; | ||
| 330 | } | ||
| 331 | |||
| 332 | static int ab8500_usb_set_host(struct otg_transceiver *otg, | ||
| 333 | struct usb_bus *host) | ||
| 334 | { | ||
| 335 | struct ab8500_usb *ab; | ||
| 336 | |||
| 337 | if (!otg) | ||
| 338 | return -ENODEV; | ||
| 339 | |||
| 340 | ab = xceiv_to_ab(otg); | ||
| 341 | |||
| 342 | /* Some drivers call this function in atomic context. | ||
| 343 | * Do not update ab8500 registers directly till this | ||
| 344 | * is fixed. | ||
| 345 | */ | ||
| 346 | |||
| 347 | if (!host) { | ||
| 348 | /* TODO: Disable regulators. */ | ||
| 349 | ab->otg.host = NULL; | ||
| 350 | schedule_work(&ab->phy_dis_work); | ||
| 351 | } else { | ||
| 352 | ab->otg.host = host; | ||
| 353 | /* Phy will not be enabled if cable is already | ||
| 354 | * plugged-in. Schedule to enable phy. | ||
| 355 | * Use same delay to avoid any race condition. | ||
| 356 | */ | ||
| 357 | schedule_delayed_work(&ab->dwork, ab->link_status_wait); | ||
| 358 | } | ||
| 359 | |||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | |||
| 363 | static void ab8500_usb_irq_free(struct ab8500_usb *ab) | ||
| 364 | { | ||
| 365 | if (ab->rev < 0x20) { | ||
| 366 | free_irq(ab->irq_num_id_rise, ab); | ||
| 367 | free_irq(ab->irq_num_id_fall, ab); | ||
| 368 | free_irq(ab->irq_num_vbus_rise, ab); | ||
| 369 | free_irq(ab->irq_num_vbus_fall, ab); | ||
| 370 | } else { | ||
| 371 | free_irq(ab->irq_num_link_status, ab); | ||
| 372 | } | ||
| 373 | } | ||
| 374 | |||
| 375 | static int ab8500_usb_v1x_res_setup(struct platform_device *pdev, | ||
| 376 | struct ab8500_usb *ab) | ||
| 377 | { | ||
| 378 | int err; | ||
| 379 | |||
| 380 | ab->irq_num_id_rise = platform_get_irq_byname(pdev, "ID_WAKEUP_R"); | ||
| 381 | if (ab->irq_num_id_rise < 0) { | ||
| 382 | dev_err(&pdev->dev, "ID rise irq not found\n"); | ||
| 383 | return ab->irq_num_id_rise; | ||
| 384 | } | ||
| 385 | err = request_threaded_irq(ab->irq_num_id_rise, NULL, | ||
| 386 | ab8500_usb_v1x_common_irq, | ||
| 387 | IRQF_NO_SUSPEND | IRQF_SHARED, | ||
| 388 | "usb-id-rise", ab); | ||
| 389 | if (err < 0) { | ||
| 390 | dev_err(ab->dev, "request_irq failed for ID rise irq\n"); | ||
| 391 | goto fail0; | ||
| 392 | } | ||
| 393 | |||
| 394 | ab->irq_num_id_fall = platform_get_irq_byname(pdev, "ID_WAKEUP_F"); | ||
| 395 | if (ab->irq_num_id_fall < 0) { | ||
| 396 | dev_err(&pdev->dev, "ID fall irq not found\n"); | ||
| 397 | return ab->irq_num_id_fall; | ||
| 398 | } | ||
| 399 | err = request_threaded_irq(ab->irq_num_id_fall, NULL, | ||
| 400 | ab8500_usb_v1x_common_irq, | ||
| 401 | IRQF_NO_SUSPEND | IRQF_SHARED, | ||
| 402 | "usb-id-fall", ab); | ||
| 403 | if (err < 0) { | ||
| 404 | dev_err(ab->dev, "request_irq failed for ID fall irq\n"); | ||
| 405 | goto fail1; | ||
| 406 | } | ||
| 407 | |||
| 408 | ab->irq_num_vbus_rise = platform_get_irq_byname(pdev, "VBUS_DET_R"); | ||
| 409 | if (ab->irq_num_vbus_rise < 0) { | ||
| 410 | dev_err(&pdev->dev, "VBUS rise irq not found\n"); | ||
| 411 | return ab->irq_num_vbus_rise; | ||
| 412 | } | ||
| 413 | err = request_threaded_irq(ab->irq_num_vbus_rise, NULL, | ||
| 414 | ab8500_usb_v1x_common_irq, | ||
| 415 | IRQF_NO_SUSPEND | IRQF_SHARED, | ||
| 416 | "usb-vbus-rise", ab); | ||
| 417 | if (err < 0) { | ||
| 418 | dev_err(ab->dev, "request_irq failed for Vbus rise irq\n"); | ||
| 419 | goto fail2; | ||
| 420 | } | ||
| 421 | |||
| 422 | ab->irq_num_vbus_fall = platform_get_irq_byname(pdev, "VBUS_DET_F"); | ||
| 423 | if (ab->irq_num_vbus_fall < 0) { | ||
| 424 | dev_err(&pdev->dev, "VBUS fall irq not found\n"); | ||
| 425 | return ab->irq_num_vbus_fall; | ||
| 426 | } | ||
| 427 | err = request_threaded_irq(ab->irq_num_vbus_fall, NULL, | ||
| 428 | ab8500_usb_v1x_vbus_fall_irq, | ||
| 429 | IRQF_NO_SUSPEND | IRQF_SHARED, | ||
| 430 | "usb-vbus-fall", ab); | ||
| 431 | if (err < 0) { | ||
| 432 | dev_err(ab->dev, "request_irq failed for Vbus fall irq\n"); | ||
| 433 | goto fail3; | ||
| 434 | } | ||
| 435 | |||
| 436 | return 0; | ||
| 437 | fail3: | ||
| 438 | free_irq(ab->irq_num_vbus_rise, ab); | ||
| 439 | fail2: | ||
| 440 | free_irq(ab->irq_num_id_fall, ab); | ||
| 441 | fail1: | ||
| 442 | free_irq(ab->irq_num_id_rise, ab); | ||
| 443 | fail0: | ||
| 444 | return err; | ||
| 445 | } | ||
| 446 | |||
| 447 | static int ab8500_usb_v2_res_setup(struct platform_device *pdev, | ||
| 448 | struct ab8500_usb *ab) | ||
| 449 | { | ||
| 450 | int err; | ||
| 451 | |||
| 452 | ab->irq_num_link_status = platform_get_irq_byname(pdev, | ||
| 453 | "USB_LINK_STATUS"); | ||
| 454 | if (ab->irq_num_link_status < 0) { | ||
| 455 | dev_err(&pdev->dev, "Link status irq not found\n"); | ||
| 456 | return ab->irq_num_link_status; | ||
| 457 | } | ||
| 458 | |||
| 459 | err = request_threaded_irq(ab->irq_num_link_status, NULL, | ||
| 460 | ab8500_usb_v20_irq, | ||
| 461 | IRQF_NO_SUSPEND | IRQF_SHARED, | ||
| 462 | "usb-link-status", ab); | ||
| 463 | if (err < 0) { | ||
| 464 | dev_err(ab->dev, | ||
| 465 | "request_irq failed for link status irq\n"); | ||
| 466 | return err; | ||
| 467 | } | ||
| 468 | |||
| 469 | return 0; | ||
| 470 | } | ||
| 471 | |||
| 472 | static int __devinit ab8500_usb_probe(struct platform_device *pdev) | ||
| 473 | { | ||
| 474 | struct ab8500_usb *ab; | ||
| 475 | int err; | ||
| 476 | int rev; | ||
| 477 | |||
| 478 | rev = abx500_get_chip_id(&pdev->dev); | ||
| 479 | if (rev < 0) { | ||
| 480 | dev_err(&pdev->dev, "Chip id read failed\n"); | ||
| 481 | return rev; | ||
| 482 | } else if (rev < 0x10) { | ||
| 483 | dev_err(&pdev->dev, "Unsupported AB8500 chip\n"); | ||
| 484 | return -ENODEV; | ||
| 485 | } | ||
| 486 | |||
| 487 | ab = kzalloc(sizeof *ab, GFP_KERNEL); | ||
| 488 | if (!ab) | ||
| 489 | return -ENOMEM; | ||
| 490 | |||
| 491 | ab->dev = &pdev->dev; | ||
| 492 | ab->rev = rev; | ||
| 493 | ab->otg.dev = ab->dev; | ||
| 494 | ab->otg.label = "ab8500"; | ||
| 495 | ab->otg.state = OTG_STATE_UNDEFINED; | ||
| 496 | ab->otg.set_host = ab8500_usb_set_host; | ||
| 497 | ab->otg.set_peripheral = ab8500_usb_set_peripheral; | ||
| 498 | ab->otg.set_suspend = ab8500_usb_set_suspend; | ||
| 499 | ab->otg.set_power = ab8500_usb_set_power; | ||
| 500 | |||
| 501 | platform_set_drvdata(pdev, ab); | ||
| 502 | |||
| 503 | BLOCKING_INIT_NOTIFIER_HEAD(&ab->otg.notifier); | ||
| 504 | |||
| 505 | /* v1: Wait for link status to become stable. | ||
| 506 | * all: Updates form set_host and set_peripheral as they are atomic. | ||
| 507 | */ | ||
| 508 | INIT_DELAYED_WORK(&ab->dwork, ab8500_usb_delayed_work); | ||
| 509 | |||
| 510 | /* all: Disable phy when called from set_host and set_peripheral */ | ||
| 511 | INIT_WORK(&ab->phy_dis_work, ab8500_usb_phy_disable_work); | ||
| 512 | |||
| 513 | if (ab->rev < 0x20) { | ||
| 514 | err = ab8500_usb_v1x_res_setup(pdev, ab); | ||
| 515 | ab->link_status_wait = AB8500_V1x_LINK_STAT_WAIT; | ||
| 516 | } else { | ||
| 517 | err = ab8500_usb_v2_res_setup(pdev, ab); | ||
| 518 | } | ||
| 519 | |||
| 520 | if (err < 0) | ||
| 521 | goto fail0; | ||
| 522 | |||
| 523 | err = otg_set_transceiver(&ab->otg); | ||
| 524 | if (err) { | ||
| 525 | dev_err(&pdev->dev, "Can't register transceiver\n"); | ||
| 526 | goto fail1; | ||
| 527 | } | ||
| 528 | |||
| 529 | dev_info(&pdev->dev, "AB8500 usb driver initialized\n"); | ||
| 530 | |||
| 531 | return 0; | ||
| 532 | fail1: | ||
| 533 | ab8500_usb_irq_free(ab); | ||
| 534 | fail0: | ||
| 535 | kfree(ab); | ||
| 536 | return err; | ||
| 537 | } | ||
| 538 | |||
| 539 | static int __devexit ab8500_usb_remove(struct platform_device *pdev) | ||
| 540 | { | ||
| 541 | struct ab8500_usb *ab = platform_get_drvdata(pdev); | ||
| 542 | |||
| 543 | ab8500_usb_irq_free(ab); | ||
| 544 | |||
| 545 | cancel_delayed_work_sync(&ab->dwork); | ||
| 546 | |||
| 547 | cancel_work_sync(&ab->phy_dis_work); | ||
| 548 | |||
| 549 | otg_set_transceiver(NULL); | ||
| 550 | |||
| 551 | ab8500_usb_host_phy_dis(ab); | ||
| 552 | ab8500_usb_peri_phy_dis(ab); | ||
| 553 | |||
| 554 | platform_set_drvdata(pdev, NULL); | ||
| 555 | |||
| 556 | kfree(ab); | ||
| 557 | |||
| 558 | return 0; | ||
| 559 | } | ||
| 560 | |||
| 561 | static struct platform_driver ab8500_usb_driver = { | ||
| 562 | .probe = ab8500_usb_probe, | ||
| 563 | .remove = __devexit_p(ab8500_usb_remove), | ||
| 564 | .driver = { | ||
| 565 | .name = "ab8500-usb", | ||
| 566 | .owner = THIS_MODULE, | ||
| 567 | }, | ||
| 568 | }; | ||
| 569 | |||
| 570 | static int __init ab8500_usb_init(void) | ||
| 571 | { | ||
| 572 | return platform_driver_register(&ab8500_usb_driver); | ||
| 573 | } | ||
| 574 | subsys_initcall(ab8500_usb_init); | ||
| 575 | |||
| 576 | static void __exit ab8500_usb_exit(void) | ||
| 577 | { | ||
| 578 | platform_driver_unregister(&ab8500_usb_driver); | ||
| 579 | } | ||
| 580 | module_exit(ab8500_usb_exit); | ||
| 581 | |||
| 582 | MODULE_ALIAS("platform:ab8500_usb"); | ||
| 583 | MODULE_AUTHOR("ST-Ericsson AB"); | ||
| 584 | MODULE_DESCRIPTION("AB8500 usb transceiver driver"); | ||
| 585 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c new file mode 100644 index 000000000000..1cd52edcd0c2 --- /dev/null +++ b/drivers/usb/otg/msm72k_otg.c | |||
| @@ -0,0 +1,1125 @@ | |||
| 1 | /* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License version 2 and | ||
| 5 | * only version 2 as published by the Free Software Foundation. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 15 | * 02110-1301, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/device.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/clk.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/err.h> | ||
| 26 | #include <linux/delay.h> | ||
| 27 | #include <linux/io.h> | ||
| 28 | #include <linux/ioport.h> | ||
| 29 | #include <linux/uaccess.h> | ||
| 30 | #include <linux/debugfs.h> | ||
| 31 | #include <linux/seq_file.h> | ||
| 32 | #include <linux/pm_runtime.h> | ||
| 33 | |||
| 34 | #include <linux/usb.h> | ||
| 35 | #include <linux/usb/otg.h> | ||
| 36 | #include <linux/usb/ulpi.h> | ||
| 37 | #include <linux/usb/gadget.h> | ||
| 38 | #include <linux/usb/hcd.h> | ||
| 39 | #include <linux/usb/msm_hsusb.h> | ||
| 40 | #include <linux/usb/msm_hsusb_hw.h> | ||
| 41 | |||
| 42 | #include <mach/clk.h> | ||
| 43 | |||
| 44 | #define MSM_USB_BASE (motg->regs) | ||
| 45 | #define DRIVER_NAME "msm_otg" | ||
| 46 | |||
| 47 | #define ULPI_IO_TIMEOUT_USEC (10 * 1000) | ||
| 48 | static int ulpi_read(struct otg_transceiver *otg, u32 reg) | ||
| 49 | { | ||
| 50 | struct msm_otg *motg = container_of(otg, struct msm_otg, otg); | ||
| 51 | int cnt = 0; | ||
| 52 | |||
| 53 | /* initiate read operation */ | ||
| 54 | writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), | ||
| 55 | USB_ULPI_VIEWPORT); | ||
| 56 | |||
| 57 | /* wait for completion */ | ||
| 58 | while (cnt < ULPI_IO_TIMEOUT_USEC) { | ||
| 59 | if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) | ||
| 60 | break; | ||
| 61 | udelay(1); | ||
| 62 | cnt++; | ||
| 63 | } | ||
| 64 | |||
| 65 | if (cnt >= ULPI_IO_TIMEOUT_USEC) { | ||
| 66 | dev_err(otg->dev, "ulpi_read: timeout %08x\n", | ||
| 67 | readl(USB_ULPI_VIEWPORT)); | ||
| 68 | return -ETIMEDOUT; | ||
| 69 | } | ||
| 70 | return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); | ||
| 71 | } | ||
| 72 | |||
| 73 | static int ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg) | ||
| 74 | { | ||
| 75 | struct msm_otg *motg = container_of(otg, struct msm_otg, otg); | ||
| 76 | int cnt = 0; | ||
| 77 | |||
| 78 | /* initiate write operation */ | ||
| 79 | writel(ULPI_RUN | ULPI_WRITE | | ||
| 80 | ULPI_ADDR(reg) | ULPI_DATA(val), | ||
| 81 | USB_ULPI_VIEWPORT); | ||
| 82 | |||
| 83 | /* wait for completion */ | ||
| 84 | while (cnt < ULPI_IO_TIMEOUT_USEC) { | ||
| 85 | if (!(readl(USB_ULPI_VIEWPORT) & ULPI_RUN)) | ||
| 86 | break; | ||
| 87 | udelay(1); | ||
| 88 | cnt++; | ||
| 89 | } | ||
| 90 | |||
| 91 | if (cnt >= ULPI_IO_TIMEOUT_USEC) { | ||
| 92 | dev_err(otg->dev, "ulpi_write: timeout\n"); | ||
| 93 | return -ETIMEDOUT; | ||
| 94 | } | ||
| 95 | return 0; | ||
| 96 | } | ||
| 97 | |||
| 98 | static struct otg_io_access_ops msm_otg_io_ops = { | ||
| 99 | .read = ulpi_read, | ||
| 100 | .write = ulpi_write, | ||
| 101 | }; | ||
| 102 | |||
| 103 | static void ulpi_init(struct msm_otg *motg) | ||
| 104 | { | ||
| 105 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
| 106 | int *seq = pdata->phy_init_seq; | ||
| 107 | |||
| 108 | if (!seq) | ||
| 109 | return; | ||
| 110 | |||
| 111 | while (seq[0] >= 0) { | ||
| 112 | dev_vdbg(motg->otg.dev, "ulpi: write 0x%02x to 0x%02x\n", | ||
| 113 | seq[0], seq[1]); | ||
| 114 | ulpi_write(&motg->otg, seq[0], seq[1]); | ||
| 115 | seq += 2; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | static int msm_otg_link_clk_reset(struct msm_otg *motg, bool assert) | ||
| 120 | { | ||
| 121 | int ret; | ||
| 122 | |||
| 123 | if (assert) { | ||
| 124 | ret = clk_reset(motg->clk, CLK_RESET_ASSERT); | ||
| 125 | if (ret) | ||
| 126 | dev_err(motg->otg.dev, "usb hs_clk assert failed\n"); | ||
| 127 | } else { | ||
| 128 | ret = clk_reset(motg->clk, CLK_RESET_DEASSERT); | ||
| 129 | if (ret) | ||
| 130 | dev_err(motg->otg.dev, "usb hs_clk deassert failed\n"); | ||
| 131 | } | ||
| 132 | return ret; | ||
| 133 | } | ||
| 134 | |||
| 135 | static int msm_otg_phy_clk_reset(struct msm_otg *motg) | ||
| 136 | { | ||
| 137 | int ret; | ||
| 138 | |||
| 139 | ret = clk_reset(motg->phy_reset_clk, CLK_RESET_ASSERT); | ||
| 140 | if (ret) { | ||
| 141 | dev_err(motg->otg.dev, "usb phy clk assert failed\n"); | ||
| 142 | return ret; | ||
| 143 | } | ||
| 144 | usleep_range(10000, 12000); | ||
| 145 | ret = clk_reset(motg->phy_reset_clk, CLK_RESET_DEASSERT); | ||
| 146 | if (ret) | ||
| 147 | dev_err(motg->otg.dev, "usb phy clk deassert failed\n"); | ||
| 148 | return ret; | ||
| 149 | } | ||
| 150 | |||
| 151 | static int msm_otg_phy_reset(struct msm_otg *motg) | ||
| 152 | { | ||
| 153 | u32 val; | ||
| 154 | int ret; | ||
| 155 | int retries; | ||
| 156 | |||
| 157 | ret = msm_otg_link_clk_reset(motg, 1); | ||
| 158 | if (ret) | ||
| 159 | return ret; | ||
| 160 | ret = msm_otg_phy_clk_reset(motg); | ||
| 161 | if (ret) | ||
| 162 | return ret; | ||
| 163 | ret = msm_otg_link_clk_reset(motg, 0); | ||
| 164 | if (ret) | ||
| 165 | return ret; | ||
| 166 | |||
| 167 | val = readl(USB_PORTSC) & ~PORTSC_PTS_MASK; | ||
| 168 | writel(val | PORTSC_PTS_ULPI, USB_PORTSC); | ||
| 169 | |||
| 170 | for (retries = 3; retries > 0; retries--) { | ||
| 171 | ret = ulpi_write(&motg->otg, ULPI_FUNC_CTRL_SUSPENDM, | ||
| 172 | ULPI_CLR(ULPI_FUNC_CTRL)); | ||
| 173 | if (!ret) | ||
| 174 | break; | ||
| 175 | ret = msm_otg_phy_clk_reset(motg); | ||
| 176 | if (ret) | ||
| 177 | return ret; | ||
| 178 | } | ||
| 179 | if (!retries) | ||
| 180 | return -ETIMEDOUT; | ||
| 181 | |||
| 182 | /* This reset calibrates the phy, if the above write succeeded */ | ||
| 183 | ret = msm_otg_phy_clk_reset(motg); | ||
| 184 | if (ret) | ||
| 185 | return ret; | ||
| 186 | |||
| 187 | for (retries = 3; retries > 0; retries--) { | ||
| 188 | ret = ulpi_read(&motg->otg, ULPI_DEBUG); | ||
| 189 | if (ret != -ETIMEDOUT) | ||
| 190 | break; | ||
| 191 | ret = msm_otg_phy_clk_reset(motg); | ||
| 192 | if (ret) | ||
| 193 | return ret; | ||
| 194 | } | ||
| 195 | if (!retries) | ||
| 196 | return -ETIMEDOUT; | ||
| 197 | |||
| 198 | dev_info(motg->otg.dev, "phy_reset: success\n"); | ||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | #define LINK_RESET_TIMEOUT_USEC (250 * 1000) | ||
| 203 | static int msm_otg_reset(struct otg_transceiver *otg) | ||
| 204 | { | ||
| 205 | struct msm_otg *motg = container_of(otg, struct msm_otg, otg); | ||
| 206 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
| 207 | int cnt = 0; | ||
| 208 | int ret; | ||
| 209 | u32 val = 0; | ||
| 210 | u32 ulpi_val = 0; | ||
| 211 | |||
| 212 | ret = msm_otg_phy_reset(motg); | ||
| 213 | if (ret) { | ||
| 214 | dev_err(otg->dev, "phy_reset failed\n"); | ||
| 215 | return ret; | ||
| 216 | } | ||
| 217 | |||
| 218 | ulpi_init(motg); | ||
| 219 | |||
| 220 | writel(USBCMD_RESET, USB_USBCMD); | ||
| 221 | while (cnt < LINK_RESET_TIMEOUT_USEC) { | ||
| 222 | if (!(readl(USB_USBCMD) & USBCMD_RESET)) | ||
| 223 | break; | ||
| 224 | udelay(1); | ||
| 225 | cnt++; | ||
| 226 | } | ||
| 227 | if (cnt >= LINK_RESET_TIMEOUT_USEC) | ||
| 228 | return -ETIMEDOUT; | ||
| 229 | |||
| 230 | /* select ULPI phy */ | ||
| 231 | writel(0x80000000, USB_PORTSC); | ||
| 232 | |||
| 233 | msleep(100); | ||
| 234 | |||
| 235 | writel(0x0, USB_AHBBURST); | ||
| 236 | writel(0x00, USB_AHBMODE); | ||
| 237 | |||
| 238 | if (pdata->otg_control == OTG_PHY_CONTROL) { | ||
| 239 | val = readl(USB_OTGSC); | ||
| 240 | if (pdata->mode == USB_OTG) { | ||
| 241 | ulpi_val = ULPI_INT_IDGRD | ULPI_INT_SESS_VALID; | ||
| 242 | val |= OTGSC_IDIE | OTGSC_BSVIE; | ||
| 243 | } else if (pdata->mode == USB_PERIPHERAL) { | ||
| 244 | ulpi_val = ULPI_INT_SESS_VALID; | ||
| 245 | val |= OTGSC_BSVIE; | ||
| 246 | } | ||
| 247 | writel(val, USB_OTGSC); | ||
| 248 | ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_RISE); | ||
| 249 | ulpi_write(otg, ulpi_val, ULPI_USB_INT_EN_FALL); | ||
| 250 | } | ||
| 251 | |||
| 252 | return 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | #define PHY_SUSPEND_TIMEOUT_USEC (500 * 1000) | ||
| 256 | static int msm_otg_suspend(struct msm_otg *motg) | ||
| 257 | { | ||
| 258 | struct otg_transceiver *otg = &motg->otg; | ||
| 259 | struct usb_bus *bus = otg->host; | ||
| 260 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
| 261 | int cnt = 0; | ||
| 262 | |||
| 263 | if (atomic_read(&motg->in_lpm)) | ||
| 264 | return 0; | ||
| 265 | |||
| 266 | disable_irq(motg->irq); | ||
| 267 | /* | ||
| 268 | * Interrupt Latch Register auto-clear feature is not present | ||
| 269 | * in all PHY versions. Latch register is clear on read type. | ||
| 270 | * Clear latch register to avoid spurious wakeup from | ||
| 271 | * low power mode (LPM). | ||
| 272 | */ | ||
| 273 | ulpi_read(otg, 0x14); | ||
| 274 | |||
| 275 | /* | ||
| 276 | * PHY comparators are disabled when PHY enters into low power | ||
| 277 | * mode (LPM). Keep PHY comparators ON in LPM only when we expect | ||
| 278 | * VBUS/Id notifications from USB PHY. Otherwise turn off USB | ||
| 279 | * PHY comparators. This save significant amount of power. | ||
| 280 | */ | ||
| 281 | if (pdata->otg_control == OTG_PHY_CONTROL) | ||
| 282 | ulpi_write(otg, 0x01, 0x30); | ||
| 283 | |||
| 284 | /* | ||
| 285 | * PLL is not turned off when PHY enters into low power mode (LPM). | ||
| 286 | * Disable PLL for maximum power savings. | ||
| 287 | */ | ||
| 288 | ulpi_write(otg, 0x08, 0x09); | ||
| 289 | |||
| 290 | /* | ||
| 291 | * PHY may take some time or even fail to enter into low power | ||
| 292 | * mode (LPM). Hence poll for 500 msec and reset the PHY and link | ||
| 293 | * in failure case. | ||
| 294 | */ | ||
| 295 | writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); | ||
| 296 | while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { | ||
| 297 | if (readl(USB_PORTSC) & PORTSC_PHCD) | ||
| 298 | break; | ||
| 299 | udelay(1); | ||
| 300 | cnt++; | ||
| 301 | } | ||
| 302 | |||
| 303 | if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) { | ||
| 304 | dev_err(otg->dev, "Unable to suspend PHY\n"); | ||
| 305 | msm_otg_reset(otg); | ||
| 306 | enable_irq(motg->irq); | ||
| 307 | return -ETIMEDOUT; | ||
| 308 | } | ||
| 309 | |||
| 310 | /* | ||
| 311 | * PHY has capability to generate interrupt asynchronously in low | ||
| 312 | * power mode (LPM). This interrupt is level triggered. So USB IRQ | ||
| 313 | * line must be disabled till async interrupt enable bit is cleared | ||
| 314 | * in USBCMD register. Assert STP (ULPI interface STOP signal) to | ||
| 315 | * block data communication from PHY. | ||
| 316 | */ | ||
| 317 | writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD); | ||
| 318 | |||
| 319 | clk_disable(motg->pclk); | ||
| 320 | clk_disable(motg->clk); | ||
| 321 | if (motg->core_clk) | ||
| 322 | clk_disable(motg->core_clk); | ||
| 323 | |||
| 324 | if (device_may_wakeup(otg->dev)) | ||
| 325 | enable_irq_wake(motg->irq); | ||
| 326 | if (bus) | ||
| 327 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); | ||
| 328 | |||
| 329 | atomic_set(&motg->in_lpm, 1); | ||
| 330 | enable_irq(motg->irq); | ||
| 331 | |||
| 332 | dev_info(otg->dev, "USB in low power mode\n"); | ||
| 333 | |||
| 334 | return 0; | ||
| 335 | } | ||
| 336 | |||
| 337 | #define PHY_RESUME_TIMEOUT_USEC (100 * 1000) | ||
| 338 | static int msm_otg_resume(struct msm_otg *motg) | ||
| 339 | { | ||
| 340 | struct otg_transceiver *otg = &motg->otg; | ||
| 341 | struct usb_bus *bus = otg->host; | ||
| 342 | int cnt = 0; | ||
| 343 | unsigned temp; | ||
| 344 | |||
| 345 | if (!atomic_read(&motg->in_lpm)) | ||
| 346 | return 0; | ||
| 347 | |||
| 348 | clk_enable(motg->pclk); | ||
| 349 | clk_enable(motg->clk); | ||
| 350 | if (motg->core_clk) | ||
| 351 | clk_enable(motg->core_clk); | ||
| 352 | |||
| 353 | temp = readl(USB_USBCMD); | ||
| 354 | temp &= ~ASYNC_INTR_CTRL; | ||
| 355 | temp &= ~ULPI_STP_CTRL; | ||
| 356 | writel(temp, USB_USBCMD); | ||
| 357 | |||
| 358 | /* | ||
| 359 | * PHY comes out of low power mode (LPM) in case of wakeup | ||
| 360 | * from asynchronous interrupt. | ||
| 361 | */ | ||
| 362 | if (!(readl(USB_PORTSC) & PORTSC_PHCD)) | ||
| 363 | goto skip_phy_resume; | ||
| 364 | |||
| 365 | writel(readl(USB_PORTSC) & ~PORTSC_PHCD, USB_PORTSC); | ||
| 366 | while (cnt < PHY_RESUME_TIMEOUT_USEC) { | ||
| 367 | if (!(readl(USB_PORTSC) & PORTSC_PHCD)) | ||
| 368 | break; | ||
| 369 | udelay(1); | ||
| 370 | cnt++; | ||
| 371 | } | ||
| 372 | |||
| 373 | if (cnt >= PHY_RESUME_TIMEOUT_USEC) { | ||
| 374 | /* | ||
| 375 | * This is a fatal error. Reset the link and | ||
| 376 | * PHY. USB state can not be restored. Re-insertion | ||
| 377 | * of USB cable is the only way to get USB working. | ||
| 378 | */ | ||
| 379 | dev_err(otg->dev, "Unable to resume USB." | ||
| 380 | "Re-plugin the cable\n"); | ||
| 381 | msm_otg_reset(otg); | ||
| 382 | } | ||
| 383 | |||
| 384 | skip_phy_resume: | ||
| 385 | if (device_may_wakeup(otg->dev)) | ||
| 386 | disable_irq_wake(motg->irq); | ||
| 387 | if (bus) | ||
| 388 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags); | ||
| 389 | |||
| 390 | if (motg->async_int) { | ||
| 391 | motg->async_int = 0; | ||
| 392 | pm_runtime_put(otg->dev); | ||
| 393 | enable_irq(motg->irq); | ||
| 394 | } | ||
| 395 | |||
| 396 | atomic_set(&motg->in_lpm, 0); | ||
| 397 | |||
| 398 | dev_info(otg->dev, "USB exited from low power mode\n"); | ||
| 399 | |||
| 400 | return 0; | ||
| 401 | } | ||
| 402 | |||
| 403 | static void msm_otg_start_host(struct otg_transceiver *otg, int on) | ||
| 404 | { | ||
| 405 | struct msm_otg *motg = container_of(otg, struct msm_otg, otg); | ||
| 406 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
| 407 | struct usb_hcd *hcd; | ||
| 408 | |||
| 409 | if (!otg->host) | ||
| 410 | return; | ||
| 411 | |||
| 412 | hcd = bus_to_hcd(otg->host); | ||
| 413 | |||
| 414 | if (on) { | ||
| 415 | dev_dbg(otg->dev, "host on\n"); | ||
| 416 | |||
| 417 | if (pdata->vbus_power) | ||
| 418 | pdata->vbus_power(1); | ||
| 419 | /* | ||
| 420 | * Some boards have a switch cotrolled by gpio | ||
| 421 | * to enable/disable internal HUB. Enable internal | ||
| 422 | * HUB before kicking the host. | ||
| 423 | */ | ||
| 424 | if (pdata->setup_gpio) | ||
| 425 | pdata->setup_gpio(OTG_STATE_A_HOST); | ||
| 426 | #ifdef CONFIG_USB | ||
| 427 | usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); | ||
| 428 | #endif | ||
| 429 | } else { | ||
| 430 | dev_dbg(otg->dev, "host off\n"); | ||
| 431 | |||
| 432 | #ifdef CONFIG_USB | ||
| 433 | usb_remove_hcd(hcd); | ||
| 434 | #endif | ||
| 435 | if (pdata->setup_gpio) | ||
| 436 | pdata->setup_gpio(OTG_STATE_UNDEFINED); | ||
| 437 | if (pdata->vbus_power) | ||
| 438 | pdata->vbus_power(0); | ||
| 439 | } | ||
| 440 | } | ||
| 441 | |||
| 442 | static int msm_otg_set_host(struct otg_transceiver *otg, struct usb_bus *host) | ||
| 443 | { | ||
| 444 | struct msm_otg *motg = container_of(otg, struct msm_otg, otg); | ||
| 445 | struct usb_hcd *hcd; | ||
| 446 | |||
| 447 | /* | ||
| 448 | * Fail host registration if this board can support | ||
| 449 | * only peripheral configuration. | ||
| 450 | */ | ||
| 451 | if (motg->pdata->mode == USB_PERIPHERAL) { | ||
| 452 | dev_info(otg->dev, "Host mode is not supported\n"); | ||
| 453 | return -ENODEV; | ||
| 454 | } | ||
| 455 | |||
| 456 | if (!host) { | ||
| 457 | if (otg->state == OTG_STATE_A_HOST) { | ||
| 458 | pm_runtime_get_sync(otg->dev); | ||
| 459 | msm_otg_start_host(otg, 0); | ||
| 460 | otg->host = NULL; | ||
| 461 | otg->state = OTG_STATE_UNDEFINED; | ||
| 462 | schedule_work(&motg->sm_work); | ||
| 463 | } else { | ||
| 464 | otg->host = NULL; | ||
| 465 | } | ||
| 466 | |||
| 467 | return 0; | ||
| 468 | } | ||
| 469 | |||
| 470 | hcd = bus_to_hcd(host); | ||
| 471 | hcd->power_budget = motg->pdata->power_budget; | ||
| 472 | |||
| 473 | otg->host = host; | ||
| 474 | dev_dbg(otg->dev, "host driver registered w/ tranceiver\n"); | ||
| 475 | |||
| 476 | /* | ||
| 477 | * Kick the state machine work, if peripheral is not supported | ||
| 478 | * or peripheral is already registered with us. | ||
| 479 | */ | ||
| 480 | if (motg->pdata->mode == USB_HOST || otg->gadget) { | ||
| 481 | pm_runtime_get_sync(otg->dev); | ||
| 482 | schedule_work(&motg->sm_work); | ||
| 483 | } | ||
| 484 | |||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | static void msm_otg_start_peripheral(struct otg_transceiver *otg, int on) | ||
| 489 | { | ||
| 490 | struct msm_otg *motg = container_of(otg, struct msm_otg, otg); | ||
| 491 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
| 492 | |||
| 493 | if (!otg->gadget) | ||
| 494 | return; | ||
| 495 | |||
| 496 | if (on) { | ||
| 497 | dev_dbg(otg->dev, "gadget on\n"); | ||
| 498 | /* | ||
| 499 | * Some boards have a switch cotrolled by gpio | ||
| 500 | * to enable/disable internal HUB. Disable internal | ||
| 501 | * HUB before kicking the gadget. | ||
| 502 | */ | ||
| 503 | if (pdata->setup_gpio) | ||
| 504 | pdata->setup_gpio(OTG_STATE_B_PERIPHERAL); | ||
| 505 | usb_gadget_vbus_connect(otg->gadget); | ||
| 506 | } else { | ||
| 507 | dev_dbg(otg->dev, "gadget off\n"); | ||
| 508 | usb_gadget_vbus_disconnect(otg->gadget); | ||
| 509 | if (pdata->setup_gpio) | ||
| 510 | pdata->setup_gpio(OTG_STATE_UNDEFINED); | ||
| 511 | } | ||
| 512 | |||
| 513 | } | ||
| 514 | |||
| 515 | static int msm_otg_set_peripheral(struct otg_transceiver *otg, | ||
| 516 | struct usb_gadget *gadget) | ||
| 517 | { | ||
| 518 | struct msm_otg *motg = container_of(otg, struct msm_otg, otg); | ||
| 519 | |||
| 520 | /* | ||
| 521 | * Fail peripheral registration if this board can support | ||
| 522 | * only host configuration. | ||
| 523 | */ | ||
| 524 | if (motg->pdata->mode == USB_HOST) { | ||
| 525 | dev_info(otg->dev, "Peripheral mode is not supported\n"); | ||
| 526 | return -ENODEV; | ||
| 527 | } | ||
| 528 | |||
| 529 | if (!gadget) { | ||
| 530 | if (otg->state == OTG_STATE_B_PERIPHERAL) { | ||
| 531 | pm_runtime_get_sync(otg->dev); | ||
| 532 | msm_otg_start_peripheral(otg, 0); | ||
| 533 | otg->gadget = NULL; | ||
| 534 | otg->state = OTG_STATE_UNDEFINED; | ||
| 535 | schedule_work(&motg->sm_work); | ||
| 536 | } else { | ||
| 537 | otg->gadget = NULL; | ||
| 538 | } | ||
| 539 | |||
| 540 | return 0; | ||
| 541 | } | ||
| 542 | otg->gadget = gadget; | ||
| 543 | dev_dbg(otg->dev, "peripheral driver registered w/ tranceiver\n"); | ||
| 544 | |||
| 545 | /* | ||
| 546 | * Kick the state machine work, if host is not supported | ||
| 547 | * or host is already registered with us. | ||
| 548 | */ | ||
| 549 | if (motg->pdata->mode == USB_PERIPHERAL || otg->host) { | ||
| 550 | pm_runtime_get_sync(otg->dev); | ||
| 551 | schedule_work(&motg->sm_work); | ||
| 552 | } | ||
| 553 | |||
| 554 | return 0; | ||
| 555 | } | ||
| 556 | |||
| 557 | /* | ||
| 558 | * We support OTG, Peripheral only and Host only configurations. In case | ||
| 559 | * of OTG, mode switch (host-->peripheral/peripheral-->host) can happen | ||
| 560 | * via Id pin status or user request (debugfs). Id/BSV interrupts are not | ||
| 561 | * enabled when switch is controlled by user and default mode is supplied | ||
| 562 | * by board file, which can be changed by userspace later. | ||
| 563 | */ | ||
| 564 | static void msm_otg_init_sm(struct msm_otg *motg) | ||
| 565 | { | ||
| 566 | struct msm_otg_platform_data *pdata = motg->pdata; | ||
| 567 | u32 otgsc = readl(USB_OTGSC); | ||
| 568 | |||
| 569 | switch (pdata->mode) { | ||
| 570 | case USB_OTG: | ||
| 571 | if (pdata->otg_control == OTG_PHY_CONTROL) { | ||
| 572 | if (otgsc & OTGSC_ID) | ||
| 573 | set_bit(ID, &motg->inputs); | ||
| 574 | else | ||
| 575 | clear_bit(ID, &motg->inputs); | ||
| 576 | |||
| 577 | if (otgsc & OTGSC_BSV) | ||
| 578 | set_bit(B_SESS_VLD, &motg->inputs); | ||
| 579 | else | ||
| 580 | clear_bit(B_SESS_VLD, &motg->inputs); | ||
| 581 | } else if (pdata->otg_control == OTG_USER_CONTROL) { | ||
| 582 | if (pdata->default_mode == USB_HOST) { | ||
| 583 | clear_bit(ID, &motg->inputs); | ||
| 584 | } else if (pdata->default_mode == USB_PERIPHERAL) { | ||
| 585 | set_bit(ID, &motg->inputs); | ||
| 586 | set_bit(B_SESS_VLD, &motg->inputs); | ||
| 587 | } else { | ||
| 588 | set_bit(ID, &motg->inputs); | ||
| 589 | clear_bit(B_SESS_VLD, &motg->inputs); | ||
| 590 | } | ||
| 591 | } | ||
| 592 | break; | ||
| 593 | case USB_HOST: | ||
| 594 | clear_bit(ID, &motg->inputs); | ||
| 595 | break; | ||
| 596 | case USB_PERIPHERAL: | ||
| 597 | set_bit(ID, &motg->inputs); | ||
| 598 | if (otgsc & OTGSC_BSV) | ||
| 599 | set_bit(B_SESS_VLD, &motg->inputs); | ||
| 600 | else | ||
| 601 | clear_bit(B_SESS_VLD, &motg->inputs); | ||
| 602 | break; | ||
| 603 | default: | ||
| 604 | break; | ||
| 605 | } | ||
| 606 | } | ||
| 607 | |||
| 608 | static void msm_otg_sm_work(struct work_struct *w) | ||
| 609 | { | ||
| 610 | struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); | ||
| 611 | struct otg_transceiver *otg = &motg->otg; | ||
| 612 | |||
| 613 | switch (otg->state) { | ||
| 614 | case OTG_STATE_UNDEFINED: | ||
| 615 | dev_dbg(otg->dev, "OTG_STATE_UNDEFINED state\n"); | ||
| 616 | msm_otg_reset(otg); | ||
| 617 | msm_otg_init_sm(motg); | ||
| 618 | otg->state = OTG_STATE_B_IDLE; | ||
| 619 | /* FALL THROUGH */ | ||
| 620 | case OTG_STATE_B_IDLE: | ||
| 621 | dev_dbg(otg->dev, "OTG_STATE_B_IDLE state\n"); | ||
| 622 | if (!test_bit(ID, &motg->inputs) && otg->host) { | ||
| 623 | /* disable BSV bit */ | ||
| 624 | writel(readl(USB_OTGSC) & ~OTGSC_BSVIE, USB_OTGSC); | ||
| 625 | msm_otg_start_host(otg, 1); | ||
| 626 | otg->state = OTG_STATE_A_HOST; | ||
| 627 | } else if (test_bit(B_SESS_VLD, &motg->inputs) && otg->gadget) { | ||
| 628 | msm_otg_start_peripheral(otg, 1); | ||
| 629 | otg->state = OTG_STATE_B_PERIPHERAL; | ||
| 630 | } | ||
| 631 | pm_runtime_put_sync(otg->dev); | ||
| 632 | break; | ||
| 633 | case OTG_STATE_B_PERIPHERAL: | ||
| 634 | dev_dbg(otg->dev, "OTG_STATE_B_PERIPHERAL state\n"); | ||
| 635 | if (!test_bit(B_SESS_VLD, &motg->inputs) || | ||
| 636 | !test_bit(ID, &motg->inputs)) { | ||
| 637 | msm_otg_start_peripheral(otg, 0); | ||
| 638 | otg->state = OTG_STATE_B_IDLE; | ||
| 639 | msm_otg_reset(otg); | ||
| 640 | schedule_work(w); | ||
| 641 | } | ||
| 642 | break; | ||
| 643 | case OTG_STATE_A_HOST: | ||
| 644 | dev_dbg(otg->dev, "OTG_STATE_A_HOST state\n"); | ||
| 645 | if (test_bit(ID, &motg->inputs)) { | ||
| 646 | msm_otg_start_host(otg, 0); | ||
| 647 | otg->state = OTG_STATE_B_IDLE; | ||
| 648 | msm_otg_reset(otg); | ||
| 649 | schedule_work(w); | ||
| 650 | } | ||
| 651 | break; | ||
| 652 | default: | ||
| 653 | break; | ||
| 654 | } | ||
| 655 | } | ||
| 656 | |||
| 657 | static irqreturn_t msm_otg_irq(int irq, void *data) | ||
| 658 | { | ||
| 659 | struct msm_otg *motg = data; | ||
| 660 | struct otg_transceiver *otg = &motg->otg; | ||
| 661 | u32 otgsc = 0; | ||
| 662 | |||
| 663 | if (atomic_read(&motg->in_lpm)) { | ||
| 664 | disable_irq_nosync(irq); | ||
| 665 | motg->async_int = 1; | ||
| 666 | pm_runtime_get(otg->dev); | ||
| 667 | return IRQ_HANDLED; | ||
| 668 | } | ||
| 669 | |||
| 670 | otgsc = readl(USB_OTGSC); | ||
| 671 | if (!(otgsc & (OTGSC_IDIS | OTGSC_BSVIS))) | ||
| 672 | return IRQ_NONE; | ||
| 673 | |||
| 674 | if ((otgsc & OTGSC_IDIS) && (otgsc & OTGSC_IDIE)) { | ||
| 675 | if (otgsc & OTGSC_ID) | ||
| 676 | set_bit(ID, &motg->inputs); | ||
| 677 | else | ||
| 678 | clear_bit(ID, &motg->inputs); | ||
| 679 | dev_dbg(otg->dev, "ID set/clear\n"); | ||
| 680 | pm_runtime_get_noresume(otg->dev); | ||
| 681 | } else if ((otgsc & OTGSC_BSVIS) && (otgsc & OTGSC_BSVIE)) { | ||
| 682 | if (otgsc & OTGSC_BSV) | ||
| 683 | set_bit(B_SESS_VLD, &motg->inputs); | ||
| 684 | else | ||
| 685 | clear_bit(B_SESS_VLD, &motg->inputs); | ||
| 686 | dev_dbg(otg->dev, "BSV set/clear\n"); | ||
| 687 | pm_runtime_get_noresume(otg->dev); | ||
| 688 | } | ||
| 689 | |||
| 690 | writel(otgsc, USB_OTGSC); | ||
| 691 | schedule_work(&motg->sm_work); | ||
| 692 | return IRQ_HANDLED; | ||
| 693 | } | ||
| 694 | |||
| 695 | static int msm_otg_mode_show(struct seq_file *s, void *unused) | ||
| 696 | { | ||
| 697 | struct msm_otg *motg = s->private; | ||
| 698 | struct otg_transceiver *otg = &motg->otg; | ||
| 699 | |||
| 700 | switch (otg->state) { | ||
| 701 | case OTG_STATE_A_HOST: | ||
| 702 | seq_printf(s, "host\n"); | ||
| 703 | break; | ||
| 704 | case OTG_STATE_B_PERIPHERAL: | ||
| 705 | seq_printf(s, "peripheral\n"); | ||
| 706 | break; | ||
| 707 | default: | ||
| 708 | seq_printf(s, "none\n"); | ||
| 709 | break; | ||
| 710 | } | ||
| 711 | |||
| 712 | return 0; | ||
| 713 | } | ||
| 714 | |||
| 715 | static int msm_otg_mode_open(struct inode *inode, struct file *file) | ||
| 716 | { | ||
| 717 | return single_open(file, msm_otg_mode_show, inode->i_private); | ||
| 718 | } | ||
| 719 | |||
| 720 | static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, | ||
| 721 | size_t count, loff_t *ppos) | ||
| 722 | { | ||
| 723 | struct msm_otg *motg = file->private_data; | ||
| 724 | char buf[16]; | ||
| 725 | struct otg_transceiver *otg = &motg->otg; | ||
| 726 | int status = count; | ||
| 727 | enum usb_mode_type req_mode; | ||
| 728 | |||
| 729 | memset(buf, 0x00, sizeof(buf)); | ||
| 730 | |||
| 731 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) { | ||
| 732 | status = -EFAULT; | ||
| 733 | goto out; | ||
| 734 | } | ||
| 735 | |||
| 736 | if (!strncmp(buf, "host", 4)) { | ||
| 737 | req_mode = USB_HOST; | ||
| 738 | } else if (!strncmp(buf, "peripheral", 10)) { | ||
| 739 | req_mode = USB_PERIPHERAL; | ||
| 740 | } else if (!strncmp(buf, "none", 4)) { | ||
| 741 | req_mode = USB_NONE; | ||
| 742 | } else { | ||
| 743 | status = -EINVAL; | ||
| 744 | goto out; | ||
| 745 | } | ||
| 746 | |||
| 747 | switch (req_mode) { | ||
| 748 | case USB_NONE: | ||
| 749 | switch (otg->state) { | ||
| 750 | case OTG_STATE_A_HOST: | ||
| 751 | case OTG_STATE_B_PERIPHERAL: | ||
| 752 | set_bit(ID, &motg->inputs); | ||
| 753 | clear_bit(B_SESS_VLD, &motg->inputs); | ||
| 754 | break; | ||
| 755 | default: | ||
| 756 | goto out; | ||
| 757 | } | ||
| 758 | break; | ||
| 759 | case USB_PERIPHERAL: | ||
| 760 | switch (otg->state) { | ||
| 761 | case OTG_STATE_B_IDLE: | ||
| 762 | case OTG_STATE_A_HOST: | ||
| 763 | set_bit(ID, &motg->inputs); | ||
| 764 | set_bit(B_SESS_VLD, &motg->inputs); | ||
| 765 | break; | ||
| 766 | default: | ||
| 767 | goto out; | ||
| 768 | } | ||
| 769 | break; | ||
| 770 | case USB_HOST: | ||
| 771 | switch (otg->state) { | ||
| 772 | case OTG_STATE_B_IDLE: | ||
| 773 | case OTG_STATE_B_PERIPHERAL: | ||
| 774 | clear_bit(ID, &motg->inputs); | ||
| 775 | break; | ||
| 776 | default: | ||
| 777 | goto out; | ||
| 778 | } | ||
| 779 | break; | ||
| 780 | default: | ||
| 781 | goto out; | ||
| 782 | } | ||
| 783 | |||
| 784 | pm_runtime_get_sync(otg->dev); | ||
| 785 | schedule_work(&motg->sm_work); | ||
| 786 | out: | ||
| 787 | return status; | ||
| 788 | } | ||
| 789 | |||
| 790 | const struct file_operations msm_otg_mode_fops = { | ||
| 791 | .open = msm_otg_mode_open, | ||
| 792 | .read = seq_read, | ||
| 793 | .write = msm_otg_mode_write, | ||
| 794 | .llseek = seq_lseek, | ||
| 795 | .release = single_release, | ||
| 796 | }; | ||
| 797 | |||
| 798 | static struct dentry *msm_otg_dbg_root; | ||
| 799 | static struct dentry *msm_otg_dbg_mode; | ||
| 800 | |||
| 801 | static int msm_otg_debugfs_init(struct msm_otg *motg) | ||
| 802 | { | ||
| 803 | msm_otg_dbg_root = debugfs_create_dir("msm_otg", NULL); | ||
| 804 | |||
| 805 | if (!msm_otg_dbg_root || IS_ERR(msm_otg_dbg_root)) | ||
| 806 | return -ENODEV; | ||
| 807 | |||
| 808 | msm_otg_dbg_mode = debugfs_create_file("mode", S_IRUGO | S_IWUSR, | ||
| 809 | msm_otg_dbg_root, motg, &msm_otg_mode_fops); | ||
| 810 | if (!msm_otg_dbg_mode) { | ||
| 811 | debugfs_remove(msm_otg_dbg_root); | ||
| 812 | msm_otg_dbg_root = NULL; | ||
| 813 | return -ENODEV; | ||
| 814 | } | ||
| 815 | |||
| 816 | return 0; | ||
| 817 | } | ||
| 818 | |||
| 819 | static void msm_otg_debugfs_cleanup(void) | ||
| 820 | { | ||
| 821 | debugfs_remove(msm_otg_dbg_mode); | ||
| 822 | debugfs_remove(msm_otg_dbg_root); | ||
| 823 | } | ||
| 824 | |||
| 825 | static int __init msm_otg_probe(struct platform_device *pdev) | ||
| 826 | { | ||
| 827 | int ret = 0; | ||
| 828 | struct resource *res; | ||
| 829 | struct msm_otg *motg; | ||
| 830 | struct otg_transceiver *otg; | ||
| 831 | |||
| 832 | dev_info(&pdev->dev, "msm_otg probe\n"); | ||
| 833 | if (!pdev->dev.platform_data) { | ||
| 834 | dev_err(&pdev->dev, "No platform data given. Bailing out\n"); | ||
| 835 | return -ENODEV; | ||
| 836 | } | ||
| 837 | |||
| 838 | motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL); | ||
| 839 | if (!motg) { | ||
| 840 | dev_err(&pdev->dev, "unable to allocate msm_otg\n"); | ||
| 841 | return -ENOMEM; | ||
| 842 | } | ||
| 843 | |||
| 844 | motg->pdata = pdev->dev.platform_data; | ||
| 845 | otg = &motg->otg; | ||
| 846 | otg->dev = &pdev->dev; | ||
| 847 | |||
| 848 | motg->phy_reset_clk = clk_get(&pdev->dev, "usb_phy_clk"); | ||
| 849 | if (IS_ERR(motg->phy_reset_clk)) { | ||
| 850 | dev_err(&pdev->dev, "failed to get usb_phy_clk\n"); | ||
| 851 | ret = PTR_ERR(motg->phy_reset_clk); | ||
| 852 | goto free_motg; | ||
| 853 | } | ||
| 854 | |||
| 855 | motg->clk = clk_get(&pdev->dev, "usb_hs_clk"); | ||
| 856 | if (IS_ERR(motg->clk)) { | ||
| 857 | dev_err(&pdev->dev, "failed to get usb_hs_clk\n"); | ||
| 858 | ret = PTR_ERR(motg->clk); | ||
| 859 | goto put_phy_reset_clk; | ||
| 860 | } | ||
| 861 | |||
| 862 | motg->pclk = clk_get(&pdev->dev, "usb_hs_pclk"); | ||
| 863 | if (IS_ERR(motg->pclk)) { | ||
| 864 | dev_err(&pdev->dev, "failed to get usb_hs_pclk\n"); | ||
| 865 | ret = PTR_ERR(motg->pclk); | ||
| 866 | goto put_clk; | ||
| 867 | } | ||
| 868 | |||
| 869 | /* | ||
| 870 | * USB core clock is not present on all MSM chips. This | ||
| 871 | * clock is introduced to remove the dependency on AXI | ||
| 872 | * bus frequency. | ||
| 873 | */ | ||
| 874 | motg->core_clk = clk_get(&pdev->dev, "usb_hs_core_clk"); | ||
| 875 | if (IS_ERR(motg->core_clk)) | ||
| 876 | motg->core_clk = NULL; | ||
| 877 | |||
| 878 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 879 | if (!res) { | ||
| 880 | dev_err(&pdev->dev, "failed to get platform resource mem\n"); | ||
| 881 | ret = -ENODEV; | ||
| 882 | goto put_core_clk; | ||
| 883 | } | ||
| 884 | |||
| 885 | motg->regs = ioremap(res->start, resource_size(res)); | ||
| 886 | if (!motg->regs) { | ||
| 887 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
| 888 | ret = -ENOMEM; | ||
| 889 | goto put_core_clk; | ||
| 890 | } | ||
| 891 | dev_info(&pdev->dev, "OTG regs = %p\n", motg->regs); | ||
| 892 | |||
| 893 | motg->irq = platform_get_irq(pdev, 0); | ||
| 894 | if (!motg->irq) { | ||
| 895 | dev_err(&pdev->dev, "platform_get_irq failed\n"); | ||
| 896 | ret = -ENODEV; | ||
| 897 | goto free_regs; | ||
| 898 | } | ||
| 899 | |||
| 900 | clk_enable(motg->clk); | ||
| 901 | clk_enable(motg->pclk); | ||
| 902 | if (motg->core_clk) | ||
| 903 | clk_enable(motg->core_clk); | ||
| 904 | |||
| 905 | writel(0, USB_USBINTR); | ||
| 906 | writel(0, USB_OTGSC); | ||
| 907 | |||
| 908 | INIT_WORK(&motg->sm_work, msm_otg_sm_work); | ||
| 909 | ret = request_irq(motg->irq, msm_otg_irq, IRQF_SHARED, | ||
| 910 | "msm_otg", motg); | ||
| 911 | if (ret) { | ||
| 912 | dev_err(&pdev->dev, "request irq failed\n"); | ||
| 913 | goto disable_clks; | ||
| 914 | } | ||
| 915 | |||
| 916 | otg->init = msm_otg_reset; | ||
| 917 | otg->set_host = msm_otg_set_host; | ||
| 918 | otg->set_peripheral = msm_otg_set_peripheral; | ||
| 919 | |||
| 920 | otg->io_ops = &msm_otg_io_ops; | ||
| 921 | |||
| 922 | ret = otg_set_transceiver(&motg->otg); | ||
| 923 | if (ret) { | ||
| 924 | dev_err(&pdev->dev, "otg_set_transceiver failed\n"); | ||
| 925 | goto free_irq; | ||
| 926 | } | ||
| 927 | |||
| 928 | platform_set_drvdata(pdev, motg); | ||
| 929 | device_init_wakeup(&pdev->dev, 1); | ||
| 930 | |||
| 931 | if (motg->pdata->mode == USB_OTG && | ||
| 932 | motg->pdata->otg_control == OTG_USER_CONTROL) { | ||
| 933 | ret = msm_otg_debugfs_init(motg); | ||
| 934 | if (ret) | ||
| 935 | dev_dbg(&pdev->dev, "mode debugfs file is" | ||
| 936 | "not available\n"); | ||
| 937 | } | ||
| 938 | |||
| 939 | pm_runtime_set_active(&pdev->dev); | ||
| 940 | pm_runtime_enable(&pdev->dev); | ||
| 941 | |||
| 942 | return 0; | ||
| 943 | free_irq: | ||
| 944 | free_irq(motg->irq, motg); | ||
| 945 | disable_clks: | ||
| 946 | clk_disable(motg->pclk); | ||
| 947 | clk_disable(motg->clk); | ||
| 948 | free_regs: | ||
| 949 | iounmap(motg->regs); | ||
| 950 | put_core_clk: | ||
| 951 | if (motg->core_clk) | ||
| 952 | clk_put(motg->core_clk); | ||
| 953 | clk_put(motg->pclk); | ||
| 954 | put_clk: | ||
| 955 | clk_put(motg->clk); | ||
| 956 | put_phy_reset_clk: | ||
| 957 | clk_put(motg->phy_reset_clk); | ||
| 958 | free_motg: | ||
| 959 | kfree(motg); | ||
| 960 | return ret; | ||
| 961 | } | ||
| 962 | |||
| 963 | static int __devexit msm_otg_remove(struct platform_device *pdev) | ||
| 964 | { | ||
| 965 | struct msm_otg *motg = platform_get_drvdata(pdev); | ||
| 966 | struct otg_transceiver *otg = &motg->otg; | ||
| 967 | int cnt = 0; | ||
| 968 | |||
| 969 | if (otg->host || otg->gadget) | ||
| 970 | return -EBUSY; | ||
| 971 | |||
| 972 | msm_otg_debugfs_cleanup(); | ||
| 973 | cancel_work_sync(&motg->sm_work); | ||
| 974 | |||
| 975 | msm_otg_resume(motg); | ||
| 976 | |||
| 977 | device_init_wakeup(&pdev->dev, 0); | ||
| 978 | pm_runtime_disable(&pdev->dev); | ||
| 979 | |||
| 980 | otg_set_transceiver(NULL); | ||
| 981 | free_irq(motg->irq, motg); | ||
| 982 | |||
| 983 | /* | ||
| 984 | * Put PHY in low power mode. | ||
| 985 | */ | ||
| 986 | ulpi_read(otg, 0x14); | ||
| 987 | ulpi_write(otg, 0x08, 0x09); | ||
| 988 | |||
| 989 | writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC); | ||
| 990 | while (cnt < PHY_SUSPEND_TIMEOUT_USEC) { | ||
| 991 | if (readl(USB_PORTSC) & PORTSC_PHCD) | ||
| 992 | break; | ||
| 993 | udelay(1); | ||
| 994 | cnt++; | ||
| 995 | } | ||
| 996 | if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) | ||
| 997 | dev_err(otg->dev, "Unable to suspend PHY\n"); | ||
| 998 | |||
| 999 | clk_disable(motg->pclk); | ||
| 1000 | clk_disable(motg->clk); | ||
| 1001 | if (motg->core_clk) | ||
| 1002 | clk_disable(motg->core_clk); | ||
| 1003 | |||
| 1004 | iounmap(motg->regs); | ||
| 1005 | pm_runtime_set_suspended(&pdev->dev); | ||
| 1006 | |||
| 1007 | clk_put(motg->phy_reset_clk); | ||
| 1008 | clk_put(motg->pclk); | ||
| 1009 | clk_put(motg->clk); | ||
| 1010 | if (motg->core_clk) | ||
| 1011 | clk_put(motg->core_clk); | ||
| 1012 | |||
| 1013 | kfree(motg); | ||
| 1014 | |||
| 1015 | return 0; | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | #ifdef CONFIG_PM_RUNTIME | ||
| 1019 | static int msm_otg_runtime_idle(struct device *dev) | ||
| 1020 | { | ||
| 1021 | struct msm_otg *motg = dev_get_drvdata(dev); | ||
| 1022 | struct otg_transceiver *otg = &motg->otg; | ||
| 1023 | |||
| 1024 | dev_dbg(dev, "OTG runtime idle\n"); | ||
| 1025 | |||
| 1026 | /* | ||
| 1027 | * It is observed some times that a spurious interrupt | ||
| 1028 | * comes when PHY is put into LPM immediately after PHY reset. | ||
| 1029 | * This 1 sec delay also prevents entering into LPM immediately | ||
| 1030 | * after asynchronous interrupt. | ||
| 1031 | */ | ||
| 1032 | if (otg->state != OTG_STATE_UNDEFINED) | ||
| 1033 | pm_schedule_suspend(dev, 1000); | ||
| 1034 | |||
| 1035 | return -EAGAIN; | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | static int msm_otg_runtime_suspend(struct device *dev) | ||
| 1039 | { | ||
| 1040 | struct msm_otg *motg = dev_get_drvdata(dev); | ||
| 1041 | |||
| 1042 | dev_dbg(dev, "OTG runtime suspend\n"); | ||
| 1043 | return msm_otg_suspend(motg); | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | static int msm_otg_runtime_resume(struct device *dev) | ||
| 1047 | { | ||
| 1048 | struct msm_otg *motg = dev_get_drvdata(dev); | ||
| 1049 | |||
| 1050 | dev_dbg(dev, "OTG runtime resume\n"); | ||
| 1051 | return msm_otg_resume(motg); | ||
| 1052 | } | ||
| 1053 | #else | ||
| 1054 | #define msm_otg_runtime_idle NULL | ||
| 1055 | #define msm_otg_runtime_suspend NULL | ||
| 1056 | #define msm_otg_runtime_resume NULL | ||
| 1057 | #endif | ||
| 1058 | |||
| 1059 | #ifdef CONFIG_PM | ||
| 1060 | static int msm_otg_pm_suspend(struct device *dev) | ||
| 1061 | { | ||
| 1062 | struct msm_otg *motg = dev_get_drvdata(dev); | ||
| 1063 | |||
| 1064 | dev_dbg(dev, "OTG PM suspend\n"); | ||
| 1065 | return msm_otg_suspend(motg); | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | static int msm_otg_pm_resume(struct device *dev) | ||
| 1069 | { | ||
| 1070 | struct msm_otg *motg = dev_get_drvdata(dev); | ||
| 1071 | int ret; | ||
| 1072 | |||
| 1073 | dev_dbg(dev, "OTG PM resume\n"); | ||
| 1074 | |||
| 1075 | ret = msm_otg_resume(motg); | ||
| 1076 | if (ret) | ||
| 1077 | return ret; | ||
| 1078 | |||
| 1079 | /* | ||
| 1080 | * Runtime PM Documentation recommends bringing the | ||
| 1081 | * device to full powered state upon resume. | ||
| 1082 | */ | ||
| 1083 | pm_runtime_disable(dev); | ||
| 1084 | pm_runtime_set_active(dev); | ||
| 1085 | pm_runtime_enable(dev); | ||
| 1086 | |||
| 1087 | return 0; | ||
| 1088 | } | ||
| 1089 | #else | ||
| 1090 | #define msm_otg_pm_suspend NULL | ||
| 1091 | #define msm_otg_pm_resume NULL | ||
| 1092 | #endif | ||
| 1093 | |||
| 1094 | static const struct dev_pm_ops msm_otg_dev_pm_ops = { | ||
| 1095 | .runtime_suspend = msm_otg_runtime_suspend, | ||
| 1096 | .runtime_resume = msm_otg_runtime_resume, | ||
| 1097 | .runtime_idle = msm_otg_runtime_idle, | ||
| 1098 | .suspend = msm_otg_pm_suspend, | ||
| 1099 | .resume = msm_otg_pm_resume, | ||
| 1100 | }; | ||
| 1101 | |||
| 1102 | static struct platform_driver msm_otg_driver = { | ||
| 1103 | .remove = __devexit_p(msm_otg_remove), | ||
| 1104 | .driver = { | ||
| 1105 | .name = DRIVER_NAME, | ||
| 1106 | .owner = THIS_MODULE, | ||
| 1107 | .pm = &msm_otg_dev_pm_ops, | ||
| 1108 | }, | ||
| 1109 | }; | ||
| 1110 | |||
| 1111 | static int __init msm_otg_init(void) | ||
| 1112 | { | ||
| 1113 | return platform_driver_probe(&msm_otg_driver, msm_otg_probe); | ||
| 1114 | } | ||
| 1115 | |||
| 1116 | static void __exit msm_otg_exit(void) | ||
| 1117 | { | ||
| 1118 | platform_driver_unregister(&msm_otg_driver); | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | module_init(msm_otg_init); | ||
| 1122 | module_exit(msm_otg_exit); | ||
| 1123 | |||
| 1124 | MODULE_LICENSE("GPL v2"); | ||
| 1125 | MODULE_DESCRIPTION("MSM USB transceiver driver"); | ||
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index d335f484fcd8..6ca505f333e4 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
| @@ -678,7 +678,8 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) | |||
| 678 | /* disable complete OTG block */ | 678 | /* disable complete OTG block */ |
| 679 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); | 679 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); |
| 680 | 680 | ||
| 681 | twl4030_phy_power(twl, 0); | 681 | if (!twl->asleep) |
| 682 | twl4030_phy_power(twl, 0); | ||
| 682 | regulator_put(twl->usb1v5); | 683 | regulator_put(twl->usb1v5); |
| 683 | regulator_put(twl->usb1v8); | 684 | regulator_put(twl->usb1v8); |
| 684 | regulator_put(twl->usb3v1); | 685 | regulator_put(twl->usb3v1); |
diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c new file mode 100644 index 000000000000..28f770103640 --- /dev/null +++ b/drivers/usb/otg/twl6030-usb.c | |||
| @@ -0,0 +1,493 @@ | |||
| 1 | /* | ||
| 2 | * twl6030_usb - TWL6030 USB transceiver, talking to OMAP OTG driver. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * Author: Hema HK <hemahk@ti.com> | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/interrupt.h> | ||
| 26 | #include <linux/platform_device.h> | ||
| 27 | #include <linux/io.h> | ||
| 28 | #include <linux/usb/otg.h> | ||
| 29 | #include <linux/i2c/twl.h> | ||
| 30 | #include <linux/regulator/consumer.h> | ||
| 31 | #include <linux/err.h> | ||
| 32 | #include <linux/notifier.h> | ||
| 33 | #include <linux/slab.h> | ||
| 34 | |||
| 35 | /* usb register definitions */ | ||
| 36 | #define USB_VENDOR_ID_LSB 0x00 | ||
| 37 | #define USB_VENDOR_ID_MSB 0x01 | ||
| 38 | #define USB_PRODUCT_ID_LSB 0x02 | ||
| 39 | #define USB_PRODUCT_ID_MSB 0x03 | ||
| 40 | #define USB_VBUS_CTRL_SET 0x04 | ||
| 41 | #define USB_VBUS_CTRL_CLR 0x05 | ||
| 42 | #define USB_ID_CTRL_SET 0x06 | ||
| 43 | #define USB_ID_CTRL_CLR 0x07 | ||
| 44 | #define USB_VBUS_INT_SRC 0x08 | ||
| 45 | #define USB_VBUS_INT_LATCH_SET 0x09 | ||
| 46 | #define USB_VBUS_INT_LATCH_CLR 0x0A | ||
| 47 | #define USB_VBUS_INT_EN_LO_SET 0x0B | ||
| 48 | #define USB_VBUS_INT_EN_LO_CLR 0x0C | ||
| 49 | #define USB_VBUS_INT_EN_HI_SET 0x0D | ||
| 50 | #define USB_VBUS_INT_EN_HI_CLR 0x0E | ||
| 51 | #define USB_ID_INT_SRC 0x0F | ||
| 52 | #define USB_ID_INT_LATCH_SET 0x10 | ||
| 53 | #define USB_ID_INT_LATCH_CLR 0x11 | ||
| 54 | |||
| 55 | #define USB_ID_INT_EN_LO_SET 0x12 | ||
| 56 | #define USB_ID_INT_EN_LO_CLR 0x13 | ||
| 57 | #define USB_ID_INT_EN_HI_SET 0x14 | ||
| 58 | #define USB_ID_INT_EN_HI_CLR 0x15 | ||
| 59 | #define USB_OTG_ADP_CTRL 0x16 | ||
| 60 | #define USB_OTG_ADP_HIGH 0x17 | ||
| 61 | #define USB_OTG_ADP_LOW 0x18 | ||
| 62 | #define USB_OTG_ADP_RISE 0x19 | ||
| 63 | #define USB_OTG_REVISION 0x1A | ||
| 64 | |||
| 65 | /* to be moved to LDO */ | ||
| 66 | #define TWL6030_MISC2 0xE5 | ||
| 67 | #define TWL6030_CFG_LDO_PD2 0xF5 | ||
| 68 | #define TWL6030_BACKUP_REG 0xFA | ||
| 69 | |||
| 70 | #define STS_HW_CONDITIONS 0x21 | ||
| 71 | |||
| 72 | /* In module TWL6030_MODULE_PM_MASTER */ | ||
| 73 | #define STS_HW_CONDITIONS 0x21 | ||
| 74 | #define STS_USB_ID BIT(2) | ||
| 75 | |||
| 76 | /* In module TWL6030_MODULE_PM_RECEIVER */ | ||
| 77 | #define VUSB_CFG_TRANS 0x71 | ||
| 78 | #define VUSB_CFG_STATE 0x72 | ||
| 79 | #define VUSB_CFG_VOLTAGE 0x73 | ||
| 80 | |||
| 81 | /* in module TWL6030_MODULE_MAIN_CHARGE */ | ||
| 82 | |||
| 83 | #define CHARGERUSB_CTRL1 0x8 | ||
| 84 | |||
| 85 | #define CONTROLLER_STAT1 0x03 | ||
| 86 | #define VBUS_DET BIT(2) | ||
| 87 | |||
| 88 | struct twl6030_usb { | ||
| 89 | struct otg_transceiver otg; | ||
| 90 | struct device *dev; | ||
| 91 | |||
| 92 | /* for vbus reporting with irqs disabled */ | ||
| 93 | spinlock_t lock; | ||
| 94 | |||
| 95 | struct regulator *usb3v3; | ||
| 96 | |||
| 97 | int irq1; | ||
| 98 | int irq2; | ||
| 99 | u8 linkstat; | ||
| 100 | u8 asleep; | ||
| 101 | bool irq_enabled; | ||
| 102 | }; | ||
| 103 | |||
| 104 | #define xceiv_to_twl(x) container_of((x), struct twl6030_usb, otg); | ||
| 105 | |||
| 106 | /*-------------------------------------------------------------------------*/ | ||
| 107 | |||
| 108 | static inline int twl6030_writeb(struct twl6030_usb *twl, u8 module, | ||
| 109 | u8 data, u8 address) | ||
| 110 | { | ||
| 111 | int ret = 0; | ||
| 112 | |||
| 113 | ret = twl_i2c_write_u8(module, data, address); | ||
| 114 | if (ret < 0) | ||
| 115 | dev_err(twl->dev, | ||
| 116 | "Write[0x%x] Error %d\n", address, ret); | ||
| 117 | return ret; | ||
| 118 | } | ||
| 119 | |||
| 120 | static inline u8 twl6030_readb(struct twl6030_usb *twl, u8 module, u8 address) | ||
| 121 | { | ||
| 122 | u8 data, ret = 0; | ||
| 123 | |||
| 124 | ret = twl_i2c_read_u8(module, &data, address); | ||
| 125 | if (ret >= 0) | ||
| 126 | ret = data; | ||
| 127 | else | ||
| 128 | dev_err(twl->dev, | ||
| 129 | "readb[0x%x,0x%x] Error %d\n", | ||
| 130 | module, address, ret); | ||
| 131 | return ret; | ||
| 132 | } | ||
| 133 | |||
| 134 | /*-------------------------------------------------------------------------*/ | ||
| 135 | static int twl6030_set_phy_clk(struct otg_transceiver *x, int on) | ||
| 136 | { | ||
| 137 | struct twl6030_usb *twl; | ||
| 138 | struct device *dev; | ||
| 139 | struct twl4030_usb_data *pdata; | ||
| 140 | |||
| 141 | twl = xceiv_to_twl(x); | ||
| 142 | dev = twl->dev; | ||
| 143 | pdata = dev->platform_data; | ||
| 144 | |||
| 145 | pdata->phy_set_clock(twl->dev, on); | ||
| 146 | |||
| 147 | return 0; | ||
| 148 | } | ||
| 149 | |||
| 150 | static int twl6030_phy_init(struct otg_transceiver *x) | ||
| 151 | { | ||
| 152 | u8 hw_state; | ||
| 153 | struct twl6030_usb *twl; | ||
| 154 | struct device *dev; | ||
| 155 | struct twl4030_usb_data *pdata; | ||
| 156 | |||
| 157 | twl = xceiv_to_twl(x); | ||
| 158 | dev = twl->dev; | ||
| 159 | pdata = dev->platform_data; | ||
| 160 | |||
| 161 | regulator_enable(twl->usb3v3); | ||
| 162 | |||
| 163 | hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); | ||
| 164 | |||
| 165 | if (hw_state & STS_USB_ID) | ||
| 166 | pdata->phy_power(twl->dev, 1, 1); | ||
| 167 | else | ||
| 168 | pdata->phy_power(twl->dev, 0, 1); | ||
| 169 | |||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | |||
| 173 | static void twl6030_phy_shutdown(struct otg_transceiver *x) | ||
| 174 | { | ||
| 175 | struct twl6030_usb *twl; | ||
| 176 | struct device *dev; | ||
| 177 | struct twl4030_usb_data *pdata; | ||
| 178 | |||
| 179 | twl = xceiv_to_twl(x); | ||
| 180 | dev = twl->dev; | ||
| 181 | pdata = dev->platform_data; | ||
| 182 | pdata->phy_power(twl->dev, 0, 0); | ||
| 183 | regulator_disable(twl->usb3v3); | ||
| 184 | } | ||
| 185 | |||
| 186 | static int twl6030_usb_ldo_init(struct twl6030_usb *twl) | ||
| 187 | { | ||
| 188 | |||
| 189 | /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */ | ||
| 190 | twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG); | ||
| 191 | |||
| 192 | /* Program CFG_LDO_PD2 register and set VUSB bit */ | ||
| 193 | twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_CFG_LDO_PD2); | ||
| 194 | |||
| 195 | /* Program MISC2 register and set bit VUSB_IN_VBAT */ | ||
| 196 | twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2); | ||
| 197 | |||
| 198 | twl->usb3v3 = regulator_get(twl->dev, "vusb"); | ||
| 199 | if (IS_ERR(twl->usb3v3)) | ||
| 200 | return -ENODEV; | ||
| 201 | |||
| 202 | regulator_enable(twl->usb3v3); | ||
| 203 | |||
| 204 | /* Program the VUSB_CFG_TRANS for ACTIVE state. */ | ||
| 205 | twl6030_writeb(twl, TWL_MODULE_PM_RECEIVER, 0x3F, | ||
| 206 | VUSB_CFG_TRANS); | ||
| 207 | |||
| 208 | /* Program the VUSB_CFG_STATE register to ON on all groups. */ | ||
| 209 | twl6030_writeb(twl, TWL_MODULE_PM_RECEIVER, 0xE1, | ||
| 210 | VUSB_CFG_STATE); | ||
| 211 | |||
| 212 | /* Program the USB_VBUS_CTRL_SET and set VBUS_ACT_COMP bit */ | ||
| 213 | twl6030_writeb(twl, TWL_MODULE_USB, 0x4, USB_VBUS_CTRL_SET); | ||
| 214 | |||
| 215 | /* | ||
| 216 | * Program the USB_ID_CTRL_SET register to enable GND drive | ||
| 217 | * and the ID comparators | ||
| 218 | */ | ||
| 219 | twl6030_writeb(twl, TWL_MODULE_USB, 0x14, USB_ID_CTRL_SET); | ||
| 220 | |||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | static ssize_t twl6030_usb_vbus_show(struct device *dev, | ||
| 225 | struct device_attribute *attr, char *buf) | ||
| 226 | { | ||
| 227 | struct twl6030_usb *twl = dev_get_drvdata(dev); | ||
| 228 | unsigned long flags; | ||
| 229 | int ret = -EINVAL; | ||
| 230 | |||
| 231 | spin_lock_irqsave(&twl->lock, flags); | ||
| 232 | |||
| 233 | switch (twl->linkstat) { | ||
| 234 | case USB_EVENT_VBUS: | ||
| 235 | ret = snprintf(buf, PAGE_SIZE, "vbus\n"); | ||
| 236 | break; | ||
| 237 | case USB_EVENT_ID: | ||
| 238 | ret = snprintf(buf, PAGE_SIZE, "id\n"); | ||
| 239 | break; | ||
| 240 | case USB_EVENT_NONE: | ||
| 241 | ret = snprintf(buf, PAGE_SIZE, "none\n"); | ||
| 242 | break; | ||
| 243 | default: | ||
| 244 | ret = snprintf(buf, PAGE_SIZE, "UNKNOWN\n"); | ||
| 245 | } | ||
| 246 | spin_unlock_irqrestore(&twl->lock, flags); | ||
| 247 | |||
| 248 | return ret; | ||
| 249 | } | ||
| 250 | static DEVICE_ATTR(vbus, 0444, twl6030_usb_vbus_show, NULL); | ||
| 251 | |||
| 252 | static irqreturn_t twl6030_usb_irq(int irq, void *_twl) | ||
| 253 | { | ||
| 254 | struct twl6030_usb *twl = _twl; | ||
| 255 | int status; | ||
| 256 | u8 vbus_state, hw_state; | ||
| 257 | |||
| 258 | hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); | ||
| 259 | |||
| 260 | vbus_state = twl6030_readb(twl, TWL_MODULE_MAIN_CHARGE, | ||
| 261 | CONTROLLER_STAT1); | ||
| 262 | if (!(hw_state & STS_USB_ID)) { | ||
| 263 | if (vbus_state & VBUS_DET) { | ||
| 264 | status = USB_EVENT_VBUS; | ||
| 265 | twl->otg.default_a = false; | ||
| 266 | twl->otg.state = OTG_STATE_B_IDLE; | ||
| 267 | } else { | ||
| 268 | status = USB_EVENT_NONE; | ||
| 269 | } | ||
| 270 | if (status >= 0) { | ||
| 271 | twl->linkstat = status; | ||
| 272 | blocking_notifier_call_chain(&twl->otg.notifier, | ||
| 273 | status, twl->otg.gadget); | ||
| 274 | } | ||
| 275 | } | ||
| 276 | sysfs_notify(&twl->dev->kobj, NULL, "vbus"); | ||
| 277 | |||
| 278 | return IRQ_HANDLED; | ||
| 279 | } | ||
| 280 | |||
| 281 | static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) | ||
| 282 | { | ||
| 283 | struct twl6030_usb *twl = _twl; | ||
| 284 | int status = USB_EVENT_NONE; | ||
| 285 | u8 hw_state; | ||
| 286 | |||
| 287 | hw_state = twl6030_readb(twl, TWL6030_MODULE_ID0, STS_HW_CONDITIONS); | ||
| 288 | |||
| 289 | if (hw_state & STS_USB_ID) { | ||
| 290 | |||
| 291 | twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1); | ||
| 292 | twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, | ||
| 293 | 0x10); | ||
| 294 | status = USB_EVENT_ID; | ||
| 295 | twl->otg.default_a = true; | ||
| 296 | twl->otg.state = OTG_STATE_A_IDLE; | ||
| 297 | blocking_notifier_call_chain(&twl->otg.notifier, status, | ||
| 298 | twl->otg.gadget); | ||
| 299 | } else { | ||
| 300 | twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, | ||
| 301 | 0x10); | ||
| 302 | twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, | ||
| 303 | 0x1); | ||
| 304 | } | ||
| 305 | twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_LATCH_CLR, status); | ||
| 306 | twl->linkstat = status; | ||
| 307 | |||
| 308 | return IRQ_HANDLED; | ||
| 309 | } | ||
| 310 | |||
| 311 | static int twl6030_set_peripheral(struct otg_transceiver *x, | ||
| 312 | struct usb_gadget *gadget) | ||
| 313 | { | ||
| 314 | struct twl6030_usb *twl; | ||
| 315 | |||
| 316 | if (!x) | ||
| 317 | return -ENODEV; | ||
| 318 | |||
| 319 | twl = xceiv_to_twl(x); | ||
| 320 | twl->otg.gadget = gadget; | ||
| 321 | if (!gadget) | ||
| 322 | twl->otg.state = OTG_STATE_UNDEFINED; | ||
| 323 | |||
| 324 | return 0; | ||
| 325 | } | ||
| 326 | |||
| 327 | static int twl6030_enable_irq(struct otg_transceiver *x) | ||
| 328 | { | ||
| 329 | struct twl6030_usb *twl = xceiv_to_twl(x); | ||
| 330 | |||
| 331 | twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x1); | ||
| 332 | twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); | ||
| 333 | twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); | ||
| 334 | |||
| 335 | twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, | ||
| 336 | REG_INT_MSK_LINE_C); | ||
| 337 | twl6030_interrupt_unmask(TWL6030_CHARGER_CTRL_INT_MASK, | ||
| 338 | REG_INT_MSK_STS_C); | ||
| 339 | twl6030_usb_irq(twl->irq2, twl); | ||
| 340 | twl6030_usbotg_irq(twl->irq1, twl); | ||
| 341 | |||
| 342 | return 0; | ||
| 343 | } | ||
| 344 | |||
| 345 | static int twl6030_set_vbus(struct otg_transceiver *x, bool enabled) | ||
| 346 | { | ||
| 347 | struct twl6030_usb *twl = xceiv_to_twl(x); | ||
| 348 | |||
| 349 | /* | ||
| 350 | * Start driving VBUS. Set OPA_MODE bit in CHARGERUSB_CTRL1 | ||
| 351 | * register. This enables boost mode. | ||
| 352 | */ | ||
| 353 | if (enabled) | ||
| 354 | twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x40, | ||
| 355 | CHARGERUSB_CTRL1); | ||
| 356 | else | ||
| 357 | twl6030_writeb(twl, TWL_MODULE_MAIN_CHARGE , 0x00, | ||
| 358 | CHARGERUSB_CTRL1); | ||
| 359 | return 0; | ||
| 360 | } | ||
| 361 | |||
| 362 | static int twl6030_set_host(struct otg_transceiver *x, struct usb_bus *host) | ||
| 363 | { | ||
| 364 | struct twl6030_usb *twl; | ||
| 365 | |||
| 366 | if (!x) | ||
| 367 | return -ENODEV; | ||
| 368 | |||
| 369 | twl = xceiv_to_twl(x); | ||
| 370 | twl->otg.host = host; | ||
| 371 | if (!host) | ||
| 372 | twl->otg.state = OTG_STATE_UNDEFINED; | ||
| 373 | return 0; | ||
| 374 | } | ||
| 375 | |||
| 376 | static int __devinit twl6030_usb_probe(struct platform_device *pdev) | ||
| 377 | { | ||
| 378 | struct twl6030_usb *twl; | ||
| 379 | int status, err; | ||
| 380 | struct twl4030_usb_data *pdata; | ||
| 381 | struct device *dev = &pdev->dev; | ||
| 382 | pdata = dev->platform_data; | ||
| 383 | |||
| 384 | twl = kzalloc(sizeof *twl, GFP_KERNEL); | ||
| 385 | if (!twl) | ||
| 386 | return -ENOMEM; | ||
| 387 | |||
| 388 | twl->dev = &pdev->dev; | ||
| 389 | twl->irq1 = platform_get_irq(pdev, 0); | ||
| 390 | twl->irq2 = platform_get_irq(pdev, 1); | ||
| 391 | twl->otg.dev = twl->dev; | ||
| 392 | twl->otg.label = "twl6030"; | ||
| 393 | twl->otg.set_host = twl6030_set_host; | ||
| 394 | twl->otg.set_peripheral = twl6030_set_peripheral; | ||
| 395 | twl->otg.set_vbus = twl6030_set_vbus; | ||
| 396 | twl->otg.init = twl6030_phy_init; | ||
| 397 | twl->otg.shutdown = twl6030_phy_shutdown; | ||
| 398 | |||
| 399 | /* init spinlock for workqueue */ | ||
| 400 | spin_lock_init(&twl->lock); | ||
| 401 | |||
| 402 | err = twl6030_usb_ldo_init(twl); | ||
| 403 | if (err) { | ||
| 404 | dev_err(&pdev->dev, "ldo init failed\n"); | ||
| 405 | kfree(twl); | ||
| 406 | return err; | ||
| 407 | } | ||
| 408 | otg_set_transceiver(&twl->otg); | ||
| 409 | |||
| 410 | platform_set_drvdata(pdev, twl); | ||
| 411 | if (device_create_file(&pdev->dev, &dev_attr_vbus)) | ||
| 412 | dev_warn(&pdev->dev, "could not create sysfs file\n"); | ||
| 413 | |||
| 414 | BLOCKING_INIT_NOTIFIER_HEAD(&twl->otg.notifier); | ||
| 415 | |||
| 416 | twl->irq_enabled = true; | ||
| 417 | status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq, | ||
| 418 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | ||
| 419 | "twl6030_usb", twl); | ||
| 420 | if (status < 0) { | ||
| 421 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", | ||
| 422 | twl->irq1, status); | ||
| 423 | device_remove_file(twl->dev, &dev_attr_vbus); | ||
| 424 | kfree(twl); | ||
| 425 | return status; | ||
| 426 | } | ||
| 427 | |||
| 428 | status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq, | ||
| 429 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | ||
| 430 | "twl6030_usb", twl); | ||
| 431 | if (status < 0) { | ||
| 432 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", | ||
| 433 | twl->irq2, status); | ||
| 434 | free_irq(twl->irq1, twl); | ||
| 435 | device_remove_file(twl->dev, &dev_attr_vbus); | ||
| 436 | kfree(twl); | ||
| 437 | return status; | ||
| 438 | } | ||
| 439 | |||
| 440 | pdata->phy_init(dev); | ||
| 441 | twl6030_enable_irq(&twl->otg); | ||
| 442 | dev_info(&pdev->dev, "Initialized TWL6030 USB module\n"); | ||
| 443 | |||
| 444 | return 0; | ||
| 445 | } | ||
| 446 | |||
| 447 | static int __exit twl6030_usb_remove(struct platform_device *pdev) | ||
| 448 | { | ||
| 449 | struct twl6030_usb *twl = platform_get_drvdata(pdev); | ||
| 450 | |||
| 451 | struct twl4030_usb_data *pdata; | ||
| 452 | struct device *dev = &pdev->dev; | ||
| 453 | pdata = dev->platform_data; | ||
| 454 | |||
| 455 | twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, | ||
| 456 | REG_INT_MSK_LINE_C); | ||
| 457 | twl6030_interrupt_mask(TWL6030_USBOTG_INT_MASK, | ||
| 458 | REG_INT_MSK_STS_C); | ||
| 459 | free_irq(twl->irq1, twl); | ||
| 460 | free_irq(twl->irq2, twl); | ||
| 461 | regulator_put(twl->usb3v3); | ||
| 462 | pdata->phy_exit(twl->dev); | ||
| 463 | device_remove_file(twl->dev, &dev_attr_vbus); | ||
| 464 | kfree(twl); | ||
| 465 | |||
| 466 | return 0; | ||
| 467 | } | ||
| 468 | |||
| 469 | static struct platform_driver twl6030_usb_driver = { | ||
| 470 | .probe = twl6030_usb_probe, | ||
| 471 | .remove = __exit_p(twl6030_usb_remove), | ||
| 472 | .driver = { | ||
| 473 | .name = "twl6030_usb", | ||
| 474 | .owner = THIS_MODULE, | ||
| 475 | }, | ||
| 476 | }; | ||
| 477 | |||
| 478 | static int __init twl6030_usb_init(void) | ||
| 479 | { | ||
| 480 | return platform_driver_register(&twl6030_usb_driver); | ||
| 481 | } | ||
| 482 | subsys_initcall(twl6030_usb_init); | ||
| 483 | |||
| 484 | static void __exit twl6030_usb_exit(void) | ||
| 485 | { | ||
| 486 | platform_driver_unregister(&twl6030_usb_driver); | ||
| 487 | } | ||
| 488 | module_exit(twl6030_usb_exit); | ||
| 489 | |||
| 490 | MODULE_ALIAS("platform:twl6030_usb"); | ||
| 491 | MODULE_AUTHOR("Hema HK <hemahk@ti.com>"); | ||
| 492 | MODULE_DESCRIPTION("TWL6030 USB transceiver driver"); | ||
| 493 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index ef2977d3a613..cdfb1868caef 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -989,6 +989,7 @@ static struct usb_serial_driver option_1port_device = { | |||
| 989 | .set_termios = usb_wwan_set_termios, | 989 | .set_termios = usb_wwan_set_termios, |
| 990 | .tiocmget = usb_wwan_tiocmget, | 990 | .tiocmget = usb_wwan_tiocmget, |
| 991 | .tiocmset = usb_wwan_tiocmset, | 991 | .tiocmset = usb_wwan_tiocmset, |
| 992 | .ioctl = usb_wwan_ioctl, | ||
| 992 | .attach = usb_wwan_startup, | 993 | .attach = usb_wwan_startup, |
| 993 | .disconnect = usb_wwan_disconnect, | 994 | .disconnect = usb_wwan_disconnect, |
| 994 | .release = usb_wwan_release, | 995 | .release = usb_wwan_release, |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index f5312dd3331b..8359ec798959 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
| @@ -79,7 +79,6 @@ struct ssu100_port_private { | |||
| 79 | u8 shadowLSR; | 79 | u8 shadowLSR; |
| 80 | u8 shadowMSR; | 80 | u8 shadowMSR; |
| 81 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | 81 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
| 82 | unsigned short max_packet_size; | ||
| 83 | struct async_icount icount; | 82 | struct async_icount icount; |
| 84 | }; | 83 | }; |
| 85 | 84 | ||
| @@ -464,36 +463,6 @@ static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | |||
| 464 | return -ENOIOCTLCMD; | 463 | return -ENOIOCTLCMD; |
| 465 | } | 464 | } |
| 466 | 465 | ||
| 467 | static void ssu100_set_max_packet_size(struct usb_serial_port *port) | ||
| 468 | { | ||
| 469 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
| 470 | struct usb_serial *serial = port->serial; | ||
| 471 | struct usb_device *udev = serial->dev; | ||
| 472 | |||
| 473 | struct usb_interface *interface = serial->interface; | ||
| 474 | struct usb_endpoint_descriptor *ep_desc = &interface->cur_altsetting->endpoint[1].desc; | ||
| 475 | |||
| 476 | unsigned num_endpoints; | ||
| 477 | int i; | ||
| 478 | unsigned long flags; | ||
| 479 | |||
| 480 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | ||
| 481 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | ||
| 482 | |||
| 483 | for (i = 0; i < num_endpoints; i++) { | ||
| 484 | dev_info(&udev->dev, "Endpoint %d MaxPacketSize %d\n", i+1, | ||
| 485 | interface->cur_altsetting->endpoint[i].desc.wMaxPacketSize); | ||
| 486 | ep_desc = &interface->cur_altsetting->endpoint[i].desc; | ||
| 487 | } | ||
| 488 | |||
| 489 | /* set max packet size based on descriptor */ | ||
| 490 | spin_lock_irqsave(&priv->status_lock, flags); | ||
| 491 | priv->max_packet_size = ep_desc->wMaxPacketSize; | ||
| 492 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
| 493 | |||
| 494 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | ||
| 495 | } | ||
| 496 | |||
| 497 | static int ssu100_attach(struct usb_serial *serial) | 466 | static int ssu100_attach(struct usb_serial *serial) |
| 498 | { | 467 | { |
| 499 | struct ssu100_port_private *priv; | 468 | struct ssu100_port_private *priv; |
| @@ -511,7 +480,6 @@ static int ssu100_attach(struct usb_serial *serial) | |||
| 511 | spin_lock_init(&priv->status_lock); | 480 | spin_lock_init(&priv->status_lock); |
| 512 | init_waitqueue_head(&priv->delta_msr_wait); | 481 | init_waitqueue_head(&priv->delta_msr_wait); |
| 513 | usb_set_serial_port_data(port, priv); | 482 | usb_set_serial_port_data(port, priv); |
| 514 | ssu100_set_max_packet_size(port); | ||
| 515 | 483 | ||
| 516 | return ssu100_initdevice(serial->dev); | 484 | return ssu100_initdevice(serial->dev); |
| 517 | } | 485 | } |
| @@ -641,13 +609,14 @@ static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, | |||
| 641 | 609 | ||
| 642 | } | 610 | } |
| 643 | 611 | ||
| 644 | static int ssu100_process_packet(struct tty_struct *tty, | 612 | static int ssu100_process_packet(struct urb *urb, |
| 645 | struct usb_serial_port *port, | 613 | struct tty_struct *tty) |
| 646 | struct ssu100_port_private *priv, | ||
| 647 | char *packet, int len) | ||
| 648 | { | 614 | { |
| 649 | int i; | 615 | struct usb_serial_port *port = urb->context; |
| 616 | char *packet = (char *)urb->transfer_buffer; | ||
| 650 | char flag = TTY_NORMAL; | 617 | char flag = TTY_NORMAL; |
| 618 | u32 len = urb->actual_length; | ||
| 619 | int i; | ||
| 651 | char *ch; | 620 | char *ch; |
| 652 | 621 | ||
| 653 | dbg("%s - port %d", __func__, port->number); | 622 | dbg("%s - port %d", __func__, port->number); |
| @@ -685,12 +654,8 @@ static int ssu100_process_packet(struct tty_struct *tty, | |||
| 685 | static void ssu100_process_read_urb(struct urb *urb) | 654 | static void ssu100_process_read_urb(struct urb *urb) |
| 686 | { | 655 | { |
| 687 | struct usb_serial_port *port = urb->context; | 656 | struct usb_serial_port *port = urb->context; |
| 688 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
| 689 | char *data = (char *)urb->transfer_buffer; | ||
| 690 | struct tty_struct *tty; | 657 | struct tty_struct *tty; |
| 691 | int count = 0; | 658 | int count; |
| 692 | int i; | ||
| 693 | int len; | ||
| 694 | 659 | ||
| 695 | dbg("%s", __func__); | 660 | dbg("%s", __func__); |
| 696 | 661 | ||
| @@ -698,10 +663,7 @@ static void ssu100_process_read_urb(struct urb *urb) | |||
| 698 | if (!tty) | 663 | if (!tty) |
| 699 | return; | 664 | return; |
| 700 | 665 | ||
| 701 | for (i = 0; i < urb->actual_length; i += priv->max_packet_size) { | 666 | count = ssu100_process_packet(urb, tty); |
| 702 | len = min_t(int, urb->actual_length - i, priv->max_packet_size); | ||
| 703 | count += ssu100_process_packet(tty, port, priv, &data[i], len); | ||
| 704 | } | ||
| 705 | 667 | ||
| 706 | if (count) | 668 | if (count) |
| 707 | tty_flip_buffer_push(tty); | 669 | tty_flip_buffer_push(tty); |
| @@ -717,8 +679,6 @@ static struct usb_serial_driver ssu100_device = { | |||
| 717 | .id_table = id_table, | 679 | .id_table = id_table, |
| 718 | .usb_driver = &ssu100_driver, | 680 | .usb_driver = &ssu100_driver, |
| 719 | .num_ports = 1, | 681 | .num_ports = 1, |
| 720 | .bulk_in_size = 256, | ||
| 721 | .bulk_out_size = 256, | ||
| 722 | .open = ssu100_open, | 682 | .open = ssu100_open, |
| 723 | .close = ssu100_close, | 683 | .close = ssu100_close, |
| 724 | .attach = ssu100_attach, | 684 | .attach = ssu100_attach, |
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index 2be298a1305b..3ab77c5d9819 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h | |||
| @@ -18,6 +18,8 @@ extern void usb_wwan_set_termios(struct tty_struct *tty, | |||
| 18 | extern int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file); | 18 | extern int usb_wwan_tiocmget(struct tty_struct *tty, struct file *file); |
| 19 | extern int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, | 19 | extern int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, |
| 20 | unsigned int set, unsigned int clear); | 20 | unsigned int set, unsigned int clear); |
| 21 | extern int usb_wwan_ioctl(struct tty_struct *tty, struct file *file, | ||
| 22 | unsigned int cmd, unsigned long arg); | ||
| 21 | extern int usb_wwan_send_setup(struct usb_serial_port *port); | 23 | extern int usb_wwan_send_setup(struct usb_serial_port *port); |
| 22 | extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, | 24 | extern int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, |
| 23 | const unsigned char *buf, int count); | 25 | const unsigned char *buf, int count); |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index fbc946797801..b004b2a485c3 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
| @@ -31,8 +31,10 @@ | |||
| 31 | #include <linux/tty_flip.h> | 31 | #include <linux/tty_flip.h> |
| 32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 33 | #include <linux/bitops.h> | 33 | #include <linux/bitops.h> |
| 34 | #include <linux/uaccess.h> | ||
| 34 | #include <linux/usb.h> | 35 | #include <linux/usb.h> |
| 35 | #include <linux/usb/serial.h> | 36 | #include <linux/usb/serial.h> |
| 37 | #include <linux/serial.h> | ||
| 36 | #include "usb-wwan.h" | 38 | #include "usb-wwan.h" |
| 37 | 39 | ||
| 38 | static int debug; | 40 | static int debug; |
| @@ -123,6 +125,83 @@ int usb_wwan_tiocmset(struct tty_struct *tty, struct file *file, | |||
| 123 | } | 125 | } |
| 124 | EXPORT_SYMBOL(usb_wwan_tiocmset); | 126 | EXPORT_SYMBOL(usb_wwan_tiocmset); |
| 125 | 127 | ||
| 128 | static int get_serial_info(struct usb_serial_port *port, | ||
| 129 | struct serial_struct __user *retinfo) | ||
| 130 | { | ||
| 131 | struct serial_struct tmp; | ||
| 132 | |||
| 133 | if (!retinfo) | ||
| 134 | return -EFAULT; | ||
| 135 | |||
| 136 | memset(&tmp, 0, sizeof(tmp)); | ||
| 137 | tmp.line = port->serial->minor; | ||
| 138 | tmp.port = port->number; | ||
| 139 | tmp.baud_base = tty_get_baud_rate(port->port.tty); | ||
| 140 | tmp.close_delay = port->port.close_delay / 10; | ||
| 141 | tmp.closing_wait = port->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? | ||
| 142 | ASYNC_CLOSING_WAIT_NONE : | ||
| 143 | port->port.closing_wait / 10; | ||
| 144 | |||
| 145 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
| 146 | return -EFAULT; | ||
| 147 | return 0; | ||
| 148 | } | ||
| 149 | |||
| 150 | static int set_serial_info(struct usb_serial_port *port, | ||
| 151 | struct serial_struct __user *newinfo) | ||
| 152 | { | ||
| 153 | struct serial_struct new_serial; | ||
| 154 | unsigned int closing_wait, close_delay; | ||
| 155 | int retval = 0; | ||
| 156 | |||
| 157 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | ||
| 158 | return -EFAULT; | ||
| 159 | |||
| 160 | close_delay = new_serial.close_delay * 10; | ||
| 161 | closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? | ||
| 162 | ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; | ||
| 163 | |||
| 164 | mutex_lock(&port->port.mutex); | ||
| 165 | |||
| 166 | if (!capable(CAP_SYS_ADMIN)) { | ||
| 167 | if ((close_delay != port->port.close_delay) || | ||
| 168 | (closing_wait != port->port.closing_wait)) | ||
| 169 | retval = -EPERM; | ||
| 170 | else | ||
| 171 | retval = -EOPNOTSUPP; | ||
| 172 | } else { | ||
| 173 | port->port.close_delay = close_delay; | ||
| 174 | port->port.closing_wait = closing_wait; | ||
| 175 | } | ||
| 176 | |||
| 177 | mutex_unlock(&port->port.mutex); | ||
| 178 | return retval; | ||
| 179 | } | ||
| 180 | |||
| 181 | int usb_wwan_ioctl(struct tty_struct *tty, struct file *file, | ||
| 182 | unsigned int cmd, unsigned long arg) | ||
| 183 | { | ||
| 184 | struct usb_serial_port *port = tty->driver_data; | ||
| 185 | |||
| 186 | dbg("%s cmd 0x%04x", __func__, cmd); | ||
| 187 | |||
| 188 | switch (cmd) { | ||
| 189 | case TIOCGSERIAL: | ||
| 190 | return get_serial_info(port, | ||
| 191 | (struct serial_struct __user *) arg); | ||
| 192 | case TIOCSSERIAL: | ||
| 193 | return set_serial_info(port, | ||
| 194 | (struct serial_struct __user *) arg); | ||
| 195 | default: | ||
| 196 | break; | ||
| 197 | } | ||
| 198 | |||
| 199 | dbg("%s arg not supported", __func__); | ||
| 200 | |||
| 201 | return -ENOIOCTLCMD; | ||
| 202 | } | ||
| 203 | EXPORT_SYMBOL(usb_wwan_ioctl); | ||
| 204 | |||
| 126 | /* Write */ | 205 | /* Write */ |
| 127 | int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, | 206 | int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port, |
| 128 | const unsigned char *buf, int count) | 207 | const unsigned char *buf, int count) |
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 339fac3949df..23f0dd9c36d4 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c | |||
| @@ -49,14 +49,17 @@ struct command_iu { | |||
| 49 | __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ | 49 | __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ |
| 50 | }; | 50 | }; |
| 51 | 51 | ||
| 52 | /* | ||
| 53 | * Also used for the Read Ready and Write Ready IUs since they have the | ||
| 54 | * same first four bytes | ||
| 55 | */ | ||
| 52 | struct sense_iu { | 56 | struct sense_iu { |
| 53 | __u8 iu_id; | 57 | __u8 iu_id; |
| 54 | __u8 rsvd1; | 58 | __u8 rsvd1; |
| 55 | __be16 tag; | 59 | __be16 tag; |
| 56 | __be16 status_qual; | 60 | __be16 status_qual; |
| 57 | __u8 status; | 61 | __u8 status; |
| 58 | __u8 service_response; | 62 | __u8 rsvd7[7]; |
| 59 | __u8 rsvd8[6]; | ||
| 60 | __be16 len; | 63 | __be16 len; |
| 61 | __u8 sense[SCSI_SENSE_BUFFERSIZE]; | 64 | __u8 sense[SCSI_SENSE_BUFFERSIZE]; |
| 62 | }; | 65 | }; |
| @@ -97,8 +100,8 @@ struct uas_dev_info { | |||
| 97 | }; | 100 | }; |
| 98 | 101 | ||
| 99 | enum { | 102 | enum { |
| 100 | ALLOC_SENSE_URB = (1 << 0), | 103 | ALLOC_STATUS_URB = (1 << 0), |
| 101 | SUBMIT_SENSE_URB = (1 << 1), | 104 | SUBMIT_STATUS_URB = (1 << 1), |
| 102 | ALLOC_DATA_IN_URB = (1 << 2), | 105 | ALLOC_DATA_IN_URB = (1 << 2), |
| 103 | SUBMIT_DATA_IN_URB = (1 << 3), | 106 | SUBMIT_DATA_IN_URB = (1 << 3), |
| 104 | ALLOC_DATA_OUT_URB = (1 << 4), | 107 | ALLOC_DATA_OUT_URB = (1 << 4), |
| @@ -112,7 +115,7 @@ struct uas_cmd_info { | |||
| 112 | unsigned int state; | 115 | unsigned int state; |
| 113 | unsigned int stream; | 116 | unsigned int stream; |
| 114 | struct urb *cmd_urb; | 117 | struct urb *cmd_urb; |
| 115 | struct urb *sense_urb; | 118 | struct urb *status_urb; |
| 116 | struct urb *data_in_urb; | 119 | struct urb *data_in_urb; |
| 117 | struct urb *data_out_urb; | 120 | struct urb *data_out_urb; |
| 118 | struct list_head list; | 121 | struct list_head list; |
| @@ -138,7 +141,7 @@ static void uas_do_work(struct work_struct *work) | |||
| 138 | struct scsi_pointer *scp = (void *)cmdinfo; | 141 | struct scsi_pointer *scp = (void *)cmdinfo; |
| 139 | struct scsi_cmnd *cmnd = container_of(scp, | 142 | struct scsi_cmnd *cmnd = container_of(scp, |
| 140 | struct scsi_cmnd, SCp); | 143 | struct scsi_cmnd, SCp); |
| 141 | uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_KERNEL); | 144 | uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO); |
| 142 | } | 145 | } |
| 143 | } | 146 | } |
| 144 | 147 | ||
| @@ -204,7 +207,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, | |||
| 204 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | 207 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; |
| 205 | int err; | 208 | int err; |
| 206 | 209 | ||
| 207 | cmdinfo->state = direction | SUBMIT_SENSE_URB; | 210 | cmdinfo->state = direction | SUBMIT_STATUS_URB; |
| 208 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); | 211 | err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); |
| 209 | if (err) { | 212 | if (err) { |
| 210 | spin_lock(&uas_work_lock); | 213 | spin_lock(&uas_work_lock); |
| @@ -294,7 +297,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
| 294 | if (!urb) | 297 | if (!urb) |
| 295 | goto out; | 298 | goto out; |
| 296 | 299 | ||
| 297 | iu = kmalloc(sizeof(*iu), gfp); | 300 | iu = kzalloc(sizeof(*iu), gfp); |
| 298 | if (!iu) | 301 | if (!iu) |
| 299 | goto free; | 302 | goto free; |
| 300 | 303 | ||
| @@ -325,7 +328,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, | |||
| 325 | if (len < 0) | 328 | if (len < 0) |
| 326 | len = 0; | 329 | len = 0; |
| 327 | len = ALIGN(len, 4); | 330 | len = ALIGN(len, 4); |
| 328 | iu = kmalloc(sizeof(*iu) + len, gfp); | 331 | iu = kzalloc(sizeof(*iu) + len, gfp); |
| 329 | if (!iu) | 332 | if (!iu) |
| 330 | goto free; | 333 | goto free; |
| 331 | 334 | ||
| @@ -357,21 +360,21 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, | |||
| 357 | { | 360 | { |
| 358 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; | 361 | struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; |
| 359 | 362 | ||
| 360 | if (cmdinfo->state & ALLOC_SENSE_URB) { | 363 | if (cmdinfo->state & ALLOC_STATUS_URB) { |
| 361 | cmdinfo->sense_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd, | 364 | cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd, |
| 362 | cmdinfo->stream); | 365 | cmdinfo->stream); |
| 363 | if (!cmdinfo->sense_urb) | 366 | if (!cmdinfo->status_urb) |
| 364 | return SCSI_MLQUEUE_DEVICE_BUSY; | 367 | return SCSI_MLQUEUE_DEVICE_BUSY; |
| 365 | cmdinfo->state &= ~ALLOC_SENSE_URB; | 368 | cmdinfo->state &= ~ALLOC_STATUS_URB; |
| 366 | } | 369 | } |
| 367 | 370 | ||
| 368 | if (cmdinfo->state & SUBMIT_SENSE_URB) { | 371 | if (cmdinfo->state & SUBMIT_STATUS_URB) { |
| 369 | if (usb_submit_urb(cmdinfo->sense_urb, gfp)) { | 372 | if (usb_submit_urb(cmdinfo->status_urb, gfp)) { |
| 370 | scmd_printk(KERN_INFO, cmnd, | 373 | scmd_printk(KERN_INFO, cmnd, |
| 371 | "sense urb submission failure\n"); | 374 | "sense urb submission failure\n"); |
| 372 | return SCSI_MLQUEUE_DEVICE_BUSY; | 375 | return SCSI_MLQUEUE_DEVICE_BUSY; |
| 373 | } | 376 | } |
| 374 | cmdinfo->state &= ~SUBMIT_SENSE_URB; | 377 | cmdinfo->state &= ~SUBMIT_STATUS_URB; |
| 375 | } | 378 | } |
| 376 | 379 | ||
| 377 | if (cmdinfo->state & ALLOC_DATA_IN_URB) { | 380 | if (cmdinfo->state & ALLOC_DATA_IN_URB) { |
| @@ -440,7 +443,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
| 440 | 443 | ||
| 441 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); | 444 | BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); |
| 442 | 445 | ||
| 443 | if (!cmdinfo->sense_urb && sdev->current_cmnd) | 446 | if (!cmdinfo->status_urb && sdev->current_cmnd) |
| 444 | return SCSI_MLQUEUE_DEVICE_BUSY; | 447 | return SCSI_MLQUEUE_DEVICE_BUSY; |
| 445 | 448 | ||
| 446 | if (blk_rq_tagged(cmnd->request)) { | 449 | if (blk_rq_tagged(cmnd->request)) { |
| @@ -452,7 +455,7 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
| 452 | 455 | ||
| 453 | cmnd->scsi_done = done; | 456 | cmnd->scsi_done = done; |
| 454 | 457 | ||
| 455 | cmdinfo->state = ALLOC_SENSE_URB | SUBMIT_SENSE_URB | | 458 | cmdinfo->state = ALLOC_STATUS_URB | SUBMIT_STATUS_URB | |
| 456 | ALLOC_CMD_URB | SUBMIT_CMD_URB; | 459 | ALLOC_CMD_URB | SUBMIT_CMD_URB; |
| 457 | 460 | ||
| 458 | switch (cmnd->sc_data_direction) { | 461 | switch (cmnd->sc_data_direction) { |
| @@ -475,8 +478,8 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, | |||
| 475 | err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC); | 478 | err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC); |
| 476 | if (err) { | 479 | if (err) { |
| 477 | /* If we did nothing, give up now */ | 480 | /* If we did nothing, give up now */ |
| 478 | if (cmdinfo->state & SUBMIT_SENSE_URB) { | 481 | if (cmdinfo->state & SUBMIT_STATUS_URB) { |
| 479 | usb_free_urb(cmdinfo->sense_urb); | 482 | usb_free_urb(cmdinfo->status_urb); |
| 480 | return SCSI_MLQUEUE_DEVICE_BUSY; | 483 | return SCSI_MLQUEUE_DEVICE_BUSY; |
| 481 | } | 484 | } |
| 482 | spin_lock(&uas_work_lock); | 485 | spin_lock(&uas_work_lock); |
| @@ -578,6 +581,34 @@ static struct usb_device_id uas_usb_ids[] = { | |||
| 578 | }; | 581 | }; |
| 579 | MODULE_DEVICE_TABLE(usb, uas_usb_ids); | 582 | MODULE_DEVICE_TABLE(usb, uas_usb_ids); |
| 580 | 583 | ||
| 584 | static int uas_is_interface(struct usb_host_interface *intf) | ||
| 585 | { | ||
| 586 | return (intf->desc.bInterfaceClass == USB_CLASS_MASS_STORAGE && | ||
| 587 | intf->desc.bInterfaceSubClass == USB_SC_SCSI && | ||
| 588 | intf->desc.bInterfaceProtocol == USB_PR_UAS); | ||
| 589 | } | ||
| 590 | |||
| 591 | static int uas_switch_interface(struct usb_device *udev, | ||
| 592 | struct usb_interface *intf) | ||
| 593 | { | ||
| 594 | int i; | ||
| 595 | |||
| 596 | if (uas_is_interface(intf->cur_altsetting)) | ||
| 597 | return 0; | ||
| 598 | |||
| 599 | for (i = 0; i < intf->num_altsetting; i++) { | ||
| 600 | struct usb_host_interface *alt = &intf->altsetting[i]; | ||
| 601 | if (alt == intf->cur_altsetting) | ||
| 602 | continue; | ||
| 603 | if (uas_is_interface(alt)) | ||
| 604 | return usb_set_interface(udev, | ||
| 605 | alt->desc.bInterfaceNumber, | ||
| 606 | alt->desc.bAlternateSetting); | ||
| 607 | } | ||
| 608 | |||
| 609 | return -ENODEV; | ||
| 610 | } | ||
| 611 | |||
| 581 | static void uas_configure_endpoints(struct uas_dev_info *devinfo) | 612 | static void uas_configure_endpoints(struct uas_dev_info *devinfo) |
| 582 | { | 613 | { |
| 583 | struct usb_host_endpoint *eps[4] = { }; | 614 | struct usb_host_endpoint *eps[4] = { }; |
| @@ -651,13 +682,8 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
| 651 | struct uas_dev_info *devinfo; | 682 | struct uas_dev_info *devinfo; |
| 652 | struct usb_device *udev = interface_to_usbdev(intf); | 683 | struct usb_device *udev = interface_to_usbdev(intf); |
| 653 | 684 | ||
| 654 | if (id->bInterfaceProtocol == 0x50) { | 685 | if (uas_switch_interface(udev, intf)) |
| 655 | int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | 686 | return -ENODEV; |
| 656 | /* XXX: Shouldn't assume that 1 is the alternative we want */ | ||
| 657 | int ret = usb_set_interface(udev, ifnum, 1); | ||
| 658 | if (ret) | ||
| 659 | return -ENODEV; | ||
| 660 | } | ||
| 661 | 687 | ||
| 662 | devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL); | 688 | devinfo = kmalloc(sizeof(struct uas_dev_info), GFP_KERNEL); |
| 663 | if (!devinfo) | 689 | if (!devinfo) |
diff --git a/drivers/uwb/i1480/i1480-est.c b/drivers/uwb/i1480/i1480-est.c index f2eb4d8b76c9..d5de5e131d47 100644 --- a/drivers/uwb/i1480/i1480-est.c +++ b/drivers/uwb/i1480/i1480-est.c | |||
| @@ -91,7 +91,7 @@ MODULE_LICENSE("GPL"); | |||
| 91 | * | 91 | * |
| 92 | * [so we are loaded when this kind device is connected] | 92 | * [so we are loaded when this kind device is connected] |
| 93 | */ | 93 | */ |
| 94 | static struct usb_device_id i1480_est_id_table[] = { | 94 | static struct usb_device_id __used i1480_est_id_table[] = { |
| 95 | { USB_DEVICE(0x8086, 0xdf3b), }, | 95 | { USB_DEVICE(0x8086, 0xdf3b), }, |
| 96 | { USB_DEVICE(0x8086, 0x0c3b), }, | 96 | { USB_DEVICE(0x8086, 0x0c3b), }, |
| 97 | { }, | 97 | { }, |
diff --git a/drivers/uwb/umc-dev.c b/drivers/uwb/umc-dev.c index 43ea9982e687..ccd2184e05d2 100644 --- a/drivers/uwb/umc-dev.c +++ b/drivers/uwb/umc-dev.c | |||
| @@ -54,11 +54,8 @@ int umc_device_register(struct umc_dev *umc) | |||
| 54 | 54 | ||
| 55 | err = request_resource(umc->resource.parent, &umc->resource); | 55 | err = request_resource(umc->resource.parent, &umc->resource); |
| 56 | if (err < 0) { | 56 | if (err < 0) { |
| 57 | dev_err(&umc->dev, "can't allocate resource range " | 57 | dev_err(&umc->dev, "can't allocate resource range %pR: %d\n", |
| 58 | "%016Lx to %016Lx: %d\n", | 58 | &umc->resource, err); |
| 59 | (unsigned long long)umc->resource.start, | ||
| 60 | (unsigned long long)umc->resource.end, | ||
| 61 | err); | ||
| 62 | goto error_request_resource; | 59 | goto error_request_resource; |
| 63 | } | 60 | } |
| 64 | 61 | ||
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c index 73495583c444..70a004aa19db 100644 --- a/drivers/uwb/whc-rc.c +++ b/drivers/uwb/whc-rc.c | |||
| @@ -449,7 +449,7 @@ static int whcrc_post_reset(struct umc_dev *umc) | |||
| 449 | } | 449 | } |
| 450 | 450 | ||
| 451 | /* PCI device ID's that we handle [so it gets loaded] */ | 451 | /* PCI device ID's that we handle [so it gets loaded] */ |
| 452 | static struct pci_device_id whcrc_id_table[] = { | 452 | static struct pci_device_id __used whcrc_id_table[] = { |
| 453 | { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) }, | 453 | { PCI_DEVICE_CLASS(PCI_CLASS_WIRELESS_WHCI, ~0) }, |
| 454 | { /* empty last entry */ } | 454 | { /* empty last entry */ } |
| 455 | }; | 455 | }; |
