X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmmc%2Fcore%2Fhost.c;h=6da80fd4d974669223ac2caf54576f6521c52083;hb=6edd8ee60ac9b974bd6ec3b1bcb2aab02762fa8c;hp=2c7ce8f43a9a60367a6f75397a7da831c3afe8d3;hpb=6ae26fa468533c86aaa6936fd366142fcf01386f;p=linux-2.6 diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 2c7ce8f43a..6da80fd4d9 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -2,7 +2,7 @@ * linux/drivers/mmc/core/host.c * * Copyright (C) 2003 Russell King, All Rights Reserved. - * Copyright (C) 2007 Pierre Ossman + * Copyright (C) 2007-2008 Pierre Ossman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -56,12 +57,25 @@ static DEFINE_SPINLOCK(mmc_host_lock); */ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) { + int err; struct mmc_host *host; + if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) + return NULL; + host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); if (!host) return NULL; + spin_lock(&mmc_host_lock); + err = idr_get_new(&mmc_host_idr, host, &host->index); + spin_unlock(&mmc_host_lock); + if (err) + goto free; + + snprintf(host->class_dev.bus_id, BUS_ID_SIZE, + "mmc%d", host->index); + host->parent = dev; host->class_dev.parent = dev; host->class_dev.class = &mmc_host_class; @@ -84,6 +98,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) host->max_blk_count = PAGE_CACHE_SIZE / 512; return host; + +free: + kfree(host); + return NULL; } EXPORT_SYMBOL(mmc_alloc_host); @@ -100,22 +118,19 @@ int mmc_add_host(struct mmc_host *host) { int err; - if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) - return -ENOMEM; - - spin_lock(&mmc_host_lock); - err = idr_get_new(&mmc_host_idr, host, &host->index); - spin_unlock(&mmc_host_lock); - if (err) - return err; + WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && + !host->ops->enable_sdio_irq); - snprintf(host->class_dev.bus_id, BUS_ID_SIZE, - "mmc%d", host->index); + led_trigger_register_simple(host->class_dev.bus_id, &host->led); err = device_add(&host->class_dev); if (err) return err; +#ifdef CONFIG_DEBUG_FS + mmc_add_host_debugfs(host); +#endif + mmc_start_host(host); return 0; @@ -135,11 +150,13 @@ void mmc_remove_host(struct mmc_host *host) { mmc_stop_host(host); +#ifdef CONFIG_DEBUG_FS + mmc_remove_host_debugfs(host); +#endif + device_del(&host->class_dev); - spin_lock(&mmc_host_lock); - idr_remove(&mmc_host_idr, host->index); - spin_unlock(&mmc_host_lock); + led_trigger_unregister_simple(host->led); } EXPORT_SYMBOL(mmc_remove_host); @@ -152,6 +169,10 @@ EXPORT_SYMBOL(mmc_remove_host); */ void mmc_free_host(struct mmc_host *host) { + spin_lock(&mmc_host_lock); + idr_remove(&mmc_host_idr, host->index); + spin_unlock(&mmc_host_lock); + put_device(&host->class_dev); }