]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'usb-gadget/next'
authorThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:59:25 +0000 (14:59 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:59:25 +0000 (14:59 +0200)
Conflicts:
drivers/usb/musb/davinci.c

1  2 
arch/arm/mach-omap2/board-omap3beagle.c
drivers/phy/phy-twl4030-usb.c
drivers/usb/gadget/storage_common.c
drivers/usb/musb/Kconfig
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_dsps.c
drivers/usb/musb/musb_virthub.c
drivers/usb/musb/omap2430.c
drivers/usb/phy/Kconfig
drivers/usb/phy/Makefile
include/linux/usb/usb_phy_gen_xceiv.h

index 6432ab8d92078ac4779627d9ae143761bd78ebef,8b9cd0690ce79328d12c664e1ef2ef301ef0b7eb..a516c1bda1418b05612a529ff1673411afe8d8f5
@@@ -25,7 -25,7 +25,7 @@@
  #include <linux/gpio.h>
  #include <linux/input.h>
  #include <linux/gpio_keys.h>
 -#include <linux/opp.h>
 +#include <linux/pm_opp.h>
  #include <linux/cpu.h>
  
  #include <linux/mtd/mtd.h>
@@@ -289,18 -289,12 +289,12 @@@ static struct regulator_consumer_suppl
  
  static struct gpio_led gpio_leds[];
  
- /* PHY's VCC regulator might be added later, so flag that we need it */
- static struct usb_phy_gen_xceiv_platform_data hsusb2_phy_data = {
-       .needs_vcc = true,
- };
  static struct usbhs_phy_data phy_data[] = {
        {
                .port = 2,
                .reset_gpio = 147,
                .vcc_gpio = -1,         /* updated in beagle_twl_gpio_setup */
                .vcc_polarity = 1,      /* updated in beagle_twl_gpio_setup */
-               .platform_data = &hsusb2_phy_data,
        },
  };
  
@@@ -522,11 -516,11 +516,11 @@@ static int __init beagle_opp_init(void
                        return -ENODEV;
                }
                /* Enable MPU 1GHz and lower opps */
 -              r = opp_enable(mpu_dev, 800000000);
 +              r = dev_pm_opp_enable(mpu_dev, 800000000);
                /* TODO: MPU 1GHz needs SR and ABB */
  
                /* Enable IVA 800MHz and lower opps */
 -              r |= opp_enable(iva_dev, 660000000);
 +              r |= dev_pm_opp_enable(iva_dev, 660000000);
                /* TODO: DSP 800MHz needs SR and ABB */
                if (r) {
                        pr_err("%s: failed to enable higher opp %d\n",
                         * Cleanup - disable the higher freqs - we dont care
                         * about the results
                         */
 -                      opp_disable(mpu_dev, 800000000);
 -                      opp_disable(iva_dev, 660000000);
 +                      dev_pm_opp_disable(mpu_dev, 800000000);
 +                      dev_pm_opp_disable(iva_dev, 660000000);
                }
        }
        return 0;
index e0212d80c75ca5450002f0d91fcd5365103bc723,5baa9c7267f4bf500e774542d23656674dfffc40..daf65e68aaab53c663847e05d2dcf1fbdb035544
@@@ -33,7 -33,6 +33,7 @@@
  #include <linux/io.h>
  #include <linux/delay.h>
  #include <linux/usb/otg.h>
 +#include <linux/phy/phy.h>
  #include <linux/usb/musb-omap.h>
  #include <linux/usb/ulpi.h>
  #include <linux/i2c/twl.h>
@@@ -422,20 -421,17 +422,20 @@@ static void twl4030_phy_power(struct tw
        }
  }
  
 -static void twl4030_phy_suspend(struct twl4030_usb *twl, int controller_off)
 +static int twl4030_phy_power_off(struct phy *phy)
  {
 +      struct twl4030_usb *twl = phy_get_drvdata(phy);
 +
        if (twl->asleep)
 -              return;
 +              return 0;
  
        twl4030_phy_power(twl, 0);
        twl->asleep = 1;
        dev_dbg(twl->dev, "%s\n", __func__);
 +      return 0;
  }
  
 -static void __twl4030_phy_resume(struct twl4030_usb *twl)
 +static void __twl4030_phy_power_on(struct twl4030_usb *twl)
  {
        twl4030_phy_power(twl, 1);
        twl4030_i2c_access(twl, 1);
                twl4030_i2c_access(twl, 0);
  }
  
 -static void twl4030_phy_resume(struct twl4030_usb *twl)
 +static int twl4030_phy_power_on(struct phy *phy)
  {
 +      struct twl4030_usb *twl = phy_get_drvdata(phy);
 +
        if (!twl->asleep)
 -              return;
 -      __twl4030_phy_resume(twl);
 +              return 0;
 +      __twl4030_phy_power_on(twl);
        twl->asleep = 0;
        dev_dbg(twl->dev, "%s\n", __func__);
  
                cancel_delayed_work(&twl->id_workaround_work);
                schedule_delayed_work(&twl->id_workaround_work, HZ);
        }
 +      return 0;
  }
  
  static int twl4030_usb_ldo_init(struct twl4030_usb *twl)
@@@ -594,9 -587,9 +594,9 @@@ static void twl4030_id_workaround_work(
        }
  }
  
 -static int twl4030_usb_phy_init(struct usb_phy *phy)
 +static int twl4030_phy_init(struct phy *phy)
  {
 -      struct twl4030_usb *twl = phy_to_twl(phy);
 +      struct twl4030_usb *twl = phy_get_drvdata(phy);
        enum omap_musb_vbus_id_status status;
  
        /*
        status = twl4030_usb_linkstat(twl);
        twl->linkstat = status;
  
 -      if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID)
 +      if (status == OMAP_MUSB_ID_GROUND || status == OMAP_MUSB_VBUS_VALID) {
                omap_musb_mailbox(twl->linkstat);
 +              twl4030_phy_power_on(phy);
 +      }
  
        sysfs_notify(&twl->dev->kobj, NULL, "vbus");
        return 0;
  }
  
 -static int twl4030_set_suspend(struct usb_phy *x, int suspend)
 -{
 -      struct twl4030_usb *twl = phy_to_twl(x);
 -
 -      if (suspend)
 -              twl4030_phy_suspend(twl, 1);
 -      else
 -              twl4030_phy_resume(twl);
 -
 -      return 0;
 -}
 -
  static int twl4030_set_peripheral(struct usb_otg *otg,
                                        struct usb_gadget *gadget)
  {
@@@ -643,23 -646,13 +643,23 @@@ static int twl4030_set_host(struct usb_
        return 0;
  }
  
 +static const struct phy_ops ops = {
 +      .init           = twl4030_phy_init,
 +      .power_on       = twl4030_phy_power_on,
 +      .power_off      = twl4030_phy_power_off,
 +      .owner          = THIS_MODULE,
 +};
 +
  static int twl4030_usb_probe(struct platform_device *pdev)
  {
        struct twl4030_usb_data *pdata = dev_get_platdata(&pdev->dev);
        struct twl4030_usb      *twl;
 +      struct phy              *phy;
        int                     status, err;
        struct usb_otg          *otg;
        struct device_node      *np = pdev->dev.of_node;
 +      struct phy_provider     *phy_provider;
 +      struct phy_init_data    *init_data = NULL;
  
        twl = devm_kzalloc(&pdev->dev, sizeof *twl, GFP_KERNEL);
        if (!twl)
        if (np)
                of_property_read_u32(np, "usb_mode",
                                (enum twl4030_usb_mode *)&twl->usb_mode);
 -      else if (pdata)
 +      else if (pdata) {
                twl->usb_mode = pdata->usb_mode;
 -      else {
 +              init_data = pdata->init_data;
 +      } else {
                dev_err(&pdev->dev, "twl4030 initialized without pdata\n");
                return -EINVAL;
        }
        twl->phy.label          = "twl4030";
        twl->phy.otg            = otg;
        twl->phy.type           = USB_PHY_TYPE_USB2;
 -      twl->phy.set_suspend    = twl4030_set_suspend;
 -      twl->phy.init           = twl4030_usb_phy_init;
  
        otg->phy                = &twl->phy;
        otg->set_host           = twl4030_set_host;
        otg->set_peripheral     = twl4030_set_peripheral;
  
 +      phy_provider = devm_of_phy_provider_register(twl->dev,
 +              of_phy_simple_xlate);
 +      if (IS_ERR(phy_provider))
 +              return PTR_ERR(phy_provider);
 +
 +      phy = devm_phy_create(twl->dev, &ops, init_data);
 +      if (IS_ERR(phy)) {
 +              dev_dbg(&pdev->dev, "Failed to create PHY\n");
 +              return PTR_ERR(phy);
 +      }
 +
 +      phy_set_drvdata(phy, twl);
 +
        /* init spinlock for workqueue */
        spin_lock_init(&twl->lock);
  
        if (device_create_file(&pdev->dev, &dev_attr_vbus))
                dev_warn(&pdev->dev, "could not create sysfs file\n");
  
+       ATOMIC_INIT_NOTIFIER_HEAD(&twl->phy.notifier);
        /* Our job is to use irqs and status from the power module
         * to keep the transceiver disabled when nothing's connected.
         *
index cd1431d850c4d84a925286de4a47667f24b19fe4,ec20a1f50c2d702e56f6e6a79f03485607a36189..20f6ec22fac322266cd9d8bef80ec6e3f7e3b54d
   * The valid range of num_buffers is: num >= 2 && num <= 4.
   */
  
+ #include <linux/module.h>
+ #include <linux/blkdev.h>
+ #include <linux/file.h>
+ #include <linux/fs.h>
+ #include <linux/usb/composite.h>
  
- #include <linux/usb/storage.h>
- #include <scsi/scsi.h>
- #include <asm/unaligned.h>
- /*
-  * Thanks to NetChip Technologies for donating this product ID.
-  *
-  * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
-  * Instead:  allocate your own, using normal USB-IF procedures.
-  */
- #define FSG_VENDOR_ID 0x0525  /* NetChip */
- #define FSG_PRODUCT_ID        0xa4a5  /* Linux-USB File-backed Storage Gadget */
- /*-------------------------------------------------------------------------*/
- #ifndef DEBUG
- #undef VERBOSE_DEBUG
- #undef DUMP_MSGS
- #endif /* !DEBUG */
- #ifdef VERBOSE_DEBUG
- #define VLDBG LDBG
- #else
- #define VLDBG(lun, fmt, args...) do { } while (0)
- #endif /* VERBOSE_DEBUG */
- #define LDBG(lun, fmt, args...)   dev_dbg (&(lun)->dev, fmt, ## args)
- #define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
- #define LWARN(lun, fmt, args...)  dev_warn(&(lun)->dev, fmt, ## args)
- #define LINFO(lun, fmt, args...)  dev_info(&(lun)->dev, fmt, ## args)
- #ifdef DUMP_MSGS
- #  define dump_msg(fsg, /* const char * */ label,                     \
-                  /* const u8 * */ buf, /* unsigned */ length) do {    \
-       if (length < 512) {                                             \
-               DBG(fsg, "%s, length %u:\n", label, length);            \
-               print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET,      \
-                              16, 1, buf, length, 0);                  \
-       }                                                               \
- } while (0)
- #  define dump_cdb(fsg) do { } while (0)
- #else
- #  define dump_msg(fsg, /* const char * */ label, \
-                  /* const u8 * */ buf, /* unsigned */ length) do { } while (0)
- #  ifdef VERBOSE_DEBUG
- #    define dump_cdb(fsg)                                             \
-       print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE,      \
-                      16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0)         \
- #  else
- #    define dump_cdb(fsg) do { } while (0)
- #  endif /* VERBOSE_DEBUG */
- #endif /* DUMP_MSGS */
- /*-------------------------------------------------------------------------*/
- /* Length of a SCSI Command Data Block */
- #define MAX_COMMAND_SIZE      16
- /* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
- #define SS_NO_SENSE                           0
- #define SS_COMMUNICATION_FAILURE              0x040800
- #define SS_INVALID_COMMAND                    0x052000
- #define SS_INVALID_FIELD_IN_CDB                       0x052400
- #define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
- #define SS_LOGICAL_UNIT_NOT_SUPPORTED         0x052500
- #define SS_MEDIUM_NOT_PRESENT                 0x023a00
- #define SS_MEDIUM_REMOVAL_PREVENTED           0x055302
- #define SS_NOT_READY_TO_READY_TRANSITION      0x062800
- #define SS_RESET_OCCURRED                     0x062900
- #define SS_SAVING_PARAMETERS_NOT_SUPPORTED    0x053900
- #define SS_UNRECOVERED_READ_ERROR             0x031100
- #define SS_WRITE_ERROR                                0x030c02
- #define SS_WRITE_PROTECTED                    0x072700
- #define SK(x)         ((u8) ((x) >> 16))      /* Sense Key byte, etc. */
- #define ASC(x)                ((u8) ((x) >> 8))
- #define ASCQ(x)               ((u8) (x))
- /*-------------------------------------------------------------------------*/
- struct fsg_lun {
-       struct file     *filp;
-       loff_t          file_length;
-       loff_t          num_sectors;
-       unsigned int    initially_ro:1;
-       unsigned int    ro:1;
-       unsigned int    removable:1;
-       unsigned int    cdrom:1;
-       unsigned int    prevent_medium_removal:1;
-       unsigned int    registered:1;
-       unsigned int    info_valid:1;
-       unsigned int    nofua:1;
-       u32             sense_data;
-       u32             sense_data_info;
-       u32             unit_attention_data;
-       unsigned int    blkbits;        /* Bits of logical block size of bound block device */
-       unsigned int    blksize;        /* logical block size of bound block device */
-       struct device   dev;
- };
- static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
- {
-       return curlun->filp != NULL;
- }
- static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev)
- {
-       return container_of(dev, struct fsg_lun, dev);
- }
- /* Big enough to hold our biggest descriptor */
- #define EP0_BUFSIZE   256
- #define DELAYED_STATUS        (EP0_BUFSIZE + 999)     /* An impossibly large value */
- #ifdef CONFIG_USB_GADGET_DEBUG_FILES
- static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
- module_param_named(num_buffers, fsg_num_buffers, uint, S_IRUGO);
- MODULE_PARM_DESC(num_buffers, "Number of pipeline buffers");
- #else
- /*
-  * Number of buffers we will use.
-  * 2 is usually enough for good buffering pipeline
-  */
- #define fsg_num_buffers       CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
- #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
- /* check if fsg_num_buffers is within a valid range */
- static inline int fsg_num_buffers_validate(void)
- {
-       if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
-               return 0;
-       pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
-              fsg_num_buffers, 2 ,4);
-       return -EINVAL;
- }
- /* Default size of buffer length. */
- #define FSG_BUFLEN    ((u32)16384)
- /* Maximal number of LUNs supported in mass storage function */
- #define FSG_MAX_LUNS  8
- enum fsg_buffer_state {
-       BUF_STATE_EMPTY = 0,
-       BUF_STATE_FULL,
-       BUF_STATE_BUSY
- };
- struct fsg_buffhd {
-       void                            *buf;
-       enum fsg_buffer_state           state;
-       struct fsg_buffhd               *next;
-       /*
-        * The NetChip 2280 is faster, and handles some protocol faults
-        * better, if we don't submit any short bulk-out read requests.
-        * So we will record the intended request length here.
-        */
-       unsigned int                    bulk_out_intended_length;
-       struct usb_request              *inreq;
-       int                             inreq_busy;
-       struct usb_request              *outreq;
-       int                             outreq_busy;
- };
- enum fsg_state {
-       /* This one isn't used anywhere */
-       FSG_STATE_COMMAND_PHASE = -10,
-       FSG_STATE_DATA_PHASE,
-       FSG_STATE_STATUS_PHASE,
-       FSG_STATE_IDLE = 0,
-       FSG_STATE_ABORT_BULK_OUT,
-       FSG_STATE_RESET,
-       FSG_STATE_INTERFACE_CHANGE,
-       FSG_STATE_CONFIG_CHANGE,
-       FSG_STATE_DISCONNECT,
-       FSG_STATE_EXIT,
-       FSG_STATE_TERMINATED
- };
- enum data_direction {
-       DATA_DIR_UNKNOWN = 0,
-       DATA_DIR_FROM_HOST,
-       DATA_DIR_TO_HOST,
-       DATA_DIR_NONE
- };
- /*-------------------------------------------------------------------------*/
- static inline u32 get_unaligned_be24(u8 *buf)
- {
-       return 0xffffff & (u32) get_unaligned_be32(buf - 1);
- }
- /*-------------------------------------------------------------------------*/
- enum {
-       FSG_STRING_INTERFACE
- };
+ #include "storage_common.h"
  
  /* There is only one interface. */
  
- static struct usb_interface_descriptor
- fsg_intf_desc = {
+ struct usb_interface_descriptor fsg_intf_desc = {
        .bLength =              sizeof fsg_intf_desc,
        .bDescriptorType =      USB_DT_INTERFACE,
  
        .bInterfaceProtocol =   USB_PR_BULK,    /* Adjusted during fsg_bind() */
        .iInterface =           FSG_STRING_INTERFACE,
  };
+ EXPORT_SYMBOL(fsg_intf_desc);
  
  /*
   * Three full-speed endpoint descriptors: bulk-in, bulk-out, and
   * interrupt-in.
   */
  
- static struct usb_endpoint_descriptor
- fsg_fs_bulk_in_desc = {
+ struct usb_endpoint_descriptor fsg_fs_bulk_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
  
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        /* wMaxPacketSize set by autoconfiguration */
  };
+ EXPORT_SYMBOL(fsg_fs_bulk_in_desc);
  
- static struct usb_endpoint_descriptor
- fsg_fs_bulk_out_desc = {
+ struct usb_endpoint_descriptor fsg_fs_bulk_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
  
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        /* wMaxPacketSize set by autoconfiguration */
  };
+ EXPORT_SYMBOL(fsg_fs_bulk_out_desc);
  
- static struct usb_descriptor_header *fsg_fs_function[] = {
+ struct usb_descriptor_header *fsg_fs_function[] = {
        (struct usb_descriptor_header *) &fsg_intf_desc,
        (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc,
        (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc,
        NULL,
  };
+ EXPORT_SYMBOL(fsg_fs_function);
  
  
  /*
   * and a "device qualifier" ... plus more construction options
   * for the configuration descriptor.
   */
- static struct usb_endpoint_descriptor
- fsg_hs_bulk_in_desc = {
+ struct usb_endpoint_descriptor fsg_hs_bulk_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
  
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(512),
  };
+ EXPORT_SYMBOL(fsg_hs_bulk_in_desc);
  
- static struct usb_endpoint_descriptor
- fsg_hs_bulk_out_desc = {
+ struct usb_endpoint_descriptor fsg_hs_bulk_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
  
        .wMaxPacketSize =       cpu_to_le16(512),
        .bInterval =            1,      /* NAK every 1 uframe */
  };
+ EXPORT_SYMBOL(fsg_hs_bulk_out_desc);
  
  
- static struct usb_descriptor_header *fsg_hs_function[] = {
+ struct usb_descriptor_header *fsg_hs_function[] = {
        (struct usb_descriptor_header *) &fsg_intf_desc,
        (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc,
        (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc,
        NULL,
  };
+ EXPORT_SYMBOL(fsg_hs_function);
  
- static struct usb_endpoint_descriptor
- fsg_ss_bulk_in_desc = {
+ struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
  
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(1024),
  };
+ EXPORT_SYMBOL(fsg_ss_bulk_in_desc);
  
- static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
+ struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
        .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
        .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
  
        /*.bMaxBurst =          DYNAMIC, */
  };
+ EXPORT_SYMBOL(fsg_ss_bulk_in_comp_desc);
  
- static struct usb_endpoint_descriptor
- fsg_ss_bulk_out_desc = {
+ struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = {
        .bLength =              USB_DT_ENDPOINT_SIZE,
        .bDescriptorType =      USB_DT_ENDPOINT,
  
        .bmAttributes =         USB_ENDPOINT_XFER_BULK,
        .wMaxPacketSize =       cpu_to_le16(1024),
  };
+ EXPORT_SYMBOL(fsg_ss_bulk_out_desc);
  
- static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
+ struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
        .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
        .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
  
        /*.bMaxBurst =          DYNAMIC, */
  };
+ EXPORT_SYMBOL(fsg_ss_bulk_out_comp_desc);
  
- static struct usb_descriptor_header *fsg_ss_function[] = {
+ struct usb_descriptor_header *fsg_ss_function[] = {
        (struct usb_descriptor_header *) &fsg_intf_desc,
        (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc,
        (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc,
        (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
        NULL,
  };
- /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */
- static struct usb_string              fsg_strings[] = {
-       {FSG_STRING_INTERFACE,          fsg_string_interface},
-       {}
- };
- static struct usb_gadget_strings      fsg_stringtab = {
-       .language       = 0x0409,               /* en-us */
-       .strings        = fsg_strings,
- };
+ EXPORT_SYMBOL(fsg_ss_function);
  
  
   /*-------------------------------------------------------------------------*/
   * the caller must own fsg->filesem for writing.
   */
  
static void fsg_lun_close(struct fsg_lun *curlun)
+ void fsg_lun_close(struct fsg_lun *curlun)
  {
        if (curlun->filp) {
                LDBG(curlun, "close backing file\n");
                curlun->filp = NULL;
        }
  }
+ EXPORT_SYMBOL(fsg_lun_close);
  
- static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
+ int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
  {
        int                             ro;
        struct file                     *filp = NULL;
         * If we can't read the file, it's no good.
         * If we can't write the file, use it read-only.
         */
 -      if (!(filp->f_op->read || filp->f_op->aio_read)) {
 +      if (!file_readable(filp)) {
                LINFO(curlun, "file not readable: %s\n", filename);
                goto out;
        }
 -      if (!(filp->f_op->write || filp->f_op->aio_write))
 +      if (!file_writable(filp))
                ro = 1;
  
        size = i_size_read(inode->i_mapping->host);
@@@ -508,6 -278,7 +278,7 @@@ out
        fput(filp);
        return rc;
  }
+ EXPORT_SYMBOL(fsg_lun_open);
  
  
  /*-------------------------------------------------------------------------*/
   * Sync the file data, don't bother with the metadata.
   * This code was copied from fs/buffer.c:sys_fdatasync().
   */
static int fsg_lun_fsync_sub(struct fsg_lun *curlun)
+ int fsg_lun_fsync_sub(struct fsg_lun *curlun)
  {
        struct file     *filp = curlun->filp;
  
                return 0;
        return vfs_fsync(filp, 1);
  }
+ EXPORT_SYMBOL(fsg_lun_fsync_sub);
  
static void store_cdrom_address(u8 *dest, int msf, u32 addr)
+ void store_cdrom_address(u8 *dest, int msf, u32 addr)
  {
        if (msf) {
                /* Convert to Minutes-Seconds-Frames */
                put_unaligned_be32(addr, dest);
        }
  }
+ EXPORT_SYMBOL(store_cdrom_address);
  
  /*-------------------------------------------------------------------------*/
  
  
- static ssize_t ro_show(struct device *dev, struct device_attribute *attr,
-                      char *buf)
+ ssize_t fsg_show_ro(struct fsg_lun *curlun, char *buf)
  {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
        return sprintf(buf, "%d\n", fsg_lun_is_open(curlun)
                                  ? curlun->ro
                                  : curlun->initially_ro);
  }
+ EXPORT_SYMBOL(fsg_show_ro);
  
- static ssize_t nofua_show(struct device *dev, struct device_attribute *attr,
-                         char *buf)
+ ssize_t fsg_show_nofua(struct fsg_lun *curlun, char *buf)
  {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
        return sprintf(buf, "%u\n", curlun->nofua);
  }
+ EXPORT_SYMBOL(fsg_show_nofua);
  
- static ssize_t file_show(struct device *dev, struct device_attribute *attr,
-                        char *buf)
+ ssize_t fsg_show_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                     char *buf)
  {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
        char            *p;
        ssize_t         rc;
  
        up_read(filesem);
        return rc;
  }
+ EXPORT_SYMBOL(fsg_show_file);
  
+ ssize_t fsg_show_cdrom(struct fsg_lun *curlun, char *buf)
+ {
+       return sprintf(buf, "%u\n", curlun->cdrom);
+ }
+ EXPORT_SYMBOL(fsg_show_cdrom);
  
- static ssize_t ro_store(struct device *dev, struct device_attribute *attr,
-                       const char *buf, size_t count)
+ ssize_t fsg_show_removable(struct fsg_lun *curlun, char *buf)
+ {
+       return sprintf(buf, "%u\n", curlun->removable);
+ }
+ EXPORT_SYMBOL(fsg_show_removable);
+ /*
+  * The caller must hold fsg->filesem for reading when calling this function.
+  */
+ static ssize_t _fsg_store_ro(struct fsg_lun *curlun, bool ro)
+ {
+       if (fsg_lun_is_open(curlun)) {
+               LDBG(curlun, "read-only status change prevented\n");
+               return -EBUSY;
+       }
+       curlun->ro = ro;
+       curlun->initially_ro = ro;
+       LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+       return 0;
+ }
+ ssize_t fsg_store_ro(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                    const char *buf, size_t count)
  {
        ssize_t         rc;
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
-       unsigned        ro;
+       bool            ro;
  
-       rc = kstrtouint(buf, 2, &ro);
+       rc = strtobool(buf, &ro);
        if (rc)
                return rc;
  
         * backing file is closed.
         */
        down_read(filesem);
-       if (fsg_lun_is_open(curlun)) {
-               LDBG(curlun, "read-only status change prevented\n");
-               rc = -EBUSY;
-       } else {
-               curlun->ro = ro;
-               curlun->initially_ro = ro;
-               LDBG(curlun, "read-only status set to %d\n", curlun->ro);
+       rc = _fsg_store_ro(curlun, ro);
+       if (!rc)
                rc = count;
-       }
        up_read(filesem);
        return rc;
  }
+ EXPORT_SYMBOL(fsg_store_ro);
  
- static ssize_t nofua_store(struct device *dev, struct device_attribute *attr,
-                          const char *buf, size_t count)
+ ssize_t fsg_store_nofua(struct fsg_lun *curlun, const char *buf, size_t count)
  {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       unsigned        nofua;
+       bool            nofua;
        int             ret;
  
-       ret = kstrtouint(buf, 2, &nofua);
+       ret = strtobool(buf, &nofua);
        if (ret)
                return ret;
  
  
        return count;
  }
+ EXPORT_SYMBOL(fsg_store_nofua);
  
- static ssize_t file_store(struct device *dev, struct device_attribute *attr,
-                         const char *buf, size_t count)
+ ssize_t fsg_store_file(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                      const char *buf, size_t count)
  {
-       struct fsg_lun  *curlun = fsg_lun_from_dev(dev);
-       struct rw_semaphore     *filesem = dev_get_drvdata(dev);
        int             rc = 0;
  
        if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
        up_write(filesem);
        return (rc < 0 ? rc : count);
  }
+ EXPORT_SYMBOL(fsg_store_file);
+ ssize_t fsg_store_cdrom(struct fsg_lun *curlun, struct rw_semaphore *filesem,
+                       const char *buf, size_t count)
+ {
+       bool            cdrom;
+       int             ret;
+       ret = strtobool(buf, &cdrom);
+       if (ret)
+               return ret;
+       down_read(filesem);
+       ret = cdrom ? _fsg_store_ro(curlun, true) : 0;
+       if (!ret) {
+               curlun->cdrom = cdrom;
+               ret = count;
+       }
+       up_read(filesem);
+       return ret;
+ }
+ EXPORT_SYMBOL(fsg_store_cdrom);
+ ssize_t fsg_store_removable(struct fsg_lun *curlun, const char *buf,
+                           size_t count)
+ {
+       bool            removable;
+       int             ret;
+       ret = strtobool(buf, &removable);
+       if (ret)
+               return ret;
+       curlun->removable = removable;
+       return count;
+ }
+ EXPORT_SYMBOL(fsg_store_removable);
+ MODULE_LICENSE("GPL");
diff --combined drivers/usb/musb/Kconfig
index 0440e2807280934a21a0f7e91f9cbec1a62a9190,0fc5bc3719401d3b08dc917960ebe4b192922e44..57dfc0cedb0055cfb28078b7d4da03d42abb37b0
@@@ -75,7 -75,6 +75,7 @@@ config USB_MUSB_TUSB601
  config USB_MUSB_OMAP2PLUS
        tristate "OMAP2430 and onwards"
        depends on ARCH_OMAP2PLUS
 +      select GENERIC_PHY
  
  config USB_MUSB_AM35X
        tristate "AM35x"
@@@ -91,7 -90,7 +91,7 @@@ config USB_MUSB_BLACKFI
        depends on (BF54x && !BF544) || (BF52x && ! BF522 && !BF523)
  
  config USB_MUSB_UX500
-       tristate "U8500 and U5500"
+       tristate "Ux500 platforms"
  
  endchoice
  
@@@ -113,7 -112,7 +113,7 @@@ choic
          allow using DMA on multiplatform kernels.
  
  config USB_UX500_DMA
-       bool 'ST Ericsson U8500 and U5500'
+       bool 'ST Ericsson Ux500'
        depends on USB_MUSB_UX500
        help
          Enable DMA transfers on UX500 platforms.
index 208785e36d5265988c807e0a5242a1579a284a77,4db987f07f67fe0241c579b7daa39075e452e9ec..0a43329569d178de72a5c8ee619e7206c360c51c
@@@ -617,7 -617,7 +617,7 @@@ static irqreturn_t musb_stage0_irq(stru
                                /* case 3 << MUSB_DEVCTL_VBUS_SHIFT: */
                                default:
                                        s = "VALID"; break;
 -                              }; s; }),
 +                              } s; }),
                                VBUSERR_RETRY_COUNT - musb->vbuserr_retry,
                                musb->port1_status);
  
@@@ -921,52 -921,6 +921,52 @@@ static void musb_generic_disable(struc
  
  }
  
 +/*
 + * Program the HDRC to start (enable interrupts, dma, etc.).
 + */
 +void musb_start(struct musb *musb)
 +{
 +      void __iomem    *regs = musb->mregs;
 +      u8              devctl = musb_readb(regs, MUSB_DEVCTL);
 +
 +      dev_dbg(musb->controller, "<== devctl %02x\n", devctl);
 +
 +      /*  Set INT enable registers, enable interrupts */
 +      musb->intrtxe = musb->epmask;
 +      musb_writew(regs, MUSB_INTRTXE, musb->intrtxe);
 +      musb->intrrxe = musb->epmask & 0xfffe;
 +      musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
 +      musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
 +
 +      musb_writeb(regs, MUSB_TESTMODE, 0);
 +
 +      /* put into basic highspeed mode and start session */
 +      musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
 +                      | MUSB_POWER_HSENAB
 +                      /* ENSUSPEND wedges tusb */
 +                      /* | MUSB_POWER_ENSUSPEND */
 +                 );
 +
 +      musb->is_active = 0;
 +      devctl = musb_readb(regs, MUSB_DEVCTL);
 +      devctl &= ~MUSB_DEVCTL_SESSION;
 +
 +      /* session started after:
 +       * (a) ID-grounded irq, host mode;
 +       * (b) vbus present/connect IRQ, peripheral mode;
 +       * (c) peripheral initiates, using SRP
 +       */
 +      if (musb->port_mode != MUSB_PORT_MODE_HOST &&
 +                      (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
 +              musb->is_active = 1;
 +      } else {
 +              devctl |= MUSB_DEVCTL_SESSION;
 +      }
 +
 +      musb_platform_enable(musb);
 +      musb_writeb(regs, MUSB_DEVCTL, devctl);
 +}
 +
  /*
   * Make the HDRC stop (disable interrupts, etc.);
   * reversible by musb_start
@@@ -1809,8 -1763,7 +1809,7 @@@ static void musb_free(struct musb *musb
                        disable_irq_wake(musb->nIrq);
                free_irq(musb->nIrq, musb);
        }
-       if (musb->dma_controller)
-               dma_controller_destroy(musb->dma_controller);
+       cancel_work_sync(&musb->irq_work);
  
        musb_host_free(musb);
  }
@@@ -1885,8 -1838,13 +1884,13 @@@ musb_init_controller(struct device *dev
  
        pm_runtime_get_sync(musb->controller);
  
-       if (use_dma && dev->dma_mask)
+       if (use_dma && dev->dma_mask) {
                musb->dma_controller = dma_controller_create(musb, musb->mregs);
+               if (IS_ERR(musb->dma_controller)) {
+                       status = PTR_ERR(musb->dma_controller);
+                       goto fail2_5;
+               }
+       }
  
        /* be sure interrupts are disabled before connecting ISR */
        musb_platform_disable(musb);
                if (status < 0)
                        goto fail3;
                status = musb_gadget_setup(musb);
+               if (status)
+                       musb_host_cleanup(musb);
                break;
        default:
                dev_err(dev, "unsupported port mode %d\n", musb->port_mode);
@@@ -1972,10 -1932,12 +1978,12 @@@ fail5
  
  fail4:
        musb_gadget_cleanup(musb);
+       musb_host_cleanup(musb);
  
  fail3:
        if (musb->dma_controller)
                dma_controller_destroy(musb->dma_controller);
+ fail2_5:
        pm_runtime_put_sync(musb->controller);
  
  fail2:
@@@ -2032,6 -1994,9 +2040,9 @@@ static int musb_remove(struct platform_
        musb_exit_debugfs(musb);
        musb_shutdown(pdev);
  
+       if (musb->dma_controller)
+               dma_controller_destroy(musb->dma_controller);
        musb_free(musb);
        device_init_wakeup(dev, 0);
        return 0;
index 1a5574c2d586c78f7de46e605cfbe0b359aa1ece,82e1da08a67b9c2b84008adee28da1072f107033..1901f6fe580749c93862910e322af543dd1eb8c7
@@@ -121,6 -121,43 +121,43 @@@ struct dsps_glue 
        unsigned long last_timer;    /* last timer data for each instance */
  };
  
+ static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
+ {
+       struct device *dev = musb->controller;
+       struct dsps_glue *glue = dev_get_drvdata(dev->parent);
+       if (timeout == 0)
+               timeout = jiffies + msecs_to_jiffies(3);
+       /* Never idle if active, or when VBUS timeout is not set as host */
+       if (musb->is_active || (musb->a_wait_bcon == 0 &&
+                               musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
+               dev_dbg(musb->controller, "%s active, deleting timer\n",
+                               usb_otg_state_string(musb->xceiv->state));
+               del_timer(&glue->timer);
+               glue->last_timer = jiffies;
+               return;
+       }
+       if (musb->port_mode != MUSB_PORT_MODE_DUAL_ROLE)
+               return;
+       if (!musb->g.dev.driver)
+               return;
+       if (time_after(glue->last_timer, timeout) &&
+                               timer_pending(&glue->timer)) {
+               dev_dbg(musb->controller,
+                       "Longer idle timer already pending, ignoring...\n");
+               return;
+       }
+       glue->last_timer = timeout;
+       dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
+               usb_otg_state_string(musb->xceiv->state),
+                       jiffies_to_msecs(timeout - jiffies));
+       mod_timer(&glue->timer, timeout);
+ }
  /**
   * dsps_musb_enable - enable interrupts
   */
@@@ -143,6 -180,7 +180,7 @@@ static void dsps_musb_enable(struct mus
        /* Force the DRVVBUS IRQ so we can start polling for ID change. */
        dsps_writel(reg_base, wrp->coreintr_set,
                    (1 << wrp->drvvbus) << wrp->usb_shift);
+       dsps_musb_try_idle(musb, 0);
  }
  
  /**
@@@ -171,6 -209,7 +209,7 @@@ static void otg_timer(unsigned long _mu
        const struct dsps_musb_wrapper *wrp = glue->wrp;
        u8 devctl;
        unsigned long flags;
+       int skip_session = 0;
  
        /*
         * We poll because DSPS IP's won't expose several OTG-critical
        spin_lock_irqsave(&musb->lock, flags);
        switch (musb->xceiv->state) {
        case OTG_STATE_A_WAIT_BCON:
-               devctl &= ~MUSB_DEVCTL_SESSION;
-               dsps_writeb(musb->mregs, MUSB_DEVCTL, devctl);
+               dsps_writeb(musb->mregs, MUSB_DEVCTL, 0);
+               skip_session = 1;
+               /* fall */
  
-               devctl = dsps_readb(musb->mregs, MUSB_DEVCTL);
+       case OTG_STATE_A_IDLE:
+       case OTG_STATE_B_IDLE:
                if (devctl & MUSB_DEVCTL_BDEVICE) {
                        musb->xceiv->state = OTG_STATE_B_IDLE;
                        MUSB_DEV_MODE(musb);
                        musb->xceiv->state = OTG_STATE_A_IDLE;
                        MUSB_HST_MODE(musb);
                }
+               if (!(devctl & MUSB_DEVCTL_SESSION) && !skip_session)
+                       dsps_writeb(mregs, MUSB_DEVCTL, MUSB_DEVCTL_SESSION);
+               mod_timer(&glue->timer, jiffies + wrp->poll_seconds * HZ);
                break;
        case OTG_STATE_A_WAIT_VFALL:
                musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
                dsps_writel(musb->ctrl_base, wrp->coreintr_set,
                            MUSB_INTR_VBUSERROR << wrp->usb_shift);
                break;
-       case OTG_STATE_B_IDLE:
-               devctl = dsps_readb(mregs, MUSB_DEVCTL);
-               if (devctl & MUSB_DEVCTL_BDEVICE)
-                       mod_timer(&glue->timer,
-                                       jiffies + wrp->poll_seconds * HZ);
-               else
-                       musb->xceiv->state = OTG_STATE_A_IDLE;
-               break;
        default:
                break;
        }
        spin_unlock_irqrestore(&musb->lock, flags);
  }
  
- static void dsps_musb_try_idle(struct musb *musb, unsigned long timeout)
- {
-       struct device *dev = musb->controller;
-       struct dsps_glue *glue = dev_get_drvdata(dev->parent);
-       if (timeout == 0)
-               timeout = jiffies + msecs_to_jiffies(3);
-       /* Never idle if active, or when VBUS timeout is not set as host */
-       if (musb->is_active || (musb->a_wait_bcon == 0 &&
-                               musb->xceiv->state == OTG_STATE_A_WAIT_BCON)) {
-               dev_dbg(musb->controller, "%s active, deleting timer\n",
-                               usb_otg_state_string(musb->xceiv->state));
-               del_timer(&glue->timer);
-               glue->last_timer = jiffies;
-               return;
-       }
-       if (musb->port_mode == MUSB_PORT_MODE_HOST)
-               return;
-       if (time_after(glue->last_timer, timeout) &&
-                               timer_pending(&glue->timer)) {
-               dev_dbg(musb->controller,
-                       "Longer idle timer already pending, ignoring...\n");
-               return;
-       }
-       glue->last_timer = timeout;
-       dev_dbg(musb->controller, "%s inactive, starting idle timer for %u ms\n",
-               usb_otg_state_string(musb->xceiv->state),
-                       jiffies_to_msecs(timeout - jiffies));
-       mod_timer(&glue->timer, timeout);
- }
  static irqreturn_t dsps_interrupt(int irq, void *hci)
  {
        struct musb  *musb = hci;
@@@ -443,7 -445,7 +445,7 @@@ static int get_musb_port_mode(struct de
        case USB_DR_MODE_OTG:
        default:
                return MUSB_PORT_MODE_DUAL_ROLE;
 -      };
 +      }
  }
  
  static int dsps_create_musb_pdev(struct dsps_glue *glue,
@@@ -535,9 -537,6 +537,9 @@@ static int dsps_probe(struct platform_d
        struct dsps_glue *glue;
        int ret;
  
 +      if (!strcmp(pdev->name, "musb-hdrc"))
 +              return -ENODEV;
 +
        match = of_match_node(musb_dsps_of_match, pdev->dev.of_node);
        if (!match) {
                dev_err(&pdev->dev, "fail to get matching of_match struct\n");
@@@ -631,7 -630,7 +633,7 @@@ static struct platform_driver dsps_usbs
        .remove         = dsps_remove,
        .driver         = {
                .name   = "musb-dsps",
-               .of_match_table = of_match_ptr(musb_dsps_of_match),
+               .of_match_table = musb_dsps_of_match,
        },
  };
  
index d1d6b83aabca61df43dffccf57ccbe7687cbe399,d8bbdb366beb83ab0a705678ab05453b08f4951c..9af6bba5eac964bb7195e78815b22bc1958c6c3c
  
  #include "musb_core.h"
  
 -/*
 -* Program the HDRC to start (enable interrupts, dma, etc.).
 -*/
 -static void musb_start(struct musb *musb)
 -{
 -      void __iomem    *regs = musb->mregs;
 -      u8              devctl = musb_readb(regs, MUSB_DEVCTL);
 -
 -      dev_dbg(musb->controller, "<== devctl %02x\n", devctl);
 -
 -      /*  Set INT enable registers, enable interrupts */
 -      musb->intrtxe = musb->epmask;
 -      musb_writew(regs, MUSB_INTRTXE, musb->intrtxe);
 -      musb->intrrxe = musb->epmask & 0xfffe;
 -      musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
 -      musb_writeb(regs, MUSB_INTRUSBE, 0xf7);
 -
 -      musb_writeb(regs, MUSB_TESTMODE, 0);
 -
 -      /* put into basic highspeed mode and start session */
 -      musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
 -                                              | MUSB_POWER_HSENAB
 -                                              /* ENSUSPEND wedges tusb */
 -                                              /* | MUSB_POWER_ENSUSPEND */
 -                                              );
 -
 -      musb->is_active = 0;
 -      devctl = musb_readb(regs, MUSB_DEVCTL);
 -      devctl &= ~MUSB_DEVCTL_SESSION;
 -
 -      /* session started after:
 -       * (a) ID-grounded irq, host mode;
 -       * (b) vbus present/connect IRQ, peripheral mode;
 -       * (c) peripheral initiates, using SRP
 -       */
 -      if (musb->port_mode != MUSB_PORT_MODE_HOST &&
 -          (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
 -              musb->is_active = 1;
 -      } else {
 -              devctl |= MUSB_DEVCTL_SESSION;
 -      }
 -
 -      musb_platform_enable(musb);
 -      musb_writeb(regs, MUSB_DEVCTL, devctl);
 -}
 -
  static void musb_port_suspend(struct musb *musb, bool do_suspend)
  {
        struct usb_otg  *otg = musb->xceiv->otg;
@@@ -220,6 -266,23 +220,23 @@@ int musb_hub_status_data(struct usb_hc
        return retval;
  }
  
+ static int musb_has_gadget(struct musb *musb)
+ {
+       /*
+        * In host-only mode we start a connection right away. In OTG mode
+        * we have to wait until we loaded a gadget. We don't really need a
+        * gadget if we operate as a host but we should not start a session
+        * as a device without a gadget or else we explode.
+        */
+ #ifdef CONFIG_USB_MUSB_HOST
+       return 1;
+ #else
+       if (musb->port_mode == MUSB_PORT_MODE_HOST)
+               return 1;
+       return musb->g.dev.driver != NULL;
+ #endif
+ }
  int musb_hub_control(
        struct usb_hcd  *hcd,
        u16             typeReq,
                         * initialization logic, e.g. for OTG, or change any
                         * logic relating to VBUS power-up.
                         */
-                       if (!hcd->self.is_b_host)
+                       if (!hcd->self.is_b_host && musb_has_gadget(musb))
                                musb_start(musb);
                        break;
                case USB_PORT_FEAT_RESET:
index 9eab645fed8b71856041ab925266f6ae4bc8303a,cefafdcbe3a62e33b11d6494a3f458ec1c825da7..2a408cdaf7b2c7102098faac6d29727505f41c91
@@@ -38,7 -38,6 +38,7 @@@
  #include <linux/delay.h>
  #include <linux/usb/musb-omap.h>
  #include <linux/usb/omap_control_usb.h>
 +#include <linux/of_platform.h>
  
  #include "musb_core.h"
  #include "omap2430.h"
@@@ -306,6 -305,9 +306,9 @@@ static void omap_musb_set_mailbox(struc
        default:
                dev_dbg(dev, "ID float\n");
        }
+       atomic_notifier_call_chain(&musb->xceiv->notifier,
+                       musb->xceiv->last_event, NULL);
  }
  
  
@@@ -349,21 -351,11 +352,21 @@@ static int omap2430_musb_init(struct mu
         * up through ULPI.  TWL4030-family PMICs include one,
         * which needs a driver, drivers aren't always needed.
         */
 -      if (dev->parent->of_node)
 +      if (dev->parent->of_node) {
 +              musb->phy = devm_phy_get(dev->parent, "usb2-phy");
 +
 +              /* We can't totally remove musb->xceiv as of now because
 +               * musb core uses xceiv.state and xceiv.otg. Once we have
 +               * a separate state machine to handle otg, these can be moved
 +               * out of xceiv and then we can start using the generic PHY
 +               * framework
 +               */
                musb->xceiv = devm_usb_get_phy_by_phandle(dev->parent,
                    "usb-phy", 0);
 -      else
 +      } else {
                musb->xceiv = devm_usb_get_phy_dev(dev, 0);
 +              musb->phy = devm_phy_get(dev, "usb");
 +      }
  
        if (IS_ERR(musb->xceiv)) {
                status = PTR_ERR(musb->xceiv);
                return -EPROBE_DEFER;
        }
  
 +      if (IS_ERR(musb->phy)) {
 +              pr_err("HS USB OTG: no PHY configured\n");
 +              return PTR_ERR(musb->phy);
 +      }
        musb->isr = omap2430_musb_interrupt;
  
        status = pm_runtime_get_sync(dev);
        if (glue->status != OMAP_MUSB_UNKNOWN)
                omap_musb_set_mailbox(glue);
  
 -      usb_phy_init(musb->xceiv);
 +      phy_init(musb->phy);
  
        pm_runtime_put_noidle(musb->controller);
        return 0;
@@@ -475,7 -463,6 +478,7 @@@ static int omap2430_musb_exit(struct mu
        del_timer_sync(&musb_idle_timer);
  
        omap2430_low_level_exit(musb);
 +      phy_exit(musb->phy);
  
        return 0;
  }
@@@ -525,12 -512,8 +528,12 @@@ static int omap2430_probe(struct platfo
        glue->dev                       = &pdev->dev;
        glue->musb                      = musb;
        glue->status                    = OMAP_MUSB_UNKNOWN;
 +      glue->control_otghs = ERR_PTR(-ENODEV);
  
        if (np) {
 +              struct device_node *control_node;
 +              struct platform_device *control_pdev;
 +
                pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
                if (!pdata) {
                        dev_err(&pdev->dev,
                of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
                of_property_read_u32(np, "power", (u32 *)&pdata->power);
                config->multipoint = of_property_read_bool(np, "multipoint");
 -              pdata->has_mailbox = of_property_read_bool(np,
 -                  "ti,has-mailbox");
  
                pdata->board_data       = data;
                pdata->config           = config;
 -      }
  
 -      if (pdata->has_mailbox) {
 -              glue->control_otghs = omap_get_control_dev();
 -              if (IS_ERR(glue->control_otghs)) {
 -                      dev_vdbg(&pdev->dev, "Failed to get control device\n");
 -                      ret = PTR_ERR(glue->control_otghs);
 -                      goto err2;
 +              control_node = of_parse_phandle(np, "ctrl-module", 0);
 +              if (control_node) {
 +                      control_pdev = of_find_device_by_node(control_node);
 +                      if (!control_pdev) {
 +                              dev_err(&pdev->dev, "Failed to get control device\n");
 +                              ret = -EINVAL;
 +                              goto err2;
 +                      }
 +                      glue->control_otghs = &control_pdev->dev;
                }
 -      } else {
 -              glue->control_otghs = ERR_PTR(-ENODEV);
        }
        pdata->platform_ops             = &omap2430_ops;
  
@@@ -656,7 -641,7 +659,7 @@@ static int omap2430_runtime_suspend(str
                                OTG_INTERFSEL);
  
                omap2430_low_level_exit(musb);
 -              usb_phy_set_suspend(musb->xceiv, 1);
 +              phy_power_off(musb->phy);
        }
  
        return 0;
@@@ -671,7 -656,8 +674,7 @@@ static int omap2430_runtime_resume(stru
                omap2430_low_level_init(musb);
                musb_writel(musb->mregs, OTG_INTERFSEL,
                                musb->context.otg_interfsel);
 -
 -              usb_phy_set_suspend(musb->xceiv, 0);
 +              phy_power_on(musb->phy);
        }
  
        return 0;
diff --combined drivers/usb/phy/Kconfig
index 64b8bef1919e7e61dfcfc3c7f7bc4caff1486d1e,c0c8cd37648e0ec923f8cd193ecba405a1047560..08e2f39027ec00ae0a7c5ae07b46fdd1cdbfae8f
@@@ -66,6 -66,17 +66,6 @@@ config OMAP_CONTROL_US
          power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an
          additional register to power on USB3 PHY.
  
 -config OMAP_USB2
 -      tristate "OMAP USB2 PHY Driver"
 -      depends on ARCH_OMAP2PLUS
 -      select OMAP_CONTROL_USB
 -      select USB_PHY
 -      help
 -        Enable this to support the transceiver that is part of SOC. This
 -        driver takes care of all the PHY functionality apart from comparator.
 -        The USB OTG controller communicates with the comparator using this
 -        driver.
 -
  config OMAP_USB3
        tristate "OMAP USB3 PHY Driver"
        depends on ARCH_OMAP2PLUS || COMPILE_TEST
@@@ -82,7 -93,6 +82,7 @@@ config AM335X_CONTROL_US
  
  config AM335X_PHY_USB
        tristate "AM335x USB PHY Driver"
 +      depends on ARM || COMPILE_TEST
        select USB_PHY
        select AM335X_CONTROL_USB
        select NOP_USB_XCEIV
@@@ -113,6 -123,16 +113,6 @@@ config SAMSUNG_USB3PH
          Enable this to support Samsung USB 3.0 (Super Speed) phy controller
          for samsung SoCs.
  
 -config TWL4030_USB
 -      tristate "TWL4030 USB Transceiver Driver"
 -      depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
 -      select USB_PHY
 -      help
 -        Enable this to support the USB OTG transceiver on TWL4030
 -        family chips (including the TWL5030 and TPS659x0 devices).
 -        This transceiver supports high and full speed devices plus,
 -        in host mode, low speed.
 -
  config TWL6030_USB
        tristate "TWL6030 USB Transceiver Driver"
        depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS
@@@ -194,6 -214,19 +194,19 @@@ config USB_RCAR_PH
          To compile this driver as a module, choose M here: the
          module will be called phy-rcar-usb.
  
+ config USB_RCAR_GEN2_PHY
+       tristate "Renesas R-Car Gen2 USB PHY support"
+       depends on ARCH_R8A7790 || ARCH_R8A7791 || COMPILE_TEST
+       select USB_PHY
+       help
+         Say Y here to add support for the Renesas R-Car Gen2 USB PHY driver.
+         It is typically used to control internal USB PHY for USBHS,
+         and to configure shared USB channels 0 and 2.
+         This driver supports R8A7790 and R8A7791.
+         To compile this driver as a module, choose M here: the
+         module will be called phy-rcar-gen2-usb.
  config USB_ULPI
        bool "Generic ULPI Transceiver Driver"
        depends on ARM
diff --combined drivers/usb/phy/Makefile
index 9c3736109c2cb3ee35e0fa866b9b7cd3ee1df97b,8c5b14764b72896ec9d641aa8dc02853c6a204cd..022c1da7fb786ffb8a1228e6fc890d442941e9ae
@@@ -15,10 -15,12 +15,10 @@@ obj-$(CONFIG_NOP_USB_XCEIV)                += phy-gen
  obj-$(CONFIG_OMAP_CONTROL_USB)                += phy-omap-control.o
  obj-$(CONFIG_AM335X_CONTROL_USB)      += phy-am335x-control.o
  obj-$(CONFIG_AM335X_PHY_USB)          += phy-am335x.o
 -obj-$(CONFIG_OMAP_USB2)                       += phy-omap-usb2.o
  obj-$(CONFIG_OMAP_USB3)                       += phy-omap-usb3.o
  obj-$(CONFIG_SAMSUNG_USBPHY)          += phy-samsung-usb.o
  obj-$(CONFIG_SAMSUNG_USB2PHY)         += phy-samsung-usb2.o
  obj-$(CONFIG_SAMSUNG_USB3PHY)         += phy-samsung-usb3.o
 -obj-$(CONFIG_TWL4030_USB)             += phy-twl4030-usb.o
  obj-$(CONFIG_TWL6030_USB)             += phy-twl6030-usb.o
  obj-$(CONFIG_USB_EHCI_TEGRA)          += phy-tegra-usb.o
  obj-$(CONFIG_USB_GPIO_VBUS)           += phy-gpio-vbus-usb.o
@@@ -27,5 -29,6 +27,6 @@@ obj-$(CONFIG_USB_MSM_OTG)             += phy-msm-u
  obj-$(CONFIG_USB_MV_OTG)              += phy-mv-usb.o
  obj-$(CONFIG_USB_MXS_PHY)             += phy-mxs-usb.o
  obj-$(CONFIG_USB_RCAR_PHY)            += phy-rcar-usb.o
+ obj-$(CONFIG_USB_RCAR_GEN2_PHY)               += phy-rcar-gen2-usb.o
  obj-$(CONFIG_USB_ULPI)                        += phy-ulpi.o
  obj-$(CONFIG_USB_ULPI_VIEWPORT)               += phy-ulpi-viewport.o
index 11d85b9c1b081af6a9f4f30ac3c1458766ed4238,42f3b71a97754cb9fde449a8350dc3daee2c06c7..cc8d818a83be40f58ae5ce29a60b08ca9b0ea8f5
@@@ -9,10 -9,11 +9,11 @@@ struct usb_phy_gen_xceiv_platform_data 
  
        /* if set fails with -EPROBE_DEFER if can't get regulator */
        unsigned int needs_vcc:1;
-       unsigned int needs_reset:1;
+       unsigned int needs_reset:1;     /* deprecated */
+       int gpio_reset;
  };
  
 -#if IS_ENABLED(CONFIG_NOP_USB_XCEIV)
 +#if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))
  /* sometimes transceivers are accessed only through e.g. ULPI */
  extern void usb_nop_xceiv_register(void);
  extern void usb_nop_xceiv_unregister(void);