Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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 Original line 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
#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);


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)
		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)


	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)
	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);
+3 −0
Original line number Original line Diff line number Diff line
@@ -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;
};
};