Commit fb8c9959 authored by Russell King's avatar Russell King
Browse files

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
Loading
Loading
Loading
Loading
+23 −54
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -75,6 +75,9 @@ struct soc_pcmcia_socket {

	unsigned int		irq_state;

#ifdef CONFIG_CPU_FREQ
	struct notifier_block	cpufreq_nb;
#endif
	struct timer_list	poll_timer;
	struct list_head	node;
};