Commit fb8c9959 authored by Russell King's avatar Russell King

pcmcia: soc_common: switch to a per-socket cpufreq notifier

Switch to a per-socket cpufreq notifier rather than a global notifier.
This allows each socket to be self-contained.
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
parent ac61b600
...@@ -732,50 +732,15 @@ static struct pccard_operations soc_common_pcmcia_operations = { ...@@ -732,50 +732,15 @@ static struct pccard_operations soc_common_pcmcia_operations = {
}; };
static LIST_HEAD(soc_pcmcia_sockets);
static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
#ifdef CONFIG_CPU_FREQ #ifdef CONFIG_CPU_FREQ
static int static int soc_common_pcmcia_cpufreq_nb(struct notifier_block *nb,
soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data) unsigned long val, void *data)
{ {
struct soc_pcmcia_socket *skt; struct soc_pcmcia_socket *skt = container_of(nb, struct soc_pcmcia_socket, cpufreq_nb);
struct cpufreq_freqs *freqs = data; struct cpufreq_freqs *freqs = data;
int ret = 0;
mutex_lock(&soc_pcmcia_sockets_lock);
list_for_each_entry(skt, &soc_pcmcia_sockets, node)
if (skt->ops->frequency_change)
ret += skt->ops->frequency_change(skt, val, freqs);
mutex_unlock(&soc_pcmcia_sockets_lock);
return ret;
}
static struct notifier_block soc_pcmcia_notifier_block = { return skt->ops->frequency_change(skt, val, freqs);
.notifier_call = soc_pcmcia_notifier
};
static int soc_pcmcia_cpufreq_register(void)
{
int ret;
ret = cpufreq_register_notifier(&soc_pcmcia_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
if (ret < 0)
printk(KERN_ERR "Unable to register CPU frequency change "
"notifier for PCMCIA (%d)\n", ret);
return ret;
}
fs_initcall(soc_pcmcia_cpufreq_register);
static void soc_pcmcia_cpufreq_unregister(void)
{
cpufreq_unregister_notifier(&soc_pcmcia_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
} }
module_exit(soc_pcmcia_cpufreq_unregister);
#endif #endif
void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
...@@ -795,19 +760,21 @@ EXPORT_SYMBOL(soc_pcmcia_init_one); ...@@ -795,19 +760,21 @@ EXPORT_SYMBOL(soc_pcmcia_init_one);
void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
{ {
mutex_lock(&soc_pcmcia_sockets_lock);
del_timer_sync(&skt->poll_timer); del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket); pcmcia_unregister_socket(&skt->socket);
#ifdef CONFIG_CPU_FREQ
if (skt->ops->frequency_change)
cpufreq_unregister_notifier(&skt->cpufreq_nb,
CPUFREQ_TRANSITION_NOTIFIER);
#endif
soc_pcmcia_hw_shutdown(skt); soc_pcmcia_hw_shutdown(skt);
/* should not be required; violates some lowlevel drivers */ /* should not be required; violates some lowlevel drivers */
soc_common_pcmcia_config_skt(skt, &dead_socket); soc_common_pcmcia_config_skt(skt, &dead_socket);
list_del(&skt->node);
mutex_unlock(&soc_pcmcia_sockets_lock);
iounmap(skt->virt_io); iounmap(skt->virt_io);
skt->virt_io = NULL; skt->virt_io = NULL;
release_resource(&skt->res_attr); release_resource(&skt->res_attr);
...@@ -849,10 +816,6 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) ...@@ -849,10 +816,6 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
goto out_err_5; goto out_err_5;
} }
mutex_lock(&soc_pcmcia_sockets_lock);
list_add(&skt->node, &soc_pcmcia_sockets);
/* /*
* We initialize default socket timing here, because * We initialize default socket timing here, because
* we are not guaranteed to see a SetIOMap operation at * we are not guaranteed to see a SetIOMap operation at
...@@ -873,14 +836,23 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) ...@@ -873,14 +836,23 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
skt->status = soc_common_pcmcia_skt_state(skt); skt->status = soc_common_pcmcia_skt_state(skt);
#ifdef CONFIG_CPU_FREQ
if (skt->ops->frequency_change) {
skt->cpufreq_nb.notifier_call = soc_common_pcmcia_cpufreq_nb;
ret = cpufreq_register_notifier(&skt->cpufreq_nb,
CPUFREQ_TRANSITION_NOTIFIER);
if (ret < 0)
dev_err(skt->socket.dev.parent,
"unable to register CPU frequency change notifier for PCMCIA (%d)\n",
ret);
}
#endif
ret = pcmcia_register_socket(&skt->socket); ret = pcmcia_register_socket(&skt->socket);
if (ret) if (ret)
goto out_err_7; 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); ret = device_create_file(&skt->socket.dev, &dev_attr_status);
if (ret) if (ret)
goto out_err_8; goto out_err_8;
...@@ -888,15 +860,12 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) ...@@ -888,15 +860,12 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
return ret; return ret;
out_err_8: out_err_8:
mutex_lock(&soc_pcmcia_sockets_lock);
del_timer_sync(&skt->poll_timer); del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket); pcmcia_unregister_socket(&skt->socket);
out_err_7: out_err_7:
soc_pcmcia_hw_shutdown(skt); soc_pcmcia_hw_shutdown(skt);
out_err_6: out_err_6:
list_del(&skt->node);
mutex_unlock(&soc_pcmcia_sockets_lock);
iounmap(skt->virt_io); iounmap(skt->virt_io);
out_err_5: out_err_5:
release_resource(&skt->res_attr); release_resource(&skt->res_attr);
......
...@@ -75,6 +75,9 @@ struct soc_pcmcia_socket { ...@@ -75,6 +75,9 @@ struct soc_pcmcia_socket {
unsigned int irq_state; unsigned int irq_state;
#ifdef CONFIG_CPU_FREQ
struct notifier_block cpufreq_nb;
#endif
struct timer_list poll_timer; struct timer_list poll_timer;
struct list_head node; struct list_head node;
}; };
......
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