static int ipmi_powernv_remove(struct platform_device *pdev) { struct ipmi_smi_powernv *smi = dev_get_drvdata(&pdev->dev); ipmi_unregister_smi(smi->intf); opal_notifier_unregister(&smi->event_nb); return 0; }
void __exit cleanup_one_kcs(struct kcs_info *to_clean) { int rv; unsigned long flags; if (! to_clean) return; /* Tell the timer and interrupt handlers that we are shutting down. */ spin_lock_irqsave(&(to_clean->kcs_lock), flags); spin_lock(&(to_clean->msg_lock)); to_clean->stop_operation = 1; if (to_clean->irq != 0) free_irq(to_clean->irq, to_clean); if (to_clean->port) { printk(KERN_INFO "ipmi_kcs: Releasing BMC @ port=0x%x\n", to_clean->port); release_region (to_clean->port, 2); } if (to_clean->addr) { printk(KERN_INFO "ipmi_kcs: Releasing BMC @ addr=0x%lx\n", to_clean->physaddr); iounmap(to_clean->addr); release_mem_region(to_clean->physaddr, 2); } spin_unlock(&(to_clean->msg_lock)); spin_unlock_irqrestore(&(to_clean->kcs_lock), flags); /* Wait until we know that we are out of any interrupt handlers might have been running before we freed the interrupt. */ synchronize_kernel(); /* Wait for the timer to stop. This avoids problems with race conditions removing the timer here. */ while (!to_clean->timer_stopped) { schedule_timeout(1); } rv = ipmi_unregister_smi(to_clean->intf); if (rv) { printk(KERN_ERR "ipmi_kcs: Unable to unregister device: errno=%d\n", rv); } initialized = 0; kfree(to_clean->kcs_sm); kfree(to_clean); }
void __exit cleanup_one_kcs(struct kcs_info *to_clean) { int rv; unsigned long flags; if (! to_clean) return; /* Tell the timer and interrupt handlers that we are shutting down. */ spin_lock_irqsave(&(to_clean->kcs_lock), flags); spin_lock(&(to_clean->msg_lock)); to_clean->stop_operation = 1; if (to_clean->irq != 0) free_irq(to_clean->irq, to_clean); if (to_clean->port) { printk(KERN_INFO "ipmi_kcs: Releasing BMC @ port=0x%x\n", to_clean->port); release_region (to_clean->port, 2); } if (to_clean->addr) { printk(KERN_INFO "ipmi_kcs: Releasing BMC @ addr=0x%lx\n", to_clean->physaddr); iounmap(to_clean->addr); release_mem_region(to_clean->physaddr, 2); } spin_unlock(&(to_clean->msg_lock)); spin_unlock_irqrestore(&(to_clean->kcs_lock), flags); /* Wait for the timer to stop. This avoids problems with race conditions removing the timer here. Hopefully this will be long enough to avoid problems with interrupts still running. */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(2); while (!to_clean->timer_stopped) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); } rv = ipmi_unregister_smi(to_clean->intf); if (rv) { printk(KERN_ERR "ipmi_kcs: Unable to unregister device: errno=%d\n", rv); } initialized = 0; kfree(to_clean->kcs_sm); kfree(to_clean); }
static int ipmi_powernv_remove(struct platform_device *pdev) { struct ipmi_smi_powernv *smi = dev_get_drvdata(&pdev->dev); ipmi_unregister_smi(smi->intf); free_irq(smi->irq, smi); irq_dispose_mapping(smi->irq); return 0; }