|
@@ -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
|
|
|
-static int
|
|
|
-soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
|
|
|
+static int soc_common_pcmcia_cpufreq_nb(struct notifier_block *nb,
|
|
|
+ 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;
|
|
|
- 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 = {
|
|
|
- .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);
|
|
|
+ return skt->ops->frequency_change(skt, val, freqs);
|
|
|
}
|
|
|
-module_exit(soc_pcmcia_cpufreq_unregister);
|
|
|
-
|
|
|
#endif
|
|
|
|
|
|
void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt,
|
|
@@ -795,19 +760,21 @@ EXPORT_SYMBOL(soc_pcmcia_init_one);
|
|
|
|
|
|
void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
|
|
|
{
|
|
|
- mutex_lock(&soc_pcmcia_sockets_lock);
|
|
|
del_timer_sync(&skt->poll_timer);
|
|
|
|
|
|
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);
|
|
|
|
|
|
/* should not be required; violates some lowlevel drivers */
|
|
|
soc_common_pcmcia_config_skt(skt, &dead_socket);
|
|
|
|
|
|
- list_del(&skt->node);
|
|
|
- mutex_unlock(&soc_pcmcia_sockets_lock);
|
|
|
-
|
|
|
iounmap(skt->virt_io);
|
|
|
skt->virt_io = NULL;
|
|
|
release_resource(&skt->res_attr);
|
|
@@ -849,10 +816,6 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
|
|
|
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 are not guaranteed to see a SetIOMap operation at
|
|
@@ -873,14 +836,23 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *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);
|
|
|
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;
|
|
@@ -888,15 +860,12 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
|
|
|
return ret;
|
|
|
|
|
|
out_err_8:
|
|
|
- mutex_lock(&soc_pcmcia_sockets_lock);
|
|
|
del_timer_sync(&skt->poll_timer);
|
|
|
pcmcia_unregister_socket(&skt->socket);
|
|
|
|
|
|
out_err_7:
|
|
|
soc_pcmcia_hw_shutdown(skt);
|
|
|
out_err_6:
|
|
|
- list_del(&skt->node);
|
|
|
- mutex_unlock(&soc_pcmcia_sockets_lock);
|
|
|
iounmap(skt->virt_io);
|
|
|
out_err_5:
|
|
|
release_resource(&skt->res_attr);
|