提交 9ab7486e 编写于 作者: L Linus Torvalds

Merge HEAD from master.kernel.org:/home/rmk/linux-2.6-mmc.git

...@@ -361,7 +361,7 @@ static void mmc_decode_cid(struct mmc_card *card) ...@@ -361,7 +361,7 @@ static void mmc_decode_cid(struct mmc_card *card)
default: default:
printk("%s: card has unknown MMCA version %d\n", printk("%s: card has unknown MMCA version %d\n",
card->host->host_name, card->csd.mmca_vsn); mmc_hostname(card->host), card->csd.mmca_vsn);
mmc_card_set_bad(card); mmc_card_set_bad(card);
break; break;
} }
...@@ -383,7 +383,7 @@ static void mmc_decode_csd(struct mmc_card *card) ...@@ -383,7 +383,7 @@ static void mmc_decode_csd(struct mmc_card *card)
csd_struct = UNSTUFF_BITS(resp, 126, 2); csd_struct = UNSTUFF_BITS(resp, 126, 2);
if (csd_struct != 1 && csd_struct != 2) { if (csd_struct != 1 && csd_struct != 2) {
printk("%s: unrecognised CSD structure version %d\n", printk("%s: unrecognised CSD structure version %d\n",
card->host->host_name, csd_struct); mmc_hostname(card->host), csd_struct);
mmc_card_set_bad(card); mmc_card_set_bad(card);
return; return;
} }
...@@ -551,7 +551,7 @@ static void mmc_discover_cards(struct mmc_host *host) ...@@ -551,7 +551,7 @@ static void mmc_discover_cards(struct mmc_host *host)
} }
if (err != MMC_ERR_NONE) { if (err != MMC_ERR_NONE) {
printk(KERN_ERR "%s: error requesting CID: %d\n", printk(KERN_ERR "%s: error requesting CID: %d\n",
host->host_name, err); mmc_hostname(host), err);
break; break;
} }
...@@ -796,17 +796,13 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) ...@@ -796,17 +796,13 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev)
{ {
struct mmc_host *host; struct mmc_host *host;
host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); host = mmc_alloc_host_sysfs(extra, dev);
if (host) { if (host) {
memset(host, 0, sizeof(struct mmc_host) + extra);
spin_lock_init(&host->lock); spin_lock_init(&host->lock);
init_waitqueue_head(&host->wq); init_waitqueue_head(&host->wq);
INIT_LIST_HEAD(&host->cards); INIT_LIST_HEAD(&host->cards);
INIT_WORK(&host->detect, mmc_rescan, host); INIT_WORK(&host->detect, mmc_rescan, host);
host->dev = dev;
/* /*
* By default, hosts do not support SGIO or large requests. * By default, hosts do not support SGIO or large requests.
* They have to set these according to their abilities. * They have to set these according to their abilities.
...@@ -828,15 +824,15 @@ EXPORT_SYMBOL(mmc_alloc_host); ...@@ -828,15 +824,15 @@ EXPORT_SYMBOL(mmc_alloc_host);
*/ */
int mmc_add_host(struct mmc_host *host) int mmc_add_host(struct mmc_host *host)
{ {
static unsigned int host_num; int ret;
snprintf(host->host_name, sizeof(host->host_name), ret = mmc_add_host_sysfs(host);
"mmc%d", host_num++); if (ret == 0) {
mmc_power_off(host);
mmc_power_off(host); mmc_detect_change(host);
mmc_detect_change(host); }
return 0; return ret;
} }
EXPORT_SYMBOL(mmc_add_host); EXPORT_SYMBOL(mmc_add_host);
...@@ -859,6 +855,7 @@ void mmc_remove_host(struct mmc_host *host) ...@@ -859,6 +855,7 @@ void mmc_remove_host(struct mmc_host *host)
} }
mmc_power_off(host); mmc_power_off(host);
mmc_remove_host_sysfs(host);
} }
EXPORT_SYMBOL(mmc_remove_host); EXPORT_SYMBOL(mmc_remove_host);
...@@ -872,7 +869,7 @@ EXPORT_SYMBOL(mmc_remove_host); ...@@ -872,7 +869,7 @@ EXPORT_SYMBOL(mmc_remove_host);
void mmc_free_host(struct mmc_host *host) void mmc_free_host(struct mmc_host *host)
{ {
flush_scheduled_work(); flush_scheduled_work();
kfree(host); mmc_free_host_sysfs(host);
} }
EXPORT_SYMBOL(mmc_free_host); EXPORT_SYMBOL(mmc_free_host);
......
...@@ -13,4 +13,9 @@ ...@@ -13,4 +13,9 @@
void mmc_init_card(struct mmc_card *card, struct mmc_host *host); void mmc_init_card(struct mmc_card *card, struct mmc_host *host);
int mmc_register_card(struct mmc_card *card); int mmc_register_card(struct mmc_card *card);
void mmc_remove_card(struct mmc_card *card); void mmc_remove_card(struct mmc_card *card);
struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev);
int mmc_add_host_sysfs(struct mmc_host *host);
void mmc_remove_host_sysfs(struct mmc_host *host);
void mmc_free_host_sysfs(struct mmc_host *host);
#endif #endif
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/idr.h>
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <linux/mmc/host.h> #include <linux/mmc/host.h>
...@@ -20,6 +21,7 @@ ...@@ -20,6 +21,7 @@
#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev)
#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
#define cls_dev_to_mmc_host(d) container_of(d, struct mmc_host, class_dev)
#define MMC_ATTR(name, fmt, args...) \ #define MMC_ATTR(name, fmt, args...) \
static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \
...@@ -206,7 +208,7 @@ void mmc_init_card(struct mmc_card *card, struct mmc_host *host) ...@@ -206,7 +208,7 @@ void mmc_init_card(struct mmc_card *card, struct mmc_host *host)
int mmc_register_card(struct mmc_card *card) int mmc_register_card(struct mmc_card *card)
{ {
snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
"%s:%04x", card->host->host_name, card->rca); "%s:%04x", mmc_hostname(card->host), card->rca);
return device_add(&card->dev); return device_add(&card->dev);
} }
...@@ -224,13 +226,97 @@ void mmc_remove_card(struct mmc_card *card) ...@@ -224,13 +226,97 @@ void mmc_remove_card(struct mmc_card *card)
} }
static void mmc_host_classdev_release(struct class_device *dev)
{
struct mmc_host *host = cls_dev_to_mmc_host(dev);
kfree(host);
}
static struct class mmc_host_class = {
.name = "mmc_host",
.release = mmc_host_classdev_release,
};
static DEFINE_IDR(mmc_host_idr);
static DEFINE_SPINLOCK(mmc_host_lock);
/*
* Internal function. Allocate a new MMC host.
*/
struct mmc_host *mmc_alloc_host_sysfs(int extra, struct device *dev)
{
struct mmc_host *host;
host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
if (host) {
memset(host, 0, sizeof(struct mmc_host) + extra);
host->dev = dev;
host->class_dev.dev = host->dev;
host->class_dev.class = &mmc_host_class;
class_device_initialize(&host->class_dev);
}
return host;
}
/*
* Internal function. Register a new MMC host with the MMC class.
*/
int mmc_add_host_sysfs(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;
snprintf(host->class_dev.class_id, BUS_ID_SIZE,
"mmc%d", host->index);
return class_device_add(&host->class_dev);
}
/*
* Internal function. Unregister a MMC host with the MMC class.
*/
void mmc_remove_host_sysfs(struct mmc_host *host)
{
class_device_del(&host->class_dev);
spin_lock(&mmc_host_lock);
idr_remove(&mmc_host_idr, host->index);
spin_unlock(&mmc_host_lock);
}
/*
* Internal function. Free a MMC host.
*/
void mmc_free_host_sysfs(struct mmc_host *host)
{
class_device_put(&host->class_dev);
}
static int __init mmc_init(void) static int __init mmc_init(void)
{ {
return bus_register(&mmc_bus_type); int ret = bus_register(&mmc_bus_type);
if (ret == 0) {
ret = class_register(&mmc_host_class);
if (ret)
bus_unregister(&mmc_bus_type);
}
return ret;
} }
static void __exit mmc_exit(void) static void __exit mmc_exit(void)
{ {
class_unregister(&mmc_host_class);
bus_unregister(&mmc_bus_type); bus_unregister(&mmc_bus_type);
} }
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#ifdef CONFIG_MMC_DEBUG #ifdef CONFIG_MMC_DEBUG
#define DBG(host,fmt,args...) \ #define DBG(host,fmt,args...) \
pr_debug("%s: %s: " fmt, host->mmc->host_name, __func__ , args) pr_debug("%s: %s: " fmt, mmc_hostname(host->mmc), __func__ , args)
#else #else
#define DBG(host,fmt,args...) do { } while (0) #define DBG(host,fmt,args...) do { } while (0)
#endif #endif
...@@ -541,7 +541,7 @@ static int mmci_probe(struct amba_device *dev, void *id) ...@@ -541,7 +541,7 @@ static int mmci_probe(struct amba_device *dev, void *id)
mmc_add_host(mmc); mmc_add_host(mmc);
printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n", printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n",
mmc->host_name, amba_rev(dev), amba_config(dev), mmc_hostname(mmc), amba_rev(dev), amba_config(dev),
dev->res.start, dev->irq[0], dev->irq[1]); dev->res.start, dev->irq[0], dev->irq[1]);
init_timer(&host->timer); init_timer(&host->timer);
......
...@@ -1796,7 +1796,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, ...@@ -1796,7 +1796,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
mmc_add_host(mmc); mmc_add_host(mmc);
printk(KERN_INFO "%s: W83L51xD", mmc->host_name); printk(KERN_INFO "%s: W83L51xD", mmc_hostname(mmc));
if (host->chip_id != 0) if (host->chip_id != 0)
printk(" id %x", (int)host->chip_id); printk(" id %x", (int)host->chip_id);
printk(" at 0x%x irq %d", (int)host->base, (int)host->irq); printk(" at 0x%x irq %d", (int)host->base, (int)host->irq);
......
...@@ -63,11 +63,12 @@ struct device; ...@@ -63,11 +63,12 @@ struct device;
struct mmc_host { struct mmc_host {
struct device *dev; struct device *dev;
struct class_device class_dev;
int index;
struct mmc_host_ops *ops; struct mmc_host_ops *ops;
unsigned int f_min; unsigned int f_min;
unsigned int f_max; unsigned int f_max;
u32 ocr_avail; u32 ocr_avail;
char host_name[8];
/* host specific block data */ /* host specific block data */
unsigned int max_seg_size; /* see blk_queue_max_segment_size */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */
...@@ -97,6 +98,7 @@ extern void mmc_free_host(struct mmc_host *); ...@@ -97,6 +98,7 @@ extern void mmc_free_host(struct mmc_host *);
#define mmc_priv(x) ((void *)((x) + 1)) #define mmc_priv(x) ((void *)((x) + 1))
#define mmc_dev(x) ((x)->dev) #define mmc_dev(x) ((x)->dev)
#define mmc_hostname(x) ((x)->class_dev.class_id)
extern int mmc_suspend_host(struct mmc_host *, pm_message_t); extern int mmc_suspend_host(struct mmc_host *, pm_message_t);
extern int mmc_resume_host(struct mmc_host *); extern int mmc_resume_host(struct mmc_host *);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册