| From c2115b2b16421d93d4993f3fe4c520e91d6fe801 Mon Sep 17 00:00:00 2001 |
| From: Miquel Raynal <miquel.raynal@bootlin.com> |
| Date: Wed, 6 Oct 2021 00:16:31 +0200 |
| Subject: usb: musb: dsps: Fix the probe error path |
| |
| From: Miquel Raynal <miquel.raynal@bootlin.com> |
| |
| commit c2115b2b16421d93d4993f3fe4c520e91d6fe801 upstream. |
| |
| Commit 7c75bde329d7 ("usb: musb: musb_dsps: request_irq() after |
| initializing musb") has inverted the calls to |
| dsps_setup_optional_vbus_irq() and dsps_create_musb_pdev() without |
| updating correctly the error path. dsps_create_musb_pdev() allocates and |
| registers a new platform device which must be unregistered and freed |
| with platform_device_unregister(), and this is missing upon |
| dsps_setup_optional_vbus_irq() error. |
| |
| While on the master branch it seems not to trigger any issue, I observed |
| a kernel crash because of a NULL pointer dereference with a v5.10.70 |
| stable kernel where the patch mentioned above was backported. With this |
| kernel version, -EPROBE_DEFER is returned the first time |
| dsps_setup_optional_vbus_irq() is called which triggers the probe to |
| error out without unregistering the platform device. Unfortunately, on |
| the Beagle Bone Black Wireless, the platform device still living in the |
| system is being used by the USB Ethernet gadget driver, which during the |
| boot phase triggers the crash. |
| |
| My limited knowledge of the musb world prevents me to revert this commit |
| which was sent to silence a robot warning which, as far as I understand, |
| does not make sense. The goal of this patch was to prevent an IRQ to |
| fire before the platform device being registered. I think this cannot |
| ever happen due to the fact that enabling the interrupts is done by the |
| ->enable() callback of the platform musb device, and this platform |
| device must be already registered in order for the core or any other |
| user to use this callback. |
| |
| Hence, I decided to fix the error path, which might prevent future |
| errors on mainline kernels while also fixing older ones. |
| |
| Fixes: 7c75bde329d7 ("usb: musb: musb_dsps: request_irq() after initializing musb") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> |
| Link: https://lore.kernel.org/r/20211005221631.1529448-1-miquel.raynal@bootlin.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/usb/musb/musb_dsps.c | 4 +++- |
| 1 file changed, 3 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/usb/musb/musb_dsps.c |
| +++ b/drivers/usb/musb/musb_dsps.c |
| @@ -899,11 +899,13 @@ static int dsps_probe(struct platform_de |
| if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) { |
| ret = dsps_setup_optional_vbus_irq(pdev, glue); |
| if (ret) |
| - goto err; |
| + goto unregister_pdev; |
| } |
| |
| return 0; |
| |
| +unregister_pdev: |
| + platform_device_unregister(glue->musb); |
| err: |
| pm_runtime_disable(&pdev->dev); |
| iounmap(glue->usbss_base); |