static int sh_mmcif_remove(struct platform_device *pdev) { struct sh_mmcif_host *host = platform_get_drvdata(pdev); host->dying = true; clk_prepare_enable(host->hclk); pm_runtime_get_sync(&pdev->dev); dev_pm_qos_hide_latency_limit(&pdev->dev); mmc_remove_host(host->mmc); sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); /* * FIXME: cancel_delayed_work(_sync)() and free_irq() race with the * mmc_remove_host() call above. But swapping order doesn't help either * (a query on the linux-mmc mailing list didn't bring any replies). */ cancel_delayed_work_sync(&host->timeout_work); clk_disable_unprepare(host->hclk); mmc_free_host(host->mmc); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; }
static int __devexit sh_mmcif_remove(struct platform_device *pdev) { struct sh_mmcif_host *host = platform_get_drvdata(pdev); struct sh_mmcif_plat_data *pd = pdev->dev.platform_data; int irq[2]; host->dying = true; clk_enable(host->hclk); pm_runtime_get_sync(&pdev->dev); dev_pm_qos_hide_latency_limit(&pdev->dev); if (pd && pd->use_cd_gpio) mmc_gpio_free_cd(host->mmc); mmc_remove_host(host->mmc); sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); /* * FIXME: cancel_delayed_work(_sync)() and free_irq() race with the * mmc_remove_host() call above. But swapping order doesn't help either * (a query on the linux-mmc mailing list didn't bring any replies). */ cancel_delayed_work_sync(&host->timeout_work); if (host->addr) iounmap(host->addr); irq[0] = platform_get_irq(pdev, 0); irq[1] = platform_get_irq(pdev, 1); free_irq(irq[0], host); free_irq(irq[1], host); platform_set_drvdata(pdev, NULL); clk_disable(host->hclk); mmc_free_host(host->mmc); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; }
/** * acpi_dev_pm_detach - Remove ACPI power management from the device. * @dev: Device to take care of. * @power_off: Whether or not to try to remove power from the device. * * Remove the device from the general ACPI PM domain and remove its wakeup * notifier. If @power_off is set, additionally remove power from the device if * possible. * * Callers must ensure proper synchronization of this function with power * management callbacks. */ static void acpi_dev_pm_detach(struct device *dev, bool power_off) { struct acpi_device *adev = ACPI_COMPANION(dev); if (adev && dev->pm_domain == &acpi_general_pm_domain) { dev->pm_domain = NULL; acpi_remove_pm_notifier(adev); if (power_off) { /* * If the device's PM QoS resume latency limit or flags * have been exposed to user space, they have to be * hidden at this point, so that they don't affect the * choice of the low-power state to put the device into. */ dev_pm_qos_hide_latency_limit(dev); dev_pm_qos_hide_flags(dev); acpi_device_wakeup(adev, ACPI_STATE_S0, false); acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0); } } }