1/* 2 * linux/drivers/mmc/core/bus.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 card bus driver model 12 */ 13 14#include <linux/device.h> 15#include <linux/err.h> 16#include <linux/slab.h> 17 18#include <linux/mmc/card.h> 19#include <linux/mmc/host.h> 20 21#include "core.h" 22#include "sdio_cis.h" 23#include "bus.h" 24 25#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) 26#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) 27 28static ssize_t mmc_type_show(struct device *dev, 29 struct device_attribute *attr, char *buf) 30{ 31 struct mmc_card *card = dev_to_mmc_card(dev); 32 33 switch (card->type) { 34 case MMC_TYPE_MMC: 35 return sprintf(buf, "MMC\n"); 36 case MMC_TYPE_SD: 37 return sprintf(buf, "SD\n"); 38 case MMC_TYPE_SDIO: 39 return sprintf(buf, "SDIO\n"); 40 case MMC_TYPE_SD_COMBO: 41 return sprintf(buf, "SDcombo\n"); 42 default: 43 return -EFAULT; 44 } 45} 46 47static struct device_attribute mmc_dev_attrs[] = { 48 __ATTR(type, S_IRUGO, mmc_type_show, NULL), 49 __ATTR_NULL, 50}; 51 52/* 53 * This currently matches any MMC driver to any MMC card - drivers 54 * themselves make the decision whether to drive this card in their 55 * probe method. 56 */ 57static int mmc_bus_match(struct device *dev, struct device_driver *drv) 58{ 59 return 1; 60} 61 62static int 63mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) 64{ 65 struct mmc_card *card = dev_to_mmc_card(dev); 66 const char *type; 67 int retval = 0; 68 69 switch (card->type) { 70 case MMC_TYPE_MMC: 71 type = "MMC"; 72 break; 73 case MMC_TYPE_SD: 74 type = "SD"; 75 break; 76 case MMC_TYPE_SDIO: 77 type = "SDIO"; 78 break; 79 case MMC_TYPE_SD_COMBO: 80 type = "SDcombo"; 81 break; 82 default: 83 type = NULL; 84 } 85 86 if (type) { 87 retval = add_uevent_var(env, "MMC_TYPE=%s", type); 88 if (retval) 89 return retval; 90 } 91 92 retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card)); 93 if (retval) 94 return retval; 95 96 /* 97 * Request the mmc_block device. Note: that this is a direct request 98 * for the module it carries no information as to what is inserted. 99 */ 100 retval = add_uevent_var(env, "MODALIAS=mmc:block"); 101 102 return retval; 103} 104 105static int mmc_bus_probe(struct device *dev) 106{ 107 struct mmc_driver *drv = to_mmc_driver(dev->driver); 108 struct mmc_card *card = dev_to_mmc_card(dev); 109 110 return drv->probe(card); 111} 112 113static int mmc_bus_remove(struct device *dev) 114{ 115 struct mmc_driver *drv = to_mmc_driver(dev->driver); 116 struct mmc_card *card = dev_to_mmc_card(dev); 117 118 drv->remove(card); 119 120 return 0; 121} 122 123static int mmc_bus_suspend(struct device *dev, pm_message_t state) 124{ 125 struct mmc_driver *drv = to_mmc_driver(dev->driver); 126 struct mmc_card *card = dev_to_mmc_card(dev); 127 int ret = 0; 128 129 if (dev->driver && drv->suspend) 130 ret = drv->suspend(card, state); 131 return ret; 132} 133 134static int mmc_bus_resume(struct device *dev) 135{ 136 struct mmc_driver *drv = to_mmc_driver(dev->driver); 137 struct mmc_card *card = dev_to_mmc_card(dev); 138 int ret = 0; 139 140 if (dev->driver && drv->resume) 141 ret = drv->resume(card); 142 return ret; 143} 144 145static struct bus_type mmc_bus_type = { 146 .name = "mmc", 147 .dev_attrs = mmc_dev_attrs, 148 .match = mmc_bus_match, 149 .uevent = mmc_bus_uevent, 150 .probe = mmc_bus_probe, 151 .remove = mmc_bus_remove, 152 .suspend = mmc_bus_suspend, 153 .resume = mmc_bus_resume, 154}; 155 156int mmc_register_bus(void) 157{ 158 return bus_register(&mmc_bus_type); 159} 160 161void mmc_unregister_bus(void) 162{ 163 bus_unregister(&mmc_bus_type); 164} 165 166/** 167 * mmc_register_driver - register a media driver 168 * @drv: MMC media driver 169 */ 170int mmc_register_driver(struct mmc_driver *drv) 171{ 172 drv->drv.bus = &mmc_bus_type; 173 return driver_register(&drv->drv); 174} 175 176EXPORT_SYMBOL(mmc_register_driver); 177 178/** 179 * mmc_unregister_driver - unregister a media driver 180 * @drv: MMC media driver 181 */ 182void mmc_unregister_driver(struct mmc_driver *drv) 183{ 184 drv->drv.bus = &mmc_bus_type; 185 driver_unregister(&drv->drv); 186} 187 188EXPORT_SYMBOL(mmc_unregister_driver); 189 190static void mmc_release_card(struct device *dev) 191{ 192 struct mmc_card *card = dev_to_mmc_card(dev); 193 194 sdio_free_common_cis(card); 195 196 if (card->info) 197 kfree(card->info); 198 199 kfree(card); 200} 201 202/* 203 * Allocate and initialise a new MMC card structure. 204 */ 205struct mmc_card *mmc_alloc_card(struct mmc_host *host, struct device_type *type) 206{ 207 struct mmc_card *card; 208 209 card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL); 210 if (!card) 211 return ERR_PTR(-ENOMEM); 212 213 card->host = host; 214 215 device_initialize(&card->dev); 216 217 card->dev.parent = mmc_classdev(host); 218 card->dev.bus = &mmc_bus_type; 219 card->dev.release = mmc_release_card; 220 card->dev.type = type; 221 222 return card; 223} 224 225/* 226 * Register a new MMC card with the driver model. 227 */ 228int mmc_add_card(struct mmc_card *card) 229{ 230 int ret; 231 const char *type; 232 233 dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca); 234 235 switch (card->type) { 236 case MMC_TYPE_MMC: 237 type = "MMC"; 238 break; 239 case MMC_TYPE_SD: 240 type = "SD"; 241 if (mmc_card_blockaddr(card)) 242 type = "SDHC"; 243 break; 244 case MMC_TYPE_SDIO: 245 type = "SDIO"; 246 break; 247 case MMC_TYPE_SD_COMBO: 248 type = "SD-combo"; 249 if (mmc_card_blockaddr(card)) 250 type = "SDHC-combo"; 251 default: 252 type = "?"; 253 break; 254 } 255 256 if (mmc_host_is_spi(card->host)) { 257 printk(KERN_INFO "%s: new %s%s card on SPI\n", 258 mmc_hostname(card->host), 259 mmc_card_highspeed(card) ? "high speed " : "", 260 type); 261 } else { 262 printk(KERN_INFO "%s: new %s%s card at address %04x\n", 263 mmc_hostname(card->host), 264 mmc_card_highspeed(card) ? "high speed " : "", 265 type, card->rca); 266 } 267 268 ret = device_add(&card->dev); 269 if (ret) 270 return ret; 271 272#ifdef CONFIG_DEBUG_FS 273 mmc_add_card_debugfs(card); 274#endif 275 276 mmc_card_set_present(card); 277 278 return 0; 279} 280 281/* 282 * Unregister a new MMC card with the driver model, and 283 * (eventually) free it. 284 */ 285void mmc_remove_card(struct mmc_card *card) 286{ 287#ifdef CONFIG_DEBUG_FS 288 mmc_remove_card_debugfs(card); 289#endif 290 291 if (mmc_card_present(card)) { 292 if (mmc_host_is_spi(card->host)) { 293 printk(KERN_INFO "%s: SPI card removed\n", 294 mmc_hostname(card->host)); 295 } else { 296 printk(KERN_INFO "%s: card %04x removed\n", 297 mmc_hostname(card->host), card->rca); 298 } 299 device_del(&card->dev); 300 } 301 302 put_device(&card->dev); 303} 304