The isp1760 driver registration function returns an error if USB is
disabled. This made sense when the driver only supported host
controllers, but now that it supports peripheral controllers host
support isn't mandatory anymore.
Fix this by returning an error only when both the HCD and UDC functions
are disabled, either through the kernel configuration or at runtime.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
struct device *dev, unsigned int devflags)
{
struct isp1760_device *isp;
struct device *dev, unsigned int devflags)
{
struct isp1760_device *isp;
+ bool udc_disabled = !(devflags & ISP1760_FLAG_ISP1761);
+ /*
+ * If neither the HCD not the UDC is enabled return an error, as no
+ * device would be registered.
+ */
+ if ((!IS_ENABLED(CONFIG_USB_ISP1760_HCD) || usb_disabled()) &&
+ (!IS_ENABLED(CONFIG_USB_ISP1761_UDC) || udc_disabled))
return -ENODEV;
/* prevent usb-core allocating DMA pages */
return -ENODEV;
/* prevent usb-core allocating DMA pages */
- ret = isp1760_hcd_register(&isp->hcd, isp->regs, mem, irq,
- irqflags | IRQF_SHARED, dev);
- if (ret < 0)
- return ret;
+ if (IS_ENABLED(CONFIG_USB_ISP1760_HCD) && !usb_disabled()) {
+ ret = isp1760_hcd_register(&isp->hcd, isp->regs, mem, irq,
+ irqflags | IRQF_SHARED, dev);
+ if (ret < 0)
+ return ret;
+ }
- if (devflags & ISP1760_FLAG_ISP1761) {
+ if (IS_ENABLED(CONFIG_USB_ISP1761_UDC) && !udc_disabled) {
ret = isp1760_udc_register(isp, irq, irqflags | IRQF_SHARED |
IRQF_DISABLED);
if (ret < 0) {
ret = isp1760_udc_register(isp, irq, irqflags | IRQF_SHARED |
IRQF_DISABLED);
if (ret < 0) {
{
struct isp1760_device *isp = dev_get_drvdata(dev);
{
struct isp1760_device *isp = dev_get_drvdata(dev);
- if (isp->devflags & ISP1760_FLAG_ISP1761)
- isp1760_udc_unregister(isp);
-
+ isp1760_udc_unregister(isp);
isp1760_hcd_unregister(&isp->hcd);
}
isp1760_hcd_unregister(&isp->hcd);
}
void isp1760_hcd_unregister(struct isp1760_hcd *priv)
{
void isp1760_hcd_unregister(struct isp1760_hcd *priv)
{
+ if (!priv->hcd)
+ return;
+
usb_remove_hcd(priv->hcd);
usb_put_hcd(priv->hcd);
}
usb_remove_hcd(priv->hcd);
usb_put_hcd(priv->hcd);
}
{
struct isp1760_udc *udc = &isp->udc;
{
struct isp1760_udc *udc = &isp->udc;
+ if (!udc->isp)
+ return;
+
usb_del_gadget_udc(&udc->gadget);
free_irq(udc->irq, udc);
usb_del_gadget_udc(&udc->gadget);
free_irq(udc->irq, udc);