2011-10-12 15:08:26 +04:00
/**
* host . c - DesignWare USB3 DRD Controller Host Glue
*
* Copyright ( C ) 2011 Texas Instruments Incorporated - http : //www.ti.com
*
* Authors : Felipe Balbi < balbi @ ti . com > ,
*
2013-06-30 15:15:11 +04:00
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 of
* the License as published by the Free Software Foundation .
2011-10-12 15:08:26 +04:00
*
2013-06-30 15:15:11 +04:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
2011-10-12 15:08:26 +04:00
*/
# include <linux/platform_device.h>
# include "core.h"
int dwc3_host_init ( struct dwc3 * dwc )
{
2016-06-21 10:58:09 +03:00
struct property_entry props [ 2 ] ;
2011-10-12 15:08:26 +04:00
struct platform_device * xhci ;
2016-06-30 14:54:17 +03:00
int ret , irq ;
struct resource * res ;
struct platform_device * dwc3_pdev = to_platform_device ( dwc - > dev ) ;
irq = platform_get_irq_byname ( dwc3_pdev , " host " ) ;
if ( irq = = - EPROBE_DEFER )
return irq ;
if ( irq < = 0 ) {
irq = platform_get_irq_byname ( dwc3_pdev , " dwc_usb3 " ) ;
if ( irq = = - EPROBE_DEFER )
return irq ;
if ( irq < = 0 ) {
irq = platform_get_irq ( dwc3_pdev , 0 ) ;
if ( irq < = 0 ) {
if ( irq ! = - EPROBE_DEFER ) {
dev_err ( dwc - > dev ,
" missing host IRQ \n " ) ;
}
if ( ! irq )
irq = - EINVAL ;
return irq ;
} else {
res = platform_get_resource ( dwc3_pdev ,
IORESOURCE_IRQ , 0 ) ;
}
} else {
res = platform_get_resource_byname ( dwc3_pdev ,
IORESOURCE_IRQ ,
" dwc_usb3 " ) ;
}
} else {
res = platform_get_resource_byname ( dwc3_pdev , IORESOURCE_IRQ ,
" host " ) ;
}
dwc - > xhci_resources [ 1 ] . start = irq ;
dwc - > xhci_resources [ 1 ] . end = irq ;
dwc - > xhci_resources [ 1 ] . flags = res - > flags ;
dwc - > xhci_resources [ 1 ] . name = res - > name ;
2011-10-12 15:08:26 +04:00
2013-01-25 15:22:02 +04:00
xhci = platform_device_alloc ( " xhci-hcd " , PLATFORM_DEVID_AUTO ) ;
2011-10-12 15:08:26 +04:00
if ( ! xhci ) {
dev_err ( dwc - > dev , " couldn't allocate xHCI device \n " ) ;
2014-11-19 18:28:23 +03:00
return - ENOMEM ;
2011-10-12 15:08:26 +04:00
}
dma_set_coherent_mask ( & xhci - > dev , dwc - > dev - > coherent_dma_mask ) ;
xhci - > dev . parent = dwc - > dev ;
xhci - > dev . dma_mask = dwc - > dev - > dma_mask ;
xhci - > dev . dma_parms = dwc - > dev - > dma_parms ;
dwc - > xhci = xhci ;
2012-04-24 15:18:39 +04:00
ret = platform_device_add_resources ( xhci , dwc - > xhci_resources ,
DWC3_XHCI_RESOURCES_NUM ) ;
2011-10-12 15:08:26 +04:00
if ( ret ) {
dev_err ( dwc - > dev , " couldn't add resources to xHCI device \n " ) ;
goto err1 ;
}
2016-06-21 10:58:09 +03:00
memset ( props , 0 , sizeof ( struct property_entry ) * ARRAY_SIZE ( props ) ) ;
2014-07-04 18:01:26 +04:00
2016-06-21 10:58:09 +03:00
if ( dwc - > usb3_lpm_capable ) {
props [ 0 ] . name = " usb3-lpm-capable " ;
ret = platform_device_add_properties ( xhci , props ) ;
if ( ret ) {
dev_err ( dwc - > dev , " failed to add properties to xHCI \n " ) ;
goto err1 ;
}
2014-07-04 18:01:26 +04:00
}
2014-11-19 18:28:23 +03:00
phy_create_lookup ( dwc - > usb2_generic_phy , " usb2-phy " ,
dev_name ( & xhci - > dev ) ) ;
phy_create_lookup ( dwc - > usb3_generic_phy , " usb3-phy " ,
dev_name ( & xhci - > dev ) ) ;
2011-10-12 15:08:26 +04:00
ret = platform_device_add ( xhci ) ;
if ( ret ) {
dev_err ( dwc - > dev , " failed to register xHCI device \n " ) ;
2014-11-19 18:28:23 +03:00
goto err2 ;
2011-10-12 15:08:26 +04:00
}
return 0 ;
2014-11-19 18:28:23 +03:00
err2 :
phy_remove_lookup ( dwc - > usb2_generic_phy , " usb2-phy " ,
dev_name ( & xhci - > dev ) ) ;
phy_remove_lookup ( dwc - > usb3_generic_phy , " usb3-phy " ,
dev_name ( & xhci - > dev ) ) ;
2011-10-12 15:08:26 +04:00
err1 :
platform_device_put ( xhci ) ;
return ret ;
}
void dwc3_host_exit ( struct dwc3 * dwc )
{
2014-11-19 18:28:23 +03:00
phy_remove_lookup ( dwc - > usb2_generic_phy , " usb2-phy " ,
dev_name ( & dwc - > xhci - > dev ) ) ;
phy_remove_lookup ( dwc - > usb3_generic_phy , " usb3-phy " ,
dev_name ( & dwc - > xhci - > dev ) ) ;
2011-10-12 15:08:26 +04:00
platform_device_unregister ( dwc - > xhci ) ;
}