SUPERH platform development
 help / color / mirror / Atom feed
* Re: [PATCH 04/04] sh: use ioread32/iowrite32 and mapped_reg for div6
From: Kuninori Morimoto @ 2011-12-09  5:49 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <20111208135922.18394.95163.sendpatchset@w520>


Hi Magnus, Paul

I tested these patch set on mackerel board with linus/master.
it works well.

But I'm afraid that this div6 patch didn't care
paul/common/clkfwk which has below commit.
it is still using clk->enable_reg.

Of course I can modify it after merge ;)

------------------------------------------------------
commit 56242a1fc595d158eddefbb4d6d76e82c2535f55
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Nov 21 21:33:18 2011 -0800

    sh: clkfwk: setup clock parent from current register value
------------------------------------------------------

Tested-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

> From: Magnus Damm <damm@opensource.se>
> 
> Convert the CPG DIV6 helper code to use the new mapped_reg
> together with ioread32() and iowrite32().
> 
> Signed-off-by: Magnus Damm <damm@opensource.se>
> ---
> 
>  drivers/sh/clk/cpg.c |   18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> --- 0011/drivers/sh/clk/cpg.c
> +++ work/drivers/sh/clk/cpg.c	2011-12-08 22:19:00.000000000 +0900
> @@ -72,7 +72,7 @@ static unsigned long sh_clk_div6_recalc(
>  	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
>  			     table, NULL);
>  
> -	idx = __raw_readl(clk->enable_reg) & 0x003f;
> +	idx = ioread32(clk->mapped_reg) & 0x003f;
>  
>  	return clk->freq_table[idx].frequency;
>  }
> @@ -98,10 +98,10 @@ static int sh_clk_div6_set_parent(struct
>  	if (ret < 0)
>  		return ret;
>  
> -	value = __raw_readl(clk->enable_reg) &
> +	value = ioread32(clk->mapped_reg) &
>  		~(((1 << clk->src_width) - 1) << clk->src_shift);
>  
> -	__raw_writel(value | (i << clk->src_shift), clk->enable_reg);
> +	iowrite32(value | (i << clk->src_shift), clk->mapped_reg);
>  
>  	/* Rebuild the frequency table */
>  	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
> @@ -119,10 +119,10 @@ static int sh_clk_div6_set_rate(struct c
>  	if (idx < 0)
>  		return idx;
>  
> -	value = __raw_readl(clk->enable_reg);
> +	value = ioread32(clk->mapped_reg);
>  	value &= ~0x3f;
>  	value |= idx;
> -	__raw_writel(value, clk->enable_reg);
> +	iowrite32(value, clk->mapped_reg);
>  	return 0;
>  }
>  
> @@ -133,9 +133,9 @@ static int sh_clk_div6_enable(struct clk
>  
>  	ret = sh_clk_div6_set_rate(clk, clk->rate);
>  	if (ret = 0) {
> -		value = __raw_readl(clk->enable_reg);
> +		value = ioread32(clk->mapped_reg);
>  		value &= ~0x100; /* clear stop bit to enable clock */
> -		__raw_writel(value, clk->enable_reg);
> +		iowrite32(value, clk->mapped_reg);
>  	}
>  	return ret;
>  }
> @@ -144,10 +144,10 @@ static void sh_clk_div6_disable(struct c
>  {
>  	unsigned long value;
>  
> -	value = __raw_readl(clk->enable_reg);
> +	value = ioread32(clk->mapped_reg);
>  	value |= 0x100; /* stop clock */
>  	value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
> -	__raw_writel(value, clk->enable_reg);
> +	iowrite32(value, clk->mapped_reg);
>  }
>  
>  static struct clk_ops sh_clk_div6_clk_ops = {


Best regards
---
Kuninori Morimoto

^ permalink raw reply

* [PATCH] sh: pfc: ioremap() support
From: Magnus Damm @ 2011-12-09  3:14 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add support for non-entity mapped PFC registers through
the use of struct resource and ioremap()/iounmap().

The PFC main data structure gets updated with a pointer
to a struct resources array that point out all register
windows used by the PFC instance. The register definitions
are kept as physical addresses but the PFC code will do
transparent conversion into virtual addresses whenever
register windows are specified using with struct resource.

To introduce as little performance penalty as possible the
virtual address of each data register is cached in memory.
The virtual address of each configuration register is however
calculated during run time. This because the configuration
is considered slow path so focus is instead put on keeping
memory foot print as small as possible.

The PFC register access  code is in this patch updated from
__raw_readN() / __raw_writeN() into ioreadN() / iowriteN().

This patch is needed to support the PFC block in r8a7779.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/sh/pfc.c       |  137 +++++++++++++++++++++++++++++++++++++++---------
 include/linux/sh_pfc.h |   11 +++
 2 files changed, 124 insertions(+), 24 deletions(-)

--- 0001/drivers/sh/pfc.c
+++ work/drivers/sh/pfc.c	2011-12-09 12:04:01.000000000 +0900
@@ -19,6 +19,75 @@
 #include <linux/irq.h>
 #include <linux/bitops.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
+#include <linux/ioport.h>
+
+static void pfc_iounmap(struct pinmux_info *pip)
+{
+	int k;
+
+	for (k = 0; k < pip->num_resources; k++)
+		if (pip->window[k].virt)
+			iounmap(pip->window[k].virt);
+
+	kfree(pip->window);
+	pip->window = NULL;
+}
+
+static int pfc_ioremap(struct pinmux_info *pip)
+{
+	struct resource *res;
+	int k;
+
+	if (!pip->num_resources)
+		return 0;
+
+	pip->window = kzalloc(pip->num_resources * sizeof(*pip->window),
+			      GFP_NOWAIT);
+	if (!pip->window)
+		goto err1;
+
+	for (k = 0; k < pip->num_resources; k++) {
+		res = pip->resource + k;
+		WARN_ON(resource_type(res) != IORESOURCE_MEM);
+		pip->window[k].phys = res->start;
+		pip->window[k].size = resource_size(res);
+		pip->window[k].virt = ioremap_nocache(res->start,
+							 resource_size(res));
+		if (!pip->window[k].virt)
+			goto err2;
+	}
+
+	return 0;
+
+err2:
+	pfc_iounmap(pip);
+err1:
+	return -1;
+}
+
+static void __iomem *pfc_phys_to_virt(struct pinmux_info *pip,
+				      unsigned long address)
+{
+	struct pfc_window *window;
+	int k;
+
+	/* scan through physical windows and convert address */
+	for (k = 0; k < pip->num_resources; k++) {
+		window = pip->window + k;
+
+		if (address < window->phys)
+			continue;
+
+		if (address >= (window->phys + window->size))
+			continue;
+
+		return window->virt + (address - window->phys);
+	}
+
+	/* no windows defined, register must be 1:1 mapped virt:phys */
+	return (void __iomem *)address;
+}
 
 static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
 {
@@ -31,35 +100,35 @@ static int enum_in_range(pinmux_enum_t e
 	return 1;
 }
 
-static unsigned long gpio_read_raw_reg(unsigned long reg,
+static unsigned long gpio_read_raw_reg(void __iomem *mapped_reg,
 				       unsigned long reg_width)
 {
 	switch (reg_width) {
 	case 8:
-		return __raw_readb(reg);
+		return ioread8(mapped_reg);
 	case 16:
-		return __raw_readw(reg);
+		return ioread16(mapped_reg);
 	case 32:
-		return __raw_readl(reg);
+		return ioread32(mapped_reg);
 	}
 
 	BUG();
 	return 0;
 }
 
-static void gpio_write_raw_reg(unsigned long reg,
+static void gpio_write_raw_reg(void __iomem *mapped_reg,
 			       unsigned long reg_width,
 			       unsigned long data)
 {
 	switch (reg_width) {
 	case 8:
-		__raw_writeb(data, reg);
+		iowrite8(data, mapped_reg);
 		return;
 	case 16:
-		__raw_writew(data, reg);
+		iowrite16(data, mapped_reg);
 		return;
 	case 32:
-		__raw_writel(data, reg);
+		iowrite32(data, mapped_reg);
 		return;
 	}
 
@@ -82,11 +151,12 @@ static void gpio_write_bit(struct pinmux
 	else
 		clear_bit(pos, &dr->reg_shadow);
 
-	gpio_write_raw_reg(dr->reg, dr->reg_width, dr->reg_shadow);
+	gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
 }
 
-static int gpio_read_reg(unsigned long reg, unsigned long reg_width,
-			 unsigned long field_width, unsigned long in_pos)
+static int gpio_read_reg(void __iomem *mapped_reg, unsigned long reg_width,
+			 unsigned long field_width, unsigned long in_pos,
+			 unsigned long reg)
 {
 	unsigned long data, mask, pos;
 
@@ -98,13 +168,13 @@ static int gpio_read_reg(unsigned long r
 		 "r_width = %ld, f_width = %ld\n",
 		 reg, pos, reg_width, field_width);
 
-	data = gpio_read_raw_reg(reg, reg_width);
+	data = gpio_read_raw_reg(mapped_reg, reg_width);
 	return (data >> pos) & mask;
 }
 
-static void gpio_write_reg(unsigned long reg, unsigned long reg_width,
+static void gpio_write_reg(void __iomem *mapped_reg, unsigned long reg_width,
 			   unsigned long field_width, unsigned long in_pos,
-			   unsigned long value)
+			   unsigned long value, unsigned long reg)
 {
 	unsigned long mask, pos;
 
@@ -120,13 +190,13 @@ static void gpio_write_reg(unsigned long
 
 	switch (reg_width) {
 	case 8:
-		__raw_writeb((__raw_readb(reg) & mask) | value, reg);
+		iowrite8((ioread8(mapped_reg) & mask) | value, mapped_reg);
 		break;
 	case 16:
-		__raw_writew((__raw_readw(reg) & mask) | value, reg);
+		iowrite16((ioread16(mapped_reg) & mask) | value, mapped_reg);
 		break;
 	case 32:
-		__raw_writel((__raw_readl(reg) & mask) | value, reg);
+		iowrite32((ioread32(mapped_reg) & mask) | value, mapped_reg);
 		break;
 	}
 }
@@ -147,6 +217,8 @@ static int setup_data_reg(struct pinmux_
 		if (!data_reg->reg_width)
 			break;
 
+		data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
+
 		for (n = 0; n < data_reg->reg_width; n++) {
 			if (data_reg->enum_ids[n] = gpiop->enum_id) {
 				gpiop->flags &= ~PINMUX_FLAG_DREG;
@@ -179,7 +251,8 @@ static void setup_data_regs(struct pinmu
 		if (!drp->reg_width)
 			break;
 
-		drp->reg_shadow = gpio_read_raw_reg(drp->reg, drp->reg_width);
+		drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
+						    drp->reg_width);
 		k++;
 	}
 }
@@ -266,12 +339,16 @@ static void write_config_reg(struct pinm
 			     int index)
 {
 	unsigned long ncomb, pos, value;
+	void __iomem *mapped_reg;
 
 	ncomb = 1 << crp->field_width;
 	pos = index / ncomb;
 	value = index % ncomb;
 
-	gpio_write_reg(crp->reg, crp->reg_width, crp->field_width, pos, value);
+	mapped_reg = pfc_phys_to_virt(gpioc, crp->reg);
+
+	gpio_write_reg(mapped_reg, crp->reg_width, crp->field_width,
+		       pos, value, crp->reg);
 }
 
 static int check_config_reg(struct pinmux_info *gpioc,
@@ -279,13 +356,16 @@ static int check_config_reg(struct pinmu
 			    int index)
 {
 	unsigned long ncomb, pos, value;
+	void __iomem *mapped_reg;
 
 	ncomb = 1 << crp->field_width;
 	pos = index / ncomb;
 	value = index % ncomb;
 
-	if (gpio_read_reg(crp->reg, crp->reg_width,
-			  crp->field_width, pos) = value)
+	mapped_reg = pfc_phys_to_virt(gpioc, crp->reg);
+
+	if (gpio_read_reg(mapped_reg, crp->reg_width,
+			  crp->field_width, pos, crp->reg) = value)
 		return 0;
 
 	return -1;
@@ -564,7 +644,7 @@ static int sh_gpio_get_value(struct pinm
 	if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
 		return -EINVAL;
 
-	return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
+	return gpio_read_reg(dr->mapped_reg, dr->reg_width, 1, bit, dr->reg);
 }
 
 static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -606,10 +686,15 @@ static int sh_gpio_to_irq(struct gpio_ch
 int register_pinmux(struct pinmux_info *pip)
 {
 	struct gpio_chip *chip = &pip->chip;
+	int ret;
 
 	pr_info("%s handling gpio %d -> %d\n",
 		pip->name, pip->first_gpio, pip->last_gpio);
 
+	ret = pfc_ioremap(pip);
+	if (ret < 0)
+		return ret;
+
 	setup_data_regs(pip);
 
 	chip->request = sh_gpio_request;
@@ -627,12 +712,16 @@ int register_pinmux(struct pinmux_info *
 	chip->base = pip->first_gpio;
 	chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
 
-	return gpiochip_add(chip);
+	ret = gpiochip_add(chip);
+	if (ret < 0)
+		pfc_iounmap(pip);
+
+	return ret;
 }
 
 int unregister_pinmux(struct pinmux_info *pip)
 {
 	pr_info("%s deregistering\n", pip->name);
-
+	pfc_iounmap(pip);
 	return gpiochip_remove(&pip->chip);
 }
--- 0001/include/linux/sh_pfc.h
+++ work/include/linux/sh_pfc.h	2011-12-09 12:02:56.000000000 +0900
@@ -55,6 +55,7 @@ struct pinmux_cfg_reg {
 struct pinmux_data_reg {
 	unsigned long reg, reg_width, reg_shadow;
 	pinmux_enum_t *enum_ids;
+	void __iomem *mapped_reg;
 };
 
 #define PINMUX_DATA_REG(name, r, r_width) \
@@ -75,6 +76,12 @@ struct pinmux_range {
 	pinmux_enum_t force;
 };
 
+struct pfc_window {
+	phys_addr_t phys;
+	void __iomem *virt;
+	unsigned long size;
+};
+
 struct pinmux_info {
 	char *name;
 	pinmux_enum_t reserved_id;
@@ -98,6 +105,10 @@ struct pinmux_info {
 	struct pinmux_irq *gpio_irq;
 	unsigned int gpio_irq_size;
 
+	struct resource *resource;
+	unsigned int num_resources;
+	struct pfc_window *window;
+
 	struct gpio_chip chip;
 };
 

^ permalink raw reply

* [PATCH 04/04] sh: use ioread32/iowrite32 and mapped_reg for div6
From: Magnus Damm @ 2011-12-08 13:59 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Convert the CPG DIV6 helper code to use the new mapped_reg
together with ioread32() and iowrite32().

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/sh/clk/cpg.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

--- 0011/drivers/sh/clk/cpg.c
+++ work/drivers/sh/clk/cpg.c	2011-12-08 22:19:00.000000000 +0900
@@ -72,7 +72,7 @@ static unsigned long sh_clk_div6_recalc(
 	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
 			     table, NULL);
 
-	idx = __raw_readl(clk->enable_reg) & 0x003f;
+	idx = ioread32(clk->mapped_reg) & 0x003f;
 
 	return clk->freq_table[idx].frequency;
 }
@@ -98,10 +98,10 @@ static int sh_clk_div6_set_parent(struct
 	if (ret < 0)
 		return ret;
 
-	value = __raw_readl(clk->enable_reg) &
+	value = ioread32(clk->mapped_reg) &
 		~(((1 << clk->src_width) - 1) << clk->src_shift);
 
-	__raw_writel(value | (i << clk->src_shift), clk->enable_reg);
+	iowrite32(value | (i << clk->src_shift), clk->mapped_reg);
 
 	/* Rebuild the frequency table */
 	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -119,10 +119,10 @@ static int sh_clk_div6_set_rate(struct c
 	if (idx < 0)
 		return idx;
 
-	value = __raw_readl(clk->enable_reg);
+	value = ioread32(clk->mapped_reg);
 	value &= ~0x3f;
 	value |= idx;
-	__raw_writel(value, clk->enable_reg);
+	iowrite32(value, clk->mapped_reg);
 	return 0;
 }
 
@@ -133,9 +133,9 @@ static int sh_clk_div6_enable(struct clk
 
 	ret = sh_clk_div6_set_rate(clk, clk->rate);
 	if (ret = 0) {
-		value = __raw_readl(clk->enable_reg);
+		value = ioread32(clk->mapped_reg);
 		value &= ~0x100; /* clear stop bit to enable clock */
-		__raw_writel(value, clk->enable_reg);
+		iowrite32(value, clk->mapped_reg);
 	}
 	return ret;
 }
@@ -144,10 +144,10 @@ static void sh_clk_div6_disable(struct c
 {
 	unsigned long value;
 
-	value = __raw_readl(clk->enable_reg);
+	value = ioread32(clk->mapped_reg);
 	value |= 0x100; /* stop clock */
 	value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */
-	__raw_writel(value, clk->enable_reg);
+	iowrite32(value, clk->mapped_reg);
 }
 
 static struct clk_ops sh_clk_div6_clk_ops = {

^ permalink raw reply

* [PATCH 03/04] sh: use ioread32/iowrite32 and mapped_reg for div4
From: Magnus Damm @ 2011-12-08 13:59 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Convert the CPG DIV4 helper code to use the new mapped_reg
together with ioread32() and iowrite32().

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/sh/clk/cpg.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

--- 0010/drivers/sh/clk/cpg.c
+++ work/drivers/sh/clk/cpg.c	2011-12-08 22:20:29.000000000 +0900
@@ -217,7 +217,7 @@ static unsigned long sh_clk_div4_recalc(
 	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
 			     table, &clk->arch_flags);
 
-	idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f;
+	idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f;
 
 	return clk->freq_table[idx].frequency;
 }
@@ -235,15 +235,15 @@ static int sh_clk_div4_set_parent(struct
 	 */
 
 	if (parent->flags & CLK_ENABLE_ON_INIT)
-		value = __raw_readl(clk->enable_reg) & ~(1 << 7);
+		value = ioread32(clk->mapped_reg) & ~(1 << 7);
 	else
-		value = __raw_readl(clk->enable_reg) | (1 << 7);
+		value = ioread32(clk->mapped_reg) | (1 << 7);
 
 	ret = clk_reparent(clk, parent);
 	if (ret < 0)
 		return ret;
 
-	__raw_writel(value, clk->enable_reg);
+	iowrite32(value, clk->mapped_reg);
 
 	/* Rebiuld the frequency table */
 	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
@@ -260,10 +260,10 @@ static int sh_clk_div4_set_rate(struct c
 	if (idx < 0)
 		return idx;
 
-	value = __raw_readl(clk->enable_reg);
+	value = ioread32(clk->mapped_reg);
 	value &= ~(0xf << clk->enable_bit);
 	value |= (idx << clk->enable_bit);
-	__raw_writel(value, clk->enable_reg);
+	iowrite32(value, clk->mapped_reg);
 
 	if (d4t->kick)
 		d4t->kick(clk);
@@ -273,13 +273,13 @@ static int sh_clk_div4_set_rate(struct c
 
 static int sh_clk_div4_enable(struct clk *clk)
 {
-	__raw_writel(__raw_readl(clk->enable_reg) & ~(1 << 8), clk->enable_reg);
+	iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg);
 	return 0;
 }
 
 static void sh_clk_div4_disable(struct clk *clk)
 {
-	__raw_writel(__raw_readl(clk->enable_reg) | (1 << 8), clk->enable_reg);
+	iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg);
 }
 
 static struct clk_ops sh_clk_div4_clk_ops = {

^ permalink raw reply

* [PATCH 02/04] sh: use ioread32/iowrite32 and mapped_reg for mstp32
From: Magnus Damm @ 2011-12-08 13:59 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Convert the CPG MSTP32 helper code to use the new mapped_reg
together with ioread32() and iowrite32().

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/sh/clk/cpg.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- 0001/drivers/sh/clk/cpg.c
+++ work/drivers/sh/clk/cpg.c	2011-12-08 13:31:24.000000000 +0900
@@ -15,15 +15,15 @@
 
 static int sh_clk_mstp32_enable(struct clk *clk)
 {
-	__raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit),
-		     clk->enable_reg);
+	iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
+		  clk->mapped_reg);
 	return 0;
 }
 
 static void sh_clk_mstp32_disable(struct clk *clk)
 {
-	__raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit),
-		     clk->enable_reg);
+	iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
+		  clk->mapped_reg);
 }
 
 static struct clk_ops sh_clk_mstp32_clk_ops = {

^ permalink raw reply

* [PATCH 01/04] sh: extend clock struct with mapped_reg member
From: Magnus Damm @ 2011-12-08 13:58 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add a "mapped_reg" member to struct clk and use that
to keep the ioremapped register based on enable_reg.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/sh/clk/core.c  |    9 +++++++--
 include/linux/sh_clk.h |    1 +
 2 files changed, 8 insertions(+), 2 deletions(-)

--- 0001/drivers/sh/clk/core.c
+++ work/drivers/sh/clk/core.c	2011-12-08 22:26:25.000000000 +0900
@@ -355,7 +355,7 @@ static int clk_establish_mapping(struct
 		 */
 		if (!clk->parent) {
 			clk->mapping = &dummy_mapping;
-			return 0;
+			goto out;
 		}
 
 		/*
@@ -384,6 +384,9 @@ static int clk_establish_mapping(struct
 	}
 
 	clk->mapping = mapping;
+ out:
+	clk->mapped_reg = clk->mapping->base;
+	clk->mapped_reg += (phys_addr_t)clk->enable_reg - clk->mapping->phys;
 	return 0;
 }
 
@@ -402,10 +405,12 @@ static void clk_teardown_mapping(struct
 
 	/* Nothing to do */
 	if (mapping = &dummy_mapping)
-		return;
+		goto out;
 
 	kref_put(&mapping->ref, clk_destroy_mapping);
 	clk->mapping = NULL;
+ out:
+	clk->mapped_reg = NULL;
 }
 
 int clk_register(struct clk *clk)
--- 0001/include/linux/sh_clk.h
+++ work/include/linux/sh_clk.h	2011-12-08 13:30:41.000000000 +0900
@@ -49,6 +49,7 @@ struct clk {
 
 	void __iomem		*enable_reg;
 	unsigned int		enable_bit;
+	void __iomem		*mapped_reg;
 
 	unsigned long		arch_flags;
 	void			*priv;

^ permalink raw reply

* [PATCH 00/04] sh: clock / CPG ioremap() update
From: Magnus Damm @ 2011-12-08 13:58 UTC (permalink / raw)
  To: linux-sh

sh: clock / CPG ioremap() update

[PATCH 01/04] sh: extend clock struct with mapped_reg member
[PATCH 02/04] sh: use ioread32/iowrite32 and mapped_reg for mstp32
[PATCH 03/04] sh: use ioread32/iowrite32 and mapped_reg for div4
[PATCH 04/04] sh: use ioread32/iowrite32 and mapped_reg for div6

These patches extend the drivers/sh/clk/ code to use ioremap().
Needed for the soc / board support code for r8a7779. Other SoCs
should just keep on working as before.

Signed-off-by: Magnus Damm <damm@opensource.se>
---
 drivers/sh/clk/core.c  |    9 +++++++--
 drivers/sh/clk/cpg.c   |   42 +++++++++++++++++++++---------------------
 include/linux/sh_clk.h |    1 +
 3 files changed, 29 insertions(+), 23 deletions(-)

^ permalink raw reply

* Re: [PATCH] sh: fix cpuidle on sh7724, possibly others
From: Guennadi Liakhovetski @ 2011-12-07 11:12 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <Pine.LNX.4.64.1112061704300.10715@axis700.grange>

On Wed, 7 Dec 2011, Guennadi Liakhovetski wrote:

> cpuidle has been broken on sh7724 and, possibly, other SuperH SoCs since 
> 
> commit f533c3d340536198a4889a42a68d6c0d79a504e7
> Author: Paul Mundt <lethal@linux-sh.org>
> Date:   Fri Oct 16 17:20:58 2009 +0900
> 
>     sh: Idle loop chainsawing for SMP-based light sleep.
> 
> i.e., since 2.6.33-rc1. The reason is a missing local_irq_enable() on the 
> path, actually entering a sleep mode. This patch adds the missing call.
> 
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
> 
> This fixes one of the problem with cpuidle on sh. When applied (suitably 
> adjusted) directly after f533c3d340536198a4889a42a68d6c0d79a504e7, it does 
> fix the problem. However, since that commit cpuidle has been broken (at 
> least for my configuration) at least once more. This time bisection points 
> out at

Apparently, a hick up during bisect: this

> commit 03625e7107cde46e2851557ec06426799e6ae7f2
> Author: Magnus Damm <damm@opensource.se>
> Date:   Fri Oct 30 04:24:32 2009 +0000
> 
>     sh: Use RSMEM for sleep code on sh7724
> 
> Still investigating.

is not the offending commit, this is the one:

commit 323ef8dba67fb7b9c709457bd0374d88cfb8f25f
Author: Magnus Damm <damm@opensource.se>
Date:   Fri Oct 30 04:24:07 2009 +0000

    sh: Rework SuperH Mobile sleep mode code

Thanks
Guennadi

> 
> diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
> index 1cc257c..e58640a 100644
> --- a/arch/sh/kernel/cpu/shmobile/cpuidle.c
> +++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
> @@ -48,6 +48,7 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev,
>  	 */
>  	k = min_t(int, allowed_state, requested_state);
>  
> +	local_irq_enable();
>  	before = ktime_get();
>  	sh_mobile_call_standby(cpuidle_mode[k]);
>  	after = ktime_get();
> 

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* [PATCH] sh: fix cpuidle on sh7724, possibly others
From: Guennadi Liakhovetski @ 2011-12-07  8:38 UTC (permalink / raw)
  To: linux-sh

cpuidle has been broken on sh7724 and, possibly, other SuperH SoCs since 

commit f533c3d340536198a4889a42a68d6c0d79a504e7
Author: Paul Mundt <lethal@linux-sh.org>
Date:   Fri Oct 16 17:20:58 2009 +0900

    sh: Idle loop chainsawing for SMP-based light sleep.

i.e., since 2.6.33-rc1. The reason is a missing local_irq_enable() on the 
path, actually entering a sleep mode. This patch adds the missing call.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

This fixes one of the problem with cpuidle on sh. When applied (suitably 
adjusted) directly after f533c3d340536198a4889a42a68d6c0d79a504e7, it does 
fix the problem. However, since that commit cpuidle has been broken (at 
least for my configuration) at least once more. This time bisection points 
out at

commit 03625e7107cde46e2851557ec06426799e6ae7f2
Author: Magnus Damm <damm@opensource.se>
Date:   Fri Oct 30 04:24:32 2009 +0000

    sh: Use RSMEM for sleep code on sh7724

Still investigating.

diff --git a/arch/sh/kernel/cpu/shmobile/cpuidle.c b/arch/sh/kernel/cpu/shmobile/cpuidle.c
index 1cc257c..e58640a 100644
--- a/arch/sh/kernel/cpu/shmobile/cpuidle.c
+++ b/arch/sh/kernel/cpu/shmobile/cpuidle.c
@@ -48,6 +48,7 @@ static int cpuidle_sleep_enter(struct cpuidle_device *dev,
 	 */
 	k = min_t(int, allowed_state, requested_state);
 
+	local_irq_enable();
 	before = ktime_get();
 	sh_mobile_call_standby(cpuidle_mode[k]);
 	after = ktime_get();

^ permalink raw reply related

* [PATCH 07/07] ARM: mach-shmobile: Marzen GPIO LED test code
From: Magnus Damm @ 2011-12-06 16:52 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add prototype code for LED2, LED3 and LED4 on the Marzen board.

Should most likely use the LED framework, but is OK as-is for
now when testing the r8a7779 GPIO/PFC code.

Not-yet-signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/board-marzen.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

--- 0010/arch/arm/mach-shmobile/board-marzen.c
+++ work/arch/arm/mach-shmobile/board-marzen.c	2011-12-07 00:25:39.000000000 +0900
@@ -25,6 +25,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 #include <linux/dma-mapping.h>
 #include <mach/hardware.h>
 #include <mach/r8a7779.h>
@@ -94,6 +95,18 @@ static void __init marzen_init(void)
 {
 	r8a7779_pinmux_init();
 
+	gpio_request(GPIO_GP_4_29, NULL); /* LED2 */
+	gpio_direction_output(GPIO_GP_4_29, 0);
+	gpio_export(GPIO_GP_4_29, false);
+
+	gpio_request(GPIO_GP_4_30, NULL); /* LED3 */
+	gpio_direction_output(GPIO_GP_4_30, 0);
+	gpio_export(GPIO_GP_4_30, false);
+
+	gpio_request(GPIO_GP_4_31, NULL); /* LED4 */
+	gpio_direction_output(GPIO_GP_4_31, 0);
+	gpio_export(GPIO_GP_4_31, false);
+
 	r8a7779_add_standard_devices();
 	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
 }

^ permalink raw reply

* [PATCH 06/07] ARM: mach-shmobile: r8a7779 PFC ioremap() workaround
From: Magnus Damm @ 2011-12-06 16:52 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Since the common pfc code does not support ioremap(),
hack the code to make use of the serial debug console
mapping. Magically makes the r8a7779 PFC code work.

Will be dropped when the pfc code knows how to ioremap().

Never-signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/pfc-r8a7779.c |   42 +++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 21 deletions(-)

--- 0010/arch/arm/mach-shmobile/pfc-r8a7779.c
+++ work/arch/arm/mach-shmobile/pfc-r8a7779.c	2011-12-07 00:21:46.000000000 +0900
@@ -163,7 +163,7 @@ static struct pinmux_gpio pinmux_gpios[]
 };
 
 static struct pinmux_cfg_reg pinmux_config_regs[] = {
-	{ PINMUX_CFG_REG("GPSR0", 0xffc00004, 32, 1) {
+	{ PINMUX_CFG_REG("GPSR0", 0xfdc00004, 32, 1) {
 		GP_0_31_FN, FN_IP3_31_29,
 		GP_0_30_FN, FN_IP3_26_24,
 		GP_0_29_FN, FN_IP3_22_21,
@@ -197,7 +197,7 @@ static struct pinmux_cfg_reg pinmux_conf
 		GP_0_1_FN, FN_AVS2,
 		GP_0_0_FN, FN_AVS1 }
 	},
-	{ PINMUX_CFG_REG("GPSR1", 0xffc00008, 32, 1) {
+	{ PINMUX_CFG_REG("GPSR1", 0xfdc00008, 32, 1) {
 		GP_1_31_FN, FN_IP5_23_21,
 		GP_1_30_FN, FN_IP5_20_17,
 		GP_1_29_FN, FN_IP5_16_15,
@@ -231,7 +231,7 @@ static struct pinmux_cfg_reg pinmux_conf
 		GP_1_1_FN, FN_IP4_4_2,
 		GP_1_0_FN, FN_IP4_1_0 }
 	},
-	{ PINMUX_CFG_REG("GPSR2", 0xffc0000c, 32, 1) {
+	{ PINMUX_CFG_REG("GPSR2", 0xfdc0000c, 32, 1) {
 		GP_2_31_FN, FN_IP10_28_26,
 		GP_2_30_FN, FN_IP10_25_24,
 		GP_2_29_FN, FN_IP10_23_21,
@@ -265,7 +265,7 @@ static struct pinmux_cfg_reg pinmux_conf
 		GP_2_1_FN, FN_IP8_20,
 		GP_2_0_FN, FN_IP5_27_24 }
 	},
-	{ PINMUX_CFG_REG("GPSR3", 0xffc00010, 32, 1) {
+	{ PINMUX_CFG_REG("GPSR3", 0xfdc00010, 32, 1) {
 		GP_3_31_FN, FN_IP6_3_2,
 		GP_3_30_FN, FN_IP6_1_0,
 		GP_3_29_FN, FN_IP5_30_29,
@@ -299,7 +299,7 @@ static struct pinmux_cfg_reg pinmux_conf
 		GP_3_1_FN, FN_IP11_2_0,
 		GP_3_0_FN, FN_IP10_31_29 }
 	},
-	{ PINMUX_CFG_REG("GPSR4", 0xffc00014, 32, 1) {
+	{ PINMUX_CFG_REG("GPSR4", 0xfdc00014, 32, 1) {
 		GP_4_31_FN, FN_IP8_19,
 		GP_4_30_FN, FN_IP8_18,
 		GP_4_29_FN, FN_IP8_17_16,
@@ -333,7 +333,7 @@ static struct pinmux_cfg_reg pinmux_conf
 		GP_4_1_FN, FN_IP6_7_6,
 		GP_4_0_FN, FN_IP6_5_4 }
 	},
-	{ PINMUX_CFG_REG("GPSR5", 0xffc00018, 32, 1) {
+	{ PINMUX_CFG_REG("GPSR5", 0xfdc00018, 32, 1) {
 		GP_5_31_FN, FN_IP3_5,
 		GP_5_30_FN, FN_IP3_4,
 		GP_5_29_FN, FN_IP3_3,
@@ -367,7 +367,7 @@ static struct pinmux_cfg_reg pinmux_conf
 		GP_5_1_FN, FN_A2,
 		GP_5_0_FN, FN_A1 }
 	},
-	{ PINMUX_CFG_REG("GPSR6", 0xffc0001c, 32, 1) {
+	{ PINMUX_CFG_REG("GPSR6", 0xfdc0001c, 32, 1) {
 		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
 		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
 		0, 0, 0, 0, 0, 0, 0, 0,
@@ -384,13 +384,13 @@ static struct pinmux_cfg_reg pinmux_conf
 		GP_6_1_FN, FN_IP3_7,
 		GP_6_0_FN, FN_IP3_6 }
 	},
-	{ PINMUX_CFG_REG("INOUTSEL0", 0xffc40004, 32, 1) { GP_INOUTSEL(0) } },
-	{ PINMUX_CFG_REG("INOUTSEL1", 0xffc41004, 32, 1) { GP_INOUTSEL(1) } },
-	{ PINMUX_CFG_REG("INOUTSEL2", 0xffc42004, 32, 1) { GP_INOUTSEL(2) } },
-	{ PINMUX_CFG_REG("INOUTSEL3", 0xffc43004, 32, 1) { GP_INOUTSEL(3) } },
-	{ PINMUX_CFG_REG("INOUTSEL4", 0xffc44004, 32, 1) { GP_INOUTSEL(4) } },
-	{ PINMUX_CFG_REG("INOUTSEL5", 0xffc45004, 32, 1) { GP_INOUTSEL(5) } },
-	{ PINMUX_CFG_REG("INOUTSEL6", 0xffc46004, 32, 1) {
+	{ PINMUX_CFG_REG("INOUTSEL0", 0xfdc40004, 32, 1) { GP_INOUTSEL(0) } },
+	{ PINMUX_CFG_REG("INOUTSEL1", 0xfdc41004, 32, 1) { GP_INOUTSEL(1) } },
+	{ PINMUX_CFG_REG("INOUTSEL2", 0xfdc42004, 32, 1) { GP_INOUTSEL(2) } },
+	{ PINMUX_CFG_REG("INOUTSEL3", 0xfdc43004, 32, 1) { GP_INOUTSEL(3) } },
+	{ PINMUX_CFG_REG("INOUTSEL4", 0xfdc44004, 32, 1) { GP_INOUTSEL(4) } },
+	{ PINMUX_CFG_REG("INOUTSEL5", 0xfdc45004, 32, 1) { GP_INOUTSEL(5) } },
+	{ PINMUX_CFG_REG("INOUTSEL6", 0xfdc46004, 32, 1) {
 		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
 		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
 		0, 0, 0, 0, 0, 0, 0, 0,
@@ -411,13 +411,13 @@ static struct pinmux_cfg_reg pinmux_conf
 };
 
 static struct pinmux_data_reg pinmux_data_regs[] = {
-	{ PINMUX_DATA_REG("INDT0", 0xffc40008, 32) { GP_INDT(0) } },
-	{ PINMUX_DATA_REG("INDT1", 0xffc41008, 32) { GP_INDT(1) } },
-	{ PINMUX_DATA_REG("INDT2", 0xffc42008, 32) { GP_INDT(2) } },
-	{ PINMUX_DATA_REG("INDT3", 0xffc43008, 32) { GP_INDT(3) } },
-	{ PINMUX_DATA_REG("INDT4", 0xffc44008, 32) { GP_INDT(4) } },
-	{ PINMUX_DATA_REG("INDT5", 0xffc45008, 32) { GP_INDT(5) } },
-	{ PINMUX_DATA_REG("INDT6", 0xffc46008, 32) {
+	{ PINMUX_DATA_REG("INDT0", 0xfdc40008, 32) { GP_INDT(0) } },
+	{ PINMUX_DATA_REG("INDT1", 0xfdc41008, 32) { GP_INDT(1) } },
+	{ PINMUX_DATA_REG("INDT2", 0xfdc42008, 32) { GP_INDT(2) } },
+	{ PINMUX_DATA_REG("INDT3", 0xfdc43008, 32) { GP_INDT(3) } },
+	{ PINMUX_DATA_REG("INDT4", 0xfdc44008, 32) { GP_INDT(4) } },
+	{ PINMUX_DATA_REG("INDT5", 0xfdc45008, 32) { GP_INDT(5) } },
+	{ PINMUX_DATA_REG("INDT6", 0xfdc46008, 32) {
 		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
 		0, 0, 0, 0, 0, 0, 0, GP_6_8_DATA,
 		GP_6_7_DATA, GP_6_6_DATA, GP_6_5_DATA, GP_6_4_DATA,

^ permalink raw reply

* [PATCH 05/07] ARM: mach-shmobile: r8a7779 PFC GPIO-only prototype
From: Magnus Damm @ 2011-12-06 16:52 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Initial r8a7779 PFC prototype support.

Only regular GPIOs are supported at this time. GPIO_FN are not
supported because they require variable bit width support in be
the shared pfc code.

This prototype requires a filthy mapping hack for the PFC/GPIO
base addresses applied on top of this patch to workt. The pfc code
needs to be extended to make use of ioremap() to support this SoC.

Not-yet-signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/Kconfig                |    2 
 arch/arm/mach-shmobile/Makefile               |    1 
 arch/arm/mach-shmobile/board-marzen.c         |    2 
 arch/arm/mach-shmobile/include/mach/common.h  |    1 
 arch/arm/mach-shmobile/include/mach/r8a7779.h |   63 +++
 arch/arm/mach-shmobile/pfc-r8a7779.c          |  452 +++++++++++++++++++++++++
 6 files changed, 520 insertions(+), 1 deletion(-)

--- 0010/arch/arm/mach-shmobile/Kconfig
+++ work/arch/arm/mach-shmobile/Kconfig	2011-12-07 00:38:57.000000000 +0900
@@ -33,6 +33,7 @@ config ARCH_R8A7779
 	select CPU_V7
 	select SH_CLK_CPG
 	select ARM_GIC
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 
 comment "SH-Mobile Board Type"
 
@@ -84,6 +85,7 @@ config MACH_KOTA2
 config MACH_MARZEN
 	bool "MARZEN board"
 	depends on ARCH_R8A7779
+	select ARCH_REQUIRE_GPIOLIB
 
 comment "SH-Mobile System Configuration"
 
--- 0010/arch/arm/mach-shmobile/Makefile
+++ work/arch/arm/mach-shmobile/Makefile	2011-12-07 00:38:57.000000000 +0900
@@ -24,6 +24,7 @@ pfc-$(CONFIG_ARCH_SH7367)	+= pfc-sh7367.
 pfc-$(CONFIG_ARCH_SH7377)	+= pfc-sh7377.o
 pfc-$(CONFIG_ARCH_SH7372)	+= pfc-sh7372.o
 pfc-$(CONFIG_ARCH_SH73A0)	+= pfc-sh73a0.o
+pfc-$(CONFIG_ARCH_R8A7779)	+= pfc-r8a7779.o
 
 # IRQ objects
 obj-$(CONFIG_ARCH_SH7367)	+= entry-intc.o
--- 0011/arch/arm/mach-shmobile/board-marzen.c
+++ work/arch/arm/mach-shmobile/board-marzen.c	2011-12-07 00:38:57.000000000 +0900
@@ -92,6 +92,8 @@ static void __init marzen_init_early(voi
 
 static void __init marzen_init(void)
 {
+	r8a7779_pinmux_init();
+
 	r8a7779_add_standard_devices();
 	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
 }
--- 0010/arch/arm/mach-shmobile/include/mach/common.h
+++ work/arch/arm/mach-shmobile/include/mach/common.h	2011-12-07 00:38:57.000000000 +0900
@@ -57,5 +57,6 @@ extern void r8a7779_init_irq(void);
 extern void r8a7779_add_early_devices(void);
 extern void r8a7779_add_standard_devices(void);
 extern void r8a7779_clock_init(void);
+extern void r8a7779_pinmux_init(void);
 
 #endif /* __ARCH_MACH_COMMON_H */
--- 0010/arch/arm/mach-shmobile/include/mach/r8a7779.h
+++ work/arch/arm/mach-shmobile/include/mach/r8a7779.h	2011-12-07 00:38:57.000000000 +0900
@@ -1,6 +1,67 @@
 #ifndef __ASM_R8A7779_H__
 #define __ASM_R8A7779_H__
 
-/* Nothing at this point */
+/* Pin Function Controller:
+ * GPIO_GP_x_x - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+	GPIO_GP_0_0, GPIO_GP_0_1, GPIO_GP_0_2, GPIO_GP_0_3,
+	GPIO_GP_0_4, GPIO_GP_0_5, GPIO_GP_0_6, GPIO_GP_0_7,
+	GPIO_GP_0_8, GPIO_GP_0_9, GPIO_GP_0_10, GPIO_GP_0_11,
+	GPIO_GP_0_12, GPIO_GP_0_13, GPIO_GP_0_14, GPIO_GP_0_15,
+	GPIO_GP_0_16, GPIO_GP_0_17, GPIO_GP_0_18, GPIO_GP_0_19,
+	GPIO_GP_0_20, GPIO_GP_0_21, GPIO_GP_0_22, GPIO_GP_0_23,
+	GPIO_GP_0_24, GPIO_GP_0_25, GPIO_GP_0_26, GPIO_GP_0_27,
+	GPIO_GP_0_28, GPIO_GP_0_29, GPIO_GP_0_30, GPIO_GP_0_31,
+
+	GPIO_GP_1_0, GPIO_GP_1_1, GPIO_GP_1_2, GPIO_GP_1_3,
+	GPIO_GP_1_4, GPIO_GP_1_5, GPIO_GP_1_6, GPIO_GP_1_7,
+	GPIO_GP_1_8, GPIO_GP_1_9, GPIO_GP_1_10, GPIO_GP_1_11,
+	GPIO_GP_1_12, GPIO_GP_1_13, GPIO_GP_1_14, GPIO_GP_1_15,
+	GPIO_GP_1_16, GPIO_GP_1_17, GPIO_GP_1_18, GPIO_GP_1_19,
+	GPIO_GP_1_20, GPIO_GP_1_21, GPIO_GP_1_22, GPIO_GP_1_23,
+	GPIO_GP_1_24, GPIO_GP_1_25, GPIO_GP_1_26, GPIO_GP_1_27,
+	GPIO_GP_1_28, GPIO_GP_1_29, GPIO_GP_1_30, GPIO_GP_1_31,
+
+	GPIO_GP_2_0, GPIO_GP_2_1, GPIO_GP_2_2, GPIO_GP_2_3,
+	GPIO_GP_2_4, GPIO_GP_2_5, GPIO_GP_2_6, GPIO_GP_2_7,
+	GPIO_GP_2_8, GPIO_GP_2_9, GPIO_GP_2_10, GPIO_GP_2_11,
+	GPIO_GP_2_12, GPIO_GP_2_13, GPIO_GP_2_14, GPIO_GP_2_15,
+	GPIO_GP_2_16, GPIO_GP_2_17, GPIO_GP_2_18, GPIO_GP_2_19,
+	GPIO_GP_2_20, GPIO_GP_2_21, GPIO_GP_2_22, GPIO_GP_2_23,
+	GPIO_GP_2_24, GPIO_GP_2_25, GPIO_GP_2_26, GPIO_GP_2_27,
+	GPIO_GP_2_28, GPIO_GP_2_29, GPIO_GP_2_30, GPIO_GP_2_31,
+
+	GPIO_GP_3_0, GPIO_GP_3_1, GPIO_GP_3_2, GPIO_GP_3_3,
+	GPIO_GP_3_4, GPIO_GP_3_5, GPIO_GP_3_6, GPIO_GP_3_7,
+	GPIO_GP_3_8, GPIO_GP_3_9, GPIO_GP_3_10, GPIO_GP_3_11,
+	GPIO_GP_3_12, GPIO_GP_3_13, GPIO_GP_3_14, GPIO_GP_3_15,
+	GPIO_GP_3_16, GPIO_GP_3_17, GPIO_GP_3_18, GPIO_GP_3_19,
+	GPIO_GP_3_20, GPIO_GP_3_21, GPIO_GP_3_22, GPIO_GP_3_23,
+	GPIO_GP_3_24, GPIO_GP_3_25, GPIO_GP_3_26, GPIO_GP_3_27,
+	GPIO_GP_3_28, GPIO_GP_3_29, GPIO_GP_3_30, GPIO_GP_3_31,
+
+	GPIO_GP_4_0, GPIO_GP_4_1, GPIO_GP_4_2, GPIO_GP_4_3,
+	GPIO_GP_4_4, GPIO_GP_4_5, GPIO_GP_4_6, GPIO_GP_4_7,
+	GPIO_GP_4_8, GPIO_GP_4_9, GPIO_GP_4_10, GPIO_GP_4_11,
+	GPIO_GP_4_12, GPIO_GP_4_13, GPIO_GP_4_14, GPIO_GP_4_15,
+	GPIO_GP_4_16, GPIO_GP_4_17, GPIO_GP_4_18, GPIO_GP_4_19,
+	GPIO_GP_4_20, GPIO_GP_4_21, GPIO_GP_4_22, GPIO_GP_4_23,
+	GPIO_GP_4_24, GPIO_GP_4_25, GPIO_GP_4_26, GPIO_GP_4_27,
+	GPIO_GP_4_28, GPIO_GP_4_29, GPIO_GP_4_30, GPIO_GP_4_31,
+
+	GPIO_GP_5_0, GPIO_GP_5_1, GPIO_GP_5_2, GPIO_GP_5_3,
+	GPIO_GP_5_4, GPIO_GP_5_5, GPIO_GP_5_6, GPIO_GP_5_7,
+	GPIO_GP_5_8, GPIO_GP_5_9, GPIO_GP_5_10, GPIO_GP_5_11,
+	GPIO_GP_5_12, GPIO_GP_5_13, GPIO_GP_5_14, GPIO_GP_5_15,
+	GPIO_GP_5_16, GPIO_GP_5_17, GPIO_GP_5_18, GPIO_GP_5_19,
+	GPIO_GP_5_20, GPIO_GP_5_21, GPIO_GP_5_22, GPIO_GP_5_23,
+	GPIO_GP_5_24, GPIO_GP_5_25, GPIO_GP_5_26, GPIO_GP_5_27,
+	GPIO_GP_5_28, GPIO_GP_5_29, GPIO_GP_5_30, GPIO_GP_5_31,
+
+	GPIO_GP_6_0, GPIO_GP_6_1, GPIO_GP_6_2, GPIO_GP_6_3,
+	GPIO_GP_6_4, GPIO_GP_6_5, GPIO_GP_6_6, GPIO_GP_6_7,
+	GPIO_GP_6_8,
+};
 
 #endif /* __ASM_R8A7779_H__ */
--- /dev/null
+++ work/arch/arm/mach-shmobile/pfc-r8a7779.c	2011-12-07 00:42:35.000000000 +0900
@@ -0,0 +1,452 @@
+/*
+ * r8a7779 processor support - PFC hardware block
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <mach/r8a7779.h>
+
+#define CPU_32_PORT(fn, pfx, sfx)				\
+	PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx),	\
+	PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx),	\
+	PORT_1(fn, pfx##31, sfx)
+
+#define CPU_32_PORT6(fn, pfx, sfx)				\
+	PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx),	\
+	PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx),	\
+	PORT_1(fn, pfx##4, sfx), PORT_1(fn, pfx##5, sfx),	\
+	PORT_1(fn, pfx##6, sfx), PORT_1(fn, pfx##7, sfx),	\
+	PORT_1(fn, pfx##8, sfx)
+
+#define CPU_ALL_PORT(fn, pfx, sfx)				\
+	CPU_32_PORT(fn, pfx##_0_, sfx),				\
+	CPU_32_PORT(fn, pfx##_1_, sfx),				\
+	CPU_32_PORT(fn, pfx##_2_, sfx),				\
+	CPU_32_PORT(fn, pfx##_3_, sfx),				\
+	CPU_32_PORT(fn, pfx##_4_, sfx),				\
+	CPU_32_PORT(fn, pfx##_5_, sfx),				\
+	CPU_32_PORT6(fn, pfx##_6_, sfx)
+
+#define _GP_GPIO(pfx, sfx) PINMUX_GPIO(GPIO_GP##pfx, GP##pfx##_DATA)
+#define _GP_DATA(pfx, sfx) PINMUX_DATA(GP##pfx##_DATA, GP##pfx##_FN,	\
+				       GP##pfx##_IN, GP##pfx##_OUT)
+
+#define _GP_INOUTSEL(pfx, sfx) GP##pfx##_IN, GP##pfx##_OUT
+#define _GP_INDT(pfx, sfx) GP##pfx##_DATA
+
+#define GP_ALL(str)	CPU_ALL_PORT(_PORT_ALL, GP, str)
+#define PINMUX_GPIO_GP_ALL()	CPU_ALL_PORT(_GP_GPIO, , unused)
+#define PINMUX_DATA_GP_ALL()	CPU_ALL_PORT(_GP_DATA, , unused)
+
+
+#define PORT_10_REV(fn, pfx, sfx)				\
+	PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx),	\
+	PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx),	\
+	PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx),	\
+	PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx),	\
+	PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx)
+
+#define CPU_32_PORT_REV(fn, pfx, sfx)					\
+	PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx),		\
+	PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx),	\
+	PORT_10_REV(fn, pfx, sfx)
+
+#define GP_INOUTSEL(bank) CPU_32_PORT_REV(_GP_INOUTSEL, _##bank##_, unused)
+#define GP_INDT(bank) CPU_32_PORT_REV(_GP_INDT, _##bank##_, unused)
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	GP_ALL(DATA), /* GP_0_0_DATA -> GP_6_8_DATA */
+	PINMUX_DATA_END,
+
+	PINMUX_INPUT_BEGIN,
+	GP_ALL(IN), /* GP_0_0_IN -> GP_6_8_IN */
+	PINMUX_INPUT_END,
+
+	PINMUX_OUTPUT_BEGIN,
+	GP_ALL(OUT), /* GP_0_0_OUT -> GP_6_8_OUT */
+	PINMUX_OUTPUT_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	GP_ALL(FN), /* GP_0_0_FN -> GP_6_8_FN */
+
+	/* GPSR0 */
+	FN_AVS1, FN_AVS2, FN_IP0_7_6, FN_A17,
+	FN_A18, FN_A19, FN_IP0_9_8, FN_IP0_11_10,
+	FN_IP0_13_12, FN_IP0_15_14, FN_IP0_18_16, FN_IP0_22_19,
+	FN_IP0_24_23, FN_IP0_25, FN_IP0_27_26, FN_IP1_1_0,
+	FN_IP1_3_2, FN_IP1_6_4, FN_IP1_10_7, FN_IP1_14_11,
+	FN_IP1_18_15, FN_IP0_5_3, FN_IP0_30_28, FN_IP2_18_16,
+	FN_IP2_21_19, FN_IP2_30_28, FN_IP2_2_0, FN_IP3_11_9,
+	FN_IP3_14_12, FN_IP3_22_21, FN_IP3_26_24, FN_IP3_31_29,
+
+	/* GPSR1 */
+	FN_IP4_1_0, FN_IP4_4_2, FN_IP4_7_5, FN_IP4_10_8,
+	FN_IP4_11, FN_IP4_12, FN_IP4_13, FN_IP4_14,
+	FN_IP4_15, FN_IP4_16, FN_IP4_19_17, FN_IP4_22_20,
+	FN_IP4_23, FN_IP4_24, FN_IP4_25, FN_IP4_26,
+	FN_IP4_27, FN_IP4_28, FN_IP4_31_29, FN_IP5_2_0,
+	FN_IP5_3, FN_IP5_4, FN_IP5_5, FN_IP5_6,
+	FN_IP5_7, FN_IP5_8, FN_IP5_10_9, FN_IP5_12_11,
+	FN_IP5_14_13, FN_IP5_16_15, FN_IP5_20_17, FN_IP5_23_21,
+
+	/* GPSR2 */
+	FN_IP5_27_24, FN_IP8_20, FN_IP8_22_21, FN_IP8_24_23,
+	FN_IP8_27_25, FN_IP8_30_28, FN_IP9_1_0, FN_IP9_3_2,
+	FN_IP9_4, FN_IP9_5, FN_IP9_6, FN_IP9_7,
+	FN_IP9_9_8, FN_IP9_11_10, FN_IP9_13_12, FN_IP9_15_14,
+	FN_IP9_18_16, FN_IP9_21_19, FN_IP9_23_22, FN_IP9_25_24,
+	FN_IP9_27_26, FN_IP9_29_28, FN_IP10_2_0, FN_IP10_5_3,
+	FN_IP10_8_6, FN_IP10_11_9, FN_IP10_14_12, FN_IP10_17_15,
+	FN_IP10_20_18, FN_IP10_23_21, FN_IP10_25_24, FN_IP10_28_26,
+
+	/* GPSR3 */
+	FN_IP10_31_29, FN_IP11_2_0, FN_IP11_5_3, FN_IP11_8_6,
+	FN_IP11_11_9, FN_IP11_14_12, FN_IP11_17_15, FN_IP11_20_18,
+	FN_IP11_23_21, FN_IP11_26_24, FN_IP11_29_27, FN_IP12_2_0,
+	FN_IP12_5_3, FN_IP12_8_6, FN_IP12_11_9, FN_IP12_14_12,
+	FN_IP12_17_15, FN_IP7_16_15, FN_IP7_18_17, FN_IP7_28_27,
+	FN_IP7_30_29, FN_IP7_20_19, FN_IP7_22_21, FN_IP7_24_23,
+	FN_IP7_26_25, FN_IP1_20_19, FN_IP1_22_21, FN_IP1_24_23,
+	FN_IP5_28, FN_IP5_30_29, FN_IP6_1_0, FN_IP6_3_2,
+
+	/* GPSR4 */
+	FN_IP6_5_4, FN_IP6_7_6, FN_IP6_8, FN_IP6_11_9,
+	FN_IP6_14_12, FN_IP6_17_15, FN_IP6_19_18, FN_IP6_22_20,
+	FN_IP6_24_23, FN_IP6_26_25, FN_IP6_30_29, FN_IP7_1_0,
+	FN_IP7_3_2, FN_IP7_6_4, FN_IP7_9_7, FN_IP7_12_10,
+	FN_IP7_14_13, FN_IP2_7_4, FN_IP2_11_8, FN_IP2_15_12,
+	FN_IP1_28_25, FN_IP2_3_0, FN_IP8_3_0, FN_IP8_7_4,
+	FN_IP8_11_8, FN_IP8_15_12, FN_PENC0, FN_PENC1,
+	FN_IP0_2_0, FN_IP8_17_16, FN_IP8_18, FN_IP8_19,
+
+	/* GPSR5 */
+	FN_A1, FN_A2, FN_A3, FN_A4,
+	FN_A5, FN_A6, FN_A7, FN_A8,
+	FN_A9, FN_A10, FN_A11, FN_A12,
+	FN_A13, FN_A14, FN_A15, FN_A16,
+	FN_RD, FN_WE0, FN_WE1, FN_EX_WAIT0,
+	FN_IP3_23, FN_IP3_27, FN_IP3_28, FN_IP2_22,
+	FN_IP2_23, FN_IP2_24, FN_IP2_25, FN_IP2_26,
+	FN_IP2_27, FN_IP3_3, FN_IP3_4, FN_IP3_5,
+
+	/* GPSR6 */
+	FN_IP3_6, FN_IP3_7, FN_IP3_8, FN_IP3_15,
+	FN_IP3_16, FN_IP3_17, FN_IP3_18, FN_IP3_19,
+	FN_IP3_20,
+	PINMUX_FUNCTION_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+	PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+	PINMUX_GPIO_GP_ALL(),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	{ PINMUX_CFG_REG("GPSR0", 0xffc00004, 32, 1) {
+		GP_0_31_FN, FN_IP3_31_29,
+		GP_0_30_FN, FN_IP3_26_24,
+		GP_0_29_FN, FN_IP3_22_21,
+		GP_0_28_FN, FN_IP3_14_12,
+		GP_0_27_FN, FN_IP3_11_9,
+		GP_0_26_FN, FN_IP2_2_0,
+		GP_0_25_FN, FN_IP2_30_28,
+		GP_0_24_FN, FN_IP2_21_19,
+		GP_0_23_FN, FN_IP2_18_16,
+		GP_0_22_FN, FN_IP0_30_28,
+		GP_0_21_FN, FN_IP0_5_3,
+		GP_0_20_FN, FN_IP1_18_15,
+		GP_0_19_FN, FN_IP1_14_11,
+		GP_0_18_FN, FN_IP1_10_7,
+		GP_0_17_FN, FN_IP1_6_4,
+		GP_0_16_FN, FN_IP1_3_2,
+		GP_0_15_FN, FN_IP1_1_0,
+		GP_0_14_FN, FN_IP0_27_26,
+		GP_0_13_FN, FN_IP0_25,
+		GP_0_12_FN, FN_IP0_24_23,
+		GP_0_11_FN, FN_IP0_22_19,
+		GP_0_10_FN, FN_IP0_18_16,
+		GP_0_9_FN, FN_IP0_15_14,
+		GP_0_8_FN, FN_IP0_13_12,
+		GP_0_7_FN, FN_IP0_11_10,
+		GP_0_6_FN, FN_IP0_9_8,
+		GP_0_5_FN, FN_A19,
+		GP_0_4_FN, FN_A18,
+		GP_0_3_FN, FN_A17,
+		GP_0_2_FN, FN_IP0_7_6,
+		GP_0_1_FN, FN_AVS2,
+		GP_0_0_FN, FN_AVS1 }
+	},
+	{ PINMUX_CFG_REG("GPSR1", 0xffc00008, 32, 1) {
+		GP_1_31_FN, FN_IP5_23_21,
+		GP_1_30_FN, FN_IP5_20_17,
+		GP_1_29_FN, FN_IP5_16_15,
+		GP_1_28_FN, FN_IP5_14_13,
+		GP_1_27_FN, FN_IP5_12_11,
+		GP_1_26_FN, FN_IP5_10_9,
+		GP_1_25_FN, FN_IP5_8,
+		GP_1_24_FN, FN_IP5_7,
+		GP_1_23_FN, FN_IP5_6,
+		GP_1_22_FN, FN_IP5_5,
+		GP_1_21_FN, FN_IP5_4,
+		GP_1_20_FN, FN_IP5_3,
+		GP_1_19_FN, FN_IP5_2_0,
+		GP_1_18_FN, FN_IP4_31_29,
+		GP_1_17_FN, FN_IP4_28,
+		GP_1_16_FN, FN_IP4_27,
+		GP_1_15_FN, FN_IP4_26,
+		GP_1_14_FN, FN_IP4_25,
+		GP_1_13_FN, FN_IP4_24,
+		GP_1_12_FN, FN_IP4_23,
+		GP_1_11_FN, FN_IP4_22_20,
+		GP_1_10_FN, FN_IP4_19_17,
+		GP_1_9_FN, FN_IP4_16,
+		GP_1_8_FN, FN_IP4_15,
+		GP_1_7_FN, FN_IP4_14,
+		GP_1_6_FN, FN_IP4_13,
+		GP_1_5_FN, FN_IP4_12,
+		GP_1_4_FN, FN_IP4_11,
+		GP_1_3_FN, FN_IP4_10_8,
+		GP_1_2_FN, FN_IP4_7_5,
+		GP_1_1_FN, FN_IP4_4_2,
+		GP_1_0_FN, FN_IP4_1_0 }
+	},
+	{ PINMUX_CFG_REG("GPSR2", 0xffc0000c, 32, 1) {
+		GP_2_31_FN, FN_IP10_28_26,
+		GP_2_30_FN, FN_IP10_25_24,
+		GP_2_29_FN, FN_IP10_23_21,
+		GP_2_28_FN, FN_IP10_20_18,
+		GP_2_27_FN, FN_IP10_17_15,
+		GP_2_26_FN, FN_IP10_14_12,
+		GP_2_25_FN, FN_IP10_11_9,
+		GP_2_24_FN, FN_IP10_8_6,
+		GP_2_23_FN, FN_IP10_5_3,
+		GP_2_22_FN, FN_IP10_2_0,
+		GP_2_21_FN, FN_IP9_29_28,
+		GP_2_20_FN, FN_IP9_27_26,
+		GP_2_19_FN, FN_IP9_25_24,
+		GP_2_18_FN, FN_IP9_23_22,
+		GP_2_17_FN, FN_IP9_21_19,
+		GP_2_16_FN, FN_IP9_18_16,
+		GP_2_15_FN, FN_IP9_15_14,
+		GP_2_14_FN, FN_IP9_13_12,
+		GP_2_13_FN, FN_IP9_11_10,
+		GP_2_12_FN, FN_IP9_9_8,
+		GP_2_11_FN, FN_IP9_7,
+		GP_2_10_FN, FN_IP9_6,
+		GP_2_9_FN, FN_IP9_5,
+		GP_2_8_FN, FN_IP9_4,
+		GP_2_7_FN, FN_IP9_3_2,
+		GP_2_6_FN, FN_IP9_1_0,
+		GP_2_5_FN, FN_IP8_30_28,
+		GP_2_4_FN, FN_IP8_27_25,
+		GP_2_3_FN, FN_IP8_24_23,
+		GP_2_2_FN, FN_IP8_22_21,
+		GP_2_1_FN, FN_IP8_20,
+		GP_2_0_FN, FN_IP5_27_24 }
+	},
+	{ PINMUX_CFG_REG("GPSR3", 0xffc00010, 32, 1) {
+		GP_3_31_FN, FN_IP6_3_2,
+		GP_3_30_FN, FN_IP6_1_0,
+		GP_3_29_FN, FN_IP5_30_29,
+		GP_3_28_FN, FN_IP5_28,
+		GP_3_27_FN, FN_IP1_24_23,
+		GP_3_26_FN, FN_IP1_22_21,
+		GP_3_25_FN, FN_IP1_20_19,
+		GP_3_24_FN, FN_IP7_26_25,
+		GP_3_23_FN, FN_IP7_24_23,
+		GP_3_22_FN, FN_IP7_22_21,
+		GP_3_21_FN, FN_IP7_20_19,
+		GP_3_20_FN, FN_IP7_30_29,
+		GP_3_19_FN, FN_IP7_28_27,
+		GP_3_18_FN, FN_IP7_18_17,
+		GP_3_17_FN, FN_IP7_16_15,
+		GP_3_16_FN, FN_IP12_17_15,
+		GP_3_15_FN, FN_IP12_14_12,
+		GP_3_14_FN, FN_IP12_11_9,
+		GP_3_13_FN, FN_IP12_8_6,
+		GP_3_12_FN, FN_IP12_5_3,
+		GP_3_11_FN, FN_IP12_2_0,
+		GP_3_10_FN, FN_IP11_29_27,
+		GP_3_9_FN, FN_IP11_26_24,
+		GP_3_8_FN, FN_IP11_23_21,
+		GP_3_7_FN, FN_IP11_20_18,
+		GP_3_6_FN, FN_IP11_17_15,
+		GP_3_5_FN, FN_IP11_14_12,
+		GP_3_4_FN, FN_IP11_11_9,
+		GP_3_3_FN, FN_IP11_8_6,
+		GP_3_2_FN, FN_IP11_5_3,
+		GP_3_1_FN, FN_IP11_2_0,
+		GP_3_0_FN, FN_IP10_31_29 }
+	},
+	{ PINMUX_CFG_REG("GPSR4", 0xffc00014, 32, 1) {
+		GP_4_31_FN, FN_IP8_19,
+		GP_4_30_FN, FN_IP8_18,
+		GP_4_29_FN, FN_IP8_17_16,
+		GP_4_28_FN, FN_IP0_2_0,
+		GP_4_27_FN, FN_PENC1,
+		GP_4_26_FN, FN_PENC0,
+		GP_4_25_FN, FN_IP8_15_12,
+		GP_4_24_FN, FN_IP8_11_8,
+		GP_4_23_FN, FN_IP8_7_4,
+		GP_4_22_FN, FN_IP8_3_0,
+		GP_4_21_FN, FN_IP2_3_0,
+		GP_4_20_FN, FN_IP1_28_25,
+		GP_4_19_FN, FN_IP2_15_12,
+		GP_4_18_FN, FN_IP2_11_8,
+		GP_4_17_FN, FN_IP2_7_4,
+		GP_4_16_FN, FN_IP7_14_13,
+		GP_4_15_FN, FN_IP7_12_10,
+		GP_4_14_FN, FN_IP7_9_7,
+		GP_4_13_FN, FN_IP7_6_4,
+		GP_4_12_FN, FN_IP7_3_2,
+		GP_4_11_FN, FN_IP7_1_0,
+		GP_4_10_FN, FN_IP6_30_29,
+		GP_4_9_FN, FN_IP6_26_25,
+		GP_4_8_FN, FN_IP6_24_23,
+		GP_4_7_FN, FN_IP6_22_20,
+		GP_4_6_FN, FN_IP6_19_18,
+		GP_4_5_FN, FN_IP6_17_15,
+		GP_4_4_FN, FN_IP6_14_12,
+		GP_4_3_FN, FN_IP6_11_9,
+		GP_4_2_FN, FN_IP6_8,
+		GP_4_1_FN, FN_IP6_7_6,
+		GP_4_0_FN, FN_IP6_5_4 }
+	},
+	{ PINMUX_CFG_REG("GPSR5", 0xffc00018, 32, 1) {
+		GP_5_31_FN, FN_IP3_5,
+		GP_5_30_FN, FN_IP3_4,
+		GP_5_29_FN, FN_IP3_3,
+		GP_5_28_FN, FN_IP2_27,
+		GP_5_27_FN, FN_IP2_26,
+		GP_5_26_FN, FN_IP2_25,
+		GP_5_25_FN, FN_IP2_24,
+		GP_5_24_FN, FN_IP2_23,
+		GP_5_23_FN, FN_IP2_22,
+		GP_5_22_FN, FN_IP3_28,
+		GP_5_21_FN, FN_IP3_27,
+		GP_5_20_FN, FN_IP3_23,
+		GP_5_19_FN, FN_EX_WAIT0,
+		GP_5_18_FN, FN_WE1,
+		GP_5_17_FN, FN_WE0,
+		GP_5_16_FN, FN_RD,
+		GP_5_15_FN, FN_A16,
+		GP_5_14_FN, FN_A15,
+		GP_5_13_FN, FN_A14,
+		GP_5_12_FN, FN_A13,
+		GP_5_11_FN, FN_A12,
+		GP_5_10_FN, FN_A11,
+		GP_5_9_FN, FN_A10,
+		GP_5_8_FN, FN_A9,
+		GP_5_7_FN, FN_A8,
+		GP_5_6_FN, FN_A7,
+		GP_5_5_FN, FN_A6,
+		GP_5_4_FN, FN_A5,
+		GP_5_3_FN, FN_A4,
+		GP_5_2_FN, FN_A3,
+		GP_5_1_FN, FN_A2,
+		GP_5_0_FN, FN_A1 }
+	},
+	{ PINMUX_CFG_REG("GPSR6", 0xffc0001c, 32, 1) {
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_6_8_FN, FN_IP3_20,
+		GP_6_7_FN, FN_IP3_19,
+		GP_6_6_FN, FN_IP3_18,
+		GP_6_5_FN, FN_IP3_17,
+		GP_6_4_FN, FN_IP3_16,
+		GP_6_3_FN, FN_IP3_15,
+		GP_6_2_FN, FN_IP3_8,
+		GP_6_1_FN, FN_IP3_7,
+		GP_6_0_FN, FN_IP3_6 }
+	},
+	{ PINMUX_CFG_REG("INOUTSEL0", 0xffc40004, 32, 1) { GP_INOUTSEL(0) } },
+	{ PINMUX_CFG_REG("INOUTSEL1", 0xffc41004, 32, 1) { GP_INOUTSEL(1) } },
+	{ PINMUX_CFG_REG("INOUTSEL2", 0xffc42004, 32, 1) { GP_INOUTSEL(2) } },
+	{ PINMUX_CFG_REG("INOUTSEL3", 0xffc43004, 32, 1) { GP_INOUTSEL(3) } },
+	{ PINMUX_CFG_REG("INOUTSEL4", 0xffc44004, 32, 1) { GP_INOUTSEL(4) } },
+	{ PINMUX_CFG_REG("INOUTSEL5", 0xffc45004, 32, 1) { GP_INOUTSEL(5) } },
+	{ PINMUX_CFG_REG("INOUTSEL6", 0xffc46004, 32, 1) {
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_6_8_IN, GP_6_8_OUT,
+		GP_6_7_IN, GP_6_7_OUT,
+		GP_6_6_IN, GP_6_6_OUT,
+		GP_6_5_IN, GP_6_5_OUT,
+		GP_6_4_IN, GP_6_4_OUT,
+		GP_6_3_IN, GP_6_3_OUT,
+		GP_6_2_IN, GP_6_2_OUT,
+		GP_6_1_IN, GP_6_1_OUT,
+		GP_6_0_IN, GP_6_0_OUT, }
+	},
+	{ },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+	{ PINMUX_DATA_REG("INDT0", 0xffc40008, 32) { GP_INDT(0) } },
+	{ PINMUX_DATA_REG("INDT1", 0xffc41008, 32) { GP_INDT(1) } },
+	{ PINMUX_DATA_REG("INDT2", 0xffc42008, 32) { GP_INDT(2) } },
+	{ PINMUX_DATA_REG("INDT3", 0xffc43008, 32) { GP_INDT(3) } },
+	{ PINMUX_DATA_REG("INDT4", 0xffc44008, 32) { GP_INDT(4) } },
+	{ PINMUX_DATA_REG("INDT5", 0xffc45008, 32) { GP_INDT(5) } },
+	{ PINMUX_DATA_REG("INDT6", 0xffc46008, 32) {
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, GP_6_8_DATA,
+		GP_6_7_DATA, GP_6_6_DATA, GP_6_5_DATA, GP_6_4_DATA,
+		GP_6_3_DATA, GP_6_2_DATA, GP_6_1_DATA, GP_6_0_DATA }
+	},
+	{ },
+};
+
+static struct pinmux_info r8a7779_pinmux_info = {
+	.name = "r8a7779_pfc",
+	.reserved_id = PINMUX_RESERVED,
+	.data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+	.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+	.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+	.first_gpio = GPIO_GP_0_0,
+	.last_gpio = GPIO_GP_6_8,
+
+	.gpios = pinmux_gpios,
+	.cfg_regs = pinmux_config_regs,
+	.data_regs = pinmux_data_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void r8a7779_pinmux_init(void)
+{
+	register_pinmux(&r8a7779_pinmux_info);
+}

^ permalink raw reply

* [PATCH 04/07] ARM: mach-shmobile: Marzen early console hack
From: Magnus Damm @ 2011-12-06 16:52 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Hack the Marzen board code to get early debug print outs.
Use with "earlyprint=sh-sci.2,11520" on the kernel command line.

Good to have when tracking down early timer or PFC issues.

Needed by the r8a7779 PFC map hack further in the series.

Never-signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/board-marzen.c  |    8 ++++++++
 arch/arm/mach-shmobile/setup-r8a7779.c |    4 ++--
 2 files changed, 10 insertions(+), 2 deletions(-)

--- 0008/arch/arm/mach-shmobile/board-marzen.c
+++ work/arch/arm/mach-shmobile/board-marzen.c	2011-12-06 23:57:23.000000000 +0900
@@ -54,6 +54,13 @@ static struct map_desc marzen_io_desc[]
 		.length		= SZ_16M,
 		.type		= MT_DEVICE_NONSHARED
 	},
+	/* 16M debug map between 0xfdxxxxxx and 0xffxxxxxx */
+	{
+		.virtual	= 0xfd000000,
+		.pfn		= __phys_to_pfn(0xff000000),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE_NONSHARED
+	},
 };
 
 static void __init marzen_map_io(void)
@@ -80,6 +87,7 @@ static void __init marzen_init_early(voi
 	 * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
 	 * command line.
 	 */
+	shmobile_setup_console();
 }
 
 static void __init marzen_init(void)
--- 0008/arch/arm/mach-shmobile/setup-r8a7779.c
+++ work/arch/arm/mach-shmobile/setup-r8a7779.c	2011-12-06 23:56:32.000000000 +0900
@@ -70,8 +70,8 @@ static struct platform_device scif1_devi
 };
 
 static struct plat_sci_port scif2_platform_data = {
-	.mapbase	= 0xffe42000,
-	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.mapbase	= 0xfde42000,
+	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
 	.scbrr_algo_id	= SCBRR_ALGO_2,
 	.type		= PORT_SCIF,

^ permalink raw reply

* [PATCH 03/07] ARM: mach-shmobile: r8a7779 and Marzen base support
From: Magnus Damm @ 2011-12-06 16:52 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Initial prototype support for the r8a7779 SoC and the Marzen board.

Only SCIF ports and the TMU are supported at this point.

To keep things simple only entity-mapped virt-to-phys mappings
are supported. This forces drivers and other SoC glue code to
make use of ioremap(). We cannot support early serial console
due to virtual address space collisions with the ARM kernel.

Not-yet-signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/Kconfig                |   10 +
 arch/arm/mach-shmobile/Makefile               |    3 
 arch/arm/mach-shmobile/board-marzen.c         |  110 +++++++++++
 arch/arm/mach-shmobile/clock-r8a7779.c        |  105 +++++++++++
 arch/arm/mach-shmobile/include/mach/common.h  |    5 
 arch/arm/mach-shmobile/include/mach/r8a7779.h |    6 
 arch/arm/mach-shmobile/intc-r8a7779.c         |   58 ++++++
 arch/arm/mach-shmobile/setup-r8a7779.c        |  231 +++++++++++++++++++++++++
 8 files changed, 528 insertions(+)

--- 0001/arch/arm/mach-shmobile/Kconfig
+++ work/arch/arm/mach-shmobile/Kconfig	2011-12-07 00:36:10.000000000 +0900
@@ -28,6 +28,12 @@ config ARCH_SH73A0
 	select ARM_GIC
 	select I2C
 
+config ARCH_R8A7779
+	bool "R-Car H1 (R8A77790)"
+	select CPU_V7
+	select SH_CLK_CPG
+	select ARM_GIC
+
 comment "SH-Mobile Board Type"
 
 config MACH_G3EVM
@@ -75,6 +81,10 @@ config MACH_KOTA2
 	select ARCH_REQUIRE_GPIOLIB
 	depends on ARCH_SH73A0
 
+config MACH_MARZEN
+	bool "MARZEN board"
+	depends on ARCH_R8A7779
+
 comment "SH-Mobile System Configuration"
 
 menu "Memory configuration"
--- 0001/arch/arm/mach-shmobile/Makefile
+++ work/arch/arm/mach-shmobile/Makefile	2011-12-07 00:37:58.000000000 +0900
@@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_SH7367)	+= setup-sh736
 obj-$(CONFIG_ARCH_SH7377)	+= setup-sh7377.o clock-sh7377.o intc-sh7377.o
 obj-$(CONFIG_ARCH_SH7372)	+= setup-sh7372.o clock-sh7372.o intc-sh7372.o
 obj-$(CONFIG_ARCH_SH73A0)	+= setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
+obj-$(CONFIG_ARCH_R8A7779)	+= setup-r8a7779.o clock-r8a7779.o
 
 # SMP objects
 smp-y				:= platsmp.o headsmp.o
@@ -29,6 +30,7 @@ obj-$(CONFIG_ARCH_SH7367)	+= entry-intc.
 obj-$(CONFIG_ARCH_SH7377)	+= entry-intc.o
 obj-$(CONFIG_ARCH_SH7372)	+= entry-intc.o
 obj-$(CONFIG_ARCH_SH73A0)	+= entry-gic.o
+obj-$(CONFIG_ARCH_R8A7779)	+= entry-gic.o intc-r8a7779.o
 
 # PM objects
 obj-$(CONFIG_SUSPEND)		+= suspend.o
@@ -42,6 +44,7 @@ obj-$(CONFIG_MACH_AP4EVB)	+= board-ap4ev
 obj-$(CONFIG_MACH_AG5EVM)	+= board-ag5evm.o
 obj-$(CONFIG_MACH_MACKEREL)	+= board-mackerel.o
 obj-$(CONFIG_MACH_KOTA2)	+= board-kota2.o
+obj-$(CONFIG_MACH_MARZEN)	+= board-marzen.o
 
 # Framework support
 obj-$(CONFIG_SMP)		+= $(smp-y)
--- /dev/null
+++ work/arch/arm/mach-shmobile/board-marzen.c	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,110 @@
+/*
+ * marzen board support
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <mach/r8a7779.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+#include <asm/traps.h>
+
+static struct platform_device *marzen_devices[] __initdata = {
+};
+
+static struct map_desc marzen_io_desc[] __initdata = {
+	/* 2M entity map for 0xf0000000 (MPCORE) */
+	{
+		.virtual	= 0xf0000000,
+		.pfn		= __phys_to_pfn(0xf0000000),
+		.length		= SZ_2M,
+		.type		= MT_DEVICE_NONSHARED
+	},
+	/* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
+	{
+		.virtual	= 0xfe000000,
+		.pfn		= __phys_to_pfn(0xfe000000),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE_NONSHARED
+	},
+};
+
+static void __init marzen_map_io(void)
+{
+	iotable_init(marzen_io_desc, ARRAY_SIZE(marzen_io_desc));
+}
+
+static void __init marzen_init_early(void)
+{
+	r8a7779_add_early_devices();
+
+	/* Early serial console setup is not included here due to
+	 * memory map collisions. The SCIF serial ports in r8a7779
+	 * are difficult to entity map 1:1 due to collision with the
+	 * virtual memory range used by the coherent DMA code on ARM.
+	 *
+	 * Anyone wanting to debug early can remove UPF_IOREMAP from
+	 * the sh-sci serial console platform data, adjust mapbase
+	 * to a static M:N virt:phys mapping that needs to be added to
+	 * the mappings passed with iotable_init() above.
+	 *
+	 * Then add a call to shmobile_setup_console() from this function.
+	 *
+	 * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
+	 * command line.
+	 */
+}
+
+static void __init marzen_init(void)
+{
+	r8a7779_add_standard_devices();
+	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
+}
+
+static void __init marzen_timer_init(void)
+{
+	r8a7779_clock_init();
+	shmobile_timer.init();
+	return;
+}
+
+struct sys_timer marzen_timer = {
+	.init	= marzen_timer_init,
+};
+
+MACHINE_START(MARZEN, "marzen")
+	.map_io		= marzen_map_io,
+	.init_early	= marzen_init_early,
+	.nr_irqs	= NR_IRQS_LEGACY,
+	.init_irq	= r8a7779_init_irq,
+	.handle_irq	= shmobile_handle_irq_gic,
+	.init_machine	= marzen_init,
+	.timer		= &marzen_timer,
+MACHINE_END
--- /dev/null
+++ work/arch/arm/mach-shmobile/clock-r8a7779.c	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,105 @@
+/*
+ * r8a7779 clock framework support
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * 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
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/common.h>
+
+#define FRQMR   0xffc80014
+#define MSTPCR0 0xffc80030
+#define MSTPCR1 0xffc80034
+#define MSTPCR3 0xffc8003c
+#define MSTPSR1 0xffc80044
+#define MSTPSR4 0xffc80048
+#define MSTPSR6 0xffc8004c
+#define MSTPCR4 0xffc80050
+#define MSTPCR5 0xffc80054
+#define MSTPCR6 0xffc80058
+#define MSTPCR7 0xffc80040
+
+/* ioremap() through clock mapping mandatory to avoid
+ * collision with ARM coherent DMA virtual memory range.
+ */
+
+static struct clk_mapping cpg_mapping = {
+	.phys	= 0xffc80000,
+	.len	= 0x80,
+};
+
+static struct clk clkp = {
+	.rate	= 62500000, /* FIXME: shortcut */
+	.flags	= CLK_ENABLE_ON_INIT,
+	.mapping = &cpg_mapping,
+};
+
+static struct clk *main_clks[] = {
+	&clkp,
+};
+
+enum { MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
+	MSTP016, MSTP015, MSTP014,
+	MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+	SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[MSTP_NR] = {
+	[MSTP026] = MSTP(&clkp, MSTPCR0, 26, 0), /* SCIF0 */
+	[MSTP025] = MSTP(&clkp, MSTPCR0, 25, 0), /* SCIF1 */
+	[MSTP024] = MSTP(&clkp, MSTPCR0, 24, 0), /* SCIF2 */
+	[MSTP023] = MSTP(&clkp, MSTPCR0, 23, 0), /* SCIF3 */
+	[MSTP022] = MSTP(&clkp, MSTPCR0, 22, 0), /* SCIF4 */
+	[MSTP021] = MSTP(&clkp, MSTPCR0, 21, 0), /* SCIF5 */
+	[MSTP016] = MSTP(&clkp, MSTPCR0, 16, 0), /* TMU0 */
+	[MSTP015] = MSTP(&clkp, MSTPCR0, 15, 0), /* TMU1 */
+	[MSTP014] = MSTP(&clkp, MSTPCR0, 14, 0), /* TMU2 */
+};
+
+static struct clk_lookup lookups[] = {
+	/* MSTP32 clocks */
+	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
+	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
+	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
+	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
+	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
+	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
+	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
+	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
+};
+
+void __init r8a7779_clock_init(void)
+{
+	int k, ret = 0;
+
+	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+		ret = clk_register(main_clks[k]);
+
+	if (!ret)
+		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	if (!ret)
+		clk_init();
+	else
+		panic("failed to setup r8a7779 clocks\n");
+}
--- 0001/arch/arm/mach-shmobile/include/mach/common.h
+++ work/arch/arm/mach-shmobile/include/mach/common.h	2011-12-07 00:36:10.000000000 +0900
@@ -53,4 +53,9 @@ extern void sh73a0_secondary_init(unsign
 extern int sh73a0_boot_secondary(unsigned int cpu);
 extern void sh73a0_smp_prepare_cpus(void);
 
+extern void r8a7779_init_irq(void);
+extern void r8a7779_add_early_devices(void);
+extern void r8a7779_add_standard_devices(void);
+extern void r8a7779_clock_init(void);
+
 #endif /* __ARCH_MACH_COMMON_H */
--- /dev/null
+++ work/arch/arm/mach-shmobile/include/mach/r8a7779.h	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,6 @@
+#ifndef __ASM_R8A7779_H__
+#define __ASM_R8A7779_H__
+
+/* Nothing at this point */
+
+#endif /* __ASM_R8A7779_H__ */
--- /dev/null
+++ work/arch/arm/mach-shmobile/intc-r8a7779.c	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,58 @@
+/*
+ * r8a7779 processor support - INTC hardware block
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/common.h>
+#include <mach/intc.h>
+#include <mach/r8a7779.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define INT2SMSKCR0 0xfe7822a0
+#define INT2SMSKCR1 0xfe7822a4
+#define INT2SMSKCR2 0xfe7822a8
+#define INT2SMSKCR3 0xfe7822ac
+#define INT2SMSKCR4 0xfe7822b0
+
+static int r8a7779_set_wake(struct irq_data *data, unsigned int on)
+{
+	return 0; /* always allow wakeup */
+}
+
+void __init r8a7779_init_irq(void)
+{
+	void __iomem *gic_dist_base = __io(0xf0001000);
+	void __iomem *gic_cpu_base = __io(0xf0000100);
+
+	/* use GIC to handle interrupts */
+	gic_init(0, 29, gic_dist_base, gic_cpu_base);
+	gic_arch_extn.irq_set_wake = r8a7779_set_wake;
+
+	/* unmask all known interrupts in INTCS2 */
+	__raw_writel(0xfffffff0, INT2SMSKCR0);
+	__raw_writel(0xfff7ffff, INT2SMSKCR1);
+	__raw_writel(0xfffbffdf, INT2SMSKCR2);
+	__raw_writel(0xbffffffc, INT2SMSKCR3);
+	__raw_writel(0x003fee3f, INT2SMSKCR4);
+}
--- /dev/null
+++ work/arch/arm/mach-shmobile/setup-r8a7779.c	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,231 @@
+/*
+ * r8a7779 processor support
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * 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; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <mach/r8a7779.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffe40000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(88), gic_spi(88),
+			    gic_spi(88), gic_spi(88) },
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xffe41000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(89), gic_spi(89),
+			    gic_spi(89), gic_spi(89) },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xffe42000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(90), gic_spi(90),
+			    gic_spi(90), gic_spi(90) },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xffe43000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(91), gic_spi(91),
+			    gic_spi(91), gic_spi(91) },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xffe44000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(92), gic_spi(92),
+			    gic_spi(92), gic_spi(92) },
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase	= 0xffe45000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(93), gic_spi(93),
+			    gic_spi(93), gic_spi(93) },
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
+	},
+};
+
+/* TMU */
+static struct sh_timer_config tmu00_platform_data = {
+	.name = "TMU00",
+	.channel_offset = 0x4,
+	.timer_bit = 0,
+	.clockevent_rating = 200,
+};
+
+static struct resource tmu00_resources[] = {
+	[0] = {
+		.name	= "TMU00",
+		.start	= 0xffd80008,
+		.end	= 0xffd80013,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(32),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device tmu00_device = {
+	.name		= "sh_tmu",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &tmu00_platform_data,
+	},
+	.resource	= tmu00_resources,
+	.num_resources	= ARRAY_SIZE(tmu00_resources),
+};
+
+static struct sh_timer_config tmu01_platform_data = {
+	.name = "TMU01",
+	.channel_offset = 0x10,
+	.timer_bit = 1,
+	.clocksource_rating = 200,
+};
+
+static struct resource tmu01_resources[] = {
+	[0] = {
+		.name	= "TMU01",
+		.start	= 0xffd80014,
+		.end	= 0xffd8001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(33),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device tmu01_device = {
+	.name		= "sh_tmu",
+	.id		= 1,
+	.dev = {
+		.platform_data	= &tmu01_platform_data,
+	},
+	.resource	= tmu01_resources,
+	.num_resources	= ARRAY_SIZE(tmu01_resources),
+};
+
+static struct platform_device *r8a7779_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
+	&tmu00_device,
+	&tmu01_device,
+};
+
+static struct platform_device *r8a7779_late_devices[] __initdata = {
+};
+
+void __init r8a7779_add_standard_devices(void)
+{
+	platform_add_devices(r8a7779_early_devices,
+			    ARRAY_SIZE(r8a7779_early_devices));
+	platform_add_devices(r8a7779_late_devices,
+			    ARRAY_SIZE(r8a7779_late_devices));
+}
+
+void __init r8a7779_add_early_devices(void)
+{
+	early_platform_add_devices(r8a7779_early_devices,
+				   ARRAY_SIZE(r8a7779_early_devices));
+}

^ permalink raw reply

* [PATCH 02/07] sh: CPG MSTP ioremap() prototype hack
From: Magnus Damm @ 2011-12-06 16:52 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Hack to use the cookie returned from ioremap(). Will be rewritten
and submitted separately in the near future. Needed by the r8a7779
clock code since entity mapping is out of the question.

Not-yet-signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/sh/clk/cpg.c |    4 ++++
 1 file changed, 4 insertions(+)

--- 0001/drivers/sh/clk/cpg.c
+++ work/drivers/sh/clk/cpg.c	2011-12-07 00:32:11.000000000 +0900
@@ -42,6 +42,10 @@ int __init sh_clk_mstp32_register(struct
 		clkp = clks + k;
 		clkp->ops = &sh_clk_mstp32_clk_ops;
 		ret |= clk_register(clkp);
+		if (!ret && clkp->mapping->base) {
+			clkp->enable_reg -= clkp->mapping->phys;
+			clkp->enable_reg += (unsigned long)clkp->mapping->base;
+		}
 	}
 
 	return ret;

^ permalink raw reply

* [PATCH 01/07] ARM: mach-shmobile: Marzen mach-type entry
From: Magnus Damm @ 2011-12-06 16:52 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

The marzen board has already been registered through the web interface,
but upstream does not include the mach-type entry yet.

Not-yet-signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/tools/mach-types |    1 +
 1 file changed, 1 insertion(+)

--- 0002/arch/arm/tools/mach-types
+++ work/arch/arm/tools/mach-types	2011-12-07 00:30:13.000000000 +0900
@@ -1127,3 +1127,4 @@ m28evk			MACH_M28EVK		M28EVK			3613
 kota2			MACH_KOTA2		KOTA2			3616
 smdk4212		MACH_SMDK4212		SMDK4212		3638
 smdk4412		MACH_SMDK4412		SMDK4412		3765
+marzen			MACH_MARZEN		MARZEN			3790

^ permalink raw reply

* [PATCH 00/07] ARM: mach-shmobile: r8a7779 and Marzen prototype V1
From: Magnus Damm @ 2011-12-06 16:51 UTC (permalink / raw)
  To: linux-sh

ARM: mach-shmobile: r8a7779 and Marzen prototype V1

[PATCH 01/07] ARM: mach-shmobile: Marzen mach-type entry
[PATCH 02/07] sh: CPG MSTP ioremap() prototype hack
[PATCH 03/07] ARM: mach-shmobile: r8a7779 and Marzen base support
[PATCH 04/07] ARM: mach-shmobile: Marzen early console hack
[PATCH 05/07] ARM: mach-shmobile: r8a7779 PFC GPIO-only prototype
[PATCH 06/07] ARM: mach-shmobile: r8a7779 PFC ioremap() workaround
[PATCH 07/07] ARM: mach-shmobile: Marzen GPIO LED test code

On the SoC-level simple things like the SCIF console, the TMU timer,
the GIC interrupt controller, initial CPG clock framework code and
and GPIO-only PFC support are implemented. On the Marzen board the
only code for now is support for LED2, LED3 and LED4. The LEDs are
used to test the GPIO-only PFC and can be toggled from user space.

On the immediate todo is:
- Rewrite [PATCH 02/07] and submit separately
- Add ioremap() support to drivers/sh/pfc.c and drop [PATCH 06/07]
- Add variable bit field length to drivers/sh/pfc.c
- Update r8a7779 PFC code to support GPIO_FN (needs variable bit field)

List of things I'm not going to touch this week:
- r8a7779 clock framework (Special gift for Morimoto-san)
- r8a7779 external IRQ pin support (INTC2 sits between IRQ pins and GIC)
- Marzen LAN89218 support (hooked up to EX_CS0/GP_0_15 and IRQ1_B/GP_4_14)

Not-yet-signed-off-by: Magnus Damm <damm@opensource.se>
---

 Do not merge - patches will be updated in the near future.

 Will most likely clash with A1 support written by Morimoto-san.
 Built on top of linus rc- git with Kota2 patches destined for -rc.

 arch/arm/mach-shmobile/Kconfig                |   12 
 arch/arm/mach-shmobile/Makefile               |    4 
 arch/arm/mach-shmobile/board-marzen.c         |  133 ++++++
 arch/arm/mach-shmobile/clock-r8a7779.c        |  105 +++++
 arch/arm/mach-shmobile/include/mach/common.h  |    6 
 arch/arm/mach-shmobile/include/mach/r8a7779.h |   69 +++
 arch/arm/mach-shmobile/intc-r8a7779.c         |   58 ++
 arch/arm/mach-shmobile/pfc-r8a7779.c          |  494 +++++++++++++++++++++++--
 arch/arm/mach-shmobile/setup-r8a7779.c        |  235 +++++++++++
 arch/arm/tools/mach-types                     |    1 
 drivers/sh/clk/cpg.c                          |    4 
 11 files changed, 1097 insertions(+), 24 deletions(-)

^ permalink raw reply

* [PATCH v2 3/3] sh: clkfwk: clock-sh73a0: all div6_clks use SH_CLK_DIV6_EXT()
From: Kuninori Morimoto @ 2011-12-06  6:29 UTC (permalink / raw)
  To: linux-sh

Current div6 clocks can specify their current parent clocks
from its register value if it is registered
by sh_clk_div6_reparent_register().
This patch modifies all div6 clocks into SH_CLK_DIV6_EXT().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2

- normal SH_CLK_DIV6_EXT()
- drop un-needed NULL from clock parent table, and add array size for table

 arch/arm/mach-shmobile/clock-sh73a0.c        |  146 ++++++++++++++++++++++----
 arch/arm/mach-shmobile/include/mach/common.h |    2 +
 2 files changed, 126 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 61a846b..8ea8c81 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -92,6 +92,24 @@ static struct clk_ops div2_clk_ops = {
 	.recalc		= div2_recalc,
 };
 
+static unsigned long div7_recalc(struct clk *clk)
+{
+	return clk->parent->rate / 7;
+}
+
+static struct clk_ops div7_clk_ops = {
+	.recalc		= div7_recalc,
+};
+
+static unsigned long div13_recalc(struct clk *clk)
+{
+	return clk->parent->rate / 13;
+}
+
+static struct clk_ops div13_clk_ops = {
+	.recalc		= div13_recalc,
+};
+
 /* Divide extal1 by two */
 static struct clk extal1_div2_clk = {
 	.ops		= &div2_clk_ops,
@@ -113,6 +131,11 @@ static struct clk main_clk = {
 	.ops		= &main_clk_ops,
 };
 
+static struct clk main_div2_clk = {
+	.ops		= &div2_clk_ops,
+	.parent		= &main_clk,
+};
+
 /* PLL0, PLL1, PLL2, PLL3 */
 static unsigned long pll_recalc(struct clk *clk)
 {
@@ -168,12 +191,29 @@ static struct clk pll3_clk = {
 	.enable_bit	= 3,
 };
 
-/* Divide PLL1 by two */
+/* Divide PLL */
 static struct clk pll1_div2_clk = {
 	.ops		= &div2_clk_ops,
 	.parent		= &pll1_clk,
 };
 
+static struct clk pll1_div7_clk = {
+	.ops		= &div7_clk_ops,
+	.parent		= &pll1_clk,
+};
+
+static struct clk pll1_div13_clk = {
+	.ops		= &div13_clk_ops,
+	.parent		= &pll1_clk,
+};
+
+/* External input clock */
+struct clk sh73a0_extcki_clk = {
+};
+
+struct clk sh73a0_extalr_clk = {
+};
+
 static struct clk *main_clks[] = {
 	&r_clk,
 	&sh73a0_extal1_clk,
@@ -181,11 +221,16 @@ static struct clk *main_clks[] = {
 	&extal1_div2_clk,
 	&extal2_div2_clk,
 	&main_clk,
+	&main_div2_clk,
 	&pll0_clk,
 	&pll1_clk,
 	&pll2_clk,
 	&pll3_clk,
 	&pll1_div2_clk,
+	&pll1_div7_clk,
+	&pll1_div13_clk,
+	&sh73a0_extcki_clk,
+	&sh73a0_extalr_clk,
 };
 
 static void div4_kick(struct clk *clk)
@@ -239,27 +284,84 @@ enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
 	DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
 	DIV6_NR };
 
+static struct clk *vck_parent[8] = {
+	[0] = &pll1_div2_clk,
+	[1] = &pll2_clk,
+	[2] = &sh73a0_extcki_clk,
+	[3] = &sh73a0_extal2_clk,
+	[4] = &main_div2_clk,
+	[5] = &sh73a0_extalr_clk,
+	[6] = &main_clk,
+};
+
+static struct clk *pll_parent[4] = {
+	[0] = &pll1_div2_clk,
+	[1] = &pll2_clk,
+	[2] = &pll1_div13_clk,
+};
+
+static struct clk *hsi_parent[4] = {
+	[0] = &pll1_div2_clk,
+	[1] = &pll2_clk,
+	[2] = &pll1_div7_clk,
+};
+
+static struct clk *pll_extal2_parent[] = {
+	[0] = &pll1_div2_clk,
+	[1] = &pll2_clk,
+	[2] = &sh73a0_extal2_clk,
+	[3] = &sh73a0_extal2_clk,
+};
+
+static struct clk *dsi_parent[8] = {
+	[0] = &pll1_div2_clk,
+	[1] = &pll2_clk,
+	[2] = &main_clk,
+	[3] = &sh73a0_extal2_clk,
+	[4] = &sh73a0_extcki_clk,
+};
+
 static struct clk div6_clks[DIV6_NR] = {
-	[DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
-	[DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
-	[DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
-	[DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, 0),
-	[DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
-	[DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
-	[DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
-	[DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
-	[DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0),
-	[DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0),
-	[DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0),
-	[DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0),
-	[DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0),
-	[DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0),
-	[DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0),
-	[DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0),
-	[DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0),
-	[DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0),
-	[DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0),
-	[DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
+	[DIV6_VCK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
+			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+	[DIV6_VCK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
+			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+	[DIV6_VCK3] = SH_CLK_DIV6_EXT(VCLKCR3, 0,
+			vck_parent, ARRAY_SIZE(vck_parent), 12, 3),
+	[DIV6_ZB1] = SH_CLK_DIV6_EXT(ZBCKCR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+	[DIV6_FLCTL] = SH_CLK_DIV6_EXT(FLCKCR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+	[DIV6_SDHI0] = SH_CLK_DIV6_EXT(SD0CKCR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+	[DIV6_SDHI1] = SH_CLK_DIV6_EXT(SD1CKCR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+	[DIV6_SDHI2] = SH_CLK_DIV6_EXT(SD2CKCR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 6, 2),
+	[DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
+	[DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 6, 1),
+	[DIV6_SUB] = SH_CLK_DIV6_EXT(SUBCKCR, 0,
+			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+	[DIV6_SPUA] = SH_CLK_DIV6_EXT(SPUACKCR, 0,
+			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+	[DIV6_SPUV] = SH_CLK_DIV6_EXT(SPUVCKCR, 0,
+			pll_extal2_parent, ARRAY_SIZE(pll_extal2_parent), 6, 2),
+	[DIV6_MSU] = SH_CLK_DIV6_EXT(MSUCKCR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+	[DIV6_HSI] = SH_CLK_DIV6_EXT(HSICKCR, 0,
+			hsi_parent, ARRAY_SIZE(hsi_parent), 6, 2),
+	[DIV6_MFG1] = SH_CLK_DIV6_EXT(MFCK1CR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+	[DIV6_MFG2] = SH_CLK_DIV6_EXT(MFCK2CR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+	[DIV6_DSIT] = SH_CLK_DIV6_EXT(DSITCKCR, 0,
+			pll_parent, ARRAY_SIZE(pll_parent), 7, 1),
+	[DIV6_DSI0P] = SH_CLK_DIV6_EXT(DSI0PCKCR, 0,
+			dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
+	[DIV6_DSI1P] = SH_CLK_DIV6_EXT(DSI1PCKCR, 0,
+			dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
 };
 
 enum { MSTP001,
@@ -387,7 +489,7 @@ void __init sh73a0_clock_init(void)
 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
 	if (!ret)
-		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+		ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
 
 	if (!ret)
 		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 834bd6c..d055d05 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -47,6 +47,8 @@ extern void sh73a0_clock_init(void);
 extern void sh73a0_pinmux_init(void);
 extern struct clk sh73a0_extal1_clk;
 extern struct clk sh73a0_extal2_clk;
+extern struct clk sh73a0_extcki_clk;
+extern struct clk sh73a0_extalr_clk;
 
 extern unsigned int sh73a0_get_core_count(void);
 extern void sh73a0_secondary_init(unsigned int cpu);
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH v2 2/3] sh: clkfwk: clock-sh7724: all div6_clks use SH_CLK_DIV6_EXT()
From: Kuninori Morimoto @ 2011-12-06  6:28 UTC (permalink / raw)
  To: linux-sh

Current div6 clocks can specify their current parent clocks
from its register value if it is registered
by sh_clk_div6_reparent_register().
This patch modifies all div6 clocks into SH_CLK_DIV6_EXT().

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2

- normal SH_CLK_DIV6_EXT() macro
- drop un-needed NULL from clock parent table, and add array size in table

 arch/sh/include/cpu-sh4/cpu/sh7724.h   |    1 +
 arch/sh/kernel/cpu/sh4a/clock-sh7724.c |   40 ++++++++++++++++++++------------
 2 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h
index cbc47e6..36ce466 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7724.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h
@@ -314,5 +314,6 @@ enum {
 
 extern struct clk sh7724_fsimcka_clk;
 extern struct clk sh7724_fsimckb_clk;
+extern struct clk sh7724_dv_clki;
 
 #endif /* __ASM_SH7724_H__ */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index 7711838..9ee4b36 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -111,13 +111,16 @@ static struct clk div3_clk = {
 	.parent		= &pll_clk,
 };
 
-/* External input clock (pin name: FSIMCKA/FSIMCKB ) */
+/* External input clock (pin name: FSIMCKA/FSIMCKB/DV_CLKI ) */
 struct clk sh7724_fsimcka_clk = {
 };
 
 struct clk sh7724_fsimckb_clk = {
 };
 
+struct clk sh7724_dv_clki = {
+};
+
 static struct clk *main_clks[] = {
 	&r_clk,
 	&extal_clk,
@@ -126,6 +129,7 @@ static struct clk *main_clks[] = {
 	&div3_clk,
 	&sh7724_fsimcka_clk,
 	&sh7724_fsimckb_clk,
+	&sh7724_dv_clki,
 };
 
 static void div4_kick(struct clk *clk)
@@ -163,17 +167,20 @@ struct clk div4_clks[DIV4_NR] = {
 	[DIV4_M1] = DIV4(FRQCRB, 4, 0x2f7c, CLK_ENABLE_ON_INIT),
 };
 
-enum { DIV6_V, DIV6_I, DIV6_S, DIV6_NR };
+enum { DIV6_V, DIV6_I, DIV6_S, DIV6_FA, DIV6_FB, DIV6_NR };
 
-static struct clk div6_clks[DIV6_NR] = {
-	[DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
-	[DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0),
-	[DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
+/* Indices are important - they are the actual src selecting values */
+static struct clk *common_parent[] = {
+	[0] = &div3_clk,
+	[1] = NULL,
 };
 
-enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR };
+static struct clk *vclkcr_parent[8] = {
+	[0] = &div3_clk,
+	[2] = &sh7724_dv_clki,
+	[4] = &extal_clk,
+};
 
-/* Indices are important - they are the actual src selecting values */
 static struct clk *fclkacr_parent[] = {
 	[0] = &div3_clk,
 	[1] = NULL,
@@ -188,7 +195,13 @@ static struct clk *fclkbcr_parent[] = {
 	[3] = NULL,
 };
 
-static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+static struct clk div6_clks[DIV6_NR] = {
+	[DIV6_V] = SH_CLK_DIV6_EXT(VCLKCR, 0,
+			vclkcr_parent, ARRAY_SIZE(vclkcr_parent), 12, 3),
+	[DIV6_I] = SH_CLK_DIV6_EXT(IRDACLKCR, 0,
+			common_parent, ARRAY_SIZE(common_parent), 6, 1),
+	[DIV6_S] = SH_CLK_DIV6_EXT(SPUCLKCR, CLK_ENABLE_ON_INIT,
+			common_parent, ARRAY_SIZE(common_parent), 6, 1),
 	[DIV6_FA] = SH_CLK_DIV6_EXT(FCLKACR, 0,
 				      fclkacr_parent, ARRAY_SIZE(fclkacr_parent), 6, 2),
 	[DIV6_FB] = SH_CLK_DIV6_EXT(FCLKBCR, 0,
@@ -269,8 +282,8 @@ static struct clk_lookup lookups[] = {
 
 	/* DIV6 clocks */
 	CLKDEV_CON_ID("video_clk", &div6_clks[DIV6_V]),
-	CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FA]),
-	CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FB]),
+	CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FA]),
+	CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FB]),
 	CLKDEV_CON_ID("irda_clk", &div6_clks[DIV6_I]),
 	CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_S]),
 
@@ -356,10 +369,7 @@ int __init arch_clk_init(void)
 		ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
 
 	if (!ret)
-		ret = sh_clk_div6_register(div6_clks, DIV6_NR);
-
-	if (!ret)
-		ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
+		ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
 
 	if (!ret)
 		ret = sh_hwblk_clk_register(mstp_clks, HWBLK_NR);
-- 
1.7.5.4


^ permalink raw reply related

* [PATCH v2 1/3] sh: clock-sh7723: add CLKDEV_ICK_ID for cleanup
From: Kuninori Morimoto @ 2011-12-06  6:26 UTC (permalink / raw)
  To: linux-sh

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
v1 -> v2

- same as v1

 arch/sh/kernel/cpu/sh4a/clock-sh7723.c |   76 +++++--------------------------
 1 files changed, 13 insertions(+), 63 deletions(-)

diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
index 3cc3827..f254166 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7723.c
@@ -233,73 +233,10 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("sh0", &mstp_clks[HWBLK_SHYWAY]),
 	CLKDEV_CON_ID("hudi0", &mstp_clks[HWBLK_HUDI]),
 	CLKDEV_CON_ID("ubc0", &mstp_clks[HWBLK_UBC]),
-	{
-		/* TMU0 */
-		.dev_id		= "sh_tmu.0",
-		.con_id		= "tmu_fck",
-		.clk		= &mstp_clks[HWBLK_TMU0],
-	}, {
-		/* TMU1 */
-		.dev_id		= "sh_tmu.1",
-		.con_id		= "tmu_fck",
-		.clk		= &mstp_clks[HWBLK_TMU0],
-	}, {
-		/* TMU2 */
-		.dev_id		= "sh_tmu.2",
-		.con_id		= "tmu_fck",
-		.clk		= &mstp_clks[HWBLK_TMU0],
-	},
 	CLKDEV_CON_ID("cmt_fck", &mstp_clks[HWBLK_CMT]),
 	CLKDEV_CON_ID("rwdt0", &mstp_clks[HWBLK_RWDT]),
 	CLKDEV_CON_ID("dmac1", &mstp_clks[HWBLK_DMAC1]),
-	{
-		/* TMU3 */
-		.dev_id		= "sh_tmu.3",
-		.con_id		= "tmu_fck",
-		.clk		= &mstp_clks[HWBLK_TMU1],
-	}, {
-		/* TMU4 */
-		.dev_id		= "sh_tmu.4",
-		.con_id		= "tmu_fck",
-		.clk		= &mstp_clks[HWBLK_TMU1],
-	}, {
-		/* TMU5 */
-		.dev_id		= "sh_tmu.5",
-		.con_id		= "tmu_fck",
-		.clk		= &mstp_clks[HWBLK_TMU1],
-	},
 	CLKDEV_CON_ID("flctl0", &mstp_clks[HWBLK_FLCTL]),
-	{
-		/* SCIF0 */
-		.dev_id		= "sh-sci.0",
-		.con_id		= "sci_fck",
-		.clk		= &mstp_clks[HWBLK_SCIF0],
-	}, {
-		/* SCIF1 */
-		.dev_id		= "sh-sci.1",
-		.con_id		= "sci_fck",
-		.clk		= &mstp_clks[HWBLK_SCIF1],
-	}, {
-		/* SCIF2 */
-		.dev_id		= "sh-sci.2",
-		.con_id		= "sci_fck",
-		.clk		= &mstp_clks[HWBLK_SCIF2],
-	}, {
-		/* SCIF3 */
-		.dev_id		= "sh-sci.3",
-		.con_id		= "sci_fck",
-		.clk		= &mstp_clks[HWBLK_SCIF3],
-	}, {
-		/* SCIF4 */
-		.dev_id		= "sh-sci.4",
-		.con_id		= "sci_fck",
-		.clk		= &mstp_clks[HWBLK_SCIF4],
-	}, {
-		/* SCIF5 */
-		.dev_id		= "sh-sci.5",
-		.con_id		= "sci_fck",
-		.clk		= &mstp_clks[HWBLK_SCIF5],
-	},
 	CLKDEV_CON_ID("msiof0", &mstp_clks[HWBLK_MSIOF0]),
 	CLKDEV_CON_ID("msiof1", &mstp_clks[HWBLK_MSIOF1]),
 	CLKDEV_CON_ID("meram0", &mstp_clks[HWBLK_MERAM]),
@@ -324,6 +261,19 @@ static struct clk_lookup lookups[] = {
 	CLKDEV_CON_ID("veu0", &mstp_clks[HWBLK_VEU2H0]),
 	CLKDEV_CON_ID("vpu0", &mstp_clks[HWBLK_VPU]),
 	CLKDEV_CON_ID("lcdc0", &mstp_clks[HWBLK_LCDC]),
+
+	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[HWBLK_TMU0]),
+	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[HWBLK_TMU0]),
+	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[HWBLK_TMU0]),
+	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[HWBLK_TMU1]),
+	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[HWBLK_TMU1]),
+	CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[HWBLK_TMU1]),
+	CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[HWBLK_SCIF0]),
+	CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[HWBLK_SCIF1]),
+	CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[HWBLK_SCIF2]),
+	CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[HWBLK_SCIF3]),
+	CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[HWBLK_SCIF4]),
+	CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[HWBLK_SCIF5]),
 };
 
 int __init arch_clk_init(void)
-- 
1.7.5.4


^ permalink raw reply related

* Re: [PATCH v2 0/4] sh: div6 clock update for paul/common/clkfwk
From: kuninori.morimoto.gx @ 2011-12-06  6:25 UTC (permalink / raw)
  To: linux-sh


Hi Paul, Magnus

These are v2 div6 clock update patch set for paul/common/clkfwk

Kuninori Morimoto (3):
       sh: clock-sh7723: add CLKDEV_ICK_ID for cleanup
       sh: clock-sh7724: all div6_clks use SH_CLK_DIV6_EXT()
       sh: clock-sh73a0: all div6_clks use SH_CLK_DIV6_EXT()
 
v1 -> v2

drop "sh: modify SH_CLK_DIV6_EXT macro parameter" patch.

^ permalink raw reply

* Re: [PATCH 3/4] sh: clock-sh7724: all div6_clks use SH_CLK_DIV6_EXT()
From: Paul Mundt @ 2011-12-06  5:51 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <8739cz8rfx.wl%kuninori.morimoto.gx@renesas.com>

On Mon, Dec 05, 2011 at 09:47:17PM -0800, Kuninori Morimoto wrote:
> > On Sun, Dec 04, 2011 at 10:26:30PM -0800, Kuninori Morimoto wrote:
> > > -static struct clk div6_clks[DIV6_NR] = {
> > > -	[DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
> > > -	[DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0),
> > > -	[DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
> > > +/* Indices are important - they are the actual src selecting values */
> > > +static struct clk *common_parent[] = {
> > > +	[0] = &div3_clk,
> > > +	[1] = NULL,
> > >  };
> > >  
> > > -enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR };
> > > +static struct clk *vclkcr_parent[] = {
> > > +	[0] = &div3_clk,
> > > +	[1] = NULL,
> > > +	[2] = &sh7724_dv_clki,
> > > +	[3] = NULL,
> > > +	[4] = &extal_clk,
> > > +	[5] = NULL,
> > > +	[6] = NULL,
> > > +	[7] = NULL,
> > > +};
> > >  
> > You don't really need any of these NULL initializers, they can all be
> > dropped.
> 
> Hmm...
> Then, I can not use ARRAY_SIZE(vclkcr_parent) ?
> 
You can just initialize the array size. There's nothing wrong with having
a vclkcr_parent[8] or some _NR define to that extent as part of the
initializer, even if you're just partially initializing the elements.

^ permalink raw reply

* Re: [PATCH 3/4] sh: clock-sh7724: all div6_clks use SH_CLK_DIV6_EXT()
From: Kuninori Morimoto @ 2011-12-06  5:47 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <8739cz8rfx.wl%kuninori.morimoto.gx@renesas.com>


Hi Paul

> On Sun, Dec 04, 2011 at 10:26:30PM -0800, Kuninori Morimoto wrote:
> > -static struct clk div6_clks[DIV6_NR] = {
> > -	[DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0),
> > -	[DIV6_I] = SH_CLK_DIV6(&div3_clk, IRDACLKCR, 0),
> > -	[DIV6_S] = SH_CLK_DIV6(&div3_clk, SPUCLKCR, CLK_ENABLE_ON_INIT),
> > +/* Indices are important - they are the actual src selecting values */
> > +static struct clk *common_parent[] = {
> > +	[0] = &div3_clk,
> > +	[1] = NULL,
> >  };
> >  
> > -enum { DIV6_FA, DIV6_FB, DIV6_REPARENT_NR };
> > +static struct clk *vclkcr_parent[] = {
> > +	[0] = &div3_clk,
> > +	[1] = NULL,
> > +	[2] = &sh7724_dv_clki,
> > +	[3] = NULL,
> > +	[4] = &extal_clk,
> > +	[5] = NULL,
> > +	[6] = NULL,
> > +	[7] = NULL,
> > +};
> >  
> You don't really need any of these NULL initializers, they can all be
> dropped.

Hmm...
Then, I can not use ARRAY_SIZE(vclkcr_parent) ?

Best regards
---
Kuninori Morimoto

^ permalink raw reply

* Re: [PATCH 2/4] sh: modify SH_CLK_DIV6_EXT macro parameter
From: Kuninori Morimoto @ 2011-12-06  5:38 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <874nxf8rgh.wl%kuninori.morimoto.gx@renesas.com>


Hi Paul

Thank you for checking patch

> On Sun, Dec 04, 2011 at 10:26:09PM -0800, Kuninori Morimoto wrote:
> > array size which can be calculated from specific table was removed,
> > and the "flags" which can use CLK_ENABLE_ON_INIT became last parameter.
> > 
> > Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> 
> It can, but no, I don't really like these sorts of changes. From a usage
> point of view it might look more straightforward but in reality it's just
> pushing down complexity in to the macro that's non-obvious without
> manually going and looking at the macro definition.
> 
> Saving a bit of screen real-estate isn't worth the hassle of having to
> track down macro definitions to find out what exactly they're doing.

OK. I understand.
I re-send v2 patch.

Best regards
---
Kuninori Morimoto

^ permalink raw reply

* Re: [PATCH 4/4] sh: clock-sh73a0: all div6_clks use SH_CLK_DIV6_EXT()
From: Paul Mundt @ 2011-12-06  5:26 UTC (permalink / raw)
  To: linux-sh
In-Reply-To: <871usj8r6b.wl%kuninori.morimoto.gx@renesas.com>

On Sun, Dec 04, 2011 at 10:32:16PM -0800, Kuninori Morimoto wrote:
> Current div6 clocks can specify their current parent clocks
> from its register value if it is registered
> by sh_clk_div6_reparent_register().
> This patch modifies all div6 clocks into SH_CLK_DIV6_EXT().
> 
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>

This one looks fine too, although it will need to be respun to not depend
on 2/4.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox