======================================================================*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/cpufreq.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include "soc_common.h"
+/* FIXME: platform dependent resource declaration has to move out of this file */
+#ifdef CONFIG_ARCH_PXA
+#include <asm/arch/pxa-regs.h>
+#endif
+
#ifdef DEBUG
static int pc_debug;
skt->ops->set_timing(skt);
- map->sys_stop -= map->sys_start;
- map->sys_stop += res->start + map->card_start;
- map->sys_start = res->start + map->card_start;
+ map->static_start = res->start + map->card_start;
return 0;
}
#define SKT_DEV_INFO_SIZE(n) \
(sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
+#ifdef CONFIG_CPU_FREQ
+static int
+soc_pcmcia_notifier(struct notifier_block *nb, unsigned long val, void *data)
+{
+ struct soc_pcmcia_socket *skt;
+ struct cpufreq_freqs *freqs = data;
+ int ret = 0;
+
+ down(&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);
+ up(&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;
+}
+
+static void soc_pcmcia_cpufreq_unregister(void)
+{
+ cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+#else
+#define soc_pcmcia_cpufreq_register()
+#define soc_pcmcia_cpufreq_unregister()
+#endif
+
int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
{
struct skt_dev_info *sinfo;
+ struct soc_pcmcia_socket *skt;
int ret, i;
down(&soc_pcmcia_sockets_lock);
* Initialise the per-socket structure.
*/
for (i = 0; i < nr; i++) {
- struct soc_pcmcia_socket *skt = &sinfo->skt[i];
+ skt = &sinfo->skt[i];
skt->socket.ops = &soc_common_pcmcia_operations;
skt->socket.owner = ops->owner;
goto out_err_5;
}
+ if ( list_empty(&soc_pcmcia_sockets) )
+ soc_pcmcia_cpufreq_register();
+
list_add(&skt->node, &soc_pcmcia_sockets);
/*
goto out;
do {
- struct soc_pcmcia_socket *skt = &sinfo->skt[i];
+ skt = &sinfo->skt[i];
del_timer_sync(&skt->poll_timer);
pcmcia_unregister_socket(&skt->socket);
release_resource(&skt->res_io);
release_resource(&skt->res_skt);
}
+ if ( list_empty(&soc_pcmcia_sockets) )
+ soc_pcmcia_cpufreq_unregister();
+
up(&soc_pcmcia_sockets_lock);
kfree(sinfo);