From: Paul Mackerras Use the pSeries_reconfig notifier chain for tearing down the iommu table when a device node is removed. Signed-off-by: Nathan Lynch Signed-off-by: Paul Mackerras Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc64/kernel/pSeries_iommu.c | 25 +++++++++++++++++++++++++ 25-akpm/arch/ppc64/kernel/pSeries_reconfig.c | 12 ------------ 2 files changed, 25 insertions(+), 12 deletions(-) diff -puN arch/ppc64/kernel/pSeries_iommu.c~ppc64-pseries_iommuc-use-pseries-reconfig-notifier arch/ppc64/kernel/pSeries_iommu.c --- 25/arch/ppc64/kernel/pSeries_iommu.c~ppc64-pseries_iommuc-use-pseries-reconfig-notifier 2005-03-18 12:55:17.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/pSeries_iommu.c 2005-03-18 12:55:17.000000000 -0800 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "pci.h" @@ -455,6 +456,28 @@ static void iommu_dev_setup_pSeries(stru } } +static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) +{ + int err = NOTIFY_OK; + struct device_node *np = node; + + switch (action) { + case PSERIES_RECONFIG_REMOVE: + if (np->iommu_table && + get_property(np, "ibm,dma-window", NULL)) + iommu_free_table(np); + break; + default: + err = NOTIFY_DONE; + break; + } + return err; +} + +static struct notifier_block iommu_reconfig_nb = { + .notifier_call = iommu_reconfig_notifier, +}; + static void iommu_bus_setup_null(struct pci_bus *b) { } static void iommu_dev_setup_null(struct pci_dev *d) { } @@ -487,6 +510,8 @@ void iommu_init_early_pSeries(void) ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; + pSeries_reconfig_notifier_register(&iommu_reconfig_nb); + pci_iommu_init(); } diff -puN arch/ppc64/kernel/pSeries_reconfig.c~ppc64-pseries_iommuc-use-pseries-reconfig-notifier arch/ppc64/kernel/pSeries_reconfig.c --- 25/arch/ppc64/kernel/pSeries_reconfig.c~ppc64-pseries_iommuc-use-pseries-reconfig-notifier 2005-03-18 12:55:17.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/pSeries_reconfig.c 2005-03-18 12:55:17.000000000 -0800 @@ -164,16 +164,6 @@ out_err: return err; } -/* - * Prepare an OF node for removal from system - * XXX move this to pSeries_iommu.c - */ -static void of_cleanup_node(struct device_node *np) -{ - if (np->iommu_table && get_property(np, "ibm,dma-window", NULL)) - iommu_free_table(np); -} - static int pSeries_reconfig_remove_node(struct device_node *np) { struct device_node *parent, *child; @@ -187,8 +177,6 @@ static int pSeries_reconfig_remove_node( return -EBUSY; } - of_cleanup_node(np); - remove_node_proc_entries(np); notifier_call_chain(&pSeries_reconfig_chain, _