Merge 5.15-rc3 into usb-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Sep 2021 14:34:40 +0000 (16:34 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Sep 2021 14:34:40 +0000 (16:34 +0200)
We need the USB fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1  2 
drivers/usb/class/cdc-acm.c
drivers/usb/core/hcd.c
drivers/usb/dwc3/core.c
drivers/usb/gadget/function/f_uac2.c
drivers/usb/host/ehci-hcd.c
drivers/usb/musb/tusb6010.c

index d77e30625f4d3d974bfad083296933b74dd4b1b4,4e2f1552f4b78386eae859abb2571087490f5750..1a84b24d199f658db2e8fb80fa337782d3a39cc5
@@@ -726,7 -726,8 +726,8 @@@ static void acm_port_destruct(struct tt
  {
        struct acm *acm = container_of(port, struct acm, port);
  
-       acm_release_minor(acm);
+       if (acm->minor != ACM_MINOR_INVALID)
+               acm_release_minor(acm);
        usb_put_intf(acm->control);
        kfree(acm->country_codes);
        kfree(acm);
@@@ -1323,8 -1324,10 +1324,10 @@@ made_compressed_probe
        usb_get_intf(acm->control); /* undone in destruct() */
  
        minor = acm_alloc_minor(acm);
-       if (minor < 0)
+       if (minor < 0) {
+               acm->minor = ACM_MINOR_INVALID;
                goto err_put_port;
+       }
  
        acm->minor = minor;
        acm->dev = usb_dev;
@@@ -1848,6 -1851,7 +1851,6 @@@ static const struct usb_device_id acm_i
        { NOKIA_PCSUITE_ACM_INFO(0x0071), }, /* Nokia N82 */
        { NOKIA_PCSUITE_ACM_INFO(0x04F0), }, /* Nokia N95 & N95-3 NAM */
        { NOKIA_PCSUITE_ACM_INFO(0x0070), }, /* Nokia N95 8GB  */
 -      { NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */
        { NOKIA_PCSUITE_ACM_INFO(0x0099), }, /* Nokia 6210 Navigator, RM-367 */
        { NOKIA_PCSUITE_ACM_INFO(0x0128), }, /* Nokia 6210 Navigator, RM-419 */
        { NOKIA_PCSUITE_ACM_INFO(0x008f), }, /* Nokia 6220 Classic */
diff --combined drivers/usb/core/hcd.c
index 104bc1ca8c44705151f82e008267fd91a6e81e1a,7ee6e4cc0d89e8c4d024a6d4f682e6ea8185c070..a3311e93784754aecaa7065b9bd22be96a337869
@@@ -2732,14 -2732,14 +2732,14 @@@ static int usb_hcd_request_irqs(struct 
                hcd->irq = irqnum;
                dev_info(hcd->self.controller, "irq %d, %s 0x%08llx\n", irqnum,
                                (hcd->driver->flags & HCD_MEMORY) ?
 -                                      "io mem" : "io base",
 -                                      (unsigned long long)hcd->rsrc_start);
 +                                      "io mem" : "io port",
 +                              (unsigned long long)hcd->rsrc_start);
        } else {
                hcd->irq = 0;
                if (hcd->rsrc_start)
                        dev_info(hcd->self.controller, "%s 0x%08llx\n",
                                        (hcd->driver->flags & HCD_MEMORY) ?
 -                                      "io mem" : "io base",
 +                                              "io mem" : "io port",
                                        (unsigned long long)hcd->rsrc_start);
        }
        return 0;
@@@ -2760,6 -2760,26 +2760,26 @@@ static void usb_put_invalidate_rhdev(st
        usb_put_dev(rhdev);
  }
  
+ /**
+  * usb_stop_hcd - Halt the HCD
+  * @hcd: the usb_hcd that has to be halted
+  *
+  * Stop the root-hub polling timer and invoke the HCD's ->stop callback.
+  */
+ static void usb_stop_hcd(struct usb_hcd *hcd)
+ {
+       hcd->rh_pollable = 0;
+       clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+       del_timer_sync(&hcd->rh_timer);
+       hcd->driver->stop(hcd);
+       hcd->state = HC_STATE_HALT;
+       /* In case the HCD restarted the timer, stop it again. */
+       clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
+       del_timer_sync(&hcd->rh_timer);
+ }
  /**
   * usb_add_hcd - finish generic HCD structure initialization and register
   * @hcd: the usb_hcd structure to initialize
@@@ -2775,6 -2795,7 +2795,7 @@@ int usb_add_hcd(struct usb_hcd *hcd
  {
        int retval;
        struct usb_device *rhdev;
+       struct usb_hcd *shared_hcd;
  
        if (!hcd->skip_phy_initialization && usb_hcd_is_primary_hcd(hcd)) {
                hcd->phy_roothub = usb_phy_roothub_alloc(hcd->self.sysdev);
                goto err_hcd_driver_start;
        }
  
+       /* starting here, usbcore will pay attention to the shared HCD roothub */
+       shared_hcd = hcd->shared_hcd;
+       if (!usb_hcd_is_primary_hcd(hcd) && shared_hcd && HCD_DEFER_RH_REGISTER(shared_hcd)) {
+               retval = register_root_hub(shared_hcd);
+               if (retval != 0)
+                       goto err_register_root_hub;
+               if (shared_hcd->uses_new_polling && HCD_POLL_RH(shared_hcd))
+                       usb_hcd_poll_rh_status(shared_hcd);
+       }
        /* starting here, usbcore will pay attention to this root hub */
-       retval = register_root_hub(hcd);
-       if (retval != 0)
-               goto err_register_root_hub;
+       if (!HCD_DEFER_RH_REGISTER(hcd)) {
+               retval = register_root_hub(hcd);
+               if (retval != 0)
+                       goto err_register_root_hub;
  
-       if (hcd->uses_new_polling && HCD_POLL_RH(hcd))
-               usb_hcd_poll_rh_status(hcd);
+               if (hcd->uses_new_polling && HCD_POLL_RH(hcd))
+                       usb_hcd_poll_rh_status(hcd);
+       }
  
        return retval;
  
  err_register_root_hub:
-       hcd->rh_pollable = 0;
-       clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
-       del_timer_sync(&hcd->rh_timer);
-       hcd->driver->stop(hcd);
-       hcd->state = HC_STATE_HALT;
-       clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
-       del_timer_sync(&hcd->rh_timer);
+       usb_stop_hcd(hcd);
  err_hcd_driver_start:
        if (usb_hcd_is_primary_hcd(hcd) && hcd->irq > 0)
                free_irq(irqnum, hcd);
@@@ -2985,6 -3013,7 +3013,7 @@@ EXPORT_SYMBOL_GPL(usb_add_hcd)
  void usb_remove_hcd(struct usb_hcd *hcd)
  {
        struct usb_device *rhdev = hcd->self.root_hub;
+       bool rh_registered;
  
        dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);
  
  
        dev_dbg(hcd->self.controller, "roothub graceful disconnect\n");
        spin_lock_irq (&hcd_root_hub_lock);
+       rh_registered = hcd->rh_registered;
        hcd->rh_registered = 0;
        spin_unlock_irq (&hcd_root_hub_lock);
  
        cancel_work_sync(&hcd->died_work);
  
        mutex_lock(&usb_bus_idr_lock);
-       usb_disconnect(&rhdev);         /* Sets rhdev to NULL */
+       if (rh_registered)
+               usb_disconnect(&rhdev);         /* Sets rhdev to NULL */
        mutex_unlock(&usb_bus_idr_lock);
  
        /*
         * interrupt occurs), but usb_hcd_poll_rh_status() won't invoke
         * the hub_status_data() callback.
         */
-       hcd->rh_pollable = 0;
-       clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
-       del_timer_sync(&hcd->rh_timer);
-       hcd->driver->stop(hcd);
-       hcd->state = HC_STATE_HALT;
-       /* In case the HCD restarted the timer, stop it again. */
-       clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
-       del_timer_sync(&hcd->rh_timer);
+       usb_stop_hcd(hcd);
  
        if (usb_hcd_is_primary_hcd(hcd)) {
                if (hcd->irq > 0)
diff --combined drivers/usb/dwc3/core.c
index ced366ff839becb8fce2f550cacb5d0da8d0a84f,0104a80b185e17a2d4ef126d75991ed2562bec59..643239d7d370078d9288d295ee67256b7cf830b1
@@@ -26,7 -26,6 +26,7 @@@
  #include <linux/acpi.h>
  #include <linux/pinctrl/consumer.h>
  #include <linux/reset.h>
 +#include <linux/bitfield.h>
  
  #include <linux/usb/ch9.h>
  #include <linux/usb/gadget.h>
@@@ -265,19 -264,6 +265,6 @@@ static int dwc3_core_soft_reset(struct 
  {
        u32             reg;
        int             retries = 1000;
-       int             ret;
-       usb_phy_init(dwc->usb2_phy);
-       usb_phy_init(dwc->usb3_phy);
-       ret = phy_init(dwc->usb2_generic_phy);
-       if (ret < 0)
-               return ret;
-       ret = phy_init(dwc->usb3_generic_phy);
-       if (ret < 0) {
-               phy_exit(dwc->usb2_generic_phy);
-               return ret;
-       }
  
        /*
         * We're resetting only the device side because, if we're in host mode,
                        udelay(1);
        } while (--retries);
  
-       phy_exit(dwc->usb3_generic_phy);
-       phy_exit(dwc->usb2_generic_phy);
        return -ETIMEDOUT;
  
  done:
@@@ -352,29 -335,6 +336,29 @@@ static void dwc3_frame_length_adjustmen
        }
  }
  
 +/**
 + * dwc3_ref_clk_period - Reference clock period configuration
 + *            Default reference clock period depends on hardware
 + *            configuration. For systems with reference clock that differs
 + *            from the default, this will set clock period in DWC3_GUCTL
 + *            register.
 + * @dwc: Pointer to our controller context structure
 + * @ref_clk_per: reference clock period in ns
 + */
 +static void dwc3_ref_clk_period(struct dwc3 *dwc)
 +{
 +      u32 reg;
 +
 +      if (dwc->ref_clk_per == 0)
 +              return;
 +
 +      reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
 +      reg &= ~DWC3_GUCTL_REFCLKPER_MASK;
 +      reg |=  FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, dwc->ref_clk_per);
 +      dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
 +}
 +
 +
  /**
   * dwc3_free_one_event_buffer - Frees one event buffer
   * @dwc: Pointer to our controller context structure
@@@ -1006,9 -966,21 +990,21 @@@ static int dwc3_core_init(struct dwc3 *
                dwc->phys_ready = true;
        }
  
+       usb_phy_init(dwc->usb2_phy);
+       usb_phy_init(dwc->usb3_phy);
+       ret = phy_init(dwc->usb2_generic_phy);
+       if (ret < 0)
+               goto err0a;
+       ret = phy_init(dwc->usb3_generic_phy);
+       if (ret < 0) {
+               phy_exit(dwc->usb2_generic_phy);
+               goto err0a;
+       }
        ret = dwc3_core_soft_reset(dwc);
        if (ret)
-               goto err0a;
+               goto err1;
  
        if (hw_mode == DWC3_GHWPARAMS0_MODE_DRD &&
            !DWC3_VER_IS_WITHIN(DWC3, ANY, 194A)) {
        /* Adjust Frame Length */
        dwc3_frame_length_adjustment(dwc);
  
 +      /* Adjust Reference Clock Period */
 +      dwc3_ref_clk_period(dwc);
 +
        dwc3_set_incr_burst_type(dwc);
  
        usb_phy_set_suspend(dwc->usb2_phy, 0);
@@@ -1420,8 -1389,6 +1416,8 @@@ static void dwc3_get_properties(struct 
                                    &dwc->hsphy_interface);
        device_property_read_u32(dev, "snps,quirk-frame-length-adjustment",
                                 &dwc->fladj);
 +      device_property_read_u32(dev, "snps,ref-clock-period-ns",
 +                               &dwc->ref_clk_per);
  
        dwc->dis_metastability_quirk = device_property_read_bool(dev,
                                "snps,dis_metastability_quirk");
index 8659784dcc78609b3083771046a5f37b6b8ccc74,be864560bfeaaace69b716bd32b8e1187d36442f..d5a4f60bdcb9af7d09ce07ad4de9dffdbfea624a
@@@ -406,6 -406,14 +406,14 @@@ static struct usb_endpoint_descriptor s
        .bInterval = 4,
  };
  
+ static struct usb_ss_ep_comp_descriptor ss_epin_fback_desc_comp = {
+       .bLength                = sizeof(ss_epin_fback_desc_comp),
+       .bDescriptorType        = USB_DT_SS_ENDPOINT_COMP,
+       .bMaxBurst              = 0,
+       .bmAttributes           = 0,
+       .wBytesPerInterval      = cpu_to_le16(4),
+ };
  
  /* Audio Streaming IN Interface - Alt0 */
  static struct usb_interface_descriptor std_as_in_if0_desc = {
@@@ -597,6 -605,7 +605,7 @@@ static struct usb_descriptor_header *ss
        (struct usb_descriptor_header *)&ss_epout_desc_comp,
        (struct usb_descriptor_header *)&as_iso_out_desc,
        (struct usb_descriptor_header *)&ss_epin_fback_desc,
+       (struct usb_descriptor_header *)&ss_epin_fback_desc_comp,
  
        (struct usb_descriptor_header *)&std_as_in_if0_desc,
        (struct usb_descriptor_header *)&std_as_in_if1_desc,
@@@ -705,6 -714,7 +714,7 @@@ static void setup_headers(struct f_uac2
  {
        struct usb_ss_ep_comp_descriptor *epout_desc_comp = NULL;
        struct usb_ss_ep_comp_descriptor *epin_desc_comp = NULL;
+       struct usb_ss_ep_comp_descriptor *epin_fback_desc_comp = NULL;
        struct usb_endpoint_descriptor *epout_desc;
        struct usb_endpoint_descriptor *epin_desc;
        struct usb_endpoint_descriptor *epin_fback_desc;
                epout_desc_comp = &ss_epout_desc_comp;
                epin_desc_comp = &ss_epin_desc_comp;
                epin_fback_desc = &ss_epin_fback_desc;
+               epin_fback_desc_comp = &ss_epin_fback_desc_comp;
                ep_int_desc = &ss_ep_int_desc;
        }
  
                headers[i++] = USBDHDR(&out_clk_src_desc);
                headers[i++] = USBDHDR(&usb_out_it_desc);
  
 -    if (FUOUT_EN(opts))
 -      headers[i++] = USBDHDR(out_feature_unit_desc);
 -  }
 +              if (FUOUT_EN(opts))
 +                      headers[i++] = USBDHDR(out_feature_unit_desc);
 +      }
  
        if (EPIN_EN(opts)) {
                headers[i++] = USBDHDR(&io_in_it_desc);
  
 -    if (FUIN_EN(opts))
 -      headers[i++] = USBDHDR(in_feature_unit_desc);
 +              if (FUIN_EN(opts))
 +                      headers[i++] = USBDHDR(in_feature_unit_desc);
  
                headers[i++] = USBDHDR(&usb_in_ot_desc);
        }
        if (EPOUT_EN(opts))
                headers[i++] = USBDHDR(&io_out_ot_desc);
  
 -  if (FUOUT_EN(opts) || FUIN_EN(opts))
 -      headers[i++] = USBDHDR(ep_int_desc);
 +      if (FUOUT_EN(opts) || FUIN_EN(opts))
 +              headers[i++] = USBDHDR(ep_int_desc);
  
 -  if (EPOUT_EN(opts)) {
 +      if (EPOUT_EN(opts)) {
                headers[i++] = USBDHDR(&std_as_out_if0_desc);
                headers[i++] = USBDHDR(&std_as_out_if1_desc);
                headers[i++] = USBDHDR(&as_out_hdr_desc);
  
                headers[i++] = USBDHDR(&as_iso_out_desc);
  
-               if (EPOUT_FBACK_IN_EN(opts))
+               if (EPOUT_FBACK_IN_EN(opts)) {
                        headers[i++] = USBDHDR(epin_fback_desc);
+                       if (epin_fback_desc_comp)
+                               headers[i++] = USBDHDR(epin_fback_desc_comp);
+               }
        }
  
        if (EPIN_EN(opts)) {
@@@ -1164,6 -1178,9 +1178,9 @@@ afunc_bind(struct usb_configuration *cf
        agdev->out_ep_maxpsize = max_t(u16, agdev->out_ep_maxpsize,
                                le16_to_cpu(ss_epout_desc.wMaxPacketSize));
  
+       ss_epin_desc_comp.wBytesPerInterval = ss_epin_desc.wMaxPacketSize;
+       ss_epout_desc_comp.wBytesPerInterval = ss_epout_desc.wMaxPacketSize;
        // HS and SS endpoint addresses are copied from autoconfigured FS descriptors
        hs_ep_int_desc.bEndpointAddress = fs_ep_int_desc.bEndpointAddress;
        hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
index 55f92d25336b0a601a4fea1f3933b9cb8be4405d,1776c05d0a4865e5371e378a52fca60f4b6bbb6a..14408032162972d22d169021fdc495b0f94b361d
@@@ -26,6 -26,7 +26,7 @@@
  #include <linux/moduleparam.h>
  #include <linux/dma-mapping.h>
  #include <linux/debugfs.h>
+ #include <linux/platform_device.h>
  #include <linux/slab.h>
  
  #include <asm/byteorder.h>
@@@ -634,16 -635,7 +635,16 @@@ static int ehci_run (struct usb_hcd *hc
        /* Wait until HC become operational */
        ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
        msleep(5);
 -      rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT, 0, 100 * 1000);
 +
 +      /* For Aspeed, STS_HALT also depends on ASS/PSS status.
 +       * Check CMD_RUN instead.
 +       */
 +      if (ehci->is_aspeed)
 +              rc = ehci_handshake(ehci, &ehci->regs->command, CMD_RUN,
 +                                  1, 100 * 1000);
 +      else
 +              rc = ehci_handshake(ehci, &ehci->regs->status, STS_HALT,
 +                                  0, 100 * 1000);
  
        up_write(&ehci_cf_port_reset_rwsem);
  
@@@ -1287,29 -1279,39 +1288,39 @@@ MODULE_LICENSE ("GPL")
  
  #ifdef CONFIG_USB_EHCI_SH
  #include "ehci-sh.c"
- #define PLATFORM_DRIVER               ehci_hcd_sh_driver
  #endif
  
  #ifdef CONFIG_PPC_PS3
  #include "ehci-ps3.c"
- #define       PS3_SYSTEM_BUS_DRIVER   ps3_ehci_driver
  #endif
  
  #ifdef CONFIG_USB_EHCI_HCD_PPC_OF
  #include "ehci-ppc-of.c"
- #define OF_PLATFORM_DRIVER    ehci_hcd_ppc_of_driver
  #endif
  
  #ifdef CONFIG_XPS_USB_HCD_XILINX
  #include "ehci-xilinx-of.c"
- #define XILINX_OF_PLATFORM_DRIVER     ehci_hcd_xilinx_of_driver
  #endif
  
  #ifdef CONFIG_SPARC_LEON
  #include "ehci-grlib.c"
- #define PLATFORM_DRIVER               ehci_grlib_driver
  #endif
  
+ static struct platform_driver * const platform_drivers[] = {
+ #ifdef CONFIG_USB_EHCI_SH
+       &ehci_hcd_sh_driver,
+ #endif
+ #ifdef CONFIG_USB_EHCI_HCD_PPC_OF
+       &ehci_hcd_ppc_of_driver,
+ #endif
+ #ifdef CONFIG_XPS_USB_HCD_XILINX
+       &ehci_hcd_xilinx_of_driver,
+ #endif
+ #ifdef CONFIG_SPARC_LEON
+       &ehci_grlib_driver,
+ #endif
+ };
  static int __init ehci_hcd_init(void)
  {
        int retval = 0;
        ehci_debug_root = debugfs_create_dir("ehci", usb_debug_root);
  #endif
  
- #ifdef PLATFORM_DRIVER
-       retval = platform_driver_register(&PLATFORM_DRIVER);
+       retval = platform_register_drivers(platform_drivers, ARRAY_SIZE(platform_drivers));
        if (retval < 0)
                goto clean0;
- #endif
- #ifdef PS3_SYSTEM_BUS_DRIVER
-       retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER);
-       if (retval < 0)
-               goto clean2;
- #endif
  
- #ifdef OF_PLATFORM_DRIVER
-       retval = platform_driver_register(&OF_PLATFORM_DRIVER);
+ #ifdef CONFIG_PPC_PS3
+       retval = ps3_ehci_driver_register(&ps3_ehci_driver);
        if (retval < 0)
-               goto clean3;
+               goto clean1;
  #endif
  
- #ifdef XILINX_OF_PLATFORM_DRIVER
-       retval = platform_driver_register(&XILINX_OF_PLATFORM_DRIVER);
-       if (retval < 0)
-               goto clean4;
- #endif
-       return retval;
+       return 0;
  
- #ifdef XILINX_OF_PLATFORM_DRIVER
-       /* platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER); */
- clean4:
- #endif
- #ifdef OF_PLATFORM_DRIVER
-       platform_driver_unregister(&OF_PLATFORM_DRIVER);
- clean3:
- #endif
- #ifdef PS3_SYSTEM_BUS_DRIVER
-       ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
- clean2:
+ #ifdef CONFIG_PPC_PS3
+ clean1:
  #endif
- #ifdef PLATFORM_DRIVER
-       platform_driver_unregister(&PLATFORM_DRIVER);
+       platform_unregister_drivers(platform_drivers, ARRAY_SIZE(platform_drivers));
  clean0:
- #endif
  #ifdef CONFIG_DYNAMIC_DEBUG
        debugfs_remove(ehci_debug_root);
        ehci_debug_root = NULL;
@@@ -1385,18 -1363,10 +1372,10 @@@ module_init(ehci_hcd_init)
  
  static void __exit ehci_hcd_cleanup(void)
  {
- #ifdef XILINX_OF_PLATFORM_DRIVER
-       platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER);
- #endif
- #ifdef OF_PLATFORM_DRIVER
-       platform_driver_unregister(&OF_PLATFORM_DRIVER);
- #endif
- #ifdef PLATFORM_DRIVER
-       platform_driver_unregister(&PLATFORM_DRIVER);
- #endif
- #ifdef PS3_SYSTEM_BUS_DRIVER
-       ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
+ #ifdef CONFIG_PPC_PS3
+       ps3_ehci_driver_unregister(&ps3_ehci_driver);
  #endif
+       platform_unregister_drivers(platform_drivers, ARRAY_SIZE(platform_drivers));
  #ifdef CONFIG_DYNAMIC_DEBUG
        debugfs_remove(ehci_debug_root);
  #endif
index e0347780907f1a6ec81e3597451dd7a802d2f61b,c968ecda42aa87d5e83ca58ea1ad6820fd7c75cd..7ed4cc348d993552223b718a722176b5ad943b72
@@@ -190,6 -190,7 +190,7 @@@ tusb_fifo_write_unaligned(void __iomem 
        }
        if (len > 0) {
                /* Write the rest 1 - 3 bytes to FIFO */
+               val = 0;
                memcpy(&val, buf, len);
                musb_writel(fifo, 0, val);
        }
@@@ -1103,11 -1104,6 +1104,11 @@@ static int tusb_musb_init(struct musb *
  
        /* dma address for async dma */
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 +      if (!mem) {
 +              pr_debug("no async dma resource?\n");
 +              ret = -ENODEV;
 +              goto done;
 +      }
        musb->async = mem->start;
  
        /* dma address for sync dma */