1 /* 2 * linux/drivers/mmc/core/host.c 3 * 4 * Copyright (C) 2003 Russell King, All Rights Reserved. 5 * Copyright (C) 2007 Pierre Ossman 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * MMC host class device management 12 */ 13 14 #include <linux/device.h> 15 #include <linux/err.h> 16 #include <linux/idr.h> 17 #include <linux/pagemap.h> 18 #include <linux/leds.h> 19 20 #include <linux/mmc/host.h> 21 22 #include "core.h" 23 #include "host.h" 24 25 #define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev) 26 27 static void mmc_host_classdev_release(struct device *dev) 28 { 29 struct mmc_host *host = cls_dev_to_mmc_host(dev); 30 kfree(host); 31 } 32 33 static struct class mmc_host_class = { 34 .name = "mmc_host", 35 .dev_release = mmc_host_classdev_release, 36 }; 37 38 int mmc_register_host_class(void) 39 { 40 return class_register(&mmc_host_class); 41 } 42 43 void mmc_unregister_host_class(void) 44 { 45 class_unregister(&mmc_host_class); 46 } 47 48 static DEFINE_IDR(mmc_host_idr); 49 static DEFINE_SPINLOCK(mmc_host_lock); 50 51 /** 52 * mmc_alloc_host - initialise the per-host structure. 53 * @extra: sizeof private data structure 54 * @dev: pointer to host device model structure 55 * 56 * Initialise the per-host structure. 57 */ 58 struct mmc_host *mmc_alloc_host(int extra, struct device *dev) 59 { 60 struct mmc_host *host; 61 62 host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); 63 if (!host) 64 return NULL; 65 66 host->parent = dev; 67 host->class_dev.parent = dev; 68 host->class_dev.class = &mmc_host_class; 69 device_initialize(&host->class_dev); 70 71 spin_lock_init(&host->lock); 72 init_waitqueue_head(&host->wq); 73 INIT_DELAYED_WORK(&host->detect, mmc_rescan); 74 75 /* 76 * By default, hosts do not support SGIO or large requests. 77 * They have to set these according to their abilities. 78 */ 79 host->max_hw_segs = 1; 80 host->max_phys_segs = 1; 81 host->max_seg_size = PAGE_CACHE_SIZE; 82 83 host->max_req_size = PAGE_CACHE_SIZE; 84 host->max_blk_size = 512; 85 host->max_blk_count = PAGE_CACHE_SIZE / 512; 86 87 return host; 88 } 89 90 EXPORT_SYMBOL(mmc_alloc_host); 91 92 /** 93 * mmc_add_host - initialise host hardware 94 * @host: mmc host 95 * 96 * Register the host with the driver model. The host must be 97 * prepared to start servicing requests before this function 98 * completes. 99 */ 100 int mmc_add_host(struct mmc_host *host) 101 { 102 int err; 103 104 WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && 105 !host->ops->enable_sdio_irq); 106 107 if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) 108 return -ENOMEM; 109 110 spin_lock(&mmc_host_lock); 111 err = idr_get_new(&mmc_host_idr, host, &host->index); 112 spin_unlock(&mmc_host_lock); 113 if (err) 114 return err; 115 116 snprintf(host->class_dev.bus_id, BUS_ID_SIZE, 117 "mmc%d", host->index); 118 119 led_trigger_register_simple(host->class_dev.bus_id, &host->led); 120 121 err = device_add(&host->class_dev); 122 if (err) 123 return err; 124 125 mmc_start_host(host); 126 127 return 0; 128 } 129 130 EXPORT_SYMBOL(mmc_add_host); 131 132 /** 133 * mmc_remove_host - remove host hardware 134 * @host: mmc host 135 * 136 * Unregister and remove all cards associated with this host, 137 * and power down the MMC bus. No new requests will be issued 138 * after this function has returned. 139 */ 140 void mmc_remove_host(struct mmc_host *host) 141 { 142 mmc_stop_host(host); 143 144 device_del(&host->class_dev); 145 146 led_trigger_unregister_simple(host->led); 147 148 spin_lock(&mmc_host_lock); 149 idr_remove(&mmc_host_idr, host->index); 150 spin_unlock(&mmc_host_lock); 151 } 152 153 EXPORT_SYMBOL(mmc_remove_host); 154 155 /** 156 * mmc_free_host - free the host structure 157 * @host: mmc host 158 * 159 * Free the host once all references to it have been dropped. 160 */ 161 void mmc_free_host(struct mmc_host *host) 162 { 163 put_device(&host->class_dev); 164 } 165 166 EXPORT_SYMBOL(mmc_free_host); 167 168