Re: [PATCH 4/4] CI13xxx: Add USB host interrupt notifier

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



the PHY notification content is whether the PHY
high speed disconnection detector need to be enabled. This
detector is used to detect whether there is a disconnection during SOF.
Let me explain when the phy need to be notified,
- After roothub finishes bus reset (enable)
- After roothub finds there is a disconnection at port (disable)
- After roothub enters suspend - portsc.suspendM is set (disable)
- After roothub finishes the resume - portsc.fpr is cleared (enable)

On Sun, May 20, 2012 at 5:23 PM, Richard Zhao <linuxzsc@xxxxxxxxx> wrote:
> How about the below?
>
> diff --git a/drivers/usb/chipidea/ci.h b/drivers/usb/chipidea/ci.h
> index 50911f8..71d7080 100644
> --- a/drivers/usb/chipidea/ci.h
> +++ b/drivers/usb/chipidea/ci.h
> @@ -160,6 +160,8 @@ struct ci13xxx {
>
>        struct ci13xxx_udc_driver       *udc_driver;
>        int                             vbus_active;
> +       /* FIXME: some day, we'll not use global phy */
> +       bool                            global_phy;
>        struct usb_phy                  *transceiver;
>        struct usb_hcd                  *hcd;
>  };
> diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> index 15e03b3..0492786 100644
> --- a/drivers/usb/chipidea/core.c
> +++ b/drivers/usb/chipidea/core.c
> @@ -365,6 +365,10 @@ static int __devinit ci_hdrc_probe(struct platform_device *pdev)
>
>        ci->dev = dev;
>        ci->udc_driver = dev->platform_data;
> +       if (ci->udc_driver->phy)
> +               ci->transceiver = ci->udc_driver->phy;
> +       else
> +               ci->global_phy = 1;
>
>        ret = hw_device_init(ci, base);
>        if (ret < 0) {
> diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
> index 9eacd21..7bc11a5 100644
> --- a/drivers/usb/chipidea/host.c
> +++ b/drivers/usb/chipidea/host.c
> @@ -121,6 +121,7 @@ static int host_start(struct ci13xxx *ci)
>        ehci = hcd_to_ehci(hcd);
>        ehci->caps = ci->hw_bank.cap;
>        ehci->has_hostpc = ci->hw_bank.lpm;
> +       ehci->transceiver = ci->transceiver;
>
>        ret = usb_add_hcd(hcd, 0, 0);
>        if (ret)
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 51f9694..22139fae 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1687,7 +1687,8 @@ static int udc_start(struct ci13xxx *udc)
>
>        udc->gadget.ep0 = &udc->ep0in->ep;
>
> -       udc->transceiver = usb_get_transceiver();
> +       if (udc->global_phy) {
> +               udc->transceiver = usb_get_transceiver();
>
>        if (udc->udc_driver->flags & CI13XXX_REQUIRE_TRANSCEIVER) {
>                if (udc->transceiver == NULL) {
> @@ -1731,7 +1732,8 @@ static int udc_start(struct ci13xxx *udc)
>  remove_trans:
>        if (udc->transceiver) {
>                otg_set_peripheral(udc->transceiver->otg, &udc->gadget);
> -               usb_put_transceiver(udc->transceiver);
> +               if (udc->global_phy)
> +                       usb_put_transceiver(udc->transceiver);
>        }
>
>        dev_err(dev, "error = %i\n", retval);
> @@ -1740,7 +1742,7 @@ remove_dbg:
>  unreg_device:
>        device_unregister(&udc->gadget.dev);
>  put_transceiver:
> -       if (udc->transceiver)
> +       if (udc->transceiver && udc->global_phy)
>                usb_put_transceiver(udc->transceiver);
>  free_pools:
>        dma_pool_destroy(udc->td_pool);
> @@ -1774,7 +1776,8 @@ static void udc_stop(struct ci13xxx *udc)
>
>        if (udc->transceiver) {
>                otg_set_peripheral(udc->transceiver->otg, NULL);
> -               usb_put_transceiver(udc->transceiver);
> +               if (udc->global_phy)
> +                       usb_put_transceiver(udc->transceiver);
>        }
>        dbg_remove_files(&udc->gadget.dev);
>        device_unregister(&udc->gadget.dev);
> diff --git a/include/linux/usb/chipidea.h b/include/linux/usb/chipidea.h
> index edb90d6..c46c9e9 100644
> --- a/include/linux/usb/chipidea.h
> +++ b/include/linux/usb/chipidea.h
> @@ -5,12 +5,15 @@
>  #ifndef __LINUX_USB_CHIPIDEA_H
>  #define __LINUX_USB_CHIPIDEA_H
>
> +#include <linux/usb/otg.h>
> +
>  struct ci13xxx;
>  struct ci13xxx_udc_driver {
>        const char      *name;
>        /* offset of the capability registers */
>        uintptr_t        capoffset;
>        unsigned         power_budget;
> +       struct usb_phy  *phy;
>        unsigned long    flags;
>  #define CI13XXX_REGS_SHARED            BIT(0)
>  #define CI13XXX_REQUIRE_TRANSCEIVER    BIT(1)
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index f644ba9..64cfd81 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -938,6 +938,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
>                                        ehci->reset_done[i] == 0))
>                                continue;
>
> +                       /* FIXME:
> +                        * - it does not work for multi-phy ehci
> +                        * - the best place is after debounce, but I can't get
> +                        *   phy there
> +                        */
> +                       if (pstatus & PORT_CSC)
> +                               usb_phy_notify_connect_change(ehci->transceiver,
> +                                               i, pstatus & PORT_CONNECT);
> +
>                        /* start 20 msec resume signaling from this port,
>                         * and make khubd collect PORT_STAT_C_SUSPEND to
>                         * stop that signaling.  Use 5 ms extra for safety,
>
>
> Thanks
> Richard
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
BR,
Peter Chen
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux