Commit 2428a8fe authored by Alex Dubov's avatar Alex Dubov Committed by Pierre Ossman

tifm: move common device management tasks from tifm_7xx1 to tifm_core

Some details of the device management (create, add, remove) are really
belong to the tifm_core, as they are not hardware specific.
Signed-off-by: default avatarAlex Dubov <oakad@yahoo.com>
Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
parent 6113ed73
...@@ -136,7 +136,6 @@ static void tifm_7xx1_switch_media(struct work_struct *work) ...@@ -136,7 +136,6 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
media_switcher); media_switcher);
unsigned long flags; unsigned long flags;
unsigned char media_id; unsigned char media_id;
char *card_name = "xx";
int cnt; int cnt;
struct tifm_dev *sock; struct tifm_dev *sock;
unsigned int socket_change_set; unsigned int socket_change_set;
...@@ -153,68 +152,45 @@ static void tifm_7xx1_switch_media(struct work_struct *work) ...@@ -153,68 +152,45 @@ static void tifm_7xx1_switch_media(struct work_struct *work)
return; return;
} }
for (cnt = 0; cnt < fm->num_sockets; cnt++) { for (cnt = 0; cnt < fm->num_sockets; cnt++) {
if (!(socket_change_set & (1 << cnt))) if (!(socket_change_set & (1 << cnt)))
continue; continue;
sock = fm->sockets[cnt]; sock = fm->sockets[cnt];
if (sock) { if (sock) {
printk(KERN_INFO DRIVER_NAME printk(KERN_INFO
": demand removing card from socket %d\n", "%s : demand removing card from socket %u:%u\n",
cnt); fm->cdev.class_id, fm->id, cnt);
fm->sockets[cnt] = NULL; fm->sockets[cnt] = NULL;
spin_unlock_irqrestore(&fm->lock, flags);
device_unregister(&sock->dev);
spin_lock_irqsave(&fm->lock, flags);
writel(0x0e00,
tifm_7xx1_sock_addr(fm->addr, cnt)
+ SOCK_CONTROL);
}
spin_unlock_irqrestore(&fm->lock, flags); spin_unlock_irqrestore(&fm->lock, flags);
media_id = tifm_7xx1_toggle_sock_power( device_unregister(&sock->dev);
tifm_7xx1_sock_addr(fm->addr, cnt)); spin_lock_irqsave(&fm->lock, flags);
if (media_id) { writel(0x0e00, tifm_7xx1_sock_addr(fm->addr, cnt)
sock = tifm_alloc_device(fm); + SOCK_CONTROL);
if (sock) { }
sock->addr = tifm_7xx1_sock_addr(fm->addr,
cnt); spin_unlock_irqrestore(&fm->lock, flags);
sock->type = media_id;
sock->socket_id = cnt; media_id = tifm_7xx1_toggle_sock_power(
switch (media_id) { tifm_7xx1_sock_addr(fm->addr, cnt));
case 1:
card_name = "xd"; // tifm_alloc_device will check if media_id is valid
break; sock = tifm_alloc_device(fm, cnt, media_id);
case 2: if (sock) {
card_name = "ms"; sock->addr = tifm_7xx1_sock_addr(fm->addr, cnt);
break;
case 3: if (!device_register(&sock->dev)) {
card_name = "sd";
break;
default:
tifm_free_device(&sock->dev);
spin_lock_irqsave(&fm->lock, flags);
continue;
}
snprintf(sock->dev.bus_id, BUS_ID_SIZE,
"tifm_%s%u:%u", card_name,
fm->id, cnt);
printk(KERN_INFO DRIVER_NAME
": %s card detected in socket %d\n",
card_name, cnt);
if (!device_register(&sock->dev)) {
spin_lock_irqsave(&fm->lock, flags);
if (!fm->sockets[cnt]) {
fm->sockets[cnt] = sock;
sock = NULL;
}
spin_unlock_irqrestore(&fm->lock, flags);
}
if (sock)
tifm_free_device(&sock->dev);
}
spin_lock_irqsave(&fm->lock, flags); spin_lock_irqsave(&fm->lock, flags);
if (!fm->sockets[cnt]) {
fm->sockets[cnt] = sock;
sock = NULL;
}
spin_unlock_irqrestore(&fm->lock, flags);
} }
if (sock)
tifm_free_device(&sock->dev);
} }
spin_lock_irqsave(&fm->lock, flags);
}
writel(TIFM_IRQ_FIFOMASK(socket_change_set) writel(TIFM_IRQ_FIFOMASK(socket_change_set)
| TIFM_IRQ_CARDMASK(socket_change_set), | TIFM_IRQ_CARDMASK(socket_change_set),
......
...@@ -232,25 +232,40 @@ EXPORT_SYMBOL(tifm_free_adapter); ...@@ -232,25 +232,40 @@ EXPORT_SYMBOL(tifm_free_adapter);
void tifm_free_device(struct device *dev) void tifm_free_device(struct device *dev)
{ {
struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
kfree(fm_dev); kfree(sock);
} }
EXPORT_SYMBOL(tifm_free_device); EXPORT_SYMBOL(tifm_free_device);
struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm) struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id,
unsigned char type)
{ {
struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); struct tifm_dev *sock = NULL;
if (!tifm_media_type_name(type, 0))
return sock;
if (dev) { sock = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL);
spin_lock_init(&dev->lock); if (sock) {
spin_lock_init(&sock->lock);
sock->type = type;
sock->socket_id = id;
sock->card_event = tifm_dummy_event;
sock->data_event = tifm_dummy_event;
dev->dev.parent = fm->cdev.dev; sock->dev.parent = fm->cdev.dev;
dev->dev.bus = &tifm_bus_type; sock->dev.bus = &tifm_bus_type;
dev->dev.release = tifm_free_device; sock->dev.dma_mask = fm->cdev.dev->dma_mask;
dev->card_event = tifm_dummy_event; sock->dev.release = tifm_free_device;
dev->data_event = tifm_dummy_event;
snprintf(sock->dev.bus_id, BUS_ID_SIZE,
"tifm_%s%u:%u", tifm_media_type_name(type, 2),
fm->id, id);
printk(KERN_INFO DRIVER_NAME
": %s card detected in socket %u:%u\n",
tifm_media_type_name(type, 0), fm->id, id);
} }
return dev; return sock;
} }
EXPORT_SYMBOL(tifm_alloc_device); EXPORT_SYMBOL(tifm_alloc_device);
......
...@@ -131,7 +131,9 @@ void tifm_remove_adapter(struct tifm_adapter *fm); ...@@ -131,7 +131,9 @@ void tifm_remove_adapter(struct tifm_adapter *fm);
void tifm_free_adapter(struct tifm_adapter *fm); void tifm_free_adapter(struct tifm_adapter *fm);
void tifm_free_device(struct device *dev); void tifm_free_device(struct device *dev);
struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm); struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id,
unsigned char type);
int tifm_register_driver(struct tifm_driver *drv); int tifm_register_driver(struct tifm_driver *drv);
void tifm_unregister_driver(struct tifm_driver *drv); void tifm_unregister_driver(struct tifm_driver *drv);
void tifm_eject(struct tifm_dev *sock); void tifm_eject(struct tifm_dev *sock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment