Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169121
b: refs/heads/master
c: 097e296
h: refs/heads/master
i:
  169119: 2ceb46d
v: v3
  • Loading branch information
Russell King - ARM Linux authored and Dominik Brodowski committed Nov 9, 2009
1 parent 8c77997 commit ce3d194
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 109 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f767de6a26a07f7d58394512b6f6c96322f047f
refs/heads/master: 097e296d6175881eba7244de7222de61e9569911
230 changes: 123 additions & 107 deletions trunk/drivers/pcmcia/soc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
EXPORT_SYMBOL(soc_pcmcia_enable_irqs);


LIST_HEAD(soc_pcmcia_sockets);
static LIST_HEAD(soc_pcmcia_sockets);
static DEFINE_MUTEX(soc_pcmcia_sockets_lock);

#ifdef CONFIG_CPU_FREQ
Expand Down Expand Up @@ -619,158 +619,174 @@ module_exit(soc_pcmcia_cpufreq_unregister);

#endif

int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
struct skt_dev_info *sinfo)
void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
{
struct soc_pcmcia_socket *skt;
int ret, i;

mutex_lock(&soc_pcmcia_sockets_lock);
del_timer_sync(&skt->poll_timer);

/*
* Initialise the per-socket structure.
*/
for (i = 0; i < sinfo->nskt; i++) {
skt = &sinfo->skt[i];
pcmcia_unregister_socket(&skt->socket);

skt->socket.ops = &soc_common_pcmcia_operations;
skt->socket.owner = ops->owner;
skt->socket.dev.parent = dev;
flush_scheduled_work();

init_timer(&skt->poll_timer);
skt->poll_timer.function = soc_common_pcmcia_poll_event;
skt->poll_timer.data = (unsigned long)skt;
skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
skt->ops->hw_shutdown(skt);

skt->dev = dev;
skt->ops = ops;
soc_common_pcmcia_config_skt(skt, &dead_socket);

ret = request_resource(&iomem_resource, &skt->res_skt);
if (ret)
goto out_err_1;
list_del(&skt->node);
mutex_unlock(&soc_pcmcia_sockets_lock);

ret = request_resource(&skt->res_skt, &skt->res_io);
if (ret)
goto out_err_2;
iounmap(skt->virt_io);
skt->virt_io = NULL;
release_resource(&skt->res_attr);
release_resource(&skt->res_mem);
release_resource(&skt->res_io);
release_resource(&skt->res_skt);
}
EXPORT_SYMBOL(soc_pcmcia_remove_one);

ret = request_resource(&skt->res_skt, &skt->res_mem);
if (ret)
goto out_err_3;
int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
{
int ret;

ret = request_resource(&skt->res_skt, &skt->res_attr);
if (ret)
goto out_err_4;
init_timer(&skt->poll_timer);
skt->poll_timer.function = soc_common_pcmcia_poll_event;
skt->poll_timer.data = (unsigned long)skt;
skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;

skt->virt_io = ioremap(skt->res_io.start, 0x10000);
if (skt->virt_io == NULL) {
ret = -ENOMEM;
goto out_err_5;
}
ret = request_resource(&iomem_resource, &skt->res_skt);
if (ret)
goto out_err_1;

list_add(&skt->node, &soc_pcmcia_sockets);
ret = request_resource(&skt->res_skt, &skt->res_io);
if (ret)
goto out_err_2;

/*
* We initialize default socket timing here, because
* we are not guaranteed to see a SetIOMap operation at
* runtime.
*/
ops->set_timing(skt);
ret = request_resource(&skt->res_skt, &skt->res_mem);
if (ret)
goto out_err_3;

ret = ops->hw_init(skt);
if (ret)
goto out_err_6;
ret = request_resource(&skt->res_skt, &skt->res_attr);
if (ret)
goto out_err_4;

skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
skt->socket.resource_ops = &pccard_static_ops;
skt->socket.irq_mask = 0;
skt->socket.map_size = PAGE_SIZE;
skt->socket.pci_irq = skt->irq;
skt->socket.io_offset = (unsigned long)skt->virt_io;
skt->virt_io = ioremap(skt->res_io.start, 0x10000);
if (skt->virt_io == NULL) {
ret = -ENOMEM;
goto out_err_5;
}

skt->status = soc_common_pcmcia_skt_state(skt);
mutex_lock(&soc_pcmcia_sockets_lock);

ret = pcmcia_register_socket(&skt->socket);
if (ret)
goto out_err_7;
list_add(&skt->node, &soc_pcmcia_sockets);

WARN_ON(skt->socket.sock != i);
/*
* We initialize default socket timing here, because
* we are not guaranteed to see a SetIOMap operation at
* runtime.
*/
skt->ops->set_timing(skt);

add_timer(&skt->poll_timer);
ret = skt->ops->hw_init(skt);
if (ret)
goto out_err_6;

ret = device_create_file(&skt->socket.dev, &dev_attr_status);
if (ret)
goto out_err_8;
}
skt->socket.ops = &soc_common_pcmcia_operations;
skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
skt->socket.resource_ops = &pccard_static_ops;
skt->socket.irq_mask = 0;
skt->socket.map_size = PAGE_SIZE;
skt->socket.pci_irq = skt->irq;
skt->socket.io_offset = (unsigned long)skt->virt_io;

dev_set_drvdata(dev, sinfo);
ret = 0;
goto out;
skt->status = soc_common_pcmcia_skt_state(skt);

do {
skt = &sinfo->skt[i];
ret = pcmcia_register_socket(&skt->socket);
if (ret)
goto out_err_7;

add_timer(&skt->poll_timer);

mutex_unlock(&soc_pcmcia_sockets_lock);

ret = device_create_file(&skt->socket.dev, &dev_attr_status);
if (ret)
goto out_err_8;

return ret;

device_remove_file(&skt->socket.dev, &dev_attr_status);
out_err_8:
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
mutex_lock(&soc_pcmcia_sockets_lock);
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);

out_err_7:
flush_scheduled_work();
flush_scheduled_work();

ops->hw_shutdown(skt);
skt->ops->hw_shutdown(skt);
out_err_6:
list_del(&skt->node);
iounmap(skt->virt_io);
list_del(&skt->node);
mutex_unlock(&soc_pcmcia_sockets_lock);
iounmap(skt->virt_io);
out_err_5:
release_resource(&skt->res_attr);
release_resource(&skt->res_attr);
out_err_4:
release_resource(&skt->res_mem);
release_resource(&skt->res_mem);
out_err_3:
release_resource(&skt->res_io);
release_resource(&skt->res_io);
out_err_2:
release_resource(&skt->res_skt);
release_resource(&skt->res_skt);
out_err_1:
i--;
} while (i > 0);

kfree(sinfo);

out:
mutex_unlock(&soc_pcmcia_sockets_lock);
return ret;
}
EXPORT_SYMBOL(soc_common_drv_pcmcia_probe);
EXPORT_SYMBOL(soc_pcmcia_add_one);

int soc_common_drv_pcmcia_remove(struct device *dev)
int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
struct skt_dev_info *sinfo)
{
struct skt_dev_info *sinfo = dev_get_drvdata(dev);
int i;
struct soc_pcmcia_socket *skt;
int ret, i;

dev_set_drvdata(dev, NULL);
/*
* Initialise the per-socket structure.
*/
for (i = ret = 0; i < sinfo->nskt; i++) {
skt = &sinfo->skt[i];

mutex_lock(&soc_pcmcia_sockets_lock);
for (i = 0; i < sinfo->nskt; i++) {
struct soc_pcmcia_socket *skt = &sinfo->skt[i];
skt->socket.owner = ops->owner;
skt->socket.dev.parent = dev;

del_timer_sync(&skt->poll_timer);
skt->dev = dev;
skt->ops = ops;

pcmcia_unregister_socket(&skt->socket);
ret = soc_pcmcia_add_one(skt);
if (ret)
break;

flush_scheduled_work();
WARN_ON(skt->socket.sock != i);
}

skt->ops->hw_shutdown(skt);
if (ret) {
while (--i >= 0)
soc_pcmcia_remove_one(&sinfo->skt[i]);
kfree(sinfo);
} else {
dev_set_drvdata(dev, sinfo);
}

soc_common_pcmcia_config_skt(skt, &dead_socket);
return ret;
}
EXPORT_SYMBOL(soc_common_drv_pcmcia_probe);

list_del(&skt->node);
iounmap(skt->virt_io);
skt->virt_io = NULL;
release_resource(&skt->res_attr);
release_resource(&skt->res_mem);
release_resource(&skt->res_io);
release_resource(&skt->res_skt);
}
mutex_unlock(&soc_pcmcia_sockets_lock);
int soc_common_drv_pcmcia_remove(struct device *dev)
{
struct skt_dev_info *sinfo = dev_get_drvdata(dev);
int i;

dev_set_drvdata(dev, NULL);

for (i = 0; i < sinfo->nskt; i++)
soc_pcmcia_remove_one(&sinfo->skt[i]);

kfree(sinfo);

Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/pcmcia/soc_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_
extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);


extern struct list_head soc_pcmcia_sockets;
void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);

extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo);
extern int soc_common_drv_pcmcia_remove(struct device *dev);
Expand Down

0 comments on commit ce3d194

Please sign in to comment.