2 * linux/drivers/mmc/core/bus.c
4 * Copyright (C) 2003 Russell King, All Rights Reserved.
5 * Copyright (C) 2007 Pierre Ossman
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.
11 * MMC card bus driver model
14 #include <linux/device.h>
15 #include <linux/err.h>
17 #include <linux/mmc/card.h>
18 #include <linux/mmc/host.h>
24 #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev)
25 #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
27 static ssize_t
mmc_type_show(struct device
*dev
,
28 struct device_attribute
*attr
, char *buf
)
30 struct mmc_card
*card
= dev_to_mmc_card(dev
);
34 return sprintf(buf
, "MMC\n");
36 return sprintf(buf
, "SD\n");
42 static struct device_attribute mmc_dev_attrs
[] = {
48 * This currently matches any MMC driver to any MMC card - drivers
49 * themselves make the decision whether to drive this card in their
52 static int mmc_bus_match(struct device
*dev
, struct device_driver
*drv
)
58 mmc_bus_uevent(struct device
*dev
, char **envp
, int num_envp
, char *buf
,
61 struct mmc_card
*card
= dev_to_mmc_card(dev
);
62 int retval
= 0, i
= 0, length
= 0;
64 #if 0 // mask by Victor Yu. 12-02-2008
65 #define add_env(fmt,val) do { \
66 retval = add_uevent_var(envp, num_envp, &i, \
67 buf, buf_size, &length, \
73 #define add_env(fmt,val) \
77 length = snprintf(buf, buf_size, fmt, val) + 1; \
90 add_env("MMC_TYPE=%s", "MMC");
93 add_env("MMC_TYPE=%s", "SD");
97 add_env("MMC_NAME=%s", mmc_card_name(card
));
106 static int mmc_bus_probe(struct device
*dev
)
108 struct mmc_driver
*drv
= to_mmc_driver(dev
->driver
);
109 struct mmc_card
*card
= dev_to_mmc_card(dev
);
111 return drv
->probe(card
);
114 static int mmc_bus_remove(struct device
*dev
)
116 struct mmc_driver
*drv
= to_mmc_driver(dev
->driver
);
117 struct mmc_card
*card
= dev_to_mmc_card(dev
);
124 static int mmc_bus_suspend(struct device
*dev
, pm_message_t state
)
126 struct mmc_driver
*drv
= to_mmc_driver(dev
->driver
);
127 struct mmc_card
*card
= dev_to_mmc_card(dev
);
130 if (dev
->driver
&& drv
->suspend
)
131 ret
= drv
->suspend(card
, state
);
135 static int mmc_bus_resume(struct device
*dev
)
137 struct mmc_driver
*drv
= to_mmc_driver(dev
->driver
);
138 struct mmc_card
*card
= dev_to_mmc_card(dev
);
141 if (dev
->driver
&& drv
->resume
)
142 ret
= drv
->resume(card
);
146 static struct bus_type mmc_bus_type
= {
148 .dev_attrs
= mmc_dev_attrs
,
149 .match
= mmc_bus_match
,
150 #if 0 // mask by Victor Yu. 12-02-2008
151 .uevent
= mmc_bus_uevent
,
152 .probe
= mmc_bus_probe
,
153 .remove
= mmc_bus_remove
,
155 .hotplug
= mmc_bus_uevent
,
157 .suspend
= mmc_bus_suspend
,
158 .resume
= mmc_bus_resume
,
161 int mmc_register_bus(void)
163 return bus_register(&mmc_bus_type
);
166 void mmc_unregister_bus(void)
168 bus_unregister(&mmc_bus_type
);
172 * mmc_register_driver - register a media driver
173 * @drv: MMC media driver
175 int mmc_register_driver(struct mmc_driver
*drv
)
177 drv
->drv
.bus
= &mmc_bus_type
;
178 #if 1 // add by Victor Yu. 12-01-2008
179 drv
->drv
.probe
= mmc_bus_probe
;
180 drv
->drv
.remove
= mmc_bus_remove
;
182 return driver_register(&drv
->drv
);
185 EXPORT_SYMBOL(mmc_register_driver
);
188 * mmc_unregister_driver - unregister a media driver
189 * @drv: MMC media driver
191 void mmc_unregister_driver(struct mmc_driver
*drv
)
193 drv
->drv
.bus
= &mmc_bus_type
;
194 driver_unregister(&drv
->drv
);
197 EXPORT_SYMBOL(mmc_unregister_driver
);
199 static void mmc_release_card(struct device
*dev
)
201 #if 0 // mask by Victor Yu. 12-03-2008
202 struct mmc_card
*card
= dev_to_mmc_card(dev
);
204 struct mmc_card
*card
;
206 card
= dev_to_mmc_card(dev
);
213 * Allocate and initialise a new MMC card structure.
215 struct mmc_card
*mmc_alloc_card(struct mmc_host
*host
)
217 struct mmc_card
*card
;
219 #if 0 // mask by Victor Yu. 12-02-2008
220 card
= kzalloc(sizeof(struct mmc_card
), GFP_KERNEL
);
222 card
= kmalloc(sizeof(struct mmc_card
), GFP_KERNEL
);
225 return ERR_PTR(-ENOMEM
);
226 #if 1 // add by Victor Yu. 12-02-2008
227 memset(card
, 0 , sizeof(struct mmc_card
));
232 device_initialize(&card
->dev
);
234 #if 0 // mask by Victor Yu. 12-02-2008
235 card
->dev
.parent
= mmc_classdev(host
);
237 card
->dev
.parent
= host
->dev
;
239 card
->dev
.bus
= &mmc_bus_type
;
240 card
->dev
.release
= mmc_release_card
;
246 * Register a new MMC card with the driver model.
248 int mmc_add_card(struct mmc_card
*card
)
253 snprintf(card
->dev
.bus_id
, sizeof(card
->dev
.bus_id
),
254 "%s:%04x", mmc_hostname(card
->host
), card
->rca
);
256 switch (card
->type
) {
262 if (mmc_card_blockaddr(card
))
270 printk(KERN_INFO
"%s: new %s%s card at address %04x\n",
271 mmc_hostname(card
->host
),
272 mmc_card_highspeed(card
) ? "high speed " : "",
275 #if 0 // mask by Victor Yu. 12-02-2008
276 card
->dev
.uevent_suppress
= 1;
279 ret
= device_add(&card
->dev
);
283 if (card
->host
->bus_ops
->sysfs_add
) {
284 ret
= card
->host
->bus_ops
->sysfs_add(card
->host
, card
);
286 device_del(&card
->dev
);
291 #if 0 // mask by Victor Yu. 12-02-2008
292 card
->dev
.uevent_suppress
= 0;
293 kobject_uevent(&card
->dev
.kobj
, KOBJ_ADD
);
296 mmc_card_set_present(card
);
302 * Unregister a new MMC card with the driver model, and
303 * (eventually) free it.
305 void mmc_remove_card(struct mmc_card
*card
)
307 if (mmc_card_present(card
)) {
308 printk(KERN_INFO
"%s: card %04x removed\n",
309 mmc_hostname(card
->host
), card
->rca
);
311 if (card
->host
->bus_ops
->sysfs_remove
) {
312 card
->host
->bus_ops
->sysfs_remove(card
->host
, card
);
314 device_del(&card
->dev
);
317 put_device(&card
->dev
);