@ -2077,6 +2077,23 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
return 0 ;
}
static void arm_smmu_bus_init ( void )
{
/* Oh, for a proper bus abstraction */
if ( ! iommu_present ( & platform_bus_type ) )
bus_set_iommu ( & platform_bus_type , & arm_smmu_ops ) ;
# ifdef CONFIG_ARM_AMBA
if ( ! iommu_present ( & amba_bustype ) )
bus_set_iommu ( & amba_bustype , & arm_smmu_ops ) ;
# endif
# ifdef CONFIG_PCI
if ( ! iommu_present ( & pci_bus_type ) ) {
pci_request_acs ( ) ;
bus_set_iommu ( & pci_bus_type , & arm_smmu_ops ) ;
}
# endif
}
static int arm_smmu_device_probe ( struct platform_device * pdev )
{
struct resource * res ;
@ -2182,21 +2199,30 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
arm_smmu_device_reset ( smmu ) ;
arm_smmu_test_smr_masks ( smmu ) ;
/* Oh, for a proper bus abstraction */
if ( ! iommu_present ( & platform_bus_type ) )
bus_set_iommu ( & platform_bus_type , & arm_smmu_ops ) ;
# ifdef CONFIG_ARM_AMBA
if ( ! iommu_present ( & amba_bustype ) )
bus_set_iommu ( & amba_bustype , & arm_smmu_ops ) ;
# endif
# ifdef CONFIG_PCI
if ( ! iommu_present ( & pci_bus_type ) ) {
pci_request_acs ( ) ;
bus_set_iommu ( & pci_bus_type , & arm_smmu_ops ) ;
}
# endif
/*
* For ACPI and generic DT bindings , an SMMU will be probed before
* any device which might need it , so we want the bus ops in place
* ready to handle default domain setup as soon as any SMMU exists .
*/
if ( ! using_legacy_binding )
arm_smmu_bus_init ( ) ;
return 0 ;
}
/*
* With the legacy DT binding in play , though , we have no guarantees about
* probe order , but then we ' re also not doing default domains , so we can
* delay setting bus ops until we ' re sure every possible SMMU is ready ,
* and that way ensure that no add_device ( ) calls get missed .
*/
static int arm_smmu_legacy_bus_init ( void )
{
if ( using_legacy_binding )
arm_smmu_bus_init ( ) ;
return 0 ;
}
device_initcall_sync ( arm_smmu_legacy_bus_init ) ;
static int arm_smmu_device_remove ( struct platform_device * pdev )
{
@ -2221,56 +2247,14 @@ static struct platform_driver arm_smmu_driver = {
. probe = arm_smmu_device_probe ,
. remove = arm_smmu_device_remove ,
} ;
static int __init arm_smmu_init ( void )
{
static bool registered ;
int ret = 0 ;
if ( ! registered ) {
ret = platform_driver_register ( & arm_smmu_driver ) ;
registered = ! ret ;
}
return ret ;
}
static void __exit arm_smmu_exit ( void )
{
return platform_driver_unregister ( & arm_smmu_driver ) ;
}
subsys_initcall ( arm_smmu_init ) ;
module_exit ( arm_smmu_exit ) ;
static int __init arm_smmu_of_init ( struct device_node * np )
{
int ret = arm_smmu_init ( ) ;
if ( ret )
return ret ;
if ( ! of_platform_device_create ( np , NULL , platform_bus_type . dev_root ) )
return - ENODEV ;
return 0 ;
}
IOMMU_OF_DECLARE ( arm_smmuv1 , " arm,smmu-v1 " , arm_smmu_of_init ) ;
IOMMU_OF_DECLARE ( arm_smmuv2 , " arm,smmu-v2 " , arm_smmu_of_init ) ;
IOMMU_OF_DECLARE ( arm_mmu400 , " arm,mmu-400 " , arm_smmu_of_init ) ;
IOMMU_OF_DECLARE ( arm_mmu401 , " arm,mmu-401 " , arm_smmu_of_init ) ;
IOMMU_OF_DECLARE ( arm_mmu500 , " arm,mmu-500 " , arm_smmu_of_init ) ;
IOMMU_OF_DECLARE ( cavium_smmuv2 , " cavium,smmu-v2 " , arm_smmu_of_init ) ;
# ifdef CONFIG_ACPI
static int __init arm_smmu_acpi_init ( struct acpi_table_header * table )
{
if ( iort_node_match ( ACPI_IORT_NODE_SMMU ) )
return arm_smmu_init ( ) ;
return 0 ;
}
IORT_ACPI_DECLARE ( arm_smmu , ACPI_SIG_IORT , arm_smmu_acpi_init ) ;
# endif
module_platform_driver ( arm_smmu_driver ) ;
IOMMU_OF_DECLARE ( arm_smmuv1 , " arm,smmu-v1 " , NULL ) ;
IOMMU_OF_DECLARE ( arm_smmuv2 , " arm,smmu-v2 " , NULL ) ;
IOMMU_OF_DECLARE ( arm_mmu400 , " arm,mmu-400 " , NULL ) ;
IOMMU_OF_DECLARE ( arm_mmu401 , " arm,mmu-401 " , NULL ) ;
IOMMU_OF_DECLARE ( arm_mmu500 , " arm,mmu-500 " , NULL ) ;
IOMMU_OF_DECLARE ( cavium_smmuv2 , " cavium,smmu-v2 " , NULL ) ;
MODULE_DESCRIPTION ( " IOMMU API for ARM architected SMMU implementations " ) ;
MODULE_AUTHOR ( " Will Deacon <will.deacon@arm.com> " ) ;