All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lars-Peter Clausen <lars@metafoo.de>
To: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org, linux-kernel@vger.kernel.org,
	Lars-Peter Clausen <lars@metafoo.de>
Subject: [RFC][PATCH 03/26] MIPS: JZ4740: Add clock API support.
Date: Wed,  2 Jun 2010 21:02:54 +0200	[thread overview]
Message-ID: <1275505397-16758-4-git-send-email-lars@metafoo.de> (raw)
In-Reply-To: <1275505397-16758-1-git-send-email-lars@metafoo.de>

This patch adds support for managing the clocks found on JZ4740 SoC through
the Linux clock API.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/clock.h |   28 +
 arch/mips/jz4740/clock-debugfs.c          |  109 ++++
 arch/mips/jz4740/clock.c                  |  920 +++++++++++++++++++++++++++++
 arch/mips/jz4740/clock.h                  |   76 +++
 4 files changed, 1133 insertions(+), 0 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-jz4740/clock.h
 create mode 100644 arch/mips/jz4740/clock-debugfs.c
 create mode 100644 arch/mips/jz4740/clock.c
 create mode 100644 arch/mips/jz4740/clock.h

diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
new file mode 100644
index 0000000..9069727
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/clock.h
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __ASM_JZ4740_CLOCK_H__
+#define __ASM_JZ4740_CLOCK_H__
+
+enum jz4740_wait_mode {
+	JZ4740_WAIT_MODE_IDLE,
+	JZ4740_WAIT_MODE_SLEEP,
+};
+
+void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
+
+void jz4740_clock_udc_enable_auto_suspend(void);
+void jz4740_clock_udc_disable_auto_suspend(void);
+
+#endif
diff --git a/arch/mips/jz4740/clock-debugfs.c b/arch/mips/jz4740/clock-debugfs.c
new file mode 100644
index 0000000..993b91b
--- /dev/null
+++ b/arch/mips/jz4740/clock-debugfs.c
@@ -0,0 +1,109 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC clock support debugfs entries
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include <asm/mach-jz4740/clock.h>
+#include "clock.h"
+
+static struct dentry *jz4740_clock_debugfs;
+
+static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
+{
+	struct clk *clk = data;
+	*value = clk_is_enabled(clk);
+
+	return 0;
+}
+
+static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
+{
+	struct clk *clk = data;
+
+	if (value)
+		return clk_enable(clk);
+	else
+		clk_disable(clk);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
+	jz4740_clock_debugfs_show_enabled,
+	jz4740_clock_debugfs_set_enabled,
+	"%llu\n");
+
+static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
+{
+	struct clk *clk = data;
+	*value = clk_get_rate(clk);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
+	jz4740_clock_debugfs_show_rate,
+	NULL,
+	"%llu\n");
+
+void jz4740_clock_debugfs_add_clk(struct clk *clk)
+{
+	if (!jz4740_clock_debugfs)
+		return;
+
+	clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
+	debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
+				&jz4740_clock_debugfs_ops_rate);
+	debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
+				&jz4740_clock_debugfs_ops_enabled);
+
+	if (clk->parent) {
+		char parent_path[100];
+		snprintf(parent_path, 100, "../%s", clk->parent->name);
+		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
+						clk->debugfs_entry,
+						parent_path);
+	}
+}
+
+/* TODO: Locking */
+void jz4740_clock_debugfs_update_parent(struct clk *clk)
+{
+	if (clk->debugfs_parent_entry)
+		debugfs_remove(clk->debugfs_parent_entry);
+
+	if (clk->parent) {
+		char parent_path[100];
+		snprintf(parent_path, 100, "../%s", clk->parent->name);
+		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
+						clk->debugfs_entry,
+						parent_path);
+	} else {
+		clk->debugfs_parent_entry = NULL;
+	}
+}
+
+void jz4740_clock_debugfs_init(void)
+{
+	jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
+	if (IS_ERR(jz4740_clock_debugfs))
+		jz4740_clock_debugfs = NULL;
+}
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
new file mode 100644
index 0000000..378f2b0
--- /dev/null
+++ b/arch/mips/jz4740/clock.c
@@ -0,0 +1,920 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC clock support
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+
+#include <asm/mach-jz4740/clock.h>
+#include <asm/mach-jz4740/base.h>
+
+#include "clock.h"
+
+#define JZ_REG_CLOCK_CTRL	0x00
+#define JZ_REG_CLOCK_LOW_POWER	0x04
+#define JZ_REG_CLOCK_PLL	0x10
+#define JZ_REG_CLOCK_GATE	0x20
+#define JZ_REG_CLOCK_SLEEP_CTRL	0x24
+#define JZ_REG_CLOCK_I2S	0x60
+#define JZ_REG_CLOCK_LCD	0x64
+#define JZ_REG_CLOCK_MMC	0x68
+#define JZ_REG_CLOCK_UHC	0x6C
+#define JZ_REG_CLOCK_SPI	0x74
+
+#define JZ_CLOCK_CTRL_I2S_SRC_PLL	BIT(31)
+#define JZ_CLOCK_CTRL_KO_ENABLE		BIT(30)
+#define JZ_CLOCK_CTRL_UDC_SRC_PLL	BIT(29)
+#define JZ_CLOCK_CTRL_UDIV_MASK		0x1f800000
+#define JZ_CLOCK_CTRL_CHANGE_ENABLE	BIT(22)
+#define JZ_CLOCK_CTRL_PLL_HALF		BIT(21)
+#define JZ_CLOCK_CTRL_LDIV_MASK		0x001f0000
+#define JZ_CLOCK_CTRL_UDIV_OFFSET	23
+#define JZ_CLOCK_CTRL_LDIV_OFFSET	16
+#define JZ_CLOCK_CTRL_MDIV_OFFSET	12
+#define JZ_CLOCK_CTRL_PDIV_OFFSET	 8
+#define JZ_CLOCK_CTRL_HDIV_OFFSET	 4
+#define JZ_CLOCK_CTRL_CDIV_OFFSET	 0
+
+#define JZ_CLOCK_GATE_UART0	BIT(0)
+#define JZ_CLOCK_GATE_TCU	BIT(1)
+#define JZ_CLOCK_GATE_RTC	BIT(2)
+#define JZ_CLOCK_GATE_I2C	BIT(3)
+#define JZ_CLOCK_GATE_SPI	BIT(4)
+#define JZ_CLOCK_GATE_AIC	BIT(5)
+#define JZ_CLOCK_GATE_I2S	BIT(6)
+#define JZ_CLOCK_GATE_MMC	BIT(7)
+#define JZ_CLOCK_GATE_ADC	BIT(8)
+#define JZ_CLOCK_GATE_CIM	BIT(9)
+#define JZ_CLOCK_GATE_LCD	BIT(10)
+#define JZ_CLOCK_GATE_UDC	BIT(11)
+#define JZ_CLOCK_GATE_DMAC	BIT(12)
+#define JZ_CLOCK_GATE_IPU	BIT(13)
+#define JZ_CLOCK_GATE_UHC	BIT(14)
+#define JZ_CLOCK_GATE_UART1	BIT(15)
+
+#define JZ_CLOCK_I2S_DIV_MASK		0x01ff
+
+#define JZ_CLOCK_LCD_DIV_MASK		0x01ff
+
+#define JZ_CLOCK_MMC_DIV_MASK		0x001f
+
+#define JZ_CLOCK_UHC_DIV_MASK		0x000f
+
+#define JZ_CLOCK_SPI_SRC_PLL		BIT(31)
+#define JZ_CLOCK_SPI_DIV_MASK		0x000f
+
+#define JZ_CLOCK_PLL_M_MASK		0x01ff
+#define JZ_CLOCK_PLL_N_MASK		0x001f
+#define JZ_CLOCK_PLL_OD_MASK		0x0003
+#define JZ_CLOCK_PLL_STABLE		BIT(10)
+#define JZ_CLOCK_PLL_BYPASS		BIT(9)
+#define JZ_CLOCK_PLL_ENABLED		BIT(8)
+#define JZ_CLOCK_PLL_STABLIZE_MASK	0x000f
+#define JZ_CLOCK_PLL_M_OFFSET		23
+#define JZ_CLOCK_PLL_N_OFFSET		18
+#define JZ_CLOCK_PLL_OD_OFFSET		16
+
+#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
+#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
+
+#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
+#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
+
+static void __iomem *jz_clock_base;
+static spinlock_t jz_clock_lock;
+static LIST_HEAD(jz_clocks);
+
+struct main_clk {
+	struct clk clk;
+	uint32_t div_offset;
+};
+
+struct divided_clk {
+	struct clk clk;
+	uint32_t reg;
+	uint32_t mask;
+};
+
+struct static_clk {
+	struct clk clk;
+	unsigned long rate;
+};
+
+static uint32_t jz_clk_reg_read(int reg)
+{
+	return readl(jz_clock_base + reg);
+}
+
+static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
+{
+	uint32_t val2;
+
+	spin_lock(&jz_clock_lock);
+	val2 = readl(jz_clock_base + reg);
+	val2 &= ~mask;
+	val2 |= val;
+	writel(val2, jz_clock_base + reg);
+	spin_unlock(&jz_clock_lock);
+}
+
+static void jz_clk_reg_set_bits(int reg, uint32_t mask)
+{
+	uint32_t val;
+
+	spin_lock(&jz_clock_lock);
+	val = readl(jz_clock_base + reg);
+	val |= mask;
+	writel(val, jz_clock_base + reg);
+	spin_unlock(&jz_clock_lock);
+}
+
+static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
+{
+	uint32_t val;
+
+	spin_lock(&jz_clock_lock);
+	val = readl(jz_clock_base + reg);
+	val &= ~mask;
+	writel(val, jz_clock_base + reg);
+	spin_unlock(&jz_clock_lock);
+}
+
+static int jz_clk_enable_gating(struct clk *clk)
+{
+	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
+		return -EINVAL;
+
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
+	return 0;
+}
+
+static int jz_clk_disable_gating(struct clk *clk)
+{
+	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
+		return -EINVAL;
+
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
+	return 0;
+}
+
+static int jz_clk_is_enabled_gating(struct clk *clk)
+{
+	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
+		return 1;
+
+	return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
+}
+
+static unsigned long jz_clk_static_get_rate(struct clk *clk)
+{
+	return ((struct static_clk *)clk)->rate;
+}
+
+static int jz_clk_ko_enable(struct clk *clk)
+{
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
+	return 0;
+}
+
+static int jz_clk_ko_disable(struct clk *clk)
+{
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
+	return 0;
+}
+
+static int jz_clk_ko_is_enabled(struct clk *clk)
+{
+	return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
+}
+
+static const int pllno[] = {1, 2, 2, 4};
+
+static unsigned long jz_clk_pll_get_rate(struct clk *clk)
+{
+	uint32_t val;
+	int m;
+	int n;
+	int od;
+
+	val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
+
+	if (val & JZ_CLOCK_PLL_BYPASS)
+		return clk_get_rate(clk->parent);
+
+	m = ((val >> 23) & 0x1ff) + 2;
+	n = ((val >> 18) & 0x1f) + 2;
+	od = (val >> 16) & 0x3;
+
+	return clk_get_rate(clk->parent) * (m / n) / pllno[od];
+}
+
+static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
+{
+	uint32_t reg;
+
+	reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
+	if (reg & JZ_CLOCK_CTRL_PLL_HALF)
+		return jz_clk_pll_get_rate(clk->parent);
+	return jz_clk_pll_get_rate(clk->parent) >> 1;
+}
+
+static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
+
+static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
+	int div;
+
+	div = parent_rate / rate;
+	if (div > 32)
+		return parent_rate / 32;
+	else if (div < 1)
+		return parent_rate;
+
+	div &= (0x3 << (ffs(div) - 1));
+
+	return parent_rate / div;
+}
+
+static unsigned long jz_clk_main_get_rate(struct clk *clk)
+{
+	struct main_clk *mclk = (struct main_clk *)clk;
+	uint32_t div;
+
+	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
+
+	div >>= mclk->div_offset;
+	div &= 0xf;
+
+	if (div >= ARRAY_SIZE(jz_clk_main_divs))
+		div = ARRAY_SIZE(jz_clk_main_divs) - 1;
+
+	return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
+}
+
+static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct main_clk *mclk = (struct main_clk *)clk;
+	int i;
+	int div;
+	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
+
+	rate = jz_clk_main_round_rate(clk, rate);
+
+	div = parent_rate / rate;
+
+	i = (ffs(div) - 1) << 1;
+	if (i > 0 && !(div & BIT(i-1)))
+		i -= 1;
+
+	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
+				0xf << mclk->div_offset);
+
+	return 0;
+}
+
+static struct clk_ops jz_clk_static_ops = {
+	.get_rate = jz_clk_static_get_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct static_clk jz_clk_ext = {
+	.clk = {
+		.name = "ext",
+		.gate_bit = JZ4740_CLK_NOT_GATED,
+		.ops = &jz_clk_static_ops,
+	},
+};
+
+static struct clk_ops jz_clk_pll_ops = {
+	.get_rate = jz_clk_static_get_rate,
+};
+
+static struct clk jz_clk_pll = {
+	.name = "pll",
+	.parent = &jz_clk_ext.clk,
+	.ops = &jz_clk_pll_ops,
+};
+
+static struct clk_ops jz_clk_pll_half_ops = {
+	.get_rate = jz_clk_pll_half_get_rate,
+};
+
+static struct clk jz_clk_pll_half = {
+	.name = "pll half",
+	.parent = &jz_clk_pll,
+	.ops = &jz_clk_pll_half_ops,
+};
+
+static const struct clk_ops jz_clk_main_ops = {
+	.get_rate = jz_clk_main_get_rate,
+	.set_rate = jz_clk_main_set_rate,
+	.round_rate = jz_clk_main_round_rate,
+};
+
+static struct main_clk jz_clk_cpu = {
+	.clk = {
+		.name = "cclk",
+		.parent = &jz_clk_pll,
+		.ops = &jz_clk_main_ops,
+	},
+	.div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
+};
+
+static struct main_clk jz_clk_memory = {
+	.clk = {
+		.name = "mclk",
+		.parent = &jz_clk_pll,
+		.ops = &jz_clk_main_ops,
+	},
+	.div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
+};
+
+static struct main_clk jz_clk_high_speed_peripheral = {
+	.clk = {
+		.name = "hclk",
+		.parent = &jz_clk_pll,
+		.ops = &jz_clk_main_ops,
+	},
+	.div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
+};
+
+
+static struct main_clk jz_clk_low_speed_peripheral = {
+	.clk = {
+		.name = "pclk",
+		.parent = &jz_clk_pll,
+		.ops = &jz_clk_main_ops,
+	},
+	.div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
+};
+
+static const struct clk_ops jz_clk_ko_ops = {
+	.enable = jz_clk_ko_enable,
+	.disable = jz_clk_ko_disable,
+	.is_enabled = jz_clk_ko_is_enabled,
+};
+
+static struct clk jz_clk_ko = {
+	.name = "cko",
+	.parent = &jz_clk_memory.clk,
+	.ops = &jz_clk_ko_ops,
+};
+
+static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
+{
+	if (parent == &jz_clk_pll)
+		jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
+	else if (parent == &jz_clk_ext.clk)
+		jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	return 0;
+}
+
+static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
+{
+	if (parent == &jz_clk_pll_half)
+		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
+	else if (parent == &jz_clk_ext.clk)
+		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	return 0;
+}
+
+static int jz_clk_udc_enable(struct clk *clk)
+{
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
+			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
+
+	return 0;
+}
+
+static int jz_clk_udc_disable(struct clk *clk)
+{
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
+			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
+
+	return 0;
+}
+
+static int jz_clk_udc_is_enabled(struct clk *clk)
+{
+	return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
+			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
+}
+static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
+{
+	if (parent == &jz_clk_pll_half)
+		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
+	else if (parent == &jz_clk_ext.clk)
+		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
+	else
+		return -EINVAL;
+
+	clk->parent = parent;
+
+	return 0;
+}
+
+static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
+{
+	int div;
+
+	if (clk->parent == &jz_clk_ext.clk)
+		return -EINVAL;
+
+	div = clk_get_rate(clk->parent) / rate - 1;
+
+	if (div < 0)
+		div = 0;
+	else if (div > 63)
+		div = 63;
+
+	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
+				JZ_CLOCK_CTRL_UDIV_MASK);
+	return 0;
+}
+
+static unsigned long jz_clk_udc_get_rate(struct clk *clk)
+{
+	int div;
+
+	if (clk->parent == &jz_clk_ext.clk)
+		return clk_get_rate(clk->parent);
+
+	div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
+	div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
+	div += 1;
+
+	return clk_get_rate(clk->parent) / div;
+}
+
+static unsigned long jz_clk_divided_get_rate(struct clk *clk)
+{
+	struct divided_clk *dclk = (struct divided_clk *)clk;
+	int div;
+
+	if (clk->parent == &jz_clk_ext.clk)
+		return clk_get_rate(clk->parent);
+
+	div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
+
+	return clk_get_rate(clk->parent) / div;
+}
+
+static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
+{
+	struct divided_clk *dclk = (struct divided_clk *)clk;
+	int div;
+
+	if (clk->parent == &jz_clk_ext.clk)
+		return -EINVAL;
+
+	div = clk_get_rate(clk->parent) / rate - 1;
+
+	if (div < 0)
+		div = 0;
+	else if (div > dclk->mask)
+		div = dclk->mask;
+
+	jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
+
+	return 0;
+}
+
+static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
+{
+	int div;
+	unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
+
+	if (rate > 150000000)
+		return 150000000;
+
+	div = parent_rate / rate;
+	if (div < 1)
+		div = 1;
+	else if (div > 32)
+		div = 32;
+
+	return parent_rate / div;
+}
+
+static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int div;
+
+	if (rate > 150000000)
+		return -EINVAL;
+
+	div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
+	if (div < 0)
+		div = 0;
+	else if (div > 31)
+		div = 31;
+
+	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
+				JZ_CLOCK_CTRL_LDIV_MASK);
+
+	return 0;
+}
+
+static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
+{
+	int div;
+
+	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
+	div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
+
+	return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
+}
+
+static const struct clk_ops jz_clk_ops_ld = {
+	.set_rate = jz_clk_ldclk_set_rate,
+	.get_rate = jz_clk_ldclk_get_rate,
+	.round_rate = jz_clk_ldclk_round_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct clk jz_clk_ld = {
+	.name = "lcd",
+	.gate_bit = JZ_CLOCK_GATE_LCD,
+	.parent = &jz_clk_pll_half,
+	.ops = &jz_clk_ops_ld,
+};
+
+static const struct clk_ops jz_clk_i2s_ops = {
+	.set_rate = jz_clk_divided_set_rate,
+	.get_rate = jz_clk_divided_get_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+	.set_parent = jz_clk_i2s_set_parent,
+};
+
+static const struct clk_ops jz_clk_spi_ops = {
+	.set_rate = jz_clk_divided_set_rate,
+	.get_rate = jz_clk_divided_get_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+	.set_parent = jz_clk_spi_set_parent,
+};
+
+static const struct clk_ops jz_clk_divided_ops = {
+	.set_rate = jz_clk_divided_set_rate,
+	.get_rate = jz_clk_divided_get_rate,
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct divided_clk jz4740_clock_divided_clks[] = {
+	{
+		.clk = {
+			.name = "lcd_pclk",
+			.parent = &jz_clk_pll_half,
+			.gate_bit = JZ4740_CLK_NOT_GATED,
+			.ops = &jz_clk_divided_ops,
+		},
+		.reg = JZ_REG_CLOCK_LCD,
+		.mask = JZ_CLOCK_LCD_DIV_MASK,
+	},
+	{
+		.clk = {
+			.name = "i2s",
+			.parent = &jz_clk_ext.clk,
+			.gate_bit = JZ_CLOCK_GATE_I2S,
+			.ops = &jz_clk_i2s_ops,
+		},
+		.reg = JZ_REG_CLOCK_I2S,
+		.mask = JZ_CLOCK_I2S_DIV_MASK,
+	},
+	{
+		.clk = {
+			.name = "spi",
+			.parent = &jz_clk_ext.clk,
+			.gate_bit = JZ_CLOCK_GATE_SPI,
+			.ops = &jz_clk_spi_ops,
+		},
+		.reg = JZ_REG_CLOCK_SPI,
+		.mask = JZ_CLOCK_SPI_DIV_MASK,
+	},
+	{
+		.clk = {
+			.name = "mmc",
+			.parent = &jz_clk_pll_half,
+			.gate_bit = JZ_CLOCK_GATE_MMC,
+			.ops = &jz_clk_divided_ops,
+		},
+		.reg = JZ_REG_CLOCK_MMC,
+		.mask = JZ_CLOCK_MMC_DIV_MASK,
+	},
+	{
+		.clk = {
+			.name = "uhc",
+			.parent = &jz_clk_pll_half,
+			.gate_bit = JZ_CLOCK_GATE_UHC,
+			.ops = &jz_clk_divided_ops,
+		},
+		.reg = JZ_REG_CLOCK_UHC,
+		.mask = JZ_CLOCK_UHC_DIV_MASK,
+	},
+};
+
+static const struct clk_ops jz_clk_udc_ops = {
+	.set_parent = jz_clk_udc_set_parent,
+	.set_rate = jz_clk_udc_set_rate,
+	.get_rate = jz_clk_udc_get_rate,
+	.enable = jz_clk_udc_enable,
+	.disable = jz_clk_udc_disable,
+	.is_enabled = jz_clk_udc_is_enabled,
+};
+
+static const struct clk_ops jz_clk_simple_ops = {
+	.enable = jz_clk_enable_gating,
+	.disable = jz_clk_disable_gating,
+	.is_enabled = jz_clk_is_enabled_gating,
+};
+
+static struct clk jz4740_clock_simple_clks[] = {
+	{
+		.name = "udc",
+		.parent = &jz_clk_ext.clk,
+		.ops = &jz_clk_udc_ops,
+	},
+	{
+		.name = "uart0",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_UART0,
+		.ops = &jz_clk_simple_ops,
+	},
+	{
+		.name = "uart1",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_UART1,
+		.ops = &jz_clk_simple_ops,
+	},
+	{
+		.name = "dma",
+		.parent = &jz_clk_high_speed_peripheral.clk,
+		.gate_bit = JZ_CLOCK_GATE_UART0,
+		.ops = &jz_clk_simple_ops,
+	},
+	{
+		.name = "ipu",
+		.parent = &jz_clk_high_speed_peripheral.clk,
+		.gate_bit = JZ_CLOCK_GATE_IPU,
+		.ops = &jz_clk_simple_ops,
+	},
+	{
+		.name = "adc",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_ADC,
+		.ops = &jz_clk_simple_ops,
+	},
+	{
+		.name = "i2c",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_I2C,
+		.ops = &jz_clk_simple_ops,
+	},
+	{
+		.name = "aic",
+		.parent = &jz_clk_ext.clk,
+		.gate_bit = JZ_CLOCK_GATE_AIC,
+		.ops = &jz_clk_simple_ops,
+	},
+};
+
+static struct static_clk jz_clk_rtc = {
+	.clk = {
+		.name = "rtc",
+		.gate_bit = JZ_CLOCK_GATE_RTC,
+		.ops = &jz_clk_static_ops,
+	},
+	.rate = 32768,
+};
+
+int clk_enable(struct clk *clk)
+{
+	if (!clk->ops->enable)
+		return -EINVAL;
+
+	return clk->ops->enable(clk);
+}
+EXPORT_SYMBOL_GPL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+	if (clk->ops->disable)
+		clk->ops->disable(clk);
+}
+EXPORT_SYMBOL_GPL(clk_disable);
+
+int clk_is_enabled(struct clk *clk)
+{
+	if (clk->ops->is_enabled)
+		return clk->ops->is_enabled(clk);
+
+	return 1;
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (clk->ops->get_rate)
+		return clk->ops->get_rate(clk);
+	if (clk->parent)
+		return clk_get_rate(clk->parent);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(clk_get_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	if (!clk->ops->set_rate)
+		return -EINVAL;
+	return clk->ops->set_rate(clk, rate);
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk->ops->round_rate)
+		return clk->ops->round_rate(clk, rate);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret;
+
+	if (!clk->ops->set_parent)
+		return -EINVAL;
+
+	clk_disable(clk);
+	ret = clk->ops->set_parent(clk, parent);
+	clk_enable(clk);
+
+	jz4740_clock_debugfs_update_parent(clk);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_parent);
+
+struct clk *clk_get(struct device *dev, const char *name)
+{
+	struct clk *clk;
+
+	list_for_each_entry(clk, &jz_clocks, list) {
+		if (strcmp(clk->name, name) == 0)
+			return clk;
+	}
+	return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL_GPL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL_GPL(clk_put);
+
+
+static inline void clk_add(struct clk *clk)
+{
+	list_add_tail(&clk->list, &jz_clocks);
+
+	jz4740_clock_debugfs_add_clk(clk);
+}
+
+static void clk_register_clks(void)
+{
+	size_t i;
+
+	clk_add(&jz_clk_ext.clk);
+	clk_add(&jz_clk_pll);
+	clk_add(&jz_clk_pll_half);
+	clk_add(&jz_clk_cpu.clk);
+	clk_add(&jz_clk_high_speed_peripheral.clk);
+	clk_add(&jz_clk_low_speed_peripheral.clk);
+	clk_add(&jz_clk_ko);
+	clk_add(&jz_clk_ld);
+	clk_add(&jz_clk_rtc.clk);
+
+	for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
+		clk_add(&jz4740_clock_divided_clks[i].clk);
+
+	for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
+		clk_add(&jz4740_clock_simple_clks[i]);
+}
+
+void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
+{
+	switch (mode) {
+	case JZ4740_WAIT_MODE_IDLE:
+		jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
+		break;
+	case JZ4740_WAIT_MODE_SLEEP:
+		jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
+		break;
+	}
+}
+
+void jz4740_clock_udc_disable_auto_suspend(void)
+{
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
+
+void jz4740_clock_udc_enable_auto_suspend(void)
+{
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
+
+void jz4740_clock_suspend(void)
+{
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
+		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
+}
+
+void jz4740_clock_resume(void)
+{
+	uint32_t pll;
+
+	jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
+
+	do {
+		pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
+	} while (!(pll & JZ_CLOCK_PLL_STABLE));
+
+	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
+		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+}
+
+static int jz4740_clock_init(void)
+{
+	uint32_t val;
+
+	jz_clock_base = ioremap(CPHYSADDR(JZ4740_CPM_BASE_ADDR), 0x100);
+	if (!jz_clock_base)
+		return -EBUSY;
+
+	spin_lock_init(&jz_clock_lock);
+
+	jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
+	jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
+
+	val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
+
+	if (val & JZ_CLOCK_SPI_SRC_PLL)
+		jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
+
+	val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
+
+	if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
+		jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
+
+	if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
+		jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
+
+	jz4740_clock_debugfs_init();
+
+	clk_register_clks();
+
+	return 0;
+}
+subsys_initcall(jz4740_clock_init);
diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
new file mode 100644
index 0000000..5d07499
--- /dev/null
+++ b/arch/mips/jz4740/clock.h
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 SoC clock support
+ *
+ *  This program is free software; you can redistribute	 it and/or modify it
+ *  under  the terms of	 the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the	License, or (at your
+ *  option) any later version.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __MIPS_JZ4740_CLOCK_H__
+#define __MIPS_JZ4740_CLOCK_H__
+
+#include <linux/list.h>
+
+struct jz4740_clock_board_data {
+	unsigned long ext_rate;
+	unsigned long rtc_rate;
+};
+
+extern struct jz4740_clock_board_data jz4740_clock_bdata;
+
+void jz4740_clock_suspend(void);
+void jz4740_clock_resume(void);
+
+struct clk;
+
+struct clk_ops {
+	unsigned long (*get_rate)(struct clk *clk);
+	unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
+	int (*set_rate)(struct clk *clk, unsigned long rate);
+	int (*enable)(struct clk *clk);
+	int (*disable)(struct clk *clk);
+	int (*is_enabled)(struct clk *clk);
+
+	int (*set_parent)(struct clk *clk, struct clk *parent);
+
+};
+
+struct clk {
+	const char *name;
+	struct clk *parent;
+
+	uint32_t gate_bit;
+
+	const struct clk_ops *ops;
+
+	struct list_head list;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *debugfs_entry;
+	struct dentry *debugfs_parent_entry;
+#endif
+
+};
+
+#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
+
+int clk_is_enabled(struct clk *clk);
+
+#ifdef CONFIG_DEBUG_FS
+void jz4740_clock_debugfs_init(void);
+void jz4740_clock_debugfs_add_clk(struct clk *clk);
+void jz4740_clock_debugfs_update_parent(struct clk *clk);
+#else
+static inline void jz4740_clock_debugfs_init(void) {};
+static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
+static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
+#endif
+
+#endif
-- 
1.5.6.5


  parent reply	other threads:[~2010-06-02 19:06 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-02 19:02 [RFC][PATCH 00/26] *** SUBJECT HERE *** Lars-Peter Clausen
2010-06-02 19:02 ` [RFC][PATCH 01/26] MIPS: Add base support for Ingenic JZ4740 System-on-a-Chip Lars-Peter Clausen
2010-06-03 14:27   ` Florian Fainelli
2010-06-03 17:03     ` Lars-Peter Clausen
2010-06-02 19:02 ` [RFC][PATCH 02/26] MIPS: jz4740: Add IRQ handler code Lars-Peter Clausen
2010-06-03 14:29   ` Florian Fainelli
2010-06-02 19:02 ` Lars-Peter Clausen [this message]
2010-06-02 22:45   ` [RFC][PATCH 03/26] MIPS: JZ4740: Add clock API support Graham Gower
2010-06-03 17:20     ` Lars-Peter Clausen
2010-06-02 19:02 ` [RFC][PATCH 04/26] MIPS: JZ4740: Add timer support Lars-Peter Clausen
2010-06-02 19:02 ` [RFC][PATCH 05/26] MIPS: JZ4740: Add clocksource/clockevent support Lars-Peter Clausen
2010-06-02 19:02 ` [RFC][PATCH 06/26] MIPS: JZ4740: Add power-management and system reset support Lars-Peter Clausen
2010-06-02 19:02 ` [RFC][PATCH 07/26] MIPS: JZ4740: Add setup code Lars-Peter Clausen
2010-06-02 19:02 ` [RFC][PATCH 08/26] MIPS: JZ4740: Add gpio support Lars-Peter Clausen
2010-06-02 19:10 ` [RFC][PATCH 09/26] MIPS: JZ4740: Add DMA support Lars-Peter Clausen
2010-06-02 19:10 ` [RFC][PATCH 10/26] MIPS: JZ4740: Add PWM support Lars-Peter Clausen
2010-06-02 19:10 ` [RFC][PATCH 11/26] MIPS: JZ4740: Add serial support Lars-Peter Clausen
2010-06-02 19:10 ` [RFC][PATCH 12/26] MIPS: JZ4740: Add prom support Lars-Peter Clausen
2010-06-02 19:10 ` [RFC][PATCH 13/26] MIPS: JZ4740: Add platform devices Lars-Peter Clausen
2010-06-02 19:10 ` [RFC][PATCH 14/26] MIPS: JZ4740: Add Kbuild files Lars-Peter Clausen
2010-06-04  0:47   ` Ralf Baechle
2010-06-02 19:10 ` [RFC][PATCH 15/26] RTC: Add JZ4740 RTC driver Lars-Peter Clausen
2010-06-05 15:48   ` [rtc-linux] " Wan ZongShun
2010-06-05 17:26     ` Lars-Peter Clausen
2010-06-02 19:10 ` [RFC][PATCH 16/26] fbdev: Add JZ4740 framebuffer driver Lars-Peter Clausen
2010-06-02 19:10   ` Lars-Peter Clausen
2010-06-02 19:36   ` Andrew Morton
2010-06-02 19:36     ` Andrew Morton
2010-06-02 20:05     ` Lars-Peter Clausen
2010-06-02 20:05       ` Lars-Peter Clausen
2010-06-02 19:12 ` [RFC][PATCH 17/26] MTD: Nand: Add JZ4740 NAND driver Lars-Peter Clausen
2010-06-02 19:12   ` Lars-Peter Clausen
2010-06-13  9:40   ` Artem Bityutskiy
2010-06-13  9:40     ` Artem Bityutskiy
2010-06-02 19:12 ` [RFC][PATCH 18/26] MMC: Add JZ4740 mmc driver Lars-Peter Clausen
2010-06-02 19:12 ` [RFC][PATCH 19/26] USB: Add JZ4740 ohci support Lars-Peter Clausen
2010-06-02 19:12 ` [RFC][PATCH 20/26] alsa: ASoC: Add JZ4740 codec driver Lars-Peter Clausen
2010-06-02 19:12   ` Lars-Peter Clausen
2010-06-03  5:45   ` [alsa-devel] " Wan ZongShun
2010-06-03 12:03     ` Mark Brown
2010-06-03 12:03       ` Mark Brown
2010-06-03 12:32   ` [alsa-devel] " Liam Girdwood
2010-06-03 12:32     ` Liam Girdwood
2010-06-03 12:50     ` [alsa-devel] " Liam Girdwood
2010-06-03 12:50       ` Liam Girdwood
2010-06-03 16:58     ` [alsa-devel] " Lars-Peter Clausen
2010-06-03 16:58       ` Lars-Peter Clausen
2010-06-03 17:49   ` Mark Brown
2010-06-03 17:49     ` Mark Brown
2010-06-03 23:57     ` Lars-Peter Clausen
2010-06-03 23:57       ` Lars-Peter Clausen
2010-06-03 23:59       ` Mark Brown
2010-06-03 23:59         ` Mark Brown
2010-06-02 19:12 ` [RFC][PATCH 21/26] alsa: ASoC: Add JZ4740 ASoC support Lars-Peter Clausen
2010-06-02 19:12   ` Lars-Peter Clausen
2010-06-03  3:36   ` [alsa-devel] " Wan ZongShun
2010-06-03  3:36     ` Wan ZongShun
2010-06-03 12:48   ` Liam Girdwood
2010-06-03 12:48     ` Liam Girdwood
2010-06-03 16:50     ` Lars-Peter Clausen
2010-06-03 16:50       ` Lars-Peter Clausen
2010-06-03 17:03       ` Liam Girdwood
2010-06-03 17:16         ` Lars-Peter Clausen
2010-06-03 17:16           ` Lars-Peter Clausen
2010-06-03 17:25           ` Liam Girdwood
2010-06-03 17:25             ` Liam Girdwood
2010-06-03 17:37             ` Lars-Peter Clausen
2010-06-03 17:37               ` Lars-Peter Clausen
2010-06-03 18:14             ` [alsa-devel] " Troy Kisky
2010-06-03 18:14               ` Troy Kisky
2010-06-03 18:14               ` [alsa-devel] " Troy Kisky
2010-11-14 13:29               ` hi!!!! dkisky
2010-06-03 17:55   ` [RFC][PATCH 21/26] alsa: ASoC: Add JZ4740 ASoC support Mark Brown
2010-06-03 17:55     ` Mark Brown
2010-06-03 19:27     ` Lars-Peter Clausen
2010-06-02 19:12 ` [RFC][PATCH 22/26] hwmon: Add JZ4740 ADC driver Lars-Peter Clausen
2010-06-02 19:12   ` [lm-sensors] " Lars-Peter Clausen
2010-06-05 17:22   ` Jonathan Cameron
2010-06-05 17:22     ` [lm-sensors] " Jonathan Cameron
2010-06-05 19:08     ` Lars-Peter Clausen
2010-06-05 19:08       ` [lm-sensors] " Lars-Peter Clausen
2010-06-05 21:07       ` Jonathan Cameron
2010-06-05 21:07         ` Jonathan Cameron
2010-06-05 22:12         ` Lars-Peter Clausen
2010-06-05 22:12           ` Lars-Peter Clausen
2010-06-02 19:12 ` [RFC][PATCH 23/26] power: Add JZ4740 battery driver Lars-Peter Clausen
2010-06-14 15:51   ` Anton Vorontsov
2010-06-15 17:28     ` Lars-Peter Clausen
2010-06-15 17:34     ` Ralf Baechle
2010-06-16 12:20       ` Mark Brown
2010-06-19  3:48         ` Lars-Peter Clausen
2010-06-02 19:12 ` [RFC][PATCH 24/26] MIPS: JZ4740: Add qi_lb60 board support Lars-Peter Clausen
2010-06-02 19:15 ` [RFC][PATCH 25/26] MIPS: Add defconfig for the qi_lb60 board Lars-Peter Clausen
2010-06-02 19:15 ` [RFC][PATCH 26/26] alsa: ASoC: JZ4740: Add qi_lb60 board driver Lars-Peter Clausen
2010-06-02 19:15   ` Lars-Peter Clausen
2010-06-03 17:57   ` Mark Brown
2010-06-03 17:57     ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1275505397-16758-4-git-send-email-lars@metafoo.de \
    --to=lars@metafoo.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=ralf@linux-mips.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.