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

Commit 300bb762 authored by Alex Raimondi's avatar Alex Raimondi Committed by Haavard Skinnemoen
Browse files

avr32: Replace static clock list with dynamic linked list



This replaces the at32_clock_list array with a linked list.
Clocks can now be registered (added) to the list.

Signed-off-by: default avatarAlex Raimondi <raimondi@miromico.ch>
Signed-off-by: default avatarHaavard Skinnemoen <haavard.skinnemoen@atmel.com>
parent 787928e7
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -2028,7 +2028,7 @@ static struct clk gclk4 = {
	.index		= 4,
};

struct clk *at32_clock_list[] = {
static __initdata struct clk *init_clocks[] = {
	&osc32k,
	&osc0,
	&osc1,
@@ -2092,7 +2092,6 @@ struct clk *at32_clock_list[] = {
	&gclk3,
	&gclk4,
};
unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list);

void __init setup_platform(void)
{
@@ -2123,14 +2122,19 @@ void __init setup_platform(void)
	genclk_init_parent(&abdac0_sample_clk);

	/*
	 * Turn on all clocks that have at least one user already, and
	 * turn off everything else. We only do this for module
	 * clocks, and even though it isn't particularly pretty to
	 * check the address of the mode function, it should do the
	 * trick...
	 * Build initial dynamic clock list by registering all clocks
	 * from the array.
	 * At the same time, turn on all clocks that have at least one
	 * user already, and turn off everything else. We only do this
	 * for module clocks, and even though it isn't particularly
	 * pretty to  check the address of the mode function, it should
	 * do the trick...
	 */
	for (i = 0; i < ARRAY_SIZE(at32_clock_list); i++) {
		struct clk *clk = at32_clock_list[i];
	for (i = 0; i < ARRAY_SIZE(init_clocks); i++) {
		struct clk *clk = init_clocks[i];

		/* first, register clock */
		at32_clk_register(clk);

		if (clk->users == 0)
			continue;
+40 −12
Original line number Diff line number Diff line
@@ -15,24 +15,40 @@
#include <linux/err.h>
#include <linux/device.h>
#include <linux/string.h>
#include <linux/list.h>

#include <mach/chip.h>

#include "clock.h"

/* at32 clock list */
static LIST_HEAD(at32_clock_list);

static DEFINE_SPINLOCK(clk_lock);
static DEFINE_SPINLOCK(clk_list_lock);

void at32_clk_register(struct clk *clk)
{
	spin_lock(&clk_list_lock);
	/* add the new item to the end of the list */
	list_add_tail(&clk->list, &at32_clock_list);
	spin_unlock(&clk_list_lock);
}

struct clk *clk_get(struct device *dev, const char *id)
{
	int i;
	struct clk *clk;

	for (i = 0; i < at32_nr_clocks; i++) {
		struct clk *clk = at32_clock_list[i];
	spin_lock(&clk_list_lock);

		if (clk->dev == dev && strcmp(id, clk->name) == 0)
	list_for_each_entry(clk, &at32_clock_list, list) {
		if (clk->dev == dev && strcmp(id, clk->name) == 0) {
			spin_unlock(&clk_list_lock);
			return clk;
		}
	}

	spin_unlock(&clk_list_lock);
	return ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL(clk_get);
@@ -203,8 +219,8 @@ dump_clock(struct clk *parent, struct clkinf *r)

	/* cost of this scan is small, but not linear... */
	r->nest = nest + NEST_DELTA;
	for (i = 3; i < at32_nr_clocks; i++) {
		clk = at32_clock_list[i];

	list_for_each_entry(clk, &at32_clock_list, list) {
		if (clk->parent == parent)
			dump_clock(clk, r);
	}
@@ -215,6 +231,7 @@ static int clk_show(struct seq_file *s, void *unused)
{
	struct clkinf	r;
	int		i;
	struct clk 	*clk;

	/* show all the power manager registers */
	seq_printf(s, "MCCTRL  = %8x\n", pm_readl(MCCTRL));
@@ -234,14 +251,25 @@ static int clk_show(struct seq_file *s, void *unused)

	seq_printf(s, "\n");

	/* show clock tree as derived from the three oscillators
	 * we "know" are at the head of the list
	 */
	r.s = s;
	r.nest = 0;
	dump_clock(at32_clock_list[0], &r);
	dump_clock(at32_clock_list[1], &r);
	dump_clock(at32_clock_list[2], &r);
	/* protected from changes on the list while dumping */
	spin_lock(&clk_list_lock);

	/* show clock tree as derived from the three oscillators */
	clk = clk_get(NULL, "osc32k");
	dump_clock(clk, &r);
	clk_put(clk);

	clk = clk_get(NULL, "osc0");
	dump_clock(clk, &r);
	clk_put(clk);

	clk = clk_get(NULL, "osc1");
	dump_clock(clk, &r);
	clk_put(clk);

	spin_unlock(&clk_list_lock);

	return 0;
}
+5 −3
Original line number Diff line number Diff line
@@ -12,8 +12,13 @@
 * published by the Free Software Foundation.
 */
#include <linux/clk.h>
#include <linux/list.h>


void at32_clk_register(struct clk *clk);

struct clk {
	struct list_head list;		/* linking element */
	const char	*name;		/* Clock name/function */
	struct device	*dev;		/* Device the clock is used by */
	struct clk	*parent;	/* Parent clock, if any */
@@ -25,6 +30,3 @@ struct clk {
	u16		users;		/* Enabled if non-zero */
	u16		index;		/* Sibling index */
};

extern struct clk *at32_clock_list[];
extern unsigned int at32_nr_clocks;