iommu/amd: Split amd_iommu_init function
Subsystems (2)
PATCH 1/1 iommu/amd: Split amd_iommu_init function
The hardware-initializtion part of the AMD IOMMU driver is split out into a seperate function. This function can now be called either from amd_iommu_init() itself or any other place if the hardware needs to be ready earlier. This will be used to implement interrupt remapping for AMD.
Signed-off-by Joerg Roedel <[email protected]>
--- drivers/iommu/amd_iommu_init.c | 123 +++++++++++++++++++++++++-------------- include/linux/amd-iommu.h | 2 +- 2 files changed, 80 insertions(+), 45 deletions(-)
drivers/iommu/amd_iommu_init.c +79 -44
@@ -1424,10 +1424,40 @@ static struct syscore_ops amd_iommu_syscore_ops = { .resume = amd_iommu_resume, }; +static void __init free_on_init_error (void ) +{ +amd_iommu_uninit_devices (); + +free_pages ((unsigned long )amd_iommu_pd_alloc_bitmap, +get_order (MAX_DOMAIN_ID /8 )); + +free_pages ((unsigned long )amd_iommu_rlookup_table, +get_order (rlookup_table_size)); + +free_pages ((unsigned long )amd_iommu_alias_table, +get_order (alias_table_size)); + +free_pages ((unsigned long )amd_iommu_dev_table, +get_order (dev_table_size)); + +free_iommu_all (); + +free_unity_maps (); + +#ifdef CONFIG_GART_IOMMU +/* +* We failed to initialize the AMD IOMMU - try fallback to GART +* if possible. +*/ +gart_iommu_init (); + +#endif +} +/* -* This is the core init function for AMD IOMMU hardware in the system. -* This function is called from the generic x86 DMA layer initialization -* code. +* This is the hardware init function for AMD IOMMU in the system. +* This function is called either from amd_iommu_init or from the interrupt +* remapping setup code. * * This function basically parses the ACPI table for AMD IOMMU (IVRS) * three times:
@@ -1446,16 +1476,21 @@ static struct syscore_ops amd_iommu_syscore_ops = {* remapping requirements parsed out of the ACPI table in * this last pass. * -* After that the hardware is initialized and ready to go. In the last -* step we do some Linux specific things like registering the driver in -* the dma_ops interface and initializing the suspend/resume support -* functions. Finally it prints some information about AMD IOMMUs and -* the driver state and enables the hardware. +* After everything is set up the IOMMUs are enabled and the necessary +* hotplug and suspend notifiers are registered. */ -static int __init amd_iommu_init (void ) +int __init amd_iommu_init_hardware (void ) {int i, ret =0 ; +if (!amd_iommu_detected) +return -ENODEV ; + +if (amd_iommu_dev_table !=NULL ) { +/* Hardware already initialized */ +return 0 ; + } +/* * First parse ACPI tables to find the largest Bus/Dev/Func * we need to handle. Upon this information the shared data
@@ -1472,9 +1507,8 @@ static int __init amd_iommu_init(void) alias_table_size =tbl_size (ALIAS_TABLE_ENTRY_SIZE ); rlookup_table_size =tbl_size (RLOOKUP_TABLE_ENTRY_SIZE ); - ret = -ENOMEM ; -/* Device table - directly used by all IOMMUs */ + ret = -ENOMEM ; amd_iommu_dev_table = (void *)__get_free_pages (GFP_KERNEL | __GFP_ZERO,get_order (dev_table_size));if (amd_iommu_dev_table ==NULL )
@@ -1546,20 +1580,46 @@ static int __init amd_iommu_init(void)enable_iommus (); +amd_iommu_init_notifier (); + +register_syscore_ops (&amd_iommu_syscore_ops); + +out: +return ret; + +free: +free_on_init_error (); + +return ret; +} + +/* +* This is the core init function for AMD IOMMU hardware in the system. +* This function is called from the generic x86 DMA layer initialization +* code. +* +* The function calls amd_iommu_init_hardware() to setup and enable the +* IOMMU hardware if this has not happened yet. After that the driver +* registers for the DMA-API and for the IOMMU-API as necessary. +*/ +static int __init amd_iommu_init (void ) +{ +int ret =0 ; + + ret =amd_iommu_init_hardware (); +if (ret) + goto out; +if (iommu_pass_through) ret =amd_iommu_init_passthrough ();else ret =amd_iommu_init_dma_ops ();if (ret) - goto free_disable; + goto free;amd_iommu_init_api (); -amd_iommu_init_notifier (); - -register_syscore_ops (&amd_iommu_syscore_ops); -if (iommu_pass_through) goto out;
@@ -1569,39 +1629,14 @@ static int __init amd_iommu_init(void)printk (KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n" ); x86_platform.iommu_shutdown = disable_iommus; + out:return ret; -free_disable: -disable_iommus (); - free: -amd_iommu_uninit_devices (); - -free_pages ((unsigned long )amd_iommu_pd_alloc_bitmap, -get_order (MAX_DOMAIN_ID /8 )); - -free_pages ((unsigned long )amd_iommu_rlookup_table, -get_order (rlookup_table_size)); - -free_pages ((unsigned long )amd_iommu_alias_table, -get_order (alias_table_size)); - -free_pages ((unsigned long )amd_iommu_dev_table, -get_order (dev_table_size)); - -free_iommu_all (); - -free_unity_maps (); - -#ifdef CONFIG_GART_IOMMU -/* -* We failed to initialize the AMD IOMMU - try fallback to GART -* if possible. -*/ -gart_iommu_init (); +disable_iommus (); -#endif +free_on_init_error (); goto out; }
include/linux/amd-iommu.h +1 -1
@@ -28,7 +28,7 @@ struct task_struct;struct pci_dev ;extern int amd_iommu_detect (void ); - +extern int amd_iommu_init_hardware (void );/** * amd_iommu_enable_device_erratum() - Enable erratum workaround for device
Signature · 1 line
1.7.5.4