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