All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/17] sh: LANDISK convert to device tree
@ 2016-06-12  6:54 ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

SH get devicetree support. But it not working on existing H/W.

IO-DATA HDL-U (aka landisk) currentry supported.
This H/W like SH7751 evalution board. It's a best to use this as a
change base H/W.

Changes V2
- split DeviceTree suppoty update.
- PCI driver update.
- Some cleanup.

Yoshinori Sato (17):
  sh: Add sh-specific early_init_dt_reserve_memory_arch
  sh: More early unflatten device tree
  sh: set preset_lpj
  sh: Use P1SEGADDR
  sh: command line passing chosen/bootargs in devicetree
  sh: FDT address save before bank change
  sh: Passing FDT address on zImage
  sh: Disable board specific code on device tree mode
  sh: Use GENERIC_IOMAP on device tree mode
  sh: convert generic drivers framework
  sh: SH7750/51 clock driver
  sh: Add PCI host bridge driver for SH7751
  sh: Add PCI definetion
  sh: SH3/4 Generic IRQCHIP driever
  sh: SH-INTC helper files
  sh: I/O DATA HDL-U (a.k.a. landisk) Device Tree
  sh: landisk CPLD interrupt controller driver

 .../bindings/clock/renesas,sh7750-div-clock.txt    |  27 ++
 .../bindings/clock/renesas,sh7750-pll-clock.txt    |  26 ++
 .../interrupt-controller/iodata-landisk.txt        |  28 ++
 .../interrupt-controller/renesas,sh7751-intc.txt   |  25 ++
 .../devicetree/bindings/pci/sh7751-pci.txt         |  51 +++
 arch/sh/Kconfig                                    |   6 +-
 arch/sh/Makefile                                   |   2 +
 arch/sh/boards/Kconfig                             |   4 +
 arch/sh/boards/of-generic.c                        |  24 +-
 arch/sh/boot/compressed/head_32.S                  |   5 +-
 arch/sh/boot/dts/include/dt-bindings               |   1 +
 arch/sh/boot/dts/landisk.dts                       | 150 +++++++
 arch/sh/drivers/Makefile                           |   2 +
 arch/sh/include/asm/io.h                           |   6 +
 arch/sh/kernel/cpu/Makefile                        |   8 +-
 arch/sh/kernel/cpu/clock.c                         |   6 +-
 arch/sh/kernel/cpu/sh4/Makefile                    |   2 +
 arch/sh/kernel/head_32.S                           |   7 +-
 arch/sh/kernel/setup.c                             |  16 +-
 drivers/clk/Kconfig                                |   1 +
 drivers/clk/Makefile                               |   3 +-
 drivers/clk/sh/Kconfig                             |   2 +
 drivers/clk/sh/Makefile                            |   2 +
 drivers/clk/sh/clk-sh7750.c                        | 240 +++++++++++
 drivers/clk/sh/clk-shdiv.c                         | 344 ++++++++++++++++
 drivers/clk/sh/clk-shdiv.h                         |  16 +
 drivers/irqchip/Kconfig                            |   5 +
 drivers/irqchip/Makefile                           |   1 +
 drivers/irqchip/irq-io-landisk.c                   |  72 ++++
 drivers/irqchip/irq-renesas-sh7751.c               | 141 +++++++
 drivers/pci/host/Kconfig                           |   7 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-sh7751.c                      | 443 +++++++++++++++++++++
 include/dt-bindings/interrupt-controller/sh_intc.h |   2 +
 34 files changed, 1656 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
 create mode 100644 Documentation/devicetree/bindings/pci/sh7751-pci.txt
 create mode 120000 arch/sh/boot/dts/include/dt-bindings
 create mode 100644 arch/sh/boot/dts/landisk.dts
 create mode 100644 drivers/clk/sh/Kconfig
 create mode 100644 drivers/clk/sh/Makefile
 create mode 100644 drivers/clk/sh/clk-sh7750.c
 create mode 100644 drivers/clk/sh/clk-shdiv.c
 create mode 100644 drivers/clk/sh/clk-shdiv.h
 create mode 100644 drivers/irqchip/irq-io-landisk.c
 create mode 100644 drivers/irqchip/irq-renesas-sh7751.c
 create mode 100644 drivers/pci/host/pci-sh7751.c
 create mode 100644 include/dt-bindings/interrupt-controller/sh_intc.h

-- 
2.7.0


^ permalink raw reply	[flat|nested] 68+ messages in thread

* [PATCH v2 00/17] sh: LANDISK convert to device tree
@ 2016-06-12  6:54 ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

SH get devicetree support. But it not working on existing H/W.

IO-DATA HDL-U (aka landisk) currentry supported.
This H/W like SH7751 evalution board. It's a best to use this as a
change base H/W.

Changes V2
- split DeviceTree suppoty update.
- PCI driver update.
- Some cleanup.

Yoshinori Sato (17):
  sh: Add sh-specific early_init_dt_reserve_memory_arch
  sh: More early unflatten device tree
  sh: set preset_lpj
  sh: Use P1SEGADDR
  sh: command line passing chosen/bootargs in devicetree
  sh: FDT address save before bank change
  sh: Passing FDT address on zImage
  sh: Disable board specific code on device tree mode
  sh: Use GENERIC_IOMAP on device tree mode
  sh: convert generic drivers framework
  sh: SH7750/51 clock driver
  sh: Add PCI host bridge driver for SH7751
  sh: Add PCI definetion
  sh: SH3/4 Generic IRQCHIP driever
  sh: SH-INTC helper files
  sh: I/O DATA HDL-U (a.k.a. landisk) Device Tree
  sh: landisk CPLD interrupt controller driver

 .../bindings/clock/renesas,sh7750-div-clock.txt    |  27 ++
 .../bindings/clock/renesas,sh7750-pll-clock.txt    |  26 ++
 .../interrupt-controller/iodata-landisk.txt        |  28 ++
 .../interrupt-controller/renesas,sh7751-intc.txt   |  25 ++
 .../devicetree/bindings/pci/sh7751-pci.txt         |  51 +++
 arch/sh/Kconfig                                    |   6 +-
 arch/sh/Makefile                                   |   2 +
 arch/sh/boards/Kconfig                             |   4 +
 arch/sh/boards/of-generic.c                        |  24 +-
 arch/sh/boot/compressed/head_32.S                  |   5 +-
 arch/sh/boot/dts/include/dt-bindings               |   1 +
 arch/sh/boot/dts/landisk.dts                       | 150 +++++++
 arch/sh/drivers/Makefile                           |   2 +
 arch/sh/include/asm/io.h                           |   6 +
 arch/sh/kernel/cpu/Makefile                        |   8 +-
 arch/sh/kernel/cpu/clock.c                         |   6 +-
 arch/sh/kernel/cpu/sh4/Makefile                    |   2 +
 arch/sh/kernel/head_32.S                           |   7 +-
 arch/sh/kernel/setup.c                             |  16 +-
 drivers/clk/Kconfig                                |   1 +
 drivers/clk/Makefile                               |   3 +-
 drivers/clk/sh/Kconfig                             |   2 +
 drivers/clk/sh/Makefile                            |   2 +
 drivers/clk/sh/clk-sh7750.c                        | 240 +++++++++++
 drivers/clk/sh/clk-shdiv.c                         | 344 ++++++++++++++++
 drivers/clk/sh/clk-shdiv.h                         |  16 +
 drivers/irqchip/Kconfig                            |   5 +
 drivers/irqchip/Makefile                           |   1 +
 drivers/irqchip/irq-io-landisk.c                   |  72 ++++
 drivers/irqchip/irq-renesas-sh7751.c               | 141 +++++++
 drivers/pci/host/Kconfig                           |   7 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-sh7751.c                      | 443 +++++++++++++++++++++
 include/dt-bindings/interrupt-controller/sh_intc.h |   2 +
 34 files changed, 1656 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
 create mode 100644 Documentation/devicetree/bindings/pci/sh7751-pci.txt
 create mode 120000 arch/sh/boot/dts/include/dt-bindings
 create mode 100644 arch/sh/boot/dts/landisk.dts
 create mode 100644 drivers/clk/sh/Kconfig
 create mode 100644 drivers/clk/sh/Makefile
 create mode 100644 drivers/clk/sh/clk-sh7750.c
 create mode 100644 drivers/clk/sh/clk-shdiv.c
 create mode 100644 drivers/clk/sh/clk-shdiv.h
 create mode 100644 drivers/irqchip/irq-io-landisk.c
 create mode 100644 drivers/irqchip/irq-renesas-sh7751.c
 create mode 100644 drivers/pci/host/pci-sh7751.c
 create mode 100644 include/dt-bindings/interrupt-controller/sh_intc.h

-- 
2.7.0

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [PATCH v2 01/17] sh: Add sh-specific early_init_dt_reserve_memory_arch
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

sh used P1 address space in early device tree.
So need convert P1 to physical address before reserve memory.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/of-generic.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
index 57d45dc..fe2d917 100644
--- a/arch/sh/boards/of-generic.c
+++ b/arch/sh/boards/of-generic.c
@@ -15,6 +15,7 @@
 #include <linux/clocksource.h>
 #include <linux/irqchip.h>
 #include <linux/clk-provider.h>
+#include <linux/memblock.h>
 #include <asm/machvec.h>
 #include <asm/rtc.h>
 
@@ -203,3 +204,14 @@ static int __init sh_of_device_init(void)
 	return 0;
 }
 arch_initcall_sync(sh_of_device_init);
+
+int __init early_init_dt_reserve_memory_arch(phys_addr_t base,
+					     phys_addr_t size, bool nomap)
+{
+	if (nomap)
+		return memblock_remove(base, size);
+
+	if (base >= P1SEG)
+		base = base & ~P1SEG;
+	return memblock_reserve(base, size);
+}
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 01/17] sh: Add sh-specific early_init_dt_reserve_memory_arch
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

sh used P1 address space in early device tree.
So need convert P1 to physical address before reserve memory.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/of-generic.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
index 57d45dc..fe2d917 100644
--- a/arch/sh/boards/of-generic.c
+++ b/arch/sh/boards/of-generic.c
@@ -15,6 +15,7 @@
 #include <linux/clocksource.h>
 #include <linux/irqchip.h>
 #include <linux/clk-provider.h>
+#include <linux/memblock.h>
 #include <asm/machvec.h>
 #include <asm/rtc.h>
 
@@ -203,3 +204,14 @@ static int __init sh_of_device_init(void)
 	return 0;
 }
 arch_initcall_sync(sh_of_device_init);
+
+int __init early_init_dt_reserve_memory_arch(phys_addr_t base,
+					     phys_addr_t size, bool nomap)
+{
+	if (nomap)
+		return memblock_remove(base, size);
+
+	if (base >= P1SEG)
+		base = base & ~P1SEG;
+	return memblock_reserve(base, size);
+}
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 02/17] sh: More early unflatten device tree
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

unflatten required MMU disabled.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/of-generic.c | 6 ------
 arch/sh/kernel/setup.c      | 7 +++++++
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
index fe2d917..d24bc02 100644
--- a/arch/sh/boards/of-generic.c
+++ b/arch/sh/boards/of-generic.c
@@ -129,12 +129,6 @@ static void __init sh_of_setup(char **cmdline_p)
 {
 	struct device_node *root;
 
-#ifdef CONFIG_USE_BUILTIN_DTB
-	unflatten_and_copy_device_tree();
-#else
-	unflatten_device_tree();
-#endif
-
 	board_time_init = sh_of_time_init;
 
 	sh_mv.mv_name = "Unknown SH model";
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 5b9eb70..86f2792 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -271,6 +271,13 @@ void __ref sh_fdt_init(phys_addr_t dt_phys)
 
 void __init setup_arch(char **cmdline_p)
 {
+#ifdef CONFIG_OF
+#ifdef CONFIG_USE_BUILTIN_DTB
+	unflatten_and_copy_device_tree();
+#else
+	unflatten_device_tree();
+#endif
+#endif
 	enable_mmu();
 
 	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 02/17] sh: More early unflatten device tree
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

unflatten required MMU disabled.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/of-generic.c | 6 ------
 arch/sh/kernel/setup.c      | 7 +++++++
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
index fe2d917..d24bc02 100644
--- a/arch/sh/boards/of-generic.c
+++ b/arch/sh/boards/of-generic.c
@@ -129,12 +129,6 @@ static void __init sh_of_setup(char **cmdline_p)
 {
 	struct device_node *root;
 
-#ifdef CONFIG_USE_BUILTIN_DTB
-	unflatten_and_copy_device_tree();
-#else
-	unflatten_device_tree();
-#endif
-
 	board_time_init = sh_of_time_init;
 
 	sh_mv.mv_name = "Unknown SH model";
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 5b9eb70..86f2792 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -271,6 +271,13 @@ void __ref sh_fdt_init(phys_addr_t dt_phys)
 
 void __init setup_arch(char **cmdline_p)
 {
+#ifdef CONFIG_OF
+#ifdef CONFIG_USE_BUILTIN_DTB
+	unflatten_and_copy_device_tree();
+#else
+	unflatten_device_tree();
+#endif
+#endif
 	enable_mmu();
 
 	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 03/17] sh: set preset_lpj
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Generic callibrate delay required this value.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/of-generic.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
index d24bc02..e2b4d98 100644
--- a/arch/sh/boards/of-generic.c
+++ b/arch/sh/boards/of-generic.c
@@ -128,6 +128,8 @@ static void __init sh_of_time_init(void)
 static void __init sh_of_setup(char **cmdline_p)
 {
 	struct device_node *root;
+	struct device_node *cpu;
+	u32 freq;
 
 	board_time_init = sh_of_time_init;
 
@@ -139,6 +141,10 @@ static void __init sh_of_setup(char **cmdline_p)
 	}
 
 	sh_of_smp_probe();
+
+	cpu = of_find_node_by_name(NULL, "cpu");
+	if (!of_property_read_u32(cpu, "clock-frequency", &freq))
+		preset_lpj = freq / CONFIG_HZ / 2;
 }
 
 static int sh_of_irq_demux(int irq)
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 03/17] sh: set preset_lpj
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Generic callibrate delay required this value.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/of-generic.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
index d24bc02..e2b4d98 100644
--- a/arch/sh/boards/of-generic.c
+++ b/arch/sh/boards/of-generic.c
@@ -128,6 +128,8 @@ static void __init sh_of_time_init(void)
 static void __init sh_of_setup(char **cmdline_p)
 {
 	struct device_node *root;
+	struct device_node *cpu;
+	u32 freq;
 
 	board_time_init = sh_of_time_init;
 
@@ -139,6 +141,10 @@ static void __init sh_of_setup(char **cmdline_p)
 	}
 
 	sh_of_smp_probe();
+
+	cpu = of_find_node_by_name(NULL, "cpu");
+	if (!of_property_read_u32(cpu, "clock-frequency", &freq))
+		preset_lpj = freq / CONFIG_HZ / 2;
 }
 
 static int sh_of_irq_demux(int irq)
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 04/17] sh: Use P1SEGADDR
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

FDT address is P1SEG. So not virtual address.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/kernel/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 86f2792..8e3b099 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -254,7 +254,7 @@ void __ref sh_fdt_init(phys_addr_t dt_phys)
 #ifdef CONFIG_USE_BUILTIN_DTB
 	dt_virt = __dtb_start;
 #else
-	dt_virt = phys_to_virt(dt_phys);
+	dt_virt = (void *)P1SEGADDR(dt_phys);
 #endif
 
 	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 04/17] sh: Use P1SEGADDR
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

FDT address is P1SEG. So not virtual address.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/kernel/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 86f2792..8e3b099 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -254,7 +254,7 @@ void __ref sh_fdt_init(phys_addr_t dt_phys)
 #ifdef CONFIG_USE_BUILTIN_DTB
 	dt_virt = __dtb_start;
 #else
-	dt_virt = phys_to_virt(dt_phys);
+	dt_virt = (void *)P1SEGADDR(dt_phys);
 #endif
 
 	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 05/17] sh: command line passing chosen/bootargs in devicetree
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/kernel/setup.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 8e3b099..d97de16 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -280,6 +280,8 @@ void __init setup_arch(char **cmdline_p)
 #endif
 	enable_mmu();
 
+
+#ifndef CONFIG_OF
 	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
 
 	printk(KERN_NOTICE "Boot params:\n"
@@ -301,6 +303,7 @@ void __init setup_arch(char **cmdline_p)
 
 	if (!MOUNT_ROOT_RDONLY)
 		root_mountflags &= ~MS_RDONLY;
+#endif
 	init_mm.start_code = (unsigned long) _text;
 	init_mm.end_code = (unsigned long) _etext;
 	init_mm.end_data = (unsigned long) _edata;
@@ -323,9 +326,13 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #endif
 
+#if !defined(CONFIG_OF) || defined(USE_BUILTIN_DTB)
 	/* Save unparsed command line copy for /proc/cmdline */
 	memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
 	*cmdline_p = command_line;
+#else
+	*cmdline_p = boot_command_line;
+#endif
 
 	parse_early_param();
 
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 05/17] sh: command line passing chosen/bootargs in devicetree
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/kernel/setup.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 8e3b099..d97de16 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -280,6 +280,8 @@ void __init setup_arch(char **cmdline_p)
 #endif
 	enable_mmu();
 
+
+#ifndef CONFIG_OF
 	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
 
 	printk(KERN_NOTICE "Boot params:\n"
@@ -301,6 +303,7 @@ void __init setup_arch(char **cmdline_p)
 
 	if (!MOUNT_ROOT_RDONLY)
 		root_mountflags &= ~MS_RDONLY;
+#endif
 	init_mm.start_code = (unsigned long) _text;
 	init_mm.end_code = (unsigned long) _etext;
 	init_mm.end_data = (unsigned long) _edata;
@@ -323,9 +326,13 @@ void __init setup_arch(char **cmdline_p)
 #endif
 #endif
 
+#if !defined(CONFIG_OF) || defined(USE_BUILTIN_DTB)
 	/* Save unparsed command line copy for /proc/cmdline */
 	memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
 	*cmdline_p = command_line;
+#else
+	*cmdline_p = boot_command_line;
+#endif
 
 	parse_early_param();
 
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 06/17] sh: FDT address save before bank change
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

SH3/4 have register bank of R0-R7.
Preset FDT address assigned bank depend on boot loader.
Before setting a bank because we don't depend on a boot loader, it's evacuated.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/kernel/head_32.S | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index 974bc15..fbf5f84 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -58,6 +58,9 @@ ENTRY(empty_zero_page)
  *
  */
 ENTRY(_stext)
+#ifdef CONFIG_OF
+	mov	r4, r12		! Store device tree blob pointer in r12
+#endif
 	!			Initialize Status Register
 	mov.l	1f, r0		! MD=1, RB=0, BL=0, IMASK=0xF
 	ldc	r0, sr
@@ -67,10 +70,6 @@ ENTRY(_stext)
 	ldc	r0, r6_bank
 #endif
 
-#ifdef CONFIG_OF
-	mov	r4, r12		! Store device tree blob pointer in r12
-#endif
-	
 	/*
 	 * Prefetch if possible to reduce cache miss penalty.
 	 *
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 06/17] sh: FDT address save before bank change
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

SH3/4 have register bank of R0-R7.
Preset FDT address assigned bank depend on boot loader.
Before setting a bank because we don't depend on a boot loader, it's evacuated.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/kernel/head_32.S | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S
index 974bc15..fbf5f84 100644
--- a/arch/sh/kernel/head_32.S
+++ b/arch/sh/kernel/head_32.S
@@ -58,6 +58,9 @@ ENTRY(empty_zero_page)
  *
  */
 ENTRY(_stext)
+#ifdef CONFIG_OF
+	mov	r4, r12		! Store device tree blob pointer in r12
+#endif
 	!			Initialize Status Register
 	mov.l	1f, r0		! MD=1, RB=0, BL=0, IMASK=0xF
 	ldc	r0, sr
@@ -67,10 +70,6 @@ ENTRY(_stext)
 	ldc	r0, r6_bank
 #endif
 
-#ifdef CONFIG_OF
-	mov	r4, r12		! Store device tree blob pointer in r12
-#endif
-	
 	/*
 	 * Prefetch if possible to reduce cache miss penalty.
 	 *
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 07/17] sh: Passing FDT address on zImage
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boot/compressed/head_32.S | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S
index 3e15032..ef70454 100644
--- a/arch/sh/boot/compressed/head_32.S
+++ b/arch/sh/boot/compressed/head_32.S
@@ -11,10 +11,11 @@
 
 	.global	startup
 startup:
+	/* Save FDT address */
+	mov	r4, r13
 	/* Load initial status register */
 	mov.l   init_sr, r1
 	ldc     r1, sr
-
 	/* Move myself to proper location if necessary */
 	mova	1f, r0
 	mov.l	1f, r2
@@ -83,7 +84,7 @@ l1:
 	/* Jump to the start of the decompressed kernel */
 	mov.l	kernel_start_addr, r0
 	jmp	@r0
-	nop
+	  mov	r13,r4
 	
 	.align	2
 bss_start_addr:
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 07/17] sh: Passing FDT address on zImage
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boot/compressed/head_32.S | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S
index 3e15032..ef70454 100644
--- a/arch/sh/boot/compressed/head_32.S
+++ b/arch/sh/boot/compressed/head_32.S
@@ -11,10 +11,11 @@
 
 	.global	startup
 startup:
+	/* Save FDT address */
+	mov	r4, r13
 	/* Load initial status register */
 	mov.l   init_sr, r1
 	ldc     r1, sr
-
 	/* Move myself to proper location if necessary */
 	mova	1f, r0
 	mov.l	1f, r2
@@ -83,7 +84,7 @@ l1:
 	/* Jump to the start of the decompressed kernel */
 	mov.l	kernel_start_addr, r0
 	jmp	@r0
-	nop
+	  mov	r13,r4
 	
 	.align	2
 bss_start_addr:
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 08/17] sh: Disable board specific code on device tree mode
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/Makefile                | 2 ++
 arch/sh/kernel/cpu/sh4/Makefile | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 3b2c8b4..8adffa8 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -132,6 +132,7 @@ core-$(CONFIG_SH_FPU_EMU)	+= arch/sh/math-emu/
 
 core-$(CONFIG_USE_BUILTIN_DTB)	+= arch/sh/boot/dts/
 
+ifneq ($(CONFIG_SH_DEVICE_TREE),y)
 # Mach groups
 machdir-$(CONFIG_SOLUTION_ENGINE)		+= mach-se
 machdir-$(CONFIG_SH_HP6XX)			+= mach-hp6xx
@@ -152,6 +153,7 @@ machdir-$(CONFIG_SH_LANDISK)			+= mach-landisk
 machdir-$(CONFIG_SH_LBOX_RE2)			+= mach-lboxre2
 machdir-$(CONFIG_SH_CAYMAN)			+= mach-cayman
 machdir-$(CONFIG_SH_RSK)			+= mach-rsk
+endif
 
 ifneq ($(machdir-y),)
 core-y	+= $(addprefix arch/sh/boards/, \
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile
index 3a1dbc7..b822c0c 100644
--- a/arch/sh/kernel/cpu/sh4/Makefile
+++ b/arch/sh/kernel/cpu/sh4/Makefile
@@ -14,6 +14,7 @@ perf-$(CONFIG_CPU_SUBTYPE_SH7750)	:= perf_event.o
 perf-$(CONFIG_CPU_SUBTYPE_SH7750S)	:= perf_event.o
 perf-$(CONFIG_CPU_SUBTYPE_SH7091)	:= perf_event.o
 
+ifndef CONFIG_OF
 # CPU subtype setup
 obj-$(CONFIG_CPU_SUBTYPE_SH7750)	+= setup-sh7750.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7750R)	+= setup-sh7750.o
@@ -31,6 +32,7 @@ endif
 
 # Additional clocks by subtype
 clock-$(CONFIG_CPU_SUBTYPE_SH4_202)	+= clock-sh4-202.o
+endif
 
 obj-y					+= $(clock-y)
 obj-$(CONFIG_PERF_EVENTS)		+= $(perf-y)
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 08/17] sh: Disable board specific code on device tree mode
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/Makefile                | 2 ++
 arch/sh/kernel/cpu/sh4/Makefile | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 3b2c8b4..8adffa8 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -132,6 +132,7 @@ core-$(CONFIG_SH_FPU_EMU)	+= arch/sh/math-emu/
 
 core-$(CONFIG_USE_BUILTIN_DTB)	+= arch/sh/boot/dts/
 
+ifneq ($(CONFIG_SH_DEVICE_TREE),y)
 # Mach groups
 machdir-$(CONFIG_SOLUTION_ENGINE)		+= mach-se
 machdir-$(CONFIG_SH_HP6XX)			+= mach-hp6xx
@@ -152,6 +153,7 @@ machdir-$(CONFIG_SH_LANDISK)			+= mach-landisk
 machdir-$(CONFIG_SH_LBOX_RE2)			+= mach-lboxre2
 machdir-$(CONFIG_SH_CAYMAN)			+= mach-cayman
 machdir-$(CONFIG_SH_RSK)			+= mach-rsk
+endif
 
 ifneq ($(machdir-y),)
 core-y	+= $(addprefix arch/sh/boards/, \
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile
index 3a1dbc7..b822c0c 100644
--- a/arch/sh/kernel/cpu/sh4/Makefile
+++ b/arch/sh/kernel/cpu/sh4/Makefile
@@ -14,6 +14,7 @@ perf-$(CONFIG_CPU_SUBTYPE_SH7750)	:= perf_event.o
 perf-$(CONFIG_CPU_SUBTYPE_SH7750S)	:= perf_event.o
 perf-$(CONFIG_CPU_SUBTYPE_SH7091)	:= perf_event.o
 
+ifndef CONFIG_OF
 # CPU subtype setup
 obj-$(CONFIG_CPU_SUBTYPE_SH7750)	+= setup-sh7750.o
 obj-$(CONFIG_CPU_SUBTYPE_SH7750R)	+= setup-sh7750.o
@@ -31,6 +32,7 @@ endif
 
 # Additional clocks by subtype
 clock-$(CONFIG_CPU_SUBTYPE_SH4_202)	+= clock-sh4-202.o
+endif
 
 obj-y					+= $(clock-y)
 obj-$(CONFIG_PERF_EVENTS)		+= $(perf-y)
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 09/17] sh: Use GENERIC_IOMAP on device tree mode
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 5e52d53..9e4ccd0 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -12,6 +12,7 @@ config SH_DEVICE_TREE
 	select OF_EARLY_FLATTREE
 	select CLKSRC_OF
 	select GENERIC_CALIBRATE_DELAY
+	select GENERIC_IOMAP
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 09/17] sh: Use GENERIC_IOMAP on device tree mode
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 5e52d53..9e4ccd0 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -12,6 +12,7 @@ config SH_DEVICE_TREE
 	select OF_EARLY_FLATTREE
 	select CLKSRC_OF
 	select GENERIC_CALIBRATE_DELAY
+	select GENERIC_IOMAP
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 10/17] sh: convert generic drivers framework
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, linux-clk; +Cc: Yoshinori Sato

Use common PCI host framework and Common Clock Freamework.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/Kconfig      |   1 +
 arch/sh/drivers/Makefile    |   2 +
 arch/sh/kernel/cpu/Makefile |   8 +-
 arch/sh/kernel/cpu/clock.c  |   6 +-
 drivers/clk/Kconfig         |   1 +
 drivers/clk/Makefile        |   3 +-
 drivers/clk/sh/Kconfig      |   2 +
 drivers/clk/sh/Makefile     |   2 +
 drivers/clk/sh/clk-shdiv.c  | 344 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/sh/clk-shdiv.h  |  16 +++
 10 files changed, 381 insertions(+), 4 deletions(-)
 create mode 100644 drivers/clk/sh/Kconfig
 create mode 100644 drivers/clk/sh/Makefile
 create mode 100644 drivers/clk/sh/clk-shdiv.c
 create mode 100644 drivers/clk/sh/clk-shdiv.h

diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 9e4ccd0..b6ff9df 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -13,6 +13,7 @@ config SH_DEVICE_TREE
 	select CLKSRC_OF
 	select GENERIC_CALIBRATE_DELAY
 	select GENERIC_IOMAP
+	select COMMON_CLK
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile
index e13f06b..382e86f 100644
--- a/arch/sh/drivers/Makefile
+++ b/arch/sh/drivers/Makefile
@@ -4,7 +4,9 @@
 
 obj-y		+= dma/
 
+ifndef CONFIG_SH_DEVICE_TREE
 obj-$(CONFIG_PCI)		+= pci/
+endif
 obj-$(CONFIG_SUPERHYWAY)	+= superhyway/
 obj-$(CONFIG_PUSH_SWITCH)	+= push-switch.o
 obj-$(CONFIG_HEARTBEAT)		+= heartbeat.o
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index accc7ca..22ad0ee 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -16,6 +16,10 @@ obj-$(CONFIG_ARCH_SHMOBILE)	+= shmobile/
 # Common interfaces.
 
 obj-$(CONFIG_SH_ADC)		+= adc.o
+ifndef CONFIG_COMMON_CLK
 obj-$(CONFIG_SH_CLK_CPG_LEGACY)	+= clock-cpg.o
-
-obj-y	+= irq/ init.o clock.o fpu.o pfc.o proc.o
+endif
+ifndef CONFIG_GENERIC_IRQ_CHIP
+obj-y	+= irq/
+endif
+obj-y	+= init.o clock.o fpu.o pfc.o proc.o
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 4187cf4..8e66e23 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -22,13 +22,15 @@
 
 int __init clk_init(void)
 {
-	int ret;
+	int ret = 0;
 
+#ifndef CONFIG_COMMON_CLK
 	ret = arch_clk_init();
 	if (unlikely(ret)) {
 		pr_err("%s: CPU clock registration failed.\n", __func__);
 		return ret;
 	}
+#endif
 
 	if (sh_mv.mv_clk_init) {
 		ret = sh_mv.mv_clk_init();
@@ -39,11 +41,13 @@ int __init clk_init(void)
 		}
 	}
 
+#ifndef CONFIG_COMMON_CLK
 	/* Kick the child clocks.. */
 	recalculate_root_clocks();
 
 	/* Enable the necessary init clocks */
 	clk_enable_init_clocks();
+#endif
 
 	return ret;
 }
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 16f7d33..19b0cd3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -202,6 +202,7 @@ source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/samsung/Kconfig"
+source "drivers/clk/sh/Kconfig"
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/ti/Kconfig"
 
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 46869d6..c75d9c8 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -83,4 +83,5 @@ obj-$(CONFIG_COMMON_CLK_VERSATILE)	+= versatile/
 obj-$(CONFIG_X86)			+= x86/
 obj-$(CONFIG_ARCH_ZX)			+= zte/
 obj-$(CONFIG_ARCH_ZYNQ)			+= zynq/
-obj-$(CONFIG_H8300)		+= h8300/
+obj-$(CONFIG_H8300)			+= h8300/
+obj-$(CONFIG_SUPERH)			+= sh/
diff --git a/drivers/clk/sh/Kconfig b/drivers/clk/sh/Kconfig
new file mode 100644
index 0000000..89e28d8
--- /dev/null
+++ b/drivers/clk/sh/Kconfig
@@ -0,0 +1,2 @@
+config COMMON_CLK_SH7750
+	bool "Clcok driver for SH7750/SH7751"
diff --git a/drivers/clk/sh/Makefile b/drivers/clk/sh/Makefile
new file mode 100644
index 0000000..468eb9d
--- /dev/null
+++ b/drivers/clk/sh/Makefile
@@ -0,0 +1,2 @@
+obj-y += clk-shdiv.o
+obj-$(CONFIG_COMMON_CLK_SH7750) += clk-sh7750.o
\ No newline at end of file
diff --git a/drivers/clk/sh/clk-shdiv.c b/drivers/clk/sh/clk-shdiv.c
new file mode 100644
index 0000000..be19ffa
--- /dev/null
+++ b/drivers/clk/sh/clk-shdiv.c
@@ -0,0 +1,344 @@
+/*
+ * SuperH divider clock driver
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include "clk-shdiv.h"
+
+#define div_mask(width) ((1 << (width)) - 1)
+#define to_sh_clk_div(_divider)					\
+	container_of(_divider, struct sh_clk_div, divider)
+
+static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
+				      u8 width)
+{
+	unsigned int maxdiv = 0, mask = div_mask(width);
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->div > maxdiv && clkt->val <= mask)
+			maxdiv = clkt->div;
+	return maxdiv;
+}
+
+static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width)
+{
+	if (table)
+		return _get_table_maxdiv(table, width);
+	return div_mask(width) + 1;
+}
+
+static unsigned int _get_table_div(const struct clk_div_table *table,
+				   unsigned int val)
+{
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->val = val)
+			return clkt->div;
+	return 0;
+}
+
+static unsigned int _get_div(const struct clk_div_table *table,
+			     unsigned int val,  u8 width)
+{
+	if (table)
+		return _get_table_div(table, val);
+	return val + 1;
+}
+
+static unsigned int _get_table_val(const struct clk_div_table *table,
+				   unsigned int div)
+{
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->div = div)
+			return clkt->val;
+	return 0;
+}
+
+static unsigned int _get_val(const struct clk_div_table *table,
+			     unsigned int div, u8 width)
+{
+	if (table)
+		return  _get_table_val(table, div);
+	return div - 1;
+}
+
+static unsigned long sh_divider_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate,
+					 unsigned int val,
+					 const struct clk_div_table *table)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	unsigned int div;
+
+	div = _get_div(table, val, divider->width);
+
+	return DIV_ROUND_UP_ULL((u64)parent_rate, div);
+}
+
+static unsigned long sh_clk_divider_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	struct sh_clk_div *sh_div = to_sh_clk_div(divider);
+	unsigned int val;
+
+	val = sh_div->read(divider);
+
+	return sh_divider_recalc_rate(hw, parent_rate, val, divider->table);
+}
+
+static bool _is_valid_table_div(const struct clk_div_table *table,
+				unsigned int div)
+{
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->div = div)
+			return true;
+	return false;
+}
+
+static bool _is_valid_div(const struct clk_div_table *table, unsigned int div)
+{
+	if (table)
+		return _is_valid_table_div(table, div);
+	return true;
+}
+
+static int _round_up_table(const struct clk_div_table *table, int div)
+{
+	const struct clk_div_table *clkt;
+	int up = INT_MAX;
+
+	for (clkt = table; clkt->div; clkt++) {
+		if (clkt->div = div)
+			return clkt->div;
+		else if (clkt->div < div)
+			continue;
+
+		if ((clkt->div - div) < (up - div))
+			up = clkt->div;
+	}
+
+	return up;
+}
+
+static int _div_round_up(const struct clk_div_table *table,
+			 unsigned long parent_rate, unsigned long rate)
+{
+	int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
+
+	if (table)
+		div = _round_up_table(table, div);
+
+	return div;
+}
+
+static int _div_round(const struct clk_div_table *table,
+		      unsigned long parent_rate, unsigned long rate)
+{
+	return _div_round_up(table, parent_rate, rate);
+}
+
+static bool _is_best_div(unsigned long rate, unsigned long now,
+			 unsigned long best)
+{
+	return now <= rate && now > best;
+}
+
+static int _next_div(const struct clk_div_table *table, int div)
+{
+	div++;
+
+	if (table)
+		return _round_up_table(table, div);
+
+	return div;
+}
+
+static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *best_parent_rate,
+			       const struct clk_div_table *table, u8 width)
+{
+	int i, bestdiv = 0;
+	unsigned long parent_rate, best = 0, now, maxdiv;
+	unsigned long parent_rate_saved = *best_parent_rate;
+
+	if (!rate)
+		rate = 1;
+
+	maxdiv = _get_maxdiv(table, width);
+
+	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+		parent_rate = *best_parent_rate;
+		bestdiv = _div_round(table, parent_rate, rate);
+		bestdiv = bestdiv = 0 ? 1 : bestdiv;
+		bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
+		return bestdiv;
+	}
+
+	/*
+	 * The maximum divider we can use without overflowing
+	 * unsigned long in rate * i below
+	 */
+	maxdiv = min(ULONG_MAX / rate, maxdiv);
+
+	for (i = _next_div(table, 0); i <= maxdiv;
+	     i = _next_div(table, i)) {
+		if (rate * i = parent_rate_saved) {
+			/*
+			 * It's the most ideal case if the requested rate can be
+			 * divided from parent clock without needing to change
+			 * parent rate, so return the divider immediately.
+			 */
+			*best_parent_rate = parent_rate_saved;
+			return i;
+		}
+		parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
+					       rate * i);
+		now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
+		if (_is_best_div(rate, now, best)) {
+			bestdiv = i;
+			best = now;
+			*best_parent_rate = parent_rate;
+		}
+	}
+
+	if (!bestdiv) {
+		bestdiv = _get_maxdiv(table, width);
+		*best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1);
+	}
+
+	return bestdiv;
+}
+
+static long sh_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+			unsigned long *prate, const struct clk_div_table *table,
+			u8 width)
+{
+	int div;
+
+	div = clk_divider_bestdiv(hw, rate, prate, table, width);
+
+	return DIV_ROUND_UP_ULL((u64)*prate, div);
+}
+
+static long sh_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+
+	return sh_divider_round_rate(hw, rate, prate, divider->table,
+				     divider->width);
+}
+
+static int sh_divider_get_val(unsigned long rate, unsigned long parent_rate,
+			   const struct clk_div_table *table, u8 width)
+{
+	unsigned int div, value;
+
+	div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
+
+	if (!_is_valid_div(table, div))
+		return -EINVAL;
+
+	value = _get_val(table, div, width);
+
+	return min_t(unsigned int, value, div_mask(width));
+}
+
+static int sh_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	struct sh_clk_div *sh_div = to_sh_clk_div(divider);
+	unsigned int value;
+	unsigned long flags = 0;
+
+	value = sh_divider_get_val(rate, parent_rate, divider->table,
+				   divider->width);
+
+	if (divider->lock)
+		spin_lock_irqsave(divider->lock, flags);
+	else
+		__acquire(divider->lock);
+
+	sh_div->write(divider, value);
+
+	if (divider->lock)
+		spin_unlock_irqrestore(divider->lock, flags);
+	else
+		__release(divider->lock);
+
+	return 0;
+}
+
+static const struct clk_ops sh_clk_divider_ops = {
+	.recalc_rate = sh_clk_divider_recalc_rate,
+	.round_rate = sh_clk_divider_round_rate,
+	.set_rate = sh_clk_divider_set_rate,
+};
+
+static struct clk *_register_divider(struct device *dev, const char *name,
+		     const char *parent_name,
+		     void __iomem *reg, u8 shift, u8 width,
+		     const struct clk_div_table *table,
+		     spinlock_t *lock,
+		     u16 (*read)(struct clk_divider *hw),
+		     void (*write)(struct clk_divider *hw, u16 val))
+{
+	struct sh_clk_div *div;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the divider */
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &sh_clk_divider_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	/* struct clk_divider assignments */
+	div->divider.reg = reg;
+	div->divider.shift = shift;
+	div->divider.width = width;
+	div->divider.lock = lock;
+	div->divider.hw.init = &init;
+	div->divider.table = table;
+	div->read = read;
+	div->write = write;
+
+	/* register the clock */
+	clk = clk_register(dev, &div->divider.hw);
+
+	if (IS_ERR(clk))
+		kfree(div);
+
+	return clk;
+}
+
+struct clk *sh_div_clk_register(struct device *dev, const char *name,
+				const char *parent_name,
+				void __iomem *reg, u8 shift, u8 width,
+				const struct clk_div_table *table,
+				spinlock_t *lock,
+				u16 (*read)(struct clk_divider *hw),
+				void (*write)(struct clk_divider *hw, u16 val))
+{
+	return _register_divider(dev, name, parent_name, reg, shift,
+				 width, table, lock, read, write);
+}
+EXPORT_SYMBOL_GPL(sh_div_clk_register);
diff --git a/drivers/clk/sh/clk-shdiv.h b/drivers/clk/sh/clk-shdiv.h
new file mode 100644
index 0000000..ebd27df
--- /dev/null
+++ b/drivers/clk/sh/clk-shdiv.h
@@ -0,0 +1,16 @@
+/* SuperH common clock divider */
+
+struct sh_clk_div {
+	struct clk_divider divider;
+	u16 (*read)(struct clk_divider *divider);
+	void (*write)(struct clk_divider *divider, u16 val);
+};
+
+struct clk *sh_div_clk_register(struct device *dev, const char *name,
+				const char *parent_name,
+				void __iomem *reg, u8 shift, u8 width,
+				const struct clk_div_table *table,
+				spinlock_t *lock,
+				u16 (*read)(struct clk_divider *hw),
+				void (*write)(struct clk_divider *hw, u16 val));
+
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 10/17] sh: convert generic drivers framework
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, linux-clk; +Cc: Yoshinori Sato

Use common PCI host framework and Common Clock Freamework.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boards/Kconfig      |   1 +
 arch/sh/drivers/Makefile    |   2 +
 arch/sh/kernel/cpu/Makefile |   8 +-
 arch/sh/kernel/cpu/clock.c  |   6 +-
 drivers/clk/Kconfig         |   1 +
 drivers/clk/Makefile        |   3 +-
 drivers/clk/sh/Kconfig      |   2 +
 drivers/clk/sh/Makefile     |   2 +
 drivers/clk/sh/clk-shdiv.c  | 344 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/sh/clk-shdiv.h  |  16 +++
 10 files changed, 381 insertions(+), 4 deletions(-)
 create mode 100644 drivers/clk/sh/Kconfig
 create mode 100644 drivers/clk/sh/Makefile
 create mode 100644 drivers/clk/sh/clk-shdiv.c
 create mode 100644 drivers/clk/sh/clk-shdiv.h

diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 9e4ccd0..b6ff9df 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -13,6 +13,7 @@ config SH_DEVICE_TREE
 	select CLKSRC_OF
 	select GENERIC_CALIBRATE_DELAY
 	select GENERIC_IOMAP
+	select COMMON_CLK
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile
index e13f06b..382e86f 100644
--- a/arch/sh/drivers/Makefile
+++ b/arch/sh/drivers/Makefile
@@ -4,7 +4,9 @@
 
 obj-y		+= dma/
 
+ifndef CONFIG_SH_DEVICE_TREE
 obj-$(CONFIG_PCI)		+= pci/
+endif
 obj-$(CONFIG_SUPERHYWAY)	+= superhyway/
 obj-$(CONFIG_PUSH_SWITCH)	+= push-switch.o
 obj-$(CONFIG_HEARTBEAT)		+= heartbeat.o
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index accc7ca..22ad0ee 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -16,6 +16,10 @@ obj-$(CONFIG_ARCH_SHMOBILE)	+= shmobile/
 # Common interfaces.
 
 obj-$(CONFIG_SH_ADC)		+= adc.o
+ifndef CONFIG_COMMON_CLK
 obj-$(CONFIG_SH_CLK_CPG_LEGACY)	+= clock-cpg.o
-
-obj-y	+= irq/ init.o clock.o fpu.o pfc.o proc.o
+endif
+ifndef CONFIG_GENERIC_IRQ_CHIP
+obj-y	+= irq/
+endif
+obj-y	+= init.o clock.o fpu.o pfc.o proc.o
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 4187cf4..8e66e23 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -22,13 +22,15 @@
 
 int __init clk_init(void)
 {
-	int ret;
+	int ret = 0;
 
+#ifndef CONFIG_COMMON_CLK
 	ret = arch_clk_init();
 	if (unlikely(ret)) {
 		pr_err("%s: CPU clock registration failed.\n", __func__);
 		return ret;
 	}
+#endif
 
 	if (sh_mv.mv_clk_init) {
 		ret = sh_mv.mv_clk_init();
@@ -39,11 +41,13 @@ int __init clk_init(void)
 		}
 	}
 
+#ifndef CONFIG_COMMON_CLK
 	/* Kick the child clocks.. */
 	recalculate_root_clocks();
 
 	/* Enable the necessary init clocks */
 	clk_enable_init_clocks();
+#endif
 
 	return ret;
 }
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 16f7d33..19b0cd3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -202,6 +202,7 @@ source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/samsung/Kconfig"
+source "drivers/clk/sh/Kconfig"
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/ti/Kconfig"
 
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 46869d6..c75d9c8 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -83,4 +83,5 @@ obj-$(CONFIG_COMMON_CLK_VERSATILE)	+= versatile/
 obj-$(CONFIG_X86)			+= x86/
 obj-$(CONFIG_ARCH_ZX)			+= zte/
 obj-$(CONFIG_ARCH_ZYNQ)			+= zynq/
-obj-$(CONFIG_H8300)		+= h8300/
+obj-$(CONFIG_H8300)			+= h8300/
+obj-$(CONFIG_SUPERH)			+= sh/
diff --git a/drivers/clk/sh/Kconfig b/drivers/clk/sh/Kconfig
new file mode 100644
index 0000000..89e28d8
--- /dev/null
+++ b/drivers/clk/sh/Kconfig
@@ -0,0 +1,2 @@
+config COMMON_CLK_SH7750
+	bool "Clcok driver for SH7750/SH7751"
diff --git a/drivers/clk/sh/Makefile b/drivers/clk/sh/Makefile
new file mode 100644
index 0000000..468eb9d
--- /dev/null
+++ b/drivers/clk/sh/Makefile
@@ -0,0 +1,2 @@
+obj-y += clk-shdiv.o
+obj-$(CONFIG_COMMON_CLK_SH7750) += clk-sh7750.o
\ No newline at end of file
diff --git a/drivers/clk/sh/clk-shdiv.c b/drivers/clk/sh/clk-shdiv.c
new file mode 100644
index 0000000..be19ffa
--- /dev/null
+++ b/drivers/clk/sh/clk-shdiv.c
@@ -0,0 +1,344 @@
+/*
+ * SuperH divider clock driver
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include "clk-shdiv.h"
+
+#define div_mask(width) ((1 << (width)) - 1)
+#define to_sh_clk_div(_divider)					\
+	container_of(_divider, struct sh_clk_div, divider)
+
+static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
+				      u8 width)
+{
+	unsigned int maxdiv = 0, mask = div_mask(width);
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->div > maxdiv && clkt->val <= mask)
+			maxdiv = clkt->div;
+	return maxdiv;
+}
+
+static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width)
+{
+	if (table)
+		return _get_table_maxdiv(table, width);
+	return div_mask(width) + 1;
+}
+
+static unsigned int _get_table_div(const struct clk_div_table *table,
+				   unsigned int val)
+{
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->val == val)
+			return clkt->div;
+	return 0;
+}
+
+static unsigned int _get_div(const struct clk_div_table *table,
+			     unsigned int val,  u8 width)
+{
+	if (table)
+		return _get_table_div(table, val);
+	return val + 1;
+}
+
+static unsigned int _get_table_val(const struct clk_div_table *table,
+				   unsigned int div)
+{
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->div == div)
+			return clkt->val;
+	return 0;
+}
+
+static unsigned int _get_val(const struct clk_div_table *table,
+			     unsigned int div, u8 width)
+{
+	if (table)
+		return  _get_table_val(table, div);
+	return div - 1;
+}
+
+static unsigned long sh_divider_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate,
+					 unsigned int val,
+					 const struct clk_div_table *table)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	unsigned int div;
+
+	div = _get_div(table, val, divider->width);
+
+	return DIV_ROUND_UP_ULL((u64)parent_rate, div);
+}
+
+static unsigned long sh_clk_divider_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	struct sh_clk_div *sh_div = to_sh_clk_div(divider);
+	unsigned int val;
+
+	val = sh_div->read(divider);
+
+	return sh_divider_recalc_rate(hw, parent_rate, val, divider->table);
+}
+
+static bool _is_valid_table_div(const struct clk_div_table *table,
+				unsigned int div)
+{
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->div == div)
+			return true;
+	return false;
+}
+
+static bool _is_valid_div(const struct clk_div_table *table, unsigned int div)
+{
+	if (table)
+		return _is_valid_table_div(table, div);
+	return true;
+}
+
+static int _round_up_table(const struct clk_div_table *table, int div)
+{
+	const struct clk_div_table *clkt;
+	int up = INT_MAX;
+
+	for (clkt = table; clkt->div; clkt++) {
+		if (clkt->div == div)
+			return clkt->div;
+		else if (clkt->div < div)
+			continue;
+
+		if ((clkt->div - div) < (up - div))
+			up = clkt->div;
+	}
+
+	return up;
+}
+
+static int _div_round_up(const struct clk_div_table *table,
+			 unsigned long parent_rate, unsigned long rate)
+{
+	int div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
+
+	if (table)
+		div = _round_up_table(table, div);
+
+	return div;
+}
+
+static int _div_round(const struct clk_div_table *table,
+		      unsigned long parent_rate, unsigned long rate)
+{
+	return _div_round_up(table, parent_rate, rate);
+}
+
+static bool _is_best_div(unsigned long rate, unsigned long now,
+			 unsigned long best)
+{
+	return now <= rate && now > best;
+}
+
+static int _next_div(const struct clk_div_table *table, int div)
+{
+	div++;
+
+	if (table)
+		return _round_up_table(table, div);
+
+	return div;
+}
+
+static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
+			       unsigned long *best_parent_rate,
+			       const struct clk_div_table *table, u8 width)
+{
+	int i, bestdiv = 0;
+	unsigned long parent_rate, best = 0, now, maxdiv;
+	unsigned long parent_rate_saved = *best_parent_rate;
+
+	if (!rate)
+		rate = 1;
+
+	maxdiv = _get_maxdiv(table, width);
+
+	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+		parent_rate = *best_parent_rate;
+		bestdiv = _div_round(table, parent_rate, rate);
+		bestdiv = bestdiv == 0 ? 1 : bestdiv;
+		bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
+		return bestdiv;
+	}
+
+	/*
+	 * The maximum divider we can use without overflowing
+	 * unsigned long in rate * i below
+	 */
+	maxdiv = min(ULONG_MAX / rate, maxdiv);
+
+	for (i = _next_div(table, 0); i <= maxdiv;
+	     i = _next_div(table, i)) {
+		if (rate * i == parent_rate_saved) {
+			/*
+			 * It's the most ideal case if the requested rate can be
+			 * divided from parent clock without needing to change
+			 * parent rate, so return the divider immediately.
+			 */
+			*best_parent_rate = parent_rate_saved;
+			return i;
+		}
+		parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
+					       rate * i);
+		now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
+		if (_is_best_div(rate, now, best)) {
+			bestdiv = i;
+			best = now;
+			*best_parent_rate = parent_rate;
+		}
+	}
+
+	if (!bestdiv) {
+		bestdiv = _get_maxdiv(table, width);
+		*best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1);
+	}
+
+	return bestdiv;
+}
+
+static long sh_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+			unsigned long *prate, const struct clk_div_table *table,
+			u8 width)
+{
+	int div;
+
+	div = clk_divider_bestdiv(hw, rate, prate, table, width);
+
+	return DIV_ROUND_UP_ULL((u64)*prate, div);
+}
+
+static long sh_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+
+	return sh_divider_round_rate(hw, rate, prate, divider->table,
+				     divider->width);
+}
+
+static int sh_divider_get_val(unsigned long rate, unsigned long parent_rate,
+			   const struct clk_div_table *table, u8 width)
+{
+	unsigned int div, value;
+
+	div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
+
+	if (!_is_valid_div(table, div))
+		return -EINVAL;
+
+	value = _get_val(table, div, width);
+
+	return min_t(unsigned int, value, div_mask(width));
+}
+
+static int sh_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct clk_divider *divider = to_clk_divider(hw);
+	struct sh_clk_div *sh_div = to_sh_clk_div(divider);
+	unsigned int value;
+	unsigned long flags = 0;
+
+	value = sh_divider_get_val(rate, parent_rate, divider->table,
+				   divider->width);
+
+	if (divider->lock)
+		spin_lock_irqsave(divider->lock, flags);
+	else
+		__acquire(divider->lock);
+
+	sh_div->write(divider, value);
+
+	if (divider->lock)
+		spin_unlock_irqrestore(divider->lock, flags);
+	else
+		__release(divider->lock);
+
+	return 0;
+}
+
+static const struct clk_ops sh_clk_divider_ops = {
+	.recalc_rate = sh_clk_divider_recalc_rate,
+	.round_rate = sh_clk_divider_round_rate,
+	.set_rate = sh_clk_divider_set_rate,
+};
+
+static struct clk *_register_divider(struct device *dev, const char *name,
+		     const char *parent_name,
+		     void __iomem *reg, u8 shift, u8 width,
+		     const struct clk_div_table *table,
+		     spinlock_t *lock,
+		     u16 (*read)(struct clk_divider *hw),
+		     void (*write)(struct clk_divider *hw, u16 val))
+{
+	struct sh_clk_div *div;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the divider */
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &sh_clk_divider_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	/* struct clk_divider assignments */
+	div->divider.reg = reg;
+	div->divider.shift = shift;
+	div->divider.width = width;
+	div->divider.lock = lock;
+	div->divider.hw.init = &init;
+	div->divider.table = table;
+	div->read = read;
+	div->write = write;
+
+	/* register the clock */
+	clk = clk_register(dev, &div->divider.hw);
+
+	if (IS_ERR(clk))
+		kfree(div);
+
+	return clk;
+}
+
+struct clk *sh_div_clk_register(struct device *dev, const char *name,
+				const char *parent_name,
+				void __iomem *reg, u8 shift, u8 width,
+				const struct clk_div_table *table,
+				spinlock_t *lock,
+				u16 (*read)(struct clk_divider *hw),
+				void (*write)(struct clk_divider *hw, u16 val))
+{
+	return _register_divider(dev, name, parent_name, reg, shift,
+				 width, table, lock, read, write);
+}
+EXPORT_SYMBOL_GPL(sh_div_clk_register);
diff --git a/drivers/clk/sh/clk-shdiv.h b/drivers/clk/sh/clk-shdiv.h
new file mode 100644
index 0000000..ebd27df
--- /dev/null
+++ b/drivers/clk/sh/clk-shdiv.h
@@ -0,0 +1,16 @@
+/* SuperH common clock divider */
+
+struct sh_clk_div {
+	struct clk_divider divider;
+	u16 (*read)(struct clk_divider *divider);
+	void (*write)(struct clk_divider *divider, u16 val);
+};
+
+struct clk *sh_div_clk_register(struct device *dev, const char *name,
+				const char *parent_name,
+				void __iomem *reg, u8 shift, u8 width,
+				const struct clk_div_table *table,
+				spinlock_t *lock,
+				u16 (*read)(struct clk_divider *hw),
+				void (*write)(struct clk_divider *hw, u16 val));
+
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 11/17] sh: SH7750/51 clock driver
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, linux-clk; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../bindings/clock/renesas,sh7750-div-clock.txt    |  27 +++
 .../bindings/clock/renesas,sh7750-pll-clock.txt    |  26 +++
 drivers/clk/sh/clk-sh7750.c                        | 240 +++++++++++++++++++++
 3 files changed, 293 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
 create mode 100644 drivers/clk/sh/clk-sh7750.c

diff --git a/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt b/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
new file mode 100644
index 0000000..8c57ab5
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
@@ -0,0 +1,27 @@
+* Renesas SH7750/51 divider clock
+
+Required Properties:
+
+  - compatible: Must be "renesas,sh7750-div-clock"
+
+  - clocks: Reference to the parent clocks (mostly PLL)
+
+  - #clock-cells: Must be 0
+
+  - reg: Base address and length of the divide rate selector
+
+  - renesas,offset: bit offset of selector
+
+  - clock-output-names: The names of the clocks.
+
+Example
+-------
+
+        iclk: iclk {
+                compatible = "renesas,sh7750-div-clock";
+                clocks = <&pllclk>;
+                #clock-cells = <0>;
+                reg = <0xffc00000 2>;
+		renesas,offset = <6>;
+		clock-output-names = "ick";
+        };
diff --git a/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt b/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
new file mode 100644
index 0000000..06a3d31
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
@@ -0,0 +1,26 @@
+Renesas SH7750/51 PLL clock
+
+This device is Clock multiplyer
+
+Required Properties:
+
+  - compatible: Must be "renesas,sh7750-pll-clock"
+
+  - clocks: Reference to the parent clocks
+
+  - #clock-cells: Must be 0
+
+  - renesas,mult: PLL1 multiply rate
+
+  - reg: Two rate selector (FRQCR / WDT) register address
+
+Example
+-------
+
+        pllclk: pllclk {
+                compatible = "renesas,sh7750-pll-clock";
+                clocks = <&oclk>;
+                #clock-cells = <0>;
+		renesas,mult = <12>;
+                reg = <0xffc00000 2>, <0xffc00008 4>;
+        };
diff --git a/drivers/clk/sh/clk-sh7750.c b/drivers/clk/sh/clk-sh7750.c
new file mode 100644
index 0000000..259f1bb
--- /dev/null
+++ b/drivers/clk/sh/clk-sh7750.c
@@ -0,0 +1,240 @@
+/*
+ * Renesas SH7750/51 clock driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include "clk-shdiv.h"
+
+static DEFINE_SPINLOCK(clklock);
+
+static struct clk_div_table pdiv_table[] = {
+	{ .val = 0, .div = 2, },
+	{ .val = 1, .div = 3, },
+	{ .val = 2, .div = 4, },
+	{ .val = 3, .div = 6, },
+	{ .val = 4, .div = 8, },
+	{ .val = 0, .div = 0, },
+};
+
+static struct clk_div_table div_table[] = {
+	{ .val = 0, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 2, .div = 3, },
+	{ .val = 3, .div = 4, },
+	{ .val = 4, .div = 6, },
+	{ .val = 5, .div = 8, },
+	{ .val = 0, .div = 0, },
+};
+
+struct pll_clock {
+	struct clk_hw hw;
+	void __iomem *freqcr;
+	void __iomem *wdt;
+	int mult;
+};
+
+#define to_pll_clock(_hw) container_of(_hw, struct pll_clock, hw)
+
+static unsigned long pll_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct pll_clock *pll_clock = to_pll_clock(hw);
+
+	if ((ioread16(pll_clock->freqcr) >> 9) & 1)
+		return parent_rate * pll_clock->mult;
+	else
+		return parent_rate;
+}
+
+static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	struct pll_clock *pll_clock = to_pll_clock(hw);
+	int mul;
+
+	mul = rate / *prate;
+	mul = (pll_clock->mult / 2 < mul)?pll_clock->mult:1;
+	return *prate * mul;
+}
+
+static int pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			unsigned long parent_rate)
+{
+	int mult;
+	unsigned char val;
+	unsigned long flags;
+	struct pll_clock *pll_clock = to_pll_clock(hw);
+
+	mult = rate / parent_rate;
+	if (mult > 1) {
+		/* PLL enable */
+		/* required stable time */
+		spin_lock_irqsave(&clklock, flags);
+		iowrite16(0x5a00, pll_clock->wdt);
+		iowrite16(0xa503, pll_clock->wdt + 2);
+		val = ioread16(pll_clock->freqcr);
+		val |= 0x0200;
+		iowrite16(val, pll_clock->freqcr);
+		spin_unlock_irqrestore(&clklock, flags);
+	} else {
+		/* PLL disable */
+		/* not required stable time */
+		val = ioread16(pll_clock->freqcr);
+		val &= ~0x0200;
+		iowrite16(val, pll_clock->freqcr);
+	}
+	return 0;
+}
+
+static const struct clk_ops pll_ops = {
+	.recalc_rate = pll_recalc_rate,
+	.round_rate = pll_round_rate,
+	.set_rate = pll_set_rate,
+};
+
+static void __init sh7750_pll_clk_setup(struct device_node *node)
+{
+	unsigned int num_parents;
+	struct clk *clk;
+	const char *clk_name = node->name;
+	const char *parent_name;
+	struct pll_clock *pll_clock;
+	struct clk_init_data init;
+
+	num_parents = of_clk_get_parent_count(node);
+	if (num_parents < 1) {
+		pr_err("%s: no parent found", clk_name);
+		return;
+	}
+
+	pll_clock = kzalloc(sizeof(struct pll_clock), GFP_KERNEL);
+	if (!pll_clock) {
+		pr_err("%s: failed to alloc memory", clk_name);
+		return;
+	}
+
+	pll_clock->freqcr = of_iomap(node, 0);
+	if (pll_clock->freqcr = NULL) {
+		pr_err("%s: failed to map frequenct control register",
+		       clk_name);
+		goto free_clock;
+	}
+
+	pll_clock->wdt = of_iomap(node, 1);
+	if (pll_clock->wdt = NULL) {
+		pr_err("%s: failed to map watchdog register", clk_name);
+		goto unmap_freqcr;
+	}
+
+	of_property_read_u32_index(node, "renesas,mult", 0, &pll_clock->mult);
+
+	parent_name = of_clk_get_parent_name(node, 0);
+	init.name = clk_name;
+	init.ops = &pll_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	pll_clock->hw.init = &init;
+
+	clk = clk_register(NULL, &pll_clock->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register %s pll clock (%ld)\n",
+		       __func__, clk_name, PTR_ERR(clk));
+		goto unmap_wdt;
+	}
+
+	of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	return;
+
+unmap_wdt:
+	iounmap(pll_clock->wdt);
+unmap_freqcr:
+	iounmap(pll_clock->freqcr);
+free_clock:
+	kfree(pll_clock);
+}
+
+static u16 sh7750_freqcr_read(struct clk_divider *divider)
+{
+	u16 val;
+
+	val = __raw_readw(divider->reg) >> divider->shift;
+	val &= ((1 << divider->width) - 1);
+	return val;
+}
+
+static void sh7750_freqcr_write(struct clk_divider *divider, u16 value)
+{
+	u16 val;
+
+	value <<= divider->shift;
+	val = __raw_readw(divider->reg);
+	val &= ~(((1 << divider->width) - 1) << divider->shift);
+	val |= value;
+	__raw_writew(val, divider->reg);
+}
+
+static void __init sh7750_div_clk_setup(struct device_node *node)
+{
+	unsigned int num_parents;
+	struct clk *clk;
+	const char *clk_name = node->name;
+	const char *parent_name;
+	void __iomem *freqcr = NULL;
+	int i;
+	int num_clks;
+	int offset;
+
+	num_parents = of_clk_get_parent_count(node);
+	if (num_parents < 1) {
+		pr_err("%s: no parent found", clk_name);
+		return;
+	}
+
+	num_clks = of_property_count_strings(node, "clock-output-names");
+	if (num_clks < 0) {
+		pr_err("%s: failed to count clocks", clk_name);
+		return;
+	}
+
+	freqcr = of_iomap(node, 0);
+	if (freqcr = NULL) {
+		pr_err("%s: failed to map divide register", clk_name);
+		goto error;
+	}
+	of_property_read_u32_index(node, "renesas,offset", 0, &offset);
+
+	parent_name = of_clk_get_parent_name(node, 0);
+	for (i = 0; i < num_clks; i++) {
+		of_property_read_string_index(node, "clock-output-names", i,
+					      &clk_name);
+		clk = sh_div_clk_register(NULL, clk_name, parent_name,
+					  freqcr,
+					  offset, 3,
+					  (offset = 0)?pdiv_table:div_table,
+					  &clklock, sh7750_freqcr_read,
+					  sh7750_freqcr_write);
+		if (IS_ERR(clk))
+			pr_err("%s: failed to register %s div clock (%ld)\n",
+			       __func__, clk_name, PTR_ERR(clk));
+		else
+			of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	}
+error:
+	if (freqcr)
+		iounmap(freqcr);
+}
+
+CLK_OF_DECLARE(sh7750_div_clk, "renesas,sh7750-div-clock",
+	       sh7750_div_clk_setup);
+CLK_OF_DECLARE(sh7750_pll_clk, "renesas,sh7750-pll-clock",
+	       sh7750_pll_clk_setup);
+
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 11/17] sh: SH7750/51 clock driver
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, linux-clk; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../bindings/clock/renesas,sh7750-div-clock.txt    |  27 +++
 .../bindings/clock/renesas,sh7750-pll-clock.txt    |  26 +++
 drivers/clk/sh/clk-sh7750.c                        | 240 +++++++++++++++++++++
 3 files changed, 293 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
 create mode 100644 drivers/clk/sh/clk-sh7750.c

diff --git a/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt b/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
new file mode 100644
index 0000000..8c57ab5
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
@@ -0,0 +1,27 @@
+* Renesas SH7750/51 divider clock
+
+Required Properties:
+
+  - compatible: Must be "renesas,sh7750-div-clock"
+
+  - clocks: Reference to the parent clocks (mostly PLL)
+
+  - #clock-cells: Must be 0
+
+  - reg: Base address and length of the divide rate selector
+
+  - renesas,offset: bit offset of selector
+
+  - clock-output-names: The names of the clocks.
+
+Example
+-------
+
+        iclk: iclk {
+                compatible = "renesas,sh7750-div-clock";
+                clocks = <&pllclk>;
+                #clock-cells = <0>;
+                reg = <0xffc00000 2>;
+		renesas,offset = <6>;
+		clock-output-names = "ick";
+        };
diff --git a/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt b/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
new file mode 100644
index 0000000..06a3d31
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
@@ -0,0 +1,26 @@
+Renesas SH7750/51 PLL clock
+
+This device is Clock multiplyer
+
+Required Properties:
+
+  - compatible: Must be "renesas,sh7750-pll-clock"
+
+  - clocks: Reference to the parent clocks
+
+  - #clock-cells: Must be 0
+
+  - renesas,mult: PLL1 multiply rate
+
+  - reg: Two rate selector (FRQCR / WDT) register address
+
+Example
+-------
+
+        pllclk: pllclk {
+                compatible = "renesas,sh7750-pll-clock";
+                clocks = <&oclk>;
+                #clock-cells = <0>;
+		renesas,mult = <12>;
+                reg = <0xffc00000 2>, <0xffc00008 4>;
+        };
diff --git a/drivers/clk/sh/clk-sh7750.c b/drivers/clk/sh/clk-sh7750.c
new file mode 100644
index 0000000..259f1bb
--- /dev/null
+++ b/drivers/clk/sh/clk-sh7750.c
@@ -0,0 +1,240 @@
+/*
+ * Renesas SH7750/51 clock driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include "clk-shdiv.h"
+
+static DEFINE_SPINLOCK(clklock);
+
+static struct clk_div_table pdiv_table[] = {
+	{ .val = 0, .div = 2, },
+	{ .val = 1, .div = 3, },
+	{ .val = 2, .div = 4, },
+	{ .val = 3, .div = 6, },
+	{ .val = 4, .div = 8, },
+	{ .val = 0, .div = 0, },
+};
+
+static struct clk_div_table div_table[] = {
+	{ .val = 0, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 2, .div = 3, },
+	{ .val = 3, .div = 4, },
+	{ .val = 4, .div = 6, },
+	{ .val = 5, .div = 8, },
+	{ .val = 0, .div = 0, },
+};
+
+struct pll_clock {
+	struct clk_hw hw;
+	void __iomem *freqcr;
+	void __iomem *wdt;
+	int mult;
+};
+
+#define to_pll_clock(_hw) container_of(_hw, struct pll_clock, hw)
+
+static unsigned long pll_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct pll_clock *pll_clock = to_pll_clock(hw);
+
+	if ((ioread16(pll_clock->freqcr) >> 9) & 1)
+		return parent_rate * pll_clock->mult;
+	else
+		return parent_rate;
+}
+
+static long pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	struct pll_clock *pll_clock = to_pll_clock(hw);
+	int mul;
+
+	mul = rate / *prate;
+	mul = (pll_clock->mult / 2 < mul)?pll_clock->mult:1;
+	return *prate * mul;
+}
+
+static int pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			unsigned long parent_rate)
+{
+	int mult;
+	unsigned char val;
+	unsigned long flags;
+	struct pll_clock *pll_clock = to_pll_clock(hw);
+
+	mult = rate / parent_rate;
+	if (mult > 1) {
+		/* PLL enable */
+		/* required stable time */
+		spin_lock_irqsave(&clklock, flags);
+		iowrite16(0x5a00, pll_clock->wdt);
+		iowrite16(0xa503, pll_clock->wdt + 2);
+		val = ioread16(pll_clock->freqcr);
+		val |= 0x0200;
+		iowrite16(val, pll_clock->freqcr);
+		spin_unlock_irqrestore(&clklock, flags);
+	} else {
+		/* PLL disable */
+		/* not required stable time */
+		val = ioread16(pll_clock->freqcr);
+		val &= ~0x0200;
+		iowrite16(val, pll_clock->freqcr);
+	}
+	return 0;
+}
+
+static const struct clk_ops pll_ops = {
+	.recalc_rate = pll_recalc_rate,
+	.round_rate = pll_round_rate,
+	.set_rate = pll_set_rate,
+};
+
+static void __init sh7750_pll_clk_setup(struct device_node *node)
+{
+	unsigned int num_parents;
+	struct clk *clk;
+	const char *clk_name = node->name;
+	const char *parent_name;
+	struct pll_clock *pll_clock;
+	struct clk_init_data init;
+
+	num_parents = of_clk_get_parent_count(node);
+	if (num_parents < 1) {
+		pr_err("%s: no parent found", clk_name);
+		return;
+	}
+
+	pll_clock = kzalloc(sizeof(struct pll_clock), GFP_KERNEL);
+	if (!pll_clock) {
+		pr_err("%s: failed to alloc memory", clk_name);
+		return;
+	}
+
+	pll_clock->freqcr = of_iomap(node, 0);
+	if (pll_clock->freqcr == NULL) {
+		pr_err("%s: failed to map frequenct control register",
+		       clk_name);
+		goto free_clock;
+	}
+
+	pll_clock->wdt = of_iomap(node, 1);
+	if (pll_clock->wdt == NULL) {
+		pr_err("%s: failed to map watchdog register", clk_name);
+		goto unmap_freqcr;
+	}
+
+	of_property_read_u32_index(node, "renesas,mult", 0, &pll_clock->mult);
+
+	parent_name = of_clk_get_parent_name(node, 0);
+	init.name = clk_name;
+	init.ops = &pll_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	pll_clock->hw.init = &init;
+
+	clk = clk_register(NULL, &pll_clock->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register %s pll clock (%ld)\n",
+		       __func__, clk_name, PTR_ERR(clk));
+		goto unmap_wdt;
+	}
+
+	of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	return;
+
+unmap_wdt:
+	iounmap(pll_clock->wdt);
+unmap_freqcr:
+	iounmap(pll_clock->freqcr);
+free_clock:
+	kfree(pll_clock);
+}
+
+static u16 sh7750_freqcr_read(struct clk_divider *divider)
+{
+	u16 val;
+
+	val = __raw_readw(divider->reg) >> divider->shift;
+	val &= ((1 << divider->width) - 1);
+	return val;
+}
+
+static void sh7750_freqcr_write(struct clk_divider *divider, u16 value)
+{
+	u16 val;
+
+	value <<= divider->shift;
+	val = __raw_readw(divider->reg);
+	val &= ~(((1 << divider->width) - 1) << divider->shift);
+	val |= value;
+	__raw_writew(val, divider->reg);
+}
+
+static void __init sh7750_div_clk_setup(struct device_node *node)
+{
+	unsigned int num_parents;
+	struct clk *clk;
+	const char *clk_name = node->name;
+	const char *parent_name;
+	void __iomem *freqcr = NULL;
+	int i;
+	int num_clks;
+	int offset;
+
+	num_parents = of_clk_get_parent_count(node);
+	if (num_parents < 1) {
+		pr_err("%s: no parent found", clk_name);
+		return;
+	}
+
+	num_clks = of_property_count_strings(node, "clock-output-names");
+	if (num_clks < 0) {
+		pr_err("%s: failed to count clocks", clk_name);
+		return;
+	}
+
+	freqcr = of_iomap(node, 0);
+	if (freqcr == NULL) {
+		pr_err("%s: failed to map divide register", clk_name);
+		goto error;
+	}
+	of_property_read_u32_index(node, "renesas,offset", 0, &offset);
+
+	parent_name = of_clk_get_parent_name(node, 0);
+	for (i = 0; i < num_clks; i++) {
+		of_property_read_string_index(node, "clock-output-names", i,
+					      &clk_name);
+		clk = sh_div_clk_register(NULL, clk_name, parent_name,
+					  freqcr,
+					  offset, 3,
+					  (offset == 0)?pdiv_table:div_table,
+					  &clklock, sh7750_freqcr_read,
+					  sh7750_freqcr_write);
+		if (IS_ERR(clk))
+			pr_err("%s: failed to register %s div clock (%ld)\n",
+			       __func__, clk_name, PTR_ERR(clk));
+		else
+			of_clk_add_provider(node, of_clk_src_simple_get, clk);
+	}
+error:
+	if (freqcr)
+		iounmap(freqcr);
+}
+
+CLK_OF_DECLARE(sh7750_div_clk, "renesas,sh7750-div-clock",
+	       sh7750_div_clk_setup);
+CLK_OF_DECLARE(sh7750_pll_clk, "renesas,sh7750-pll-clock",
+	       sh7750_pll_clk_setup);
+
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, linux-pci, devicetree; +Cc: Yoshinori Sato

This is alternative SH7751 PCI driver.
Existing driver (arch/sh/drivers/pci/pci-sh7751) use SH specific interface.
But this driver using common PCI interface. It more mordan and generic.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../devicetree/bindings/pci/sh7751-pci.txt         |  51 +++
 arch/sh/boards/Kconfig                             |   1 +
 drivers/pci/host/Kconfig                           |   7 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-sh7751.c                      | 443 +++++++++++++++++++++
 5 files changed, 503 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sh7751-pci.txt
 create mode 100644 drivers/pci/host/pci-sh7751.c

diff --git a/Documentation/devicetree/bindings/pci/sh7751-pci.txt b/Documentation/devicetree/bindings/pci/sh7751-pci.txt
new file mode 100644
index 0000000..c3ec71a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/sh7751-pci.txt
@@ -0,0 +1,51 @@
+* Renesas SH7751 PCI host interfaces
+
+Required properties:
+  - compatible: "renesas,sh7751-pci" is required.
+    And board specific compatible if fixup required.
+
+  - reg: base address and length of the PCI controller registers.
+  - #address-cells: set to <2>
+  - #size-cells: set to <1>
+  - bus-range: PCI bus numbers covered
+  - device_type: set to "pci"
+  - ranges: ranges for the PCI memory and I/O regions.
+  - interrupt-map-mask and interrupt-map: standard PCI properties
+	to define the mapping of the PCI interface to interrupt
+	numbers.
+
+Example:
+	pci: pci-controller@fe200000 {
+		compatible = "renesas,sh7751-pci", "iodata,landisk";
+		device_type = "pci";
+		bus-range = <0 0>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>,
+		         <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>;
+		reg = <0xfe200000 0x0400>,
+		      <0x0c000000 0x04000000>,
+		      <0xff800000 0x0030>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0x1800 0 7>;
+		interrupt-map = <0x0000 0 1 &cpldintc evt2irq(0x2a0) 0
+		                 0x0000 0 2 &cpldintc evt2irq(0x2c0) 0
+		                 0x0000 0 3 &cpldintc evt2irq(0x2e0) 0
+		                 0x0000 0 4 &cpldintc evt2irq(0x300) 0
+
+		                 0x0800 0 1 &cpldintc evt2irq(0x2c0) 0
+		                 0x0800 0 2 &cpldintc evt2irq(0x2e0) 0
+		                 0x0800 0 3 &cpldintc evt2irq(0x300) 0
+		                 0x0800 0 4 &cpldintc evt2irq(0x2a0) 0
+
+		                 0x1000 0 1 &cpldintc evt2irq(0x2e0) 0
+		                 0x1000 0 2 &cpldintc evt2irq(0x300) 0
+		                 0x1000 0 3 &cpldintc evt2irq(0x2a0) 0
+		                 0x1000 0 4 &cpldintc evt2irq(0x2c0) 0
+
+		                 0x1800 0 1 &cpldintc evt2irq(0x300) 0
+		                 0x1800 0 2 &cpldintc evt2irq(0x2a0) 0
+		                 0x1800 0 3 &cpldintc evt2irq(0x2c0) 0
+		                 0x1800 0 4 &cpldintc evt2irq(0x2e0) 0>;
+	};
+};
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index b6ff9df..cfde921 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -14,6 +14,7 @@ config SH_DEVICE_TREE
 	select GENERIC_CALIBRATE_DELAY
 	select GENERIC_IOMAP
 	select COMMON_CLK
+	select SYS_SUPPORTS_PCI
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 7a0780d..a8596db 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -231,4 +231,11 @@ config PCI_HOST_THUNDER_ECAM
 	help
 	  Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs.
 
+config PCI_SH7751
+	bool "Renesas SH7751 On-Chip PCI controller"
+	depends on OF && SUPERH
+	select PCI_HOST_COMMON
+	help
+	  Say Y here if you want PCI support on SH7751.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index d85b5fa..91268cb 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
 obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
 obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
 obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
+obj-$(CONFIG_PCI_SH7751) += pci-sh7751.o
diff --git a/drivers/pci/host/pci-sh7751.c b/drivers/pci/host/pci-sh7751.c
new file mode 100644
index 0000000..c029e5b
--- /dev/null
+++ b/drivers/pci/host/pci-sh7751.c
@@ -0,0 +1,443 @@
+/*
+ * SH7751 PCI driver
+ * Copyright (C) 2016 Yoshinori Sato
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include "pci-host-common.h"
+
+#define SH4_PCICR		0x100		/* PCI Control Register */
+  #define SH4_PCICR_PREFIX	  0xA5000000	/* CR prefix for write */
+  #define SH4_PCICR_FTO		  BIT(10)	/* TRDY/IRDY Enable */
+  #define SH4_PCICR_TRSB	  BIT(9)	/* Target Read Single */
+  #define SH4_PCICR_BSWP	  BIT(8)	/* Target Byte Swap */
+  #define SH4_PCICR_PLUP	  BIT(7)	/* Enable PCI Pullup */
+  #define SH4_PCICR_ARBM	  BIT(6)	/* PCI Arbitration Mode */
+#define SH4_PCICR_MD		  (BIT(4) | BIT(5))	/* MD9 and MD10 status */
+  #define SH4_PCICR_SERR	  BIT(3)	/* SERR output assert */
+  #define SH4_PCICR_INTA	  BIT(2)	/* INTA output assert */
+  #define SH4_PCICR_PRST	  BIT(1)	/* PCI Reset Assert */
+  #define SH4_PCICR_CFIN	  BIT(0)	/* Central Fun. Init Done */
+#define SH4_PCILSR0		0x104		/* PCI Local Space Register0 */
+#define SH4_PCILSR1		0x108		/* PCI Local Space Register1 */
+#define SH4_PCILAR0		0x10C		/* PCI Local Addr Register1 */
+#define SH4_PCILAR1		0x110		/* PCI Local Addr Register1 */
+#define SH4_PCIPAR		0x1C0		/* PIO Address Register */
+  #define SH4_PCIPAR_CFGEN	  0x80000000	/* Configuration Enable */
+  #define SH4_PCIPAR_BUSNO	  0x00FF0000	/* Config. Bus Number */
+  #define SH4_PCIPAR_DEVNO	  0x0000FF00	/* Config. Device Number */
+  #define SH4_PCIPAR_REGAD	  0x000000FC	/* Register Address Number */
+#define SH4_PCIMBR		0x1C4		/* Memory Base Address */
+  #define SH4_PCIMBR_MASK	  0xFF000000	/* Memory Space Mask */
+  #define SH4_PCIMBR_LOCK	  0x00000001	/* Lock Memory Space */
+#define SH4_PCIIOBR		0x1C8		/* I/O Base Address Register */
+  #define SH4_PCIIOBR_MASK	  0xFFFC0000	/* IO Space Mask */
+  #define SH4_PCIIOBR_LOCK	  0x00000001	/* Lock IO Space */
+#define SH4_PCIPINT		0x1CC		/* Power Mgmnt Int. Register */
+  #define SH4_PCIPINT_D3	  0x00000002	/* D3 Pwr Mgmt. Interrupt */
+  #define SH4_PCIPINT_D0	  0x00000001	/* D0 Pwr Mgmt. Interrupt */
+#define SH4_PCIPINTM		0x1D0		/* Power Mgmnt Mask Register */
+#define SH4_PCICLKR		0x1D4		/* Clock Ctrl. Register */
+  #define SH4_PCICLKR_PCSTP	  0x00000002	/* PCI Clock Stop */
+  #define SH4_PCICLKR_BCSTP	  0x00000001	/* BCLK Clock Stop */
+/* For definitions of BCR, MCR see ... */
+#define SH4_PCIBCR1		0x1E0		/* Memory BCR1 Register */
+  #define SH4_PCIMBR0		SH4_PCIBCR1
+#define SH4_PCIBCR2		0x1E4		/* Memory BCR2 Register */
+  #define SH4_PCIMBMR0		SH4_PCIBCR2
+#define SH4_PCIWCR1		0x1E8		/* Wait Control 1 Register */
+#define SH4_PCIWCR2		0x1EC		/* Wait Control 2 Register */
+#define SH4_PCIWCR3		0x1F0		/* Wait Control 3 Register */
+  #define SH4_PCIMBR2		SH4_PCIWCR3
+#define SH4_PCIMCR		0x1F4		/* Memory Control Register */
+#define SH4_PCIBCR3		0x1f8		/* Memory BCR3 Register */
+#define SH4_PCIPCTR             0x200		/* Port Control Register */
+  #define SH4_PCIPCTR_P2EN	  0x000400000	/* Port 2 Enable */
+  #define SH4_PCIPCTR_P1EN	  0x000200000	/* Port 1 Enable */
+  #define SH4_PCIPCTR_P0EN	  0x000100000	/* Port 0 Enable */
+  #define SH4_PCIPCTR_P2UP	  0x000000020	/* Port2 Pull Up Enable */
+  #define SH4_PCIPCTR_P2IO	  0x000000010	/* Port2 Output Enable */
+  #define SH4_PCIPCTR_P1UP	  0x000000008	/* Port1 Pull Up Enable */
+  #define SH4_PCIPCTR_P1IO	  0x000000004	/* Port1 Output Enable */
+  #define SH4_PCIPCTR_P0UP	  0x000000002	/* Port0 Pull Up Enable */
+  #define SH4_PCIPCTR_P0IO	  0x000000001	/* Port0 Output Enable */
+#define SH4_PCIPDTR		0x204		/* Port Data Register */
+  #define SH4_PCIPDTR_PB5	  0x000000020	/* Port 5 Enable */
+  #define SH4_PCIPDTR_PB4	  0x000000010	/* Port 4 Enable */
+  #define SH4_PCIPDTR_PB3	  0x000000008	/* Port 3 Enable */
+  #define SH4_PCIPDTR_PB2	  0x000000004	/* Port 2 Enable */
+  #define SH4_PCIPDTR_PB1	  0x000000002	/* Port 1 Enable */
+  #define SH4_PCIPDTR_PB0	  0x000000001	/* Port 0 Enable */
+#define SH4_PCIPDR		0x220		/* Port IO Data Register */
+
+/* Platform Specific Values */
+#define SH7751_VENDOR_ID             0x1054
+#define SH7751_DEVICE_ID             0x3505
+#define SH7751R_DEVICE_ID            0x350e
+
+/* Memory Control Registers */
+#define SH7751_BCR1                0x0000    /* Memory BCR1 Register */
+#define SH7751_BCR2                0x0004    /* Memory BCR2 Register */
+#define SH7751_BCR3                0x0050    /* Memory BCR3 Register */
+#define SH7751_WCR1                0x0008    /* Wait Control 1 Register */
+#define SH7751_WCR2                0x000C    /* Wait Control 2 Register */
+#define SH7751_WCR3                0x0010    /* Wait Control 3 Register */
+#define SH7751_MCR                 0x0014    /* Memory Control Register */
+
+/* General Memory Config Addresses */
+#define SH7751_CS0_BASE_ADDR       0x0
+#define SH7751_MEM_REGION_SIZE     0x04000000
+#define SH7751_CS1_BASE_ADDR \
+	(SH7751_CS0_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS2_BASE_ADDR \
+	(SH7751_CS1_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS3_BASE_ADDR \
+	(SH7751_CS2_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS4_BASE_ADDR \
+	(SH7751_CS3_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS5_BASE_ADDR \
+	(SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS6_BASE_ADDR \
+	(SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+
+#define pcic_writel(val, reg) __raw_writel(val, pci_reg_base + (reg))
+#define pcic_readl(reg) __raw_readl(pci_reg_base + (reg))
+
+unsigned long PCIBIOS_MIN_IO;
+unsigned long PCIBIOS_MIN_MEM;
+DEFINE_RAW_SPINLOCK(pci_config_lock);
+
+/*
+ * PCIC fixups
+ */
+
+#define PCIMCR_MRSET 0x40000000
+#define PCIMCR_RFSH  0x00000004
+
+static void __init landisk_fixup(void __iomem *pci_reg_base, void __iomem *bcr)
+{
+	unsigned long bcr1, mcr;
+
+	bcr1 = __raw_readl(bcr + SH7751_BCR1);
+	bcr1 |= 0x00080000;	/* Enable Bit 19 BREQEN, set PCIC to slave */
+	pcic_writel(bcr1, SH4_PCIBCR1);
+
+	mcr = __raw_readl(bcr + SH7751_MCR);
+	mcr &= (~PCIMCR_MRSET) & (~PCIMCR_RFSH);
+	pcic_writel(mcr, SH4_PCIMCR);
+
+	pcic_writel(0x0c000000, PCI_BASE_ADDRESS_1);
+	pcic_writel(0xd0000000, PCI_BASE_ADDRESS_2);
+	pcic_writel(0x0c000000, SH4_PCILAR0);
+	pcic_writel(0x00000000, SH4_PCILAR1);
+}
+
+static __initconst const struct fixups {
+	char *compatible;
+	void (*fixup)(void __iomem *, void __iomem *);
+} fixup_list[] = {
+	{
+		.compatible = "iodata,landisk",
+		.fixup = landisk_fixup,
+	},
+};
+
+static __init void pcic_fixups(struct device_node *np,
+		       void __iomem *pcic, void __iomem *bcr)
+{
+	int i;
+	const struct fixups *f = fixup_list;
+
+	for (i = 0; i < ARRAY_SIZE(fixup_list); i++) {
+		if (of_device_is_compatible(np, f->compatible)) {
+			f->fixup(pcic, bcr);
+			break;
+		}
+	}
+}
+
+/*
+ * Direct access to PCI hardware...
+ */
+#define CONFIG_CMD(bus, devfn, where) \
+	(0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
+
+/*
+ * Functions for accessing PCI configuration space with type 1 accesses
+ */
+static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
+			   int where, int size, u32 *val)
+{
+	struct gen_pci *pci = bus->sysdata;
+	void __iomem *pci_reg_base;
+	unsigned long flags;
+	u32 data;
+
+	pci_reg_base = ioremap(pci->cfg.res.start,
+			       pci->cfg.res.end - pci->cfg.res.start);
+
+	/*
+	 * PCIPDR may only be accessed as 32 bit words,
+	 * so we must do byte alignment by hand
+	 */
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
+	pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
+	data = pcic_readl(SH4_PCIPDR);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	switch (size) {
+	case 1:
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+		break;
+	case 2:
+		*val = (data >> ((where & 2) << 3)) & 0xffff;
+		break;
+	case 4:
+		*val = data;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Since SH4 only does 32bit access we'll have to do a read,
+ * mask,write operation.
+ * We'll allow an odd byte offset, though it should be illegal.
+ */
+static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn,
+			 int where, int size, u32 val)
+{
+	struct gen_pci *pci = bus->sysdata;
+	void __iomem *pci_reg_base;
+	unsigned long flags;
+	int shift;
+	u32 data;
+
+	pci_reg_base = ioremap(pci->cfg.res.start,
+			       pci->cfg.res.end - pci->cfg.res.start);
+
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
+	pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
+	data = pcic_readl(SH4_PCIPDR);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	switch (size) {
+	case 1:
+		shift = (where & 3) << 3;
+		data &= ~(0xff << shift);
+		data |= ((val & 0xff) << shift);
+		break;
+	case 2:
+		shift = (where & 2) << 3;
+		data &= ~(0xffff << shift);
+		data |= ((val & 0xffff) << shift);
+		break;
+	case 4:
+		data = val;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	pcic_writel(data, SH4_PCIPDR);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct gen_pci_cfg_bus_ops pci_sh7751_ops = {
+	.ops = {
+		.read	= sh4_pci_read,
+		.write	= sh4_pci_write,
+	},
+};
+
+/*
+ * Called after each bus is probed, but before its children
+ * are examined.
+ */
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ */
+resource_size_t pcibios_align_resource(void *data,
+				       const struct resource *res,
+				       resource_size_t size,
+				       resource_size_t align)
+{
+	resource_size_t start = res->start;
+
+	return start;
+}
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine)
+{
+	/*
+	 * I/O space can be accessed via normal processor loads and stores on
+	 * this platform but for now we elect not to do this and portable
+	 * drivers should not do this anyway.
+	 */
+	if (mmap_state = pci_mmap_io)
+		return -EINVAL;
+
+	/*
+	 * Ignore write-combine; for now only return uncached mappings.
+	 */
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			       vma->vm_end - vma->vm_start,
+			       vma->vm_page_prot);
+}
+
+static const struct of_device_id sh7751_pci_of_match[] = {
+	{ .compatible = "renesas,sh7751-pci", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, sh7751_pci_of_match);
+
+static void __init set_pci_bcr(void __iomem *pci_reg_base,
+			       void __iomem *bcr,
+			       unsigned int area)
+{
+	unsigned long word;
+
+	word = __raw_readl(bcr + SH7751_BCR1);
+	/* check BCR for SDRAM in area */
+	if (((word >> area) & 1) = 0) {
+		pr_info("PCI: Area %d is not configured for SDRAM. BCR1=0x%lx\n",
+			area, word);
+		return;
+	}
+	pcic_writel(word, SH4_PCIBCR1);
+
+	word = __raw_readw(bcr + SH7751_BCR2);
+	/* check BCR2 for 32bit SDRAM interface*/
+	if (((word >> (area << 1)) & 0x3) != 0x3) {
+		pr_info("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%lx\n",
+			area, word);
+		return;
+	}
+	pcic_writel(word, SH4_PCIBCR2);
+}
+
+static __init int sh7751_pci_probe(struct platform_device *pdev)
+{
+	struct resource *res, *wres;
+	u32 id;
+	u32 reg, word;
+	void __iomem *pci_reg_base;
+	void __iomem *bcr;
+	struct gen_pci *pci;
+
+	pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL);
+	if (!pci)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	pci_reg_base = ioremap(res->start, res->end - res->start);
+	if (IS_ERR(pci_reg_base))
+		return PTR_ERR(pci_reg_base);
+
+	wres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (IS_ERR(wres))
+		return PTR_ERR(wres);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	bcr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(bcr))
+		return PTR_ERR(bcr);
+
+	/* check for SH7751/SH7751R hardware */
+	id = pcic_readl(PCI_VENDOR_ID);
+	if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
+	    id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
+		pr_warn("PCI: This is not an SH7751(R)\n");
+		return -ENODEV;
+	}
+	dev_info(&pdev->dev, "PCI core found at %pR\n",
+		pci_reg_base);
+
+	/* Set the BCRs to enable PCI access */
+	reg = __raw_readl(bcr);
+	reg |= 0x80000;
+	__raw_writel(reg, bcr);
+
+	/* Turn the clocks back on (not done in reset)*/
+	pcic_writel(0, SH4_PCICLKR);
+	/* Clear Powerdown IRQs (not done in reset) */
+	word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0;
+	pcic_writel(word, SH4_PCIPINT);
+
+	/* set the command/status bits to:
+	 * Wait Cycle Control + Parity Enable + Bus Master +
+	 * Mem space enable
+	 */
+	word = PCI_COMMAND_WAIT | PCI_COMMAND_PARITY |
+	       PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pcic_writel(word, PCI_COMMAND);
+
+	/* define this host as the host bridge */
+	word = PCI_BASE_CLASS_BRIDGE << 24;
+	pcic_writel(word, PCI_CLASS_REVISION);
+
+	/* Set IO and Mem windows to local address
+	 * Make PCI and local address the same for easy 1 to 1 mapping
+	 */
+	word = wres->end - wres->start - 1;
+	pcic_writel(word, SH4_PCILSR0);
+	/* Set the values on window 0 PCI config registers */
+	word = P2SEGADDR(wres->start);
+	pcic_writel(word, SH4_PCILAR0);
+	pcic_writel(word, PCI_BASE_ADDRESS_1);
+
+	set_pci_bcr(pci_reg_base, bcr, (wres->start >> 27) & 0x07);
+
+	/* configure the wait control registers */
+	word = __raw_readl(bcr + SH7751_WCR1);
+	pcic_writel(word, SH4_PCIWCR1);
+	word = __raw_readl(bcr + SH7751_WCR2);
+	pcic_writel(word, SH4_PCIWCR2);
+	word = __raw_readl(bcr + SH7751_WCR3);
+	pcic_writel(word, SH4_PCIWCR3);
+	word = __raw_readl(bcr + SH7751_MCR);
+	pcic_writel(word, SH4_PCIMCR);
+
+	pcic_fixups(pdev->dev.of_node, pci_reg_base, bcr);
+
+	/*
+	 * SH7751 init done, set central function init complete
+	 * use round robin mode to stop a device starving/overruning
+	 */
+	word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM;
+	pcic_writel(word, SH4_PCICR);
+
+	pci->cfg.ops = &pci_sh7751_ops;
+	return pci_host_common_probe(pdev, pci);
+}
+
+static __refdata struct platform_driver sh7751_pci_driver = {
+	.driver = {
+		.name = "sh7751-pci",
+		.of_match_table = sh7751_pci_of_match,
+	},
+	.probe = sh7751_pci_probe,
+};
+builtin_platform_driver(sh7751_pci_driver);
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, linux-pci, devicetree; +Cc: Yoshinori Sato

This is alternative SH7751 PCI driver.
Existing driver (arch/sh/drivers/pci/pci-sh7751) use SH specific interface.
But this driver using common PCI interface. It more mordan and generic.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../devicetree/bindings/pci/sh7751-pci.txt         |  51 +++
 arch/sh/boards/Kconfig                             |   1 +
 drivers/pci/host/Kconfig                           |   7 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-sh7751.c                      | 443 +++++++++++++++++++++
 5 files changed, 503 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/sh7751-pci.txt
 create mode 100644 drivers/pci/host/pci-sh7751.c

diff --git a/Documentation/devicetree/bindings/pci/sh7751-pci.txt b/Documentation/devicetree/bindings/pci/sh7751-pci.txt
new file mode 100644
index 0000000..c3ec71a
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/sh7751-pci.txt
@@ -0,0 +1,51 @@
+* Renesas SH7751 PCI host interfaces
+
+Required properties:
+  - compatible: "renesas,sh7751-pci" is required.
+    And board specific compatible if fixup required.
+
+  - reg: base address and length of the PCI controller registers.
+  - #address-cells: set to <2>
+  - #size-cells: set to <1>
+  - bus-range: PCI bus numbers covered
+  - device_type: set to "pci"
+  - ranges: ranges for the PCI memory and I/O regions.
+  - interrupt-map-mask and interrupt-map: standard PCI properties
+	to define the mapping of the PCI interface to interrupt
+	numbers.
+
+Example:
+	pci: pci-controller@fe200000 {
+		compatible = "renesas,sh7751-pci", "iodata,landisk";
+		device_type = "pci";
+		bus-range = <0 0>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>,
+		         <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>;
+		reg = <0xfe200000 0x0400>,
+		      <0x0c000000 0x04000000>,
+		      <0xff800000 0x0030>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0x1800 0 7>;
+		interrupt-map = <0x0000 0 1 &cpldintc evt2irq(0x2a0) 0
+		                 0x0000 0 2 &cpldintc evt2irq(0x2c0) 0
+		                 0x0000 0 3 &cpldintc evt2irq(0x2e0) 0
+		                 0x0000 0 4 &cpldintc evt2irq(0x300) 0
+
+		                 0x0800 0 1 &cpldintc evt2irq(0x2c0) 0
+		                 0x0800 0 2 &cpldintc evt2irq(0x2e0) 0
+		                 0x0800 0 3 &cpldintc evt2irq(0x300) 0
+		                 0x0800 0 4 &cpldintc evt2irq(0x2a0) 0
+
+		                 0x1000 0 1 &cpldintc evt2irq(0x2e0) 0
+		                 0x1000 0 2 &cpldintc evt2irq(0x300) 0
+		                 0x1000 0 3 &cpldintc evt2irq(0x2a0) 0
+		                 0x1000 0 4 &cpldintc evt2irq(0x2c0) 0
+
+		                 0x1800 0 1 &cpldintc evt2irq(0x300) 0
+		                 0x1800 0 2 &cpldintc evt2irq(0x2a0) 0
+		                 0x1800 0 3 &cpldintc evt2irq(0x2c0) 0
+		                 0x1800 0 4 &cpldintc evt2irq(0x2e0) 0>;
+	};
+};
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index b6ff9df..cfde921 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -14,6 +14,7 @@ config SH_DEVICE_TREE
 	select GENERIC_CALIBRATE_DELAY
 	select GENERIC_IOMAP
 	select COMMON_CLK
+	select SYS_SUPPORTS_PCI
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 7a0780d..a8596db 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -231,4 +231,11 @@ config PCI_HOST_THUNDER_ECAM
 	help
 	  Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs.
 
+config PCI_SH7751
+	bool "Renesas SH7751 On-Chip PCI controller"
+	depends on OF && SUPERH
+	select PCI_HOST_COMMON
+	help
+	  Say Y here if you want PCI support on SH7751.
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index d85b5fa..91268cb 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
 obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
 obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
 obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
+obj-$(CONFIG_PCI_SH7751) += pci-sh7751.o
diff --git a/drivers/pci/host/pci-sh7751.c b/drivers/pci/host/pci-sh7751.c
new file mode 100644
index 0000000..c029e5b
--- /dev/null
+++ b/drivers/pci/host/pci-sh7751.c
@@ -0,0 +1,443 @@
+/*
+ * SH7751 PCI driver
+ * Copyright (C) 2016 Yoshinori Sato
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include "pci-host-common.h"
+
+#define SH4_PCICR		0x100		/* PCI Control Register */
+  #define SH4_PCICR_PREFIX	  0xA5000000	/* CR prefix for write */
+  #define SH4_PCICR_FTO		  BIT(10)	/* TRDY/IRDY Enable */
+  #define SH4_PCICR_TRSB	  BIT(9)	/* Target Read Single */
+  #define SH4_PCICR_BSWP	  BIT(8)	/* Target Byte Swap */
+  #define SH4_PCICR_PLUP	  BIT(7)	/* Enable PCI Pullup */
+  #define SH4_PCICR_ARBM	  BIT(6)	/* PCI Arbitration Mode */
+#define SH4_PCICR_MD		  (BIT(4) | BIT(5))	/* MD9 and MD10 status */
+  #define SH4_PCICR_SERR	  BIT(3)	/* SERR output assert */
+  #define SH4_PCICR_INTA	  BIT(2)	/* INTA output assert */
+  #define SH4_PCICR_PRST	  BIT(1)	/* PCI Reset Assert */
+  #define SH4_PCICR_CFIN	  BIT(0)	/* Central Fun. Init Done */
+#define SH4_PCILSR0		0x104		/* PCI Local Space Register0 */
+#define SH4_PCILSR1		0x108		/* PCI Local Space Register1 */
+#define SH4_PCILAR0		0x10C		/* PCI Local Addr Register1 */
+#define SH4_PCILAR1		0x110		/* PCI Local Addr Register1 */
+#define SH4_PCIPAR		0x1C0		/* PIO Address Register */
+  #define SH4_PCIPAR_CFGEN	  0x80000000	/* Configuration Enable */
+  #define SH4_PCIPAR_BUSNO	  0x00FF0000	/* Config. Bus Number */
+  #define SH4_PCIPAR_DEVNO	  0x0000FF00	/* Config. Device Number */
+  #define SH4_PCIPAR_REGAD	  0x000000FC	/* Register Address Number */
+#define SH4_PCIMBR		0x1C4		/* Memory Base Address */
+  #define SH4_PCIMBR_MASK	  0xFF000000	/* Memory Space Mask */
+  #define SH4_PCIMBR_LOCK	  0x00000001	/* Lock Memory Space */
+#define SH4_PCIIOBR		0x1C8		/* I/O Base Address Register */
+  #define SH4_PCIIOBR_MASK	  0xFFFC0000	/* IO Space Mask */
+  #define SH4_PCIIOBR_LOCK	  0x00000001	/* Lock IO Space */
+#define SH4_PCIPINT		0x1CC		/* Power Mgmnt Int. Register */
+  #define SH4_PCIPINT_D3	  0x00000002	/* D3 Pwr Mgmt. Interrupt */
+  #define SH4_PCIPINT_D0	  0x00000001	/* D0 Pwr Mgmt. Interrupt */
+#define SH4_PCIPINTM		0x1D0		/* Power Mgmnt Mask Register */
+#define SH4_PCICLKR		0x1D4		/* Clock Ctrl. Register */
+  #define SH4_PCICLKR_PCSTP	  0x00000002	/* PCI Clock Stop */
+  #define SH4_PCICLKR_BCSTP	  0x00000001	/* BCLK Clock Stop */
+/* For definitions of BCR, MCR see ... */
+#define SH4_PCIBCR1		0x1E0		/* Memory BCR1 Register */
+  #define SH4_PCIMBR0		SH4_PCIBCR1
+#define SH4_PCIBCR2		0x1E4		/* Memory BCR2 Register */
+  #define SH4_PCIMBMR0		SH4_PCIBCR2
+#define SH4_PCIWCR1		0x1E8		/* Wait Control 1 Register */
+#define SH4_PCIWCR2		0x1EC		/* Wait Control 2 Register */
+#define SH4_PCIWCR3		0x1F0		/* Wait Control 3 Register */
+  #define SH4_PCIMBR2		SH4_PCIWCR3
+#define SH4_PCIMCR		0x1F4		/* Memory Control Register */
+#define SH4_PCIBCR3		0x1f8		/* Memory BCR3 Register */
+#define SH4_PCIPCTR             0x200		/* Port Control Register */
+  #define SH4_PCIPCTR_P2EN	  0x000400000	/* Port 2 Enable */
+  #define SH4_PCIPCTR_P1EN	  0x000200000	/* Port 1 Enable */
+  #define SH4_PCIPCTR_P0EN	  0x000100000	/* Port 0 Enable */
+  #define SH4_PCIPCTR_P2UP	  0x000000020	/* Port2 Pull Up Enable */
+  #define SH4_PCIPCTR_P2IO	  0x000000010	/* Port2 Output Enable */
+  #define SH4_PCIPCTR_P1UP	  0x000000008	/* Port1 Pull Up Enable */
+  #define SH4_PCIPCTR_P1IO	  0x000000004	/* Port1 Output Enable */
+  #define SH4_PCIPCTR_P0UP	  0x000000002	/* Port0 Pull Up Enable */
+  #define SH4_PCIPCTR_P0IO	  0x000000001	/* Port0 Output Enable */
+#define SH4_PCIPDTR		0x204		/* Port Data Register */
+  #define SH4_PCIPDTR_PB5	  0x000000020	/* Port 5 Enable */
+  #define SH4_PCIPDTR_PB4	  0x000000010	/* Port 4 Enable */
+  #define SH4_PCIPDTR_PB3	  0x000000008	/* Port 3 Enable */
+  #define SH4_PCIPDTR_PB2	  0x000000004	/* Port 2 Enable */
+  #define SH4_PCIPDTR_PB1	  0x000000002	/* Port 1 Enable */
+  #define SH4_PCIPDTR_PB0	  0x000000001	/* Port 0 Enable */
+#define SH4_PCIPDR		0x220		/* Port IO Data Register */
+
+/* Platform Specific Values */
+#define SH7751_VENDOR_ID             0x1054
+#define SH7751_DEVICE_ID             0x3505
+#define SH7751R_DEVICE_ID            0x350e
+
+/* Memory Control Registers */
+#define SH7751_BCR1                0x0000    /* Memory BCR1 Register */
+#define SH7751_BCR2                0x0004    /* Memory BCR2 Register */
+#define SH7751_BCR3                0x0050    /* Memory BCR3 Register */
+#define SH7751_WCR1                0x0008    /* Wait Control 1 Register */
+#define SH7751_WCR2                0x000C    /* Wait Control 2 Register */
+#define SH7751_WCR3                0x0010    /* Wait Control 3 Register */
+#define SH7751_MCR                 0x0014    /* Memory Control Register */
+
+/* General Memory Config Addresses */
+#define SH7751_CS0_BASE_ADDR       0x0
+#define SH7751_MEM_REGION_SIZE     0x04000000
+#define SH7751_CS1_BASE_ADDR \
+	(SH7751_CS0_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS2_BASE_ADDR \
+	(SH7751_CS1_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS3_BASE_ADDR \
+	(SH7751_CS2_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS4_BASE_ADDR \
+	(SH7751_CS3_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS5_BASE_ADDR \
+	(SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+#define SH7751_CS6_BASE_ADDR \
+	(SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE)
+
+#define pcic_writel(val, reg) __raw_writel(val, pci_reg_base + (reg))
+#define pcic_readl(reg) __raw_readl(pci_reg_base + (reg))
+
+unsigned long PCIBIOS_MIN_IO;
+unsigned long PCIBIOS_MIN_MEM;
+DEFINE_RAW_SPINLOCK(pci_config_lock);
+
+/*
+ * PCIC fixups
+ */
+
+#define PCIMCR_MRSET 0x40000000
+#define PCIMCR_RFSH  0x00000004
+
+static void __init landisk_fixup(void __iomem *pci_reg_base, void __iomem *bcr)
+{
+	unsigned long bcr1, mcr;
+
+	bcr1 = __raw_readl(bcr + SH7751_BCR1);
+	bcr1 |= 0x00080000;	/* Enable Bit 19 BREQEN, set PCIC to slave */
+	pcic_writel(bcr1, SH4_PCIBCR1);
+
+	mcr = __raw_readl(bcr + SH7751_MCR);
+	mcr &= (~PCIMCR_MRSET) & (~PCIMCR_RFSH);
+	pcic_writel(mcr, SH4_PCIMCR);
+
+	pcic_writel(0x0c000000, PCI_BASE_ADDRESS_1);
+	pcic_writel(0xd0000000, PCI_BASE_ADDRESS_2);
+	pcic_writel(0x0c000000, SH4_PCILAR0);
+	pcic_writel(0x00000000, SH4_PCILAR1);
+}
+
+static __initconst const struct fixups {
+	char *compatible;
+	void (*fixup)(void __iomem *, void __iomem *);
+} fixup_list[] = {
+	{
+		.compatible = "iodata,landisk",
+		.fixup = landisk_fixup,
+	},
+};
+
+static __init void pcic_fixups(struct device_node *np,
+		       void __iomem *pcic, void __iomem *bcr)
+{
+	int i;
+	const struct fixups *f = fixup_list;
+
+	for (i = 0; i < ARRAY_SIZE(fixup_list); i++) {
+		if (of_device_is_compatible(np, f->compatible)) {
+			f->fixup(pcic, bcr);
+			break;
+		}
+	}
+}
+
+/*
+ * Direct access to PCI hardware...
+ */
+#define CONFIG_CMD(bus, devfn, where) \
+	(0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
+
+/*
+ * Functions for accessing PCI configuration space with type 1 accesses
+ */
+static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
+			   int where, int size, u32 *val)
+{
+	struct gen_pci *pci = bus->sysdata;
+	void __iomem *pci_reg_base;
+	unsigned long flags;
+	u32 data;
+
+	pci_reg_base = ioremap(pci->cfg.res.start,
+			       pci->cfg.res.end - pci->cfg.res.start);
+
+	/*
+	 * PCIPDR may only be accessed as 32 bit words,
+	 * so we must do byte alignment by hand
+	 */
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
+	pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
+	data = pcic_readl(SH4_PCIPDR);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	switch (size) {
+	case 1:
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+		break;
+	case 2:
+		*val = (data >> ((where & 2) << 3)) & 0xffff;
+		break;
+	case 4:
+		*val = data;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/*
+ * Since SH4 only does 32bit access we'll have to do a read,
+ * mask,write operation.
+ * We'll allow an odd byte offset, though it should be illegal.
+ */
+static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn,
+			 int where, int size, u32 val)
+{
+	struct gen_pci *pci = bus->sysdata;
+	void __iomem *pci_reg_base;
+	unsigned long flags;
+	int shift;
+	u32 data;
+
+	pci_reg_base = ioremap(pci->cfg.res.start,
+			       pci->cfg.res.end - pci->cfg.res.start);
+
+	raw_spin_lock_irqsave(&pci_config_lock, flags);
+	pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
+	data = pcic_readl(SH4_PCIPDR);
+	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	switch (size) {
+	case 1:
+		shift = (where & 3) << 3;
+		data &= ~(0xff << shift);
+		data |= ((val & 0xff) << shift);
+		break;
+	case 2:
+		shift = (where & 2) << 3;
+		data &= ~(0xffff << shift);
+		data |= ((val & 0xffff) << shift);
+		break;
+	case 4:
+		data = val;
+		break;
+	default:
+		return PCIBIOS_FUNC_NOT_SUPPORTED;
+	}
+
+	pcic_writel(data, SH4_PCIPDR);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct gen_pci_cfg_bus_ops pci_sh7751_ops = {
+	.ops = {
+		.read	= sh4_pci_read,
+		.write	= sh4_pci_write,
+	},
+};
+
+/*
+ * Called after each bus is probed, but before its children
+ * are examined.
+ */
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+}
+
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ */
+resource_size_t pcibios_align_resource(void *data,
+				       const struct resource *res,
+				       resource_size_t size,
+				       resource_size_t align)
+{
+	resource_size_t start = res->start;
+
+	return start;
+}
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine)
+{
+	/*
+	 * I/O space can be accessed via normal processor loads and stores on
+	 * this platform but for now we elect not to do this and portable
+	 * drivers should not do this anyway.
+	 */
+	if (mmap_state == pci_mmap_io)
+		return -EINVAL;
+
+	/*
+	 * Ignore write-combine; for now only return uncached mappings.
+	 */
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			       vma->vm_end - vma->vm_start,
+			       vma->vm_page_prot);
+}
+
+static const struct of_device_id sh7751_pci_of_match[] = {
+	{ .compatible = "renesas,sh7751-pci", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, sh7751_pci_of_match);
+
+static void __init set_pci_bcr(void __iomem *pci_reg_base,
+			       void __iomem *bcr,
+			       unsigned int area)
+{
+	unsigned long word;
+
+	word = __raw_readl(bcr + SH7751_BCR1);
+	/* check BCR for SDRAM in area */
+	if (((word >> area) & 1) == 0) {
+		pr_info("PCI: Area %d is not configured for SDRAM. BCR1=0x%lx\n",
+			area, word);
+		return;
+	}
+	pcic_writel(word, SH4_PCIBCR1);
+
+	word = __raw_readw(bcr + SH7751_BCR2);
+	/* check BCR2 for 32bit SDRAM interface*/
+	if (((word >> (area << 1)) & 0x3) != 0x3) {
+		pr_info("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%lx\n",
+			area, word);
+		return;
+	}
+	pcic_writel(word, SH4_PCIBCR2);
+}
+
+static __init int sh7751_pci_probe(struct platform_device *pdev)
+{
+	struct resource *res, *wres;
+	u32 id;
+	u32 reg, word;
+	void __iomem *pci_reg_base;
+	void __iomem *bcr;
+	struct gen_pci *pci;
+
+	pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL);
+	if (!pci)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	pci_reg_base = ioremap(res->start, res->end - res->start);
+	if (IS_ERR(pci_reg_base))
+		return PTR_ERR(pci_reg_base);
+
+	wres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (IS_ERR(wres))
+		return PTR_ERR(wres);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	bcr = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(bcr))
+		return PTR_ERR(bcr);
+
+	/* check for SH7751/SH7751R hardware */
+	id = pcic_readl(PCI_VENDOR_ID);
+	if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
+	    id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
+		pr_warn("PCI: This is not an SH7751(R)\n");
+		return -ENODEV;
+	}
+	dev_info(&pdev->dev, "PCI core found at %pR\n",
+		pci_reg_base);
+
+	/* Set the BCRs to enable PCI access */
+	reg = __raw_readl(bcr);
+	reg |= 0x80000;
+	__raw_writel(reg, bcr);
+
+	/* Turn the clocks back on (not done in reset)*/
+	pcic_writel(0, SH4_PCICLKR);
+	/* Clear Powerdown IRQs (not done in reset) */
+	word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0;
+	pcic_writel(word, SH4_PCIPINT);
+
+	/* set the command/status bits to:
+	 * Wait Cycle Control + Parity Enable + Bus Master +
+	 * Mem space enable
+	 */
+	word = PCI_COMMAND_WAIT | PCI_COMMAND_PARITY |
+	       PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pcic_writel(word, PCI_COMMAND);
+
+	/* define this host as the host bridge */
+	word = PCI_BASE_CLASS_BRIDGE << 24;
+	pcic_writel(word, PCI_CLASS_REVISION);
+
+	/* Set IO and Mem windows to local address
+	 * Make PCI and local address the same for easy 1 to 1 mapping
+	 */
+	word = wres->end - wres->start - 1;
+	pcic_writel(word, SH4_PCILSR0);
+	/* Set the values on window 0 PCI config registers */
+	word = P2SEGADDR(wres->start);
+	pcic_writel(word, SH4_PCILAR0);
+	pcic_writel(word, PCI_BASE_ADDRESS_1);
+
+	set_pci_bcr(pci_reg_base, bcr, (wres->start >> 27) & 0x07);
+
+	/* configure the wait control registers */
+	word = __raw_readl(bcr + SH7751_WCR1);
+	pcic_writel(word, SH4_PCIWCR1);
+	word = __raw_readl(bcr + SH7751_WCR2);
+	pcic_writel(word, SH4_PCIWCR2);
+	word = __raw_readl(bcr + SH7751_WCR3);
+	pcic_writel(word, SH4_PCIWCR3);
+	word = __raw_readl(bcr + SH7751_MCR);
+	pcic_writel(word, SH4_PCIMCR);
+
+	pcic_fixups(pdev->dev.of_node, pci_reg_base, bcr);
+
+	/*
+	 * SH7751 init done, set central function init complete
+	 * use round robin mode to stop a device starving/overruning
+	 */
+	word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM;
+	pcic_writel(word, SH4_PCICR);
+
+	pci->cfg.ops = &pci_sh7751_ops;
+	return pci_host_common_probe(pdev, pci);
+}
+
+static __refdata struct platform_driver sh7751_pci_driver = {
+	.driver = {
+		.name = "sh7751-pci",
+		.of_match_table = sh7751_pci_of_match,
+	},
+	.probe = sh7751_pci_probe,
+};
+builtin_platform_driver(sh7751_pci_driver);
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 13/17] sh: Add PCI definetion
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/include/asm/io.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 3280a6b..df62a9f 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -387,6 +387,12 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
 int valid_phys_addr_range(phys_addr_t addr, size_t size);
 int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
 
+#define PCI_IOBASE	0xfe240000UL
+
+#define HAVE_ARCH_PIO_SIZE
+#define PIO_OFFSET	PCI_IOBASE
+#define PIO_MASK	0x3ffffUL
+#define PIO_RESERVED	0x40000UL
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_IO_H */
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 13/17] sh: Add PCI definetion
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/include/asm/io.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 3280a6b..df62a9f 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -387,6 +387,12 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
 int valid_phys_addr_range(phys_addr_t addr, size_t size);
 int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
 
+#define PCI_IOBASE	0xfe240000UL
+
+#define HAVE_ARCH_PIO_SIZE
+#define PIO_OFFSET	PCI_IOBASE
+#define PIO_MASK	0x3ffffUL
+#define PIO_RESERVED	0x40000UL
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_IO_H */
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 14/17] sh: SH3/4 Generic IRQCHIP driever
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, devicetree; +Cc: Yoshinori Sato

IPR based IRQ chip driver.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../interrupt-controller/renesas,sh7751-intc.txt   |  25 ++++
 arch/sh/Kconfig                                    |   6 +-
 arch/sh/boards/Kconfig                             |   1 +
 drivers/irqchip/Kconfig                            |   5 +
 drivers/irqchip/Makefile                           |   1 +
 drivers/irqchip/irq-renesas-sh7751.c               | 141 +++++++++++++++++++++
 6 files changed, 176 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
 create mode 100644 drivers/irqchip/irq-renesas-sh7751.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
new file mode 100644
index 0000000..2bc6f22f
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
@@ -0,0 +1,25 @@
+DT bindings for the SH7751 interrupt controller
+
+Required properties:
+
+  - compatible: has to be "renesas,sh7751-intc".
+
+  - reg: Base address and length of interrupt controller register
+         and extend register.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+
+  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
+    in interrupts.txt in this directory.
+
+Example
+-------
+
+	shintc: interrupt-controller@ffd00000 {
+		compatible = "renesas,sh7751-intc";
+		#interrupt-cells = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-controller;
+		reg = <0xffd00000 14>, <0xfe080000 128>;
+	};
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 4fa5894..f268277 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -28,7 +28,7 @@ config SUPERH
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_REGS_AND_STACK_ACCESS_API
-	select MAY_HAVE_SPARSE_IRQ
+	select MAY_HAVE_SPARSE_IRQ if !SH_DEVICE_TREE
 	select IRQ_FORCED_THREADING
 	select RTC_LIB
 	select GENERIC_ATOMIC64
@@ -67,7 +67,7 @@ config SUPERH32
 	select HAVE_MIXED_BREAKPOINTS_REGS
 	select PERF_EVENTS
 	select ARCH_HIBERNATION_POSSIBLE if MMU
-	select SPARSE_IRQ
+	select SPARSE_IRQ if !SH_DEVICE_TREE
 	select HAVE_CC_STACKPROTECTOR
 
 config SUPERH64
@@ -860,7 +860,7 @@ config PCI
 	depends on SYS_SUPPORTS_PCI
 	select PCI_DOMAINS
 	select GENERIC_PCI_IOMAP
-	select NO_GENERIC_PCI_IOPORT_MAP
+	select NO_GENERIC_PCI_IOPORT_MAP if !SH_DEVICE_TREE
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
 	  bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index cfde921..d33ae46 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -15,6 +15,7 @@ config SH_DEVICE_TREE
 	select GENERIC_IOMAP
 	select COMMON_CLK
 	select SYS_SUPPORTS_PCI
+	select GENERIC_IRQ_CHIP
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3e12479..273f19d 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -244,3 +244,8 @@ config IRQ_MXS
 config MVEBU_ODMI
 	bool
 	select GENERIC_MSI_IRQ_DOMAIN
+
+config RENESAS_SH_INTC
+	def_bool y if SH_DEVICE_TREE
+	select IRQ_DOMAIN
+	select IRQ_DOMAIN_HIERARCHY
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b03cfcb..dac7e90 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -65,3 +65,4 @@ obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
 obj-$(CONFIG_PIC32_EVIC)		+= irq-pic32-evic.o
 obj-$(CONFIG_MVEBU_ODMI)		+= irq-mvebu-odmi.o
+obj-$(CONFIG_RENESAS_SH_INTC)	+= irq-renesas-sh7751.o irq-io-landisk.o
diff --git a/drivers/irqchip/irq-renesas-sh7751.c b/drivers/irqchip/irq-renesas-sh7751.c
new file mode 100644
index 0000000..ea7002a
--- /dev/null
+++ b/drivers/irqchip/irq-renesas-sh7751.c
@@ -0,0 +1,141 @@
+/*
+ * SH7751 interrupt contoller driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of.h>
+#include <linxu/io.h>
+
+static struct sh7751_intc_regs {
+	void *icr;
+	void *ipr;
+	void *intpri00;
+	void *intreq00;
+	void *intmsk00;
+	void *intmskclr00;
+} sh7751_regs;
+
+static const unsigned int ipr_table[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */
+	0x41, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 8 - 15 */
+	0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x11, /* 16 - 23 */
+	0x11, 0x11, 0x11, 0x13, 0x12, 0x12, 0xff, 0xff, /* 24 - 31 */
+	0x30, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x21, /* 32 - 39 */
+	0x21, 0x21, 0x21, 0x21, 0x32, 0x32, 0x32, 0x32, /* 40 - 47 */
+	0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 48 - 55 */
+	0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 56 - 63 */
+};
+
+static const unsigned int pri_table[] = {
+	0, 4, 4, 4, 4, 4, 4, 4,
+	8, 32, 32, 32, 12, 32, 32, 32,
+};
+
+static void sh_disable_irq(struct irq_data *data)
+{
+	int pos;
+	unsigned int addr;
+	unsigned long pri;
+	int irq = data->irq;
+	struct sh7751_intc_regs *reg = data->chip_data;
+
+	if (irq < 64) {
+		if (ipr_table[irq] != 0xff) {
+			addr = (ipr_table[irq] & 0xf0) >> 2;
+			pos = (ipr_table[irq] & 0x0f) << 4;
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->ipr + addr);
+			__raw_writew(pri, reg->ipr + addr);
+		}
+	} else {
+		if (pri_table[irq - 64] < 32) {
+			pos = pri_table[irq - 64];
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->intpri00);
+			__raw_writew(pri, reg->intpri00);
+		}
+	}
+}
+
+static void sh_enable_irq(struct irq_data *data)
+{
+	int pos;
+	unsigned int addr;
+	unsigned long pri;
+	int irq = data->irq;
+	struct sh7751_intc_regs *reg = data->chip_data;
+
+	if (irq < 64) {
+		if (ipr_table[irq] != 0xff) {
+			addr = (ipr_table[irq] & 0xf0) >> 2;
+			pos = (ipr_table[irq] & 0x0f) * 4;
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->ipr + addr);
+			pri |= 1 << pos;
+			__raw_writew(pri, reg->ipr + addr);
+		}
+	} else {
+		if (pri_table[irq - 64] < 32) {
+			pos = pri_table[irq - 64];
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->intpri00);
+			pri |= 1 << pos;
+			__raw_writew(pri, reg->intpri00);
+		}
+	}
+}
+
+static struct irq_chip sh_irq_chip = {
+	.name		= "SH-IPR",
+	.irq_unmask	= sh_enable_irq,
+	.irq_mask	= sh_disable_irq,
+};
+
+static __init int irq_map(struct irq_domain *h, unsigned int virq,
+			  irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &sh_irq_chip, handle_level_irq);
+	irq_get_irq_data(virq)->chip_data = h->host_data;
+	irq_modify_status(virq, IRQ_NOREQUEST, IRQ_NOPROBE);
+
+	return 0;
+}
+
+static struct irq_domain_ops irq_ops = {
+	.map    = irq_map,
+	.xlate  = irq_domain_xlate_onecell,
+};
+
+static int __init sh_intc_7751_init(struct device_node *intc,
+				    struct device_node *parent)
+{
+	struct irq_domain *domain;
+	void *intc_baseaddr;
+	void *intc_baseaddr2;
+
+	intc_baseaddr = of_iomap(intc, 0);
+	intc_baseaddr2 = of_iomap(intc, 1);
+	if (!intc_baseaddr || !intc_baseaddr2)
+		panic("INTC regsiter not defined");
+
+	sh7751_regs.icr = intc_baseaddr;
+	sh7751_regs.ipr = intc_baseaddr + 4;
+	sh7751_regs.intpri00 = intc_baseaddr2;
+	sh7751_regs.intreq00 = intc_baseaddr2 + 0x20;
+	sh7751_regs.intmsk00 = intc_baseaddr2 + 0x40;
+	sh7751_regs.intmskclr00 = intc_baseaddr2 + 0x60;
+
+	domain = irq_domain_add_linear(intc, NR_IRQS, &irq_ops, &sh7751_regs);
+	if (!domain)
+		panic("%s: unable to create IRQ domain\n", intc->full_name);
+
+	irq_set_default_host(domain);
+	return 0;
+}
+
+IRQCHIP_DECLARE(sh_7751_intc, "renesas,sh7751-intc", sh_intc_7751_init);
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 14/17] sh: SH3/4 Generic IRQCHIP driever
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, devicetree; +Cc: Yoshinori Sato

IPR based IRQ chip driver.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../interrupt-controller/renesas,sh7751-intc.txt   |  25 ++++
 arch/sh/Kconfig                                    |   6 +-
 arch/sh/boards/Kconfig                             |   1 +
 drivers/irqchip/Kconfig                            |   5 +
 drivers/irqchip/Makefile                           |   1 +
 drivers/irqchip/irq-renesas-sh7751.c               | 141 +++++++++++++++++++++
 6 files changed, 176 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
 create mode 100644 drivers/irqchip/irq-renesas-sh7751.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
new file mode 100644
index 0000000..2bc6f22f
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
@@ -0,0 +1,25 @@
+DT bindings for the SH7751 interrupt controller
+
+Required properties:
+
+  - compatible: has to be "renesas,sh7751-intc".
+
+  - reg: Base address and length of interrupt controller register
+         and extend register.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+
+  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
+    in interrupts.txt in this directory.
+
+Example
+-------
+
+	shintc: interrupt-controller@ffd00000 {
+		compatible = "renesas,sh7751-intc";
+		#interrupt-cells = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-controller;
+		reg = <0xffd00000 14>, <0xfe080000 128>;
+	};
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 4fa5894..f268277 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -28,7 +28,7 @@ config SUPERH
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_REGS_AND_STACK_ACCESS_API
-	select MAY_HAVE_SPARSE_IRQ
+	select MAY_HAVE_SPARSE_IRQ if !SH_DEVICE_TREE
 	select IRQ_FORCED_THREADING
 	select RTC_LIB
 	select GENERIC_ATOMIC64
@@ -67,7 +67,7 @@ config SUPERH32
 	select HAVE_MIXED_BREAKPOINTS_REGS
 	select PERF_EVENTS
 	select ARCH_HIBERNATION_POSSIBLE if MMU
-	select SPARSE_IRQ
+	select SPARSE_IRQ if !SH_DEVICE_TREE
 	select HAVE_CC_STACKPROTECTOR
 
 config SUPERH64
@@ -860,7 +860,7 @@ config PCI
 	depends on SYS_SUPPORTS_PCI
 	select PCI_DOMAINS
 	select GENERIC_PCI_IOMAP
-	select NO_GENERIC_PCI_IOPORT_MAP
+	select NO_GENERIC_PCI_IOPORT_MAP if !SH_DEVICE_TREE
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
 	  bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index cfde921..d33ae46 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -15,6 +15,7 @@ config SH_DEVICE_TREE
 	select GENERIC_IOMAP
 	select COMMON_CLK
 	select SYS_SUPPORTS_PCI
+	select GENERIC_IRQ_CHIP
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3e12479..273f19d 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -244,3 +244,8 @@ config IRQ_MXS
 config MVEBU_ODMI
 	bool
 	select GENERIC_MSI_IRQ_DOMAIN
+
+config RENESAS_SH_INTC
+	def_bool y if SH_DEVICE_TREE
+	select IRQ_DOMAIN
+	select IRQ_DOMAIN_HIERARCHY
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b03cfcb..dac7e90 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -65,3 +65,4 @@ obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
 obj-$(CONFIG_PIC32_EVIC)		+= irq-pic32-evic.o
 obj-$(CONFIG_MVEBU_ODMI)		+= irq-mvebu-odmi.o
+obj-$(CONFIG_RENESAS_SH_INTC)	+= irq-renesas-sh7751.o irq-io-landisk.o
diff --git a/drivers/irqchip/irq-renesas-sh7751.c b/drivers/irqchip/irq-renesas-sh7751.c
new file mode 100644
index 0000000..ea7002a
--- /dev/null
+++ b/drivers/irqchip/irq-renesas-sh7751.c
@@ -0,0 +1,141 @@
+/*
+ * SH7751 interrupt contoller driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of.h>
+#include <linxu/io.h>
+
+static struct sh7751_intc_regs {
+	void *icr;
+	void *ipr;
+	void *intpri00;
+	void *intreq00;
+	void *intmsk00;
+	void *intmskclr00;
+} sh7751_regs;
+
+static const unsigned int ipr_table[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */
+	0x41, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 8 - 15 */
+	0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x11, /* 16 - 23 */
+	0x11, 0x11, 0x11, 0x13, 0x12, 0x12, 0xff, 0xff, /* 24 - 31 */
+	0x30, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x21, /* 32 - 39 */
+	0x21, 0x21, 0x21, 0x21, 0x32, 0x32, 0x32, 0x32, /* 40 - 47 */
+	0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 48 - 55 */
+	0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 56 - 63 */
+};
+
+static const unsigned int pri_table[] = {
+	0, 4, 4, 4, 4, 4, 4, 4,
+	8, 32, 32, 32, 12, 32, 32, 32,
+};
+
+static void sh_disable_irq(struct irq_data *data)
+{
+	int pos;
+	unsigned int addr;
+	unsigned long pri;
+	int irq = data->irq;
+	struct sh7751_intc_regs *reg = data->chip_data;
+
+	if (irq < 64) {
+		if (ipr_table[irq] != 0xff) {
+			addr = (ipr_table[irq] & 0xf0) >> 2;
+			pos = (ipr_table[irq] & 0x0f) << 4;
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->ipr + addr);
+			__raw_writew(pri, reg->ipr + addr);
+		}
+	} else {
+		if (pri_table[irq - 64] < 32) {
+			pos = pri_table[irq - 64];
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->intpri00);
+			__raw_writew(pri, reg->intpri00);
+		}
+	}
+}
+
+static void sh_enable_irq(struct irq_data *data)
+{
+	int pos;
+	unsigned int addr;
+	unsigned long pri;
+	int irq = data->irq;
+	struct sh7751_intc_regs *reg = data->chip_data;
+
+	if (irq < 64) {
+		if (ipr_table[irq] != 0xff) {
+			addr = (ipr_table[irq] & 0xf0) >> 2;
+			pos = (ipr_table[irq] & 0x0f) * 4;
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->ipr + addr);
+			pri |= 1 << pos;
+			__raw_writew(pri, reg->ipr + addr);
+		}
+	} else {
+		if (pri_table[irq - 64] < 32) {
+			pos = pri_table[irq - 64];
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->intpri00);
+			pri |= 1 << pos;
+			__raw_writew(pri, reg->intpri00);
+		}
+	}
+}
+
+static struct irq_chip sh_irq_chip = {
+	.name		= "SH-IPR",
+	.irq_unmask	= sh_enable_irq,
+	.irq_mask	= sh_disable_irq,
+};
+
+static __init int irq_map(struct irq_domain *h, unsigned int virq,
+			  irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &sh_irq_chip, handle_level_irq);
+	irq_get_irq_data(virq)->chip_data = h->host_data;
+	irq_modify_status(virq, IRQ_NOREQUEST, IRQ_NOPROBE);
+
+	return 0;
+}
+
+static struct irq_domain_ops irq_ops = {
+	.map    = irq_map,
+	.xlate  = irq_domain_xlate_onecell,
+};
+
+static int __init sh_intc_7751_init(struct device_node *intc,
+				    struct device_node *parent)
+{
+	struct irq_domain *domain;
+	void *intc_baseaddr;
+	void *intc_baseaddr2;
+
+	intc_baseaddr = of_iomap(intc, 0);
+	intc_baseaddr2 = of_iomap(intc, 1);
+	if (!intc_baseaddr || !intc_baseaddr2)
+		panic("INTC regsiter not defined");
+
+	sh7751_regs.icr = intc_baseaddr;
+	sh7751_regs.ipr = intc_baseaddr + 4;
+	sh7751_regs.intpri00 = intc_baseaddr2;
+	sh7751_regs.intreq00 = intc_baseaddr2 + 0x20;
+	sh7751_regs.intmsk00 = intc_baseaddr2 + 0x40;
+	sh7751_regs.intmskclr00 = intc_baseaddr2 + 0x60;
+
+	domain = irq_domain_add_linear(intc, NR_IRQS, &irq_ops, &sh7751_regs);
+	if (!domain)
+		panic("%s: unable to create IRQ domain\n", intc->full_name);
+
+	irq_set_default_host(domain);
+	return 0;
+}
+
+IRQCHIP_DECLARE(sh_7751_intc, "renesas,sh7751-intc", sh_intc_7751_init);
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 15/17] sh: SH-INTC helper files
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boot/dts/include/dt-bindings               | 1 +
 include/dt-bindings/interrupt-controller/sh_intc.h | 2 ++
 2 files changed, 3 insertions(+)
 create mode 120000 arch/sh/boot/dts/include/dt-bindings
 create mode 100644 include/dt-bindings/interrupt-controller/sh_intc.h

diff --git a/arch/sh/boot/dts/include/dt-bindings b/arch/sh/boot/dts/include/dt-bindings
new file mode 120000
index 0000000..08c00e4
--- /dev/null
+++ b/arch/sh/boot/dts/include/dt-bindings
@@ -0,0 +1 @@
+../../../../../include/dt-bindings
\ No newline at end of file
diff --git a/include/dt-bindings/interrupt-controller/sh_intc.h b/include/dt-bindings/interrupt-controller/sh_intc.h
new file mode 100644
index 0000000..8c9dcdc
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/sh_intc.h
@@ -0,0 +1,2 @@
+#define evt2irq(evt)		(((evt) >> 5) - 16)
+#define irq2evt(irq)		(((irq) + 16) << 5)
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 15/17] sh: SH-INTC helper files
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boot/dts/include/dt-bindings               | 1 +
 include/dt-bindings/interrupt-controller/sh_intc.h | 2 ++
 2 files changed, 3 insertions(+)
 create mode 120000 arch/sh/boot/dts/include/dt-bindings
 create mode 100644 include/dt-bindings/interrupt-controller/sh_intc.h

diff --git a/arch/sh/boot/dts/include/dt-bindings b/arch/sh/boot/dts/include/dt-bindings
new file mode 120000
index 0000000..08c00e4
--- /dev/null
+++ b/arch/sh/boot/dts/include/dt-bindings
@@ -0,0 +1 @@
+../../../../../include/dt-bindings
\ No newline at end of file
diff --git a/include/dt-bindings/interrupt-controller/sh_intc.h b/include/dt-bindings/interrupt-controller/sh_intc.h
new file mode 100644
index 0000000..8c9dcdc
--- /dev/null
+++ b/include/dt-bindings/interrupt-controller/sh_intc.h
@@ -0,0 +1,2 @@
+#define evt2irq(evt)		(((evt) >> 5) - 16)
+#define irq2evt(irq)		(((irq) + 16) << 5)
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 16/17] sh: I/O DATA HDL-U (a.k.a. landisk) Device Tree
  2016-06-12  6:54 ` Yoshinori Sato
@ 2016-06-12  6:54   ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, devicetree; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boot/dts/landisk.dts | 150 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)
 create mode 100644 arch/sh/boot/dts/landisk.dts

diff --git a/arch/sh/boot/dts/landisk.dts b/arch/sh/boot/dts/landisk.dts
new file mode 100644
index 0000000..23396a0
--- /dev/null
+++ b/arch/sh/boot/dts/landisk.dts
@@ -0,0 +1,150 @@
+#include <dt-bindings/interrupt-controller/sh_intc.h>
+
+/dts-v1/;
+/ {
+	model = "I/O DATA HDL-U";
+	compatible = "iodata,hdl-u";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&shintc>;
+	chosen {
+		stdout-path = &sci1;
+		bootargs = "console=ttySC1,115200";
+	};
+	aliases {
+		serial0 = &sci0;
+		serial1 = &sci1;
+	};
+
+	oclk: oscillator {
+                #clock-cells = <0>;
+                compatible = "fixed-clock";
+                clock-frequency = <22222222>;
+        };
+        pllclk: pllclk {
+                compatible = "renesas,sh7750-pll-clock";
+                clocks = <&oclk>;
+                #clock-cells = <0>;
+		renesas,mult = <12>;
+                reg = <0xffc00000 2>, <0xffc00008 4>;
+        };
+        iclk: iclk {
+                compatible = "renesas,sh7750-div-clock";
+                clocks = <&pllclk>;
+                #clock-cells = <0>;
+                reg = <0xffc00000 2>;
+		renesas,offset = <6>;
+		clock-output-names = "ick";
+        };
+        bclk: bclk {
+                compatible = "renesas,sh7750-div-clock";
+                clocks = <&pllclk>;
+                #clock-cells = <0>;
+                reg = <0xffc00000 2>;
+		renesas,offset = <3>;
+		clock-output-names = "bck";
+        };
+        fclk: fclk {
+                compatible = "renesas,sh7750-div-clock";
+                clocks = <&pllclk>;
+                #clock-cells = <0>;
+                reg = <0xffc00000 2>;
+		renesas,offset = <0>;
+		clock-output-names = "fck";
+        };
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu@0 {
+		      compatible = "renesas,sh4", "renesas,sh";
+		      clock-frequency = <266666666>;
+		};
+	};
+	memory@0c000000 {
+		device_type = "memory";
+		reg = <0x0c000000 0x4000000>;
+	};
+	shintc: interrupt-controller@ffd00000 {
+		compatible = "renesas,sh7751-intc";
+		#interrupt-cells = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-controller;
+		reg = <0xffd00000 14>, <0xfe080000 128>;
+
+	};
+	cpldintc: cpld@b0000000 {
+		compatible = "iodata,landisk-intc";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xb0000000 8>;
+		interrupt-map=<0 &shintc 0 0>, <1 &shintc 1 0>,
+		              <2 &shintc 2 0>, <3 &shintc 3 0>,
+		              <4 &shintc 4 0>, <5 &shintc 5 0>,
+		              <6 &shintc 6 0>, <7 &shintc 7 0>;
+	};
+	sci0: serial@ffe00000 {
+		compatible = "renesas,scif";
+		reg = <0xffe00000 0x20>;
+		interrupts = <evt2irq(0x4e0) 0
+		              evt2irq(0x500) 0
+		              evt2irq(0x540) 0
+		              evt2irq(0x520) 0>;
+		clocks = <&fclk>;
+		clock-names = "fck";
+	};
+	sci1: serial@ffe80000 {
+		compatible = "renesas,scif";
+		reg = <0xffe80000 0x100>;
+		interrupts = <evt2irq(0x700) 0
+			      evt2irq(0x720) 0
+			      evt2irq(0x760) 0
+			      evt2irq(0x740) 0>;
+		clocks = <&fclk>;
+		clock-names = "fck";
+	};
+	tmu: timer@ffd80000 {
+		compatible = "renesas,tmu";
+		reg = <0xffd80000 12>;
+		interrupts = <evt2irq(0x400) 0
+			      evt2irq(0x420) 0
+			      evt2irq(0x440) 0>;
+		clocks = <&fclk>;
+		clock-names = "fck";
+		renesas,channels-mask = <0x03>;
+	};
+
+	pci: pci-controller@fe200000 {
+		compatible = "renesas,sh7751-pci", "iodata,landisk";
+		device_type = "pci";
+		bus-range = <0 0>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>,
+		         <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>;
+		reg = <0xfe200000 0x0400>,
+		      <0x0c000000 0x04000000>,
+		      <0xff800000 0x0030>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0x1800 0 7>;
+		interrupt-map = <0x0000 0 1 &cpldintc evt2irq(0x2a0) 0
+		                 0x0000 0 2 &cpldintc evt2irq(0x2c0) 0
+		                 0x0000 0 3 &cpldintc evt2irq(0x2e0) 0
+		                 0x0000 0 4 &cpldintc evt2irq(0x300) 0
+
+		                 0x0800 0 1 &cpldintc evt2irq(0x2c0) 0
+		                 0x0800 0 2 &cpldintc evt2irq(0x2e0) 0
+		                 0x0800 0 3 &cpldintc evt2irq(0x300) 0
+		                 0x0800 0 4 &cpldintc evt2irq(0x2a0) 0
+
+		                 0x1000 0 1 &cpldintc evt2irq(0x2e0) 0
+		                 0x1000 0 2 &cpldintc evt2irq(0x300) 0
+		                 0x1000 0 3 &cpldintc evt2irq(0x2a0) 0
+		                 0x1000 0 4 &cpldintc evt2irq(0x2c0) 0
+
+		                 0x1800 0 1 &cpldintc evt2irq(0x300) 0
+		                 0x1800 0 2 &cpldintc evt2irq(0x2a0) 0
+		                 0x1800 0 3 &cpldintc evt2irq(0x2c0) 0
+		                 0x1800 0 4 &cpldintc evt2irq(0x2e0) 0>;
+	};
+};
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 16/17] sh: I/O DATA HDL-U (a.k.a. landisk) Device Tree
@ 2016-06-12  6:54   ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, devicetree; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 arch/sh/boot/dts/landisk.dts | 150 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)
 create mode 100644 arch/sh/boot/dts/landisk.dts

diff --git a/arch/sh/boot/dts/landisk.dts b/arch/sh/boot/dts/landisk.dts
new file mode 100644
index 0000000..23396a0
--- /dev/null
+++ b/arch/sh/boot/dts/landisk.dts
@@ -0,0 +1,150 @@
+#include <dt-bindings/interrupt-controller/sh_intc.h>
+
+/dts-v1/;
+/ {
+	model = "I/O DATA HDL-U";
+	compatible = "iodata,hdl-u";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	interrupt-parent = <&shintc>;
+	chosen {
+		stdout-path = &sci1;
+		bootargs = "console=ttySC1,115200";
+	};
+	aliases {
+		serial0 = &sci0;
+		serial1 = &sci1;
+	};
+
+	oclk: oscillator {
+                #clock-cells = <0>;
+                compatible = "fixed-clock";
+                clock-frequency = <22222222>;
+        };
+        pllclk: pllclk {
+                compatible = "renesas,sh7750-pll-clock";
+                clocks = <&oclk>;
+                #clock-cells = <0>;
+		renesas,mult = <12>;
+                reg = <0xffc00000 2>, <0xffc00008 4>;
+        };
+        iclk: iclk {
+                compatible = "renesas,sh7750-div-clock";
+                clocks = <&pllclk>;
+                #clock-cells = <0>;
+                reg = <0xffc00000 2>;
+		renesas,offset = <6>;
+		clock-output-names = "ick";
+        };
+        bclk: bclk {
+                compatible = "renesas,sh7750-div-clock";
+                clocks = <&pllclk>;
+                #clock-cells = <0>;
+                reg = <0xffc00000 2>;
+		renesas,offset = <3>;
+		clock-output-names = "bck";
+        };
+        fclk: fclk {
+                compatible = "renesas,sh7750-div-clock";
+                clocks = <&pllclk>;
+                #clock-cells = <0>;
+                reg = <0xffc00000 2>;
+		renesas,offset = <0>;
+		clock-output-names = "fck";
+        };
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		cpu@0 {
+		      compatible = "renesas,sh4", "renesas,sh";
+		      clock-frequency = <266666666>;
+		};
+	};
+	memory@0c000000 {
+		device_type = "memory";
+		reg = <0x0c000000 0x4000000>;
+	};
+	shintc: interrupt-controller@ffd00000 {
+		compatible = "renesas,sh7751-intc";
+		#interrupt-cells = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-controller;
+		reg = <0xffd00000 14>, <0xfe080000 128>;
+
+	};
+	cpldintc: cpld@b0000000 {
+		compatible = "iodata,landisk-intc";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xb0000000 8>;
+		interrupt-map=<0 &shintc 0 0>, <1 &shintc 1 0>,
+		              <2 &shintc 2 0>, <3 &shintc 3 0>,
+		              <4 &shintc 4 0>, <5 &shintc 5 0>,
+		              <6 &shintc 6 0>, <7 &shintc 7 0>;
+	};
+	sci0: serial@ffe00000 {
+		compatible = "renesas,scif";
+		reg = <0xffe00000 0x20>;
+		interrupts = <evt2irq(0x4e0) 0
+		              evt2irq(0x500) 0
+		              evt2irq(0x540) 0
+		              evt2irq(0x520) 0>;
+		clocks = <&fclk>;
+		clock-names = "fck";
+	};
+	sci1: serial@ffe80000 {
+		compatible = "renesas,scif";
+		reg = <0xffe80000 0x100>;
+		interrupts = <evt2irq(0x700) 0
+			      evt2irq(0x720) 0
+			      evt2irq(0x760) 0
+			      evt2irq(0x740) 0>;
+		clocks = <&fclk>;
+		clock-names = "fck";
+	};
+	tmu: timer@ffd80000 {
+		compatible = "renesas,tmu";
+		reg = <0xffd80000 12>;
+		interrupts = <evt2irq(0x400) 0
+			      evt2irq(0x420) 0
+			      evt2irq(0x440) 0>;
+		clocks = <&fclk>;
+		clock-names = "fck";
+		renesas,channels-mask = <0x03>;
+	};
+
+	pci: pci-controller@fe200000 {
+		compatible = "renesas,sh7751-pci", "iodata,landisk";
+		device_type = "pci";
+		bus-range = <0 0>;
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>,
+		         <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>;
+		reg = <0xfe200000 0x0400>,
+		      <0x0c000000 0x04000000>,
+		      <0xff800000 0x0030>;
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0x1800 0 7>;
+		interrupt-map = <0x0000 0 1 &cpldintc evt2irq(0x2a0) 0
+		                 0x0000 0 2 &cpldintc evt2irq(0x2c0) 0
+		                 0x0000 0 3 &cpldintc evt2irq(0x2e0) 0
+		                 0x0000 0 4 &cpldintc evt2irq(0x300) 0
+
+		                 0x0800 0 1 &cpldintc evt2irq(0x2c0) 0
+		                 0x0800 0 2 &cpldintc evt2irq(0x2e0) 0
+		                 0x0800 0 3 &cpldintc evt2irq(0x300) 0
+		                 0x0800 0 4 &cpldintc evt2irq(0x2a0) 0
+
+		                 0x1000 0 1 &cpldintc evt2irq(0x2e0) 0
+		                 0x1000 0 2 &cpldintc evt2irq(0x300) 0
+		                 0x1000 0 3 &cpldintc evt2irq(0x2a0) 0
+		                 0x1000 0 4 &cpldintc evt2irq(0x2c0) 0
+
+		                 0x1800 0 1 &cpldintc evt2irq(0x300) 0
+		                 0x1800 0 2 &cpldintc evt2irq(0x2a0) 0
+		                 0x1800 0 3 &cpldintc evt2irq(0x2c0) 0
+		                 0x1800 0 4 &cpldintc evt2irq(0x2e0) 0>;
+	};
+};
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 17/17] sh: landisk CPLD interrupt controller driver
  2016-06-12  6:54 ` Yoshinori Sato
  (?)
@ 2016-06-12  6:54     ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../interrupt-controller/iodata-landisk.txt        | 28 +++++++++
 drivers/irqchip/irq-io-landisk.c                   | 72 ++++++++++++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
 create mode 100644 drivers/irqchip/irq-io-landisk.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
new file mode 100644
index 0000000..d398538
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
@@ -0,0 +1,28 @@
+DT bindings for the I/O DATA HDL-U interrupt controller
+
+Required properties:
+
+  - compatible: has to be "iodata,landisk-intc".
+
+  - reg: Base address and length of interrupt controller register.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+
+  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
+    in interrupts.txt in this directory.
+
+  - interrupt-map: Interrupt mapping on parent controller.
+
+Example
+-------
+
+	cpldintc: cpld@b0000000 {
+		compatible = "iodata,landisk-intc";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xb0000000 8>;
+		interrupt-map=<0 &shintc 0 0>, <1 &shintc 1 0>,
+		              <2 &shintc 2 0>, <3 &shintc 3 0>,
+		              <4 &shintc 4 0>, <5 &shintc 5 0>,
+		              <6 &shintc 6 0>, <7 &shintc 7 0>;
+	};
diff --git a/drivers/irqchip/irq-io-landisk.c b/drivers/irqchip/irq-io-landisk.c
new file mode 100644
index 0000000..973c4fb
--- /dev/null
+++ b/drivers/irqchip/irq-io-landisk.c
@@ -0,0 +1,72 @@
+/*
+ * IO-DATA LANDISK CPLD IRQ driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+
+static void landisk_mask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask &= !(1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static void landisk_unmask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask |= (1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static struct irq_chip cpld_irq_chip = {
+	.name		= "LANDISK-CPLD",
+	.irq_unmask	= landisk_unmask_irq,
+	.irq_mask	= landisk_mask_irq,
+};
+
+static int cpld_map(struct irq_domain *d, unsigned int virq,
+		    irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &cpld_irq_chip,
+				 handle_simple_irq);
+	irq_set_chip_data(virq, d->host_data);
+
+	return 0;
+}
+
+static struct irq_domain_ops irq_ops = {
+	.xlate	= irq_domain_xlate_twocell,
+	.map	= cpld_map,
+};
+
+static int __init landisk_intc_of_init(struct device_node *intc,
+				    struct device_node *parent)
+{
+	struct irq_domain *domain, *pdomain;
+	int num_irqpin;
+	void *baseaddr;
+
+	baseaddr = of_iomap(intc, 0);
+	pdomain = irq_find_host(parent);
+	of_get_property(intc, "interrupt-map", &num_irqpin);
+	num_irqpin /= sizeof(u32) * 3;
+	domain = irq_domain_create_hierarchy(pdomain, 0, num_irqpin,
+					     of_node_to_fwnode(intc),
+					     &irq_ops, baseaddr);
+	if (!domain)
+		panic"%s: unable to create IRQ domain\n", intc->full_name);
+	irq_domain_associate_many(domain, 0, 0, 8);
+	return 0;
+}
+
+IRQCHIP_DECLARE(cpld_intc, "iodata,landisk-intc", landisk_intc_of_init);
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 17/17] sh: landisk CPLD interrupt controller driver
@ 2016-06-12  6:54     ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh, linux-kernel, devicetree; +Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../interrupt-controller/iodata-landisk.txt        | 28 +++++++++
 drivers/irqchip/irq-io-landisk.c                   | 72 ++++++++++++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
 create mode 100644 drivers/irqchip/irq-io-landisk.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
new file mode 100644
index 0000000..d398538
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
@@ -0,0 +1,28 @@
+DT bindings for the I/O DATA HDL-U interrupt controller
+
+Required properties:
+
+  - compatible: has to be "iodata,landisk-intc".
+
+  - reg: Base address and length of interrupt controller register.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+
+  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
+    in interrupts.txt in this directory.
+
+  - interrupt-map: Interrupt mapping on parent controller.
+
+Example
+-------
+
+	cpldintc: cpld@b0000000 {
+		compatible = "iodata,landisk-intc";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xb0000000 8>;
+		interrupt-map=<0 &shintc 0 0>, <1 &shintc 1 0>,
+		              <2 &shintc 2 0>, <3 &shintc 3 0>,
+		              <4 &shintc 4 0>, <5 &shintc 5 0>,
+		              <6 &shintc 6 0>, <7 &shintc 7 0>;
+	};
diff --git a/drivers/irqchip/irq-io-landisk.c b/drivers/irqchip/irq-io-landisk.c
new file mode 100644
index 0000000..973c4fb
--- /dev/null
+++ b/drivers/irqchip/irq-io-landisk.c
@@ -0,0 +1,72 @@
+/*
+ * IO-DATA LANDISK CPLD IRQ driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+
+static void landisk_mask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask &= !(1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static void landisk_unmask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask |= (1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static struct irq_chip cpld_irq_chip = {
+	.name		= "LANDISK-CPLD",
+	.irq_unmask	= landisk_unmask_irq,
+	.irq_mask	= landisk_mask_irq,
+};
+
+static int cpld_map(struct irq_domain *d, unsigned int virq,
+		    irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &cpld_irq_chip,
+				 handle_simple_irq);
+	irq_set_chip_data(virq, d->host_data);
+
+	return 0;
+}
+
+static struct irq_domain_ops irq_ops = {
+	.xlate	= irq_domain_xlate_twocell,
+	.map	= cpld_map,
+};
+
+static int __init landisk_intc_of_init(struct device_node *intc,
+				    struct device_node *parent)
+{
+	struct irq_domain *domain, *pdomain;
+	int num_irqpin;
+	void *baseaddr;
+
+	baseaddr = of_iomap(intc, 0);
+	pdomain = irq_find_host(parent);
+	of_get_property(intc, "interrupt-map", &num_irqpin);
+	num_irqpin /= sizeof(u32) * 3;
+	domain = irq_domain_create_hierarchy(pdomain, 0, num_irqpin,
+					     of_node_to_fwnode(intc),
+					     &irq_ops, baseaddr);
+	if (!domain)
+		panic"%s: unable to create IRQ domain\n", intc->full_name);
+	irq_domain_associate_many(domain, 0, 0, 8);
+	return 0;
+}
+
+IRQCHIP_DECLARE(cpld_intc, "iodata,landisk-intc", landisk_intc_of_init);
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 17/17] sh: landisk CPLD interrupt controller driver
@ 2016-06-12  6:54     ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  6:54 UTC (permalink / raw)
  To: linux-sh-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA
  Cc: Yoshinori Sato

Signed-off-by: Yoshinori Sato <ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org>
---
 .../interrupt-controller/iodata-landisk.txt        | 28 +++++++++
 drivers/irqchip/irq-io-landisk.c                   | 72 ++++++++++++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
 create mode 100644 drivers/irqchip/irq-io-landisk.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
new file mode 100644
index 0000000..d398538
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
@@ -0,0 +1,28 @@
+DT bindings for the I/O DATA HDL-U interrupt controller
+
+Required properties:
+
+  - compatible: has to be "iodata,landisk-intc".
+
+  - reg: Base address and length of interrupt controller register.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+
+  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
+    in interrupts.txt in this directory.
+
+  - interrupt-map: Interrupt mapping on parent controller.
+
+Example
+-------
+
+	cpldintc: cpld@b0000000 {
+		compatible = "iodata,landisk-intc";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xb0000000 8>;
+		interrupt-map=<0 &shintc 0 0>, <1 &shintc 1 0>,
+		              <2 &shintc 2 0>, <3 &shintc 3 0>,
+		              <4 &shintc 4 0>, <5 &shintc 5 0>,
+		              <6 &shintc 6 0>, <7 &shintc 7 0>;
+	};
diff --git a/drivers/irqchip/irq-io-landisk.c b/drivers/irqchip/irq-io-landisk.c
new file mode 100644
index 0000000..973c4fb
--- /dev/null
+++ b/drivers/irqchip/irq-io-landisk.c
@@ -0,0 +1,72 @@
+/*
+ * IO-DATA LANDISK CPLD IRQ driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org>
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+
+static void landisk_mask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask &= !(1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static void landisk_unmask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask |= (1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static struct irq_chip cpld_irq_chip = {
+	.name		= "LANDISK-CPLD",
+	.irq_unmask	= landisk_unmask_irq,
+	.irq_mask	= landisk_mask_irq,
+};
+
+static int cpld_map(struct irq_domain *d, unsigned int virq,
+		    irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &cpld_irq_chip,
+				 handle_simple_irq);
+	irq_set_chip_data(virq, d->host_data);
+
+	return 0;
+}
+
+static struct irq_domain_ops irq_ops = {
+	.xlate	= irq_domain_xlate_twocell,
+	.map	= cpld_map,
+};
+
+static int __init landisk_intc_of_init(struct device_node *intc,
+				    struct device_node *parent)
+{
+	struct irq_domain *domain, *pdomain;
+	int num_irqpin;
+	void *baseaddr;
+
+	baseaddr = of_iomap(intc, 0);
+	pdomain = irq_find_host(parent);
+	of_get_property(intc, "interrupt-map", &num_irqpin);
+	num_irqpin /= sizeof(u32) * 3;
+	domain = irq_domain_create_hierarchy(pdomain, 0, num_irqpin,
+					     of_node_to_fwnode(intc),
+					     &irq_ops, baseaddr);
+	if (!domain)
+		panic"%s: unable to create IRQ domain\n", intc->full_name);
+	irq_domain_associate_many(domain, 0, 0, 8);
+	return 0;
+}
+
+IRQCHIP_DECLARE(cpld_intc, "iodata,landisk-intc", landisk_intc_of_init);
-- 
2.7.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 14/17] sh: SH3/4 Generic IRQCHIP driever
  2016-06-12  6:54   ` Yoshinori Sato
@ 2016-06-12  7:43     ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  7:43 UTC (permalink / raw)
  To: linux-sh, linux-kernel, devicetree; +Cc: Yoshinori Sato

Sorry. I send old patches.
Please ignore previous files.

IPR based IRQ chip driver.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../interrupt-controller/renesas,sh7751-intc.txt   |  25 ++++
 arch/sh/Kconfig                                    |   6 +-
 arch/sh/boards/Kconfig                             |   1 +
 drivers/irqchip/Kconfig                            |   5 +
 drivers/irqchip/Makefile                           |   1 +
 drivers/irqchip/irq-renesas-sh7751.c               | 141 +++++++++++++++++++++
 6 files changed, 176 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
 create mode 100644 drivers/irqchip/irq-renesas-sh7751.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
new file mode 100644
index 0000000..2bc6f22f
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
@@ -0,0 +1,25 @@
+DT bindings for the SH7751 interrupt controller
+
+Required properties:
+
+  - compatible: has to be "renesas,sh7751-intc".
+
+  - reg: Base address and length of interrupt controller register
+         and extend register.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+
+  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
+    in interrupts.txt in this directory.
+
+Example
+-------
+
+	shintc: interrupt-controller@ffd00000 {
+		compatible = "renesas,sh7751-intc";
+		#interrupt-cells = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-controller;
+		reg = <0xffd00000 14>, <0xfe080000 128>;
+	};
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 4fa5894..f268277 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -28,7 +28,7 @@ config SUPERH
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_REGS_AND_STACK_ACCESS_API
-	select MAY_HAVE_SPARSE_IRQ
+	select MAY_HAVE_SPARSE_IRQ if !SH_DEVICE_TREE
 	select IRQ_FORCED_THREADING
 	select RTC_LIB
 	select GENERIC_ATOMIC64
@@ -67,7 +67,7 @@ config SUPERH32
 	select HAVE_MIXED_BREAKPOINTS_REGS
 	select PERF_EVENTS
 	select ARCH_HIBERNATION_POSSIBLE if MMU
-	select SPARSE_IRQ
+	select SPARSE_IRQ if !SH_DEVICE_TREE
 	select HAVE_CC_STACKPROTECTOR
 
 config SUPERH64
@@ -860,7 +860,7 @@ config PCI
 	depends on SYS_SUPPORTS_PCI
 	select PCI_DOMAINS
 	select GENERIC_PCI_IOMAP
-	select NO_GENERIC_PCI_IOPORT_MAP
+	select NO_GENERIC_PCI_IOPORT_MAP if !SH_DEVICE_TREE
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
 	  bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index cfde921..d33ae46 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -15,6 +15,7 @@ config SH_DEVICE_TREE
 	select GENERIC_IOMAP
 	select COMMON_CLK
 	select SYS_SUPPORTS_PCI
+	select GENERIC_IRQ_CHIP
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3e12479..273f19d 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -244,3 +244,8 @@ config IRQ_MXS
 config MVEBU_ODMI
 	bool
 	select GENERIC_MSI_IRQ_DOMAIN
+
+config RENESAS_SH_INTC
+	def_bool y if SH_DEVICE_TREE
+	select IRQ_DOMAIN
+	select IRQ_DOMAIN_HIERARCHY
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b03cfcb..dac7e90 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -65,3 +65,4 @@ obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
 obj-$(CONFIG_PIC32_EVIC)		+= irq-pic32-evic.o
 obj-$(CONFIG_MVEBU_ODMI)		+= irq-mvebu-odmi.o
+obj-$(CONFIG_RENESAS_SH_INTC)	+= irq-renesas-sh7751.o irq-io-landisk.o
diff --git a/drivers/irqchip/irq-renesas-sh7751.c b/drivers/irqchip/irq-renesas-sh7751.c
new file mode 100644
index 0000000..1710978
--- /dev/null
+++ b/drivers/irqchip/irq-renesas-sh7751.c
@@ -0,0 +1,141 @@
+/*
+ * SH7751 interrupt contoller driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of.h>
+#include <linux/io.h>
+
+static struct sh7751_intc_regs {
+	void *icr;
+	void *ipr;
+	void *intpri00;
+	void *intreq00;
+	void *intmsk00;
+	void *intmskclr00;
+} sh7751_regs;
+
+static const unsigned int ipr_table[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */
+	0x41, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 8 - 15 */
+	0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x11, /* 16 - 23 */
+	0x11, 0x11, 0x11, 0x13, 0x12, 0x12, 0xff, 0xff, /* 24 - 31 */
+	0x30, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x21, /* 32 - 39 */
+	0x21, 0x21, 0x21, 0x21, 0x32, 0x32, 0x32, 0x32, /* 40 - 47 */
+	0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 48 - 55 */
+	0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 56 - 63 */
+};
+
+static const unsigned int pri_table[] = {
+	0, 4, 4, 4, 4, 4, 4, 4,
+	8, 32, 32, 32, 12, 32, 32, 32,
+};
+
+static void sh_disable_irq(struct irq_data *data)
+{
+	int pos;
+	unsigned int addr;
+	unsigned long pri;
+	int irq = data->irq;
+	struct sh7751_intc_regs *reg = data->chip_data;
+
+	if (irq < 64) {
+		if (ipr_table[irq] != 0xff) {
+			addr = (ipr_table[irq] & 0xf0) >> 2;
+			pos = (ipr_table[irq] & 0x0f) << 4;
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->ipr + addr);
+			__raw_writew(pri, reg->ipr + addr);
+		}
+	} else {
+		if (pri_table[irq - 64] < 32) {
+			pos = pri_table[irq - 64];
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->intpri00);
+			__raw_writew(pri, reg->intpri00);
+		}
+	}
+}
+
+static void sh_enable_irq(struct irq_data *data)
+{
+	int pos;
+	unsigned int addr;
+	unsigned long pri;
+	int irq = data->irq;
+	struct sh7751_intc_regs *reg = data->chip_data;
+
+	if (irq < 64) {
+		if (ipr_table[irq] != 0xff) {
+			addr = (ipr_table[irq] & 0xf0) >> 2;
+			pos = (ipr_table[irq] & 0x0f) * 4;
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->ipr + addr);
+			pri |= 1 << pos;
+			__raw_writew(pri, reg->ipr + addr);
+		}
+	} else {
+		if (pri_table[irq - 64] < 32) {
+			pos = pri_table[irq - 64];
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->intpri00);
+			pri |= 1 << pos;
+			__raw_writew(pri, reg->intpri00);
+		}
+	}
+}
+
+static struct irq_chip sh_irq_chip = {
+	.name		= "SH-IPR",
+	.irq_unmask	= sh_enable_irq,
+	.irq_mask	= sh_disable_irq,
+};
+
+static __init int irq_map(struct irq_domain *h, unsigned int virq,
+			  irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &sh_irq_chip, handle_level_irq);
+	irq_get_irq_data(virq)->chip_data = h->host_data;
+	irq_modify_status(virq, IRQ_NOREQUEST, IRQ_NOPROBE);
+
+	return 0;
+}
+
+static struct irq_domain_ops irq_ops = {
+	.map    = irq_map,
+	.xlate  = irq_domain_xlate_onecell,
+};
+
+static int __init sh_intc_7751_init(struct device_node *intc,
+				    struct device_node *parent)
+{
+	struct irq_domain *domain;
+	void *intc_baseaddr;
+	void *intc_baseaddr2;
+
+	intc_baseaddr = of_iomap(intc, 0);
+	intc_baseaddr2 = of_iomap(intc, 1);
+	if (!intc_baseaddr || !intc_baseaddr2)
+		panic("INTC regsiter not defined");
+
+	sh7751_regs.icr = intc_baseaddr;
+	sh7751_regs.ipr = intc_baseaddr + 4;
+	sh7751_regs.intpri00 = intc_baseaddr2;
+	sh7751_regs.intreq00 = intc_baseaddr2 + 0x20;
+	sh7751_regs.intmsk00 = intc_baseaddr2 + 0x40;
+	sh7751_regs.intmskclr00 = intc_baseaddr2 + 0x60;
+
+	domain = irq_domain_add_linear(intc, NR_IRQS, &irq_ops, &sh7751_regs);
+	if (!domain)
+		panic("%s: unable to create IRQ domain\n", intc->full_name);
+
+	irq_set_default_host(domain);
+	return 0;
+}
+
+IRQCHIP_DECLARE(sh_7751_intc, "renesas,sh7751-intc", sh_intc_7751_init);
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 14/17] sh: SH3/4 Generic IRQCHIP driever
@ 2016-06-12  7:43     ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  7:43 UTC (permalink / raw)
  To: linux-sh, linux-kernel, devicetree; +Cc: Yoshinori Sato

Sorry. I send old patches.
Please ignore previous files.

IPR based IRQ chip driver.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../interrupt-controller/renesas,sh7751-intc.txt   |  25 ++++
 arch/sh/Kconfig                                    |   6 +-
 arch/sh/boards/Kconfig                             |   1 +
 drivers/irqchip/Kconfig                            |   5 +
 drivers/irqchip/Makefile                           |   1 +
 drivers/irqchip/irq-renesas-sh7751.c               | 141 +++++++++++++++++++++
 6 files changed, 176 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
 create mode 100644 drivers/irqchip/irq-renesas-sh7751.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
new file mode 100644
index 0000000..2bc6f22f
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
@@ -0,0 +1,25 @@
+DT bindings for the SH7751 interrupt controller
+
+Required properties:
+
+  - compatible: has to be "renesas,sh7751-intc".
+
+  - reg: Base address and length of interrupt controller register
+         and extend register.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+
+  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
+    in interrupts.txt in this directory.
+
+Example
+-------
+
+	shintc: interrupt-controller@ffd00000 {
+		compatible = "renesas,sh7751-intc";
+		#interrupt-cells = <2>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		interrupt-controller;
+		reg = <0xffd00000 14>, <0xfe080000 128>;
+	};
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 4fa5894..f268277 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -28,7 +28,7 @@ config SUPERH
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_REGS_AND_STACK_ACCESS_API
-	select MAY_HAVE_SPARSE_IRQ
+	select MAY_HAVE_SPARSE_IRQ if !SH_DEVICE_TREE
 	select IRQ_FORCED_THREADING
 	select RTC_LIB
 	select GENERIC_ATOMIC64
@@ -67,7 +67,7 @@ config SUPERH32
 	select HAVE_MIXED_BREAKPOINTS_REGS
 	select PERF_EVENTS
 	select ARCH_HIBERNATION_POSSIBLE if MMU
-	select SPARSE_IRQ
+	select SPARSE_IRQ if !SH_DEVICE_TREE
 	select HAVE_CC_STACKPROTECTOR
 
 config SUPERH64
@@ -860,7 +860,7 @@ config PCI
 	depends on SYS_SUPPORTS_PCI
 	select PCI_DOMAINS
 	select GENERIC_PCI_IOMAP
-	select NO_GENERIC_PCI_IOPORT_MAP
+	select NO_GENERIC_PCI_IOPORT_MAP if !SH_DEVICE_TREE
 	help
 	  Find out whether you have a PCI motherboard. PCI is the name of a
 	  bus system, i.e. the way the CPU talks to the other stuff inside
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index cfde921..d33ae46 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -15,6 +15,7 @@ config SH_DEVICE_TREE
 	select GENERIC_IOMAP
 	select COMMON_CLK
 	select SYS_SUPPORTS_PCI
+	select GENERIC_IRQ_CHIP
 	help
 	  Select Board Described by Device Tree to build a kernel that
 	  does not hard-code any board-specific knowledge but instead uses
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3e12479..273f19d 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -244,3 +244,8 @@ config IRQ_MXS
 config MVEBU_ODMI
 	bool
 	select GENERIC_MSI_IRQ_DOMAIN
+
+config RENESAS_SH_INTC
+	def_bool y if SH_DEVICE_TREE
+	select IRQ_DOMAIN
+	select IRQ_DOMAIN_HIERARCHY
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b03cfcb..dac7e90 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -65,3 +65,4 @@ obj-$(CONFIG_INGENIC_IRQ)		+= irq-ingenic.o
 obj-$(CONFIG_IMX_GPCV2)			+= irq-imx-gpcv2.o
 obj-$(CONFIG_PIC32_EVIC)		+= irq-pic32-evic.o
 obj-$(CONFIG_MVEBU_ODMI)		+= irq-mvebu-odmi.o
+obj-$(CONFIG_RENESAS_SH_INTC)	+= irq-renesas-sh7751.o irq-io-landisk.o
diff --git a/drivers/irqchip/irq-renesas-sh7751.c b/drivers/irqchip/irq-renesas-sh7751.c
new file mode 100644
index 0000000..1710978
--- /dev/null
+++ b/drivers/irqchip/irq-renesas-sh7751.c
@@ -0,0 +1,141 @@
+/*
+ * SH7751 interrupt contoller driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of.h>
+#include <linux/io.h>
+
+static struct sh7751_intc_regs {
+	void *icr;
+	void *ipr;
+	void *intpri00;
+	void *intreq00;
+	void *intmsk00;
+	void *intmskclr00;
+} sh7751_regs;
+
+static const unsigned int ipr_table[] = {
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */
+	0x41, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 8 - 15 */
+	0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x11, /* 16 - 23 */
+	0x11, 0x11, 0x11, 0x13, 0x12, 0x12, 0xff, 0xff, /* 24 - 31 */
+	0x30, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x21, /* 32 - 39 */
+	0x21, 0x21, 0x21, 0x21, 0x32, 0x32, 0x32, 0x32, /* 40 - 47 */
+	0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 48 - 55 */
+	0xff, 0xff, 0xff, 0x40, 0xff, 0xff, 0xff, 0xff, /* 56 - 63 */
+};
+
+static const unsigned int pri_table[] = {
+	0, 4, 4, 4, 4, 4, 4, 4,
+	8, 32, 32, 32, 12, 32, 32, 32,
+};
+
+static void sh_disable_irq(struct irq_data *data)
+{
+	int pos;
+	unsigned int addr;
+	unsigned long pri;
+	int irq = data->irq;
+	struct sh7751_intc_regs *reg = data->chip_data;
+
+	if (irq < 64) {
+		if (ipr_table[irq] != 0xff) {
+			addr = (ipr_table[irq] & 0xf0) >> 2;
+			pos = (ipr_table[irq] & 0x0f) << 4;
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->ipr + addr);
+			__raw_writew(pri, reg->ipr + addr);
+		}
+	} else {
+		if (pri_table[irq - 64] < 32) {
+			pos = pri_table[irq - 64];
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->intpri00);
+			__raw_writew(pri, reg->intpri00);
+		}
+	}
+}
+
+static void sh_enable_irq(struct irq_data *data)
+{
+	int pos;
+	unsigned int addr;
+	unsigned long pri;
+	int irq = data->irq;
+	struct sh7751_intc_regs *reg = data->chip_data;
+
+	if (irq < 64) {
+		if (ipr_table[irq] != 0xff) {
+			addr = (ipr_table[irq] & 0xf0) >> 2;
+			pos = (ipr_table[irq] & 0x0f) * 4;
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->ipr + addr);
+			pri |= 1 << pos;
+			__raw_writew(pri, reg->ipr + addr);
+		}
+	} else {
+		if (pri_table[irq - 64] < 32) {
+			pos = pri_table[irq - 64];
+			pri = ~(0x000f << pos);
+			pri &= __raw_readw(reg->intpri00);
+			pri |= 1 << pos;
+			__raw_writew(pri, reg->intpri00);
+		}
+	}
+}
+
+static struct irq_chip sh_irq_chip = {
+	.name		= "SH-IPR",
+	.irq_unmask	= sh_enable_irq,
+	.irq_mask	= sh_disable_irq,
+};
+
+static __init int irq_map(struct irq_domain *h, unsigned int virq,
+			  irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &sh_irq_chip, handle_level_irq);
+	irq_get_irq_data(virq)->chip_data = h->host_data;
+	irq_modify_status(virq, IRQ_NOREQUEST, IRQ_NOPROBE);
+
+	return 0;
+}
+
+static struct irq_domain_ops irq_ops = {
+	.map    = irq_map,
+	.xlate  = irq_domain_xlate_onecell,
+};
+
+static int __init sh_intc_7751_init(struct device_node *intc,
+				    struct device_node *parent)
+{
+	struct irq_domain *domain;
+	void *intc_baseaddr;
+	void *intc_baseaddr2;
+
+	intc_baseaddr = of_iomap(intc, 0);
+	intc_baseaddr2 = of_iomap(intc, 1);
+	if (!intc_baseaddr || !intc_baseaddr2)
+		panic("INTC regsiter not defined");
+
+	sh7751_regs.icr = intc_baseaddr;
+	sh7751_regs.ipr = intc_baseaddr + 4;
+	sh7751_regs.intpri00 = intc_baseaddr2;
+	sh7751_regs.intreq00 = intc_baseaddr2 + 0x20;
+	sh7751_regs.intmsk00 = intc_baseaddr2 + 0x40;
+	sh7751_regs.intmskclr00 = intc_baseaddr2 + 0x60;
+
+	domain = irq_domain_add_linear(intc, NR_IRQS, &irq_ops, &sh7751_regs);
+	if (!domain)
+		panic("%s: unable to create IRQ domain\n", intc->full_name);
+
+	irq_set_default_host(domain);
+	return 0;
+}
+
+IRQCHIP_DECLARE(sh_7751_intc, "renesas,sh7751-intc", sh_intc_7751_init);
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 17/17] sh: landisk CPLD interrupt controller driver
  2016-06-12  6:54     ` Yoshinori Sato
@ 2016-06-12  7:44       ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  7:44 UTC (permalink / raw)
  To: linux-sh, linux-kernel, devicetree; +Cc: Yoshinori Sato

Sorry. I send old patches.
Please ignore previous files.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../interrupt-controller/iodata-landisk.txt        | 28 +++++++++
 drivers/irqchip/irq-io-landisk.c                   | 72 ++++++++++++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
 create mode 100644 drivers/irqchip/irq-io-landisk.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
new file mode 100644
index 0000000..d398538
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
@@ -0,0 +1,28 @@
+DT bindings for the I/O DATA HDL-U interrupt controller
+
+Required properties:
+
+  - compatible: has to be "iodata,landisk-intc".
+
+  - reg: Base address and length of interrupt controller register.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+
+  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
+    in interrupts.txt in this directory.
+
+  - interrupt-map: Interrupt mapping on parent controller.
+
+Example
+-------
+
+	cpldintc: cpld@b0000000 {
+		compatible = "iodata,landisk-intc";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xb0000000 8>;
+		interrupt-map=<0 &shintc 0 0>, <1 &shintc 1 0>,
+		              <2 &shintc 2 0>, <3 &shintc 3 0>,
+		              <4 &shintc 4 0>, <5 &shintc 5 0>,
+		              <6 &shintc 6 0>, <7 &shintc 7 0>;
+	};
diff --git a/drivers/irqchip/irq-io-landisk.c b/drivers/irqchip/irq-io-landisk.c
new file mode 100644
index 0000000..7db20d6
--- /dev/null
+++ b/drivers/irqchip/irq-io-landisk.c
@@ -0,0 +1,72 @@
+/*
+ * IO-DATA LANDISK CPLD IRQ driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+
+static void landisk_mask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask &= !(1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static void landisk_unmask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask |= (1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static struct irq_chip cpld_irq_chip = {
+	.name		= "LANDISK-CPLD",
+	.irq_unmask	= landisk_unmask_irq,
+	.irq_mask	= landisk_mask_irq,
+};
+
+static int cpld_map(struct irq_domain *d, unsigned int virq,
+		    irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &cpld_irq_chip,
+				 handle_simple_irq);
+	irq_set_chip_data(virq, d->host_data);
+
+	return 0;
+}
+
+static struct irq_domain_ops irq_ops = {
+	.xlate	= irq_domain_xlate_twocell,
+	.map	= cpld_map,
+};
+
+static int __init landisk_intc_of_init(struct device_node *intc,
+				    struct device_node *parent)
+{
+	struct irq_domain *domain, *pdomain;
+	int num_irqpin;
+	void *baseaddr;
+
+	baseaddr = of_iomap(intc, 0);
+	pdomain = irq_find_host(parent);
+	of_get_property(intc, "interrupt-map", &num_irqpin);
+	num_irqpin /= sizeof(u32) * 3;
+	domain = irq_domain_create_hierarchy(pdomain, 0, num_irqpin,
+					     of_node_to_fwnode(intc),
+					     &irq_ops, baseaddr);
+	if (!domain)
+		panic("%s: unable to create IRQ domain\n", intc->full_name);
+	irq_domain_associate_many(domain, 0, 0, 8);
+	return 0;
+}
+
+IRQCHIP_DECLARE(cpld_intc, "iodata,landisk-intc", landisk_intc_of_init);
-- 
2.7.0


^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [PATCH v2 17/17] sh: landisk CPLD interrupt controller driver
@ 2016-06-12  7:44       ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-12  7:44 UTC (permalink / raw)
  To: linux-sh, linux-kernel, devicetree; +Cc: Yoshinori Sato

Sorry. I send old patches.
Please ignore previous files.

Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
---
 .../interrupt-controller/iodata-landisk.txt        | 28 +++++++++
 drivers/irqchip/irq-io-landisk.c                   | 72 ++++++++++++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
 create mode 100644 drivers/irqchip/irq-io-landisk.c

diff --git a/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
new file mode 100644
index 0000000..d398538
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
@@ -0,0 +1,28 @@
+DT bindings for the I/O DATA HDL-U interrupt controller
+
+Required properties:
+
+  - compatible: has to be "iodata,landisk-intc".
+
+  - reg: Base address and length of interrupt controller register.
+
+  - interrupt-controller: Identifies the node as an interrupt controller.
+
+  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
+    in interrupts.txt in this directory.
+
+  - interrupt-map: Interrupt mapping on parent controller.
+
+Example
+-------
+
+	cpldintc: cpld@b0000000 {
+		compatible = "iodata,landisk-intc";
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		reg = <0xb0000000 8>;
+		interrupt-map=<0 &shintc 0 0>, <1 &shintc 1 0>,
+		              <2 &shintc 2 0>, <3 &shintc 3 0>,
+		              <4 &shintc 4 0>, <5 &shintc 5 0>,
+		              <6 &shintc 6 0>, <7 &shintc 7 0>;
+	};
diff --git a/drivers/irqchip/irq-io-landisk.c b/drivers/irqchip/irq-io-landisk.c
new file mode 100644
index 0000000..7db20d6
--- /dev/null
+++ b/drivers/irqchip/irq-io-landisk.c
@@ -0,0 +1,72 @@
+/*
+ * IO-DATA LANDISK CPLD IRQ driver
+ *
+ * Copyright 2016 Yoshinori Sato <ysato@users.sourceforge.jp>
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdomain.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/io.h>
+
+static void landisk_mask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask &= !(1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static void landisk_unmask_irq(struct irq_data *data)
+{
+	u8 mask = __raw_readb(data->chip_data + 5);
+
+	mask |= (1 << (data->irq - 5));
+	__raw_writeb(mask, data->chip_data + 5);
+}
+
+static struct irq_chip cpld_irq_chip = {
+	.name		= "LANDISK-CPLD",
+	.irq_unmask	= landisk_unmask_irq,
+	.irq_mask	= landisk_mask_irq,
+};
+
+static int cpld_map(struct irq_domain *d, unsigned int virq,
+		    irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &cpld_irq_chip,
+				 handle_simple_irq);
+	irq_set_chip_data(virq, d->host_data);
+
+	return 0;
+}
+
+static struct irq_domain_ops irq_ops = {
+	.xlate	= irq_domain_xlate_twocell,
+	.map	= cpld_map,
+};
+
+static int __init landisk_intc_of_init(struct device_node *intc,
+				    struct device_node *parent)
+{
+	struct irq_domain *domain, *pdomain;
+	int num_irqpin;
+	void *baseaddr;
+
+	baseaddr = of_iomap(intc, 0);
+	pdomain = irq_find_host(parent);
+	of_get_property(intc, "interrupt-map", &num_irqpin);
+	num_irqpin /= sizeof(u32) * 3;
+	domain = irq_domain_create_hierarchy(pdomain, 0, num_irqpin,
+					     of_node_to_fwnode(intc),
+					     &irq_ops, baseaddr);
+	if (!domain)
+		panic("%s: unable to create IRQ domain\n", intc->full_name);
+	irq_domain_associate_many(domain, 0, 0, 8);
+	return 0;
+}
+
+IRQCHIP_DECLARE(cpld_intc, "iodata,landisk-intc", landisk_intc_of_init);
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 01/17] sh: Add sh-specific early_init_dt_reserve_memory_arch
  2016-06-12  6:54   ` Yoshinori Sato
@ 2016-06-12 11:29     ` Sergei Shtylyov
  -1 siblings, 0 replies; 68+ messages in thread
From: Sergei Shtylyov @ 2016-06-12 11:29 UTC (permalink / raw)
  To: Yoshinori Sato, linux-sh, linux-kernel

On 6/12/2016 9:54 AM, Yoshinori Sato wrote:

> sh used P1 address space in early device tree.
> So need convert P1 to physical address before reserve memory.
>
> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  arch/sh/boards/of-generic.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
> index 57d45dc..fe2d917 100644
> --- a/arch/sh/boards/of-generic.c
> +++ b/arch/sh/boards/of-generic.c
[...]
> @@ -203,3 +204,14 @@ static int __init sh_of_device_init(void)
>  	return 0;
>  }
>  arch_initcall_sync(sh_of_device_init);
> +
> +int __init early_init_dt_reserve_memory_arch(phys_addr_t base,
> +					     phys_addr_t size, bool nomap)
> +{
> +	if (nomap)
> +		return memblock_remove(base, size);
> +
> +	if (base >= P1SEG)
> +		base = base & ~P1SEG;

		base &= ~P1SEG;

> +	return memblock_reserve(base, size);
> +}

MBR, Sergei


^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 01/17] sh: Add sh-specific early_init_dt_reserve_memory_arch
@ 2016-06-12 11:29     ` Sergei Shtylyov
  0 siblings, 0 replies; 68+ messages in thread
From: Sergei Shtylyov @ 2016-06-12 11:29 UTC (permalink / raw)
  To: Yoshinori Sato, linux-sh, linux-kernel

On 6/12/2016 9:54 AM, Yoshinori Sato wrote:

> sh used P1 address space in early device tree.
> So need convert P1 to physical address before reserve memory.
>
> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  arch/sh/boards/of-generic.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c
> index 57d45dc..fe2d917 100644
> --- a/arch/sh/boards/of-generic.c
> +++ b/arch/sh/boards/of-generic.c
[...]
> @@ -203,3 +204,14 @@ static int __init sh_of_device_init(void)
>  	return 0;
>  }
>  arch_initcall_sync(sh_of_device_init);
> +
> +int __init early_init_dt_reserve_memory_arch(phys_addr_t base,
> +					     phys_addr_t size, bool nomap)
> +{
> +	if (nomap)
> +		return memblock_remove(base, size);
> +
> +	if (base >= P1SEG)
> +		base = base & ~P1SEG;

		base &= ~P1SEG;

> +	return memblock_reserve(base, size);
> +}

MBR, Sergei

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 05/17] sh: command line passing chosen/bootargs in devicetree
  2016-06-12  6:54   ` Yoshinori Sato
@ 2016-06-12 11:32     ` Sergei Shtylyov
  -1 siblings, 0 replies; 68+ messages in thread
From: Sergei Shtylyov @ 2016-06-12 11:32 UTC (permalink / raw)
  To: Yoshinori Sato, linux-sh, linux-kernel

On 6/12/2016 9:54 AM, Yoshinori Sato wrote:

> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  arch/sh/kernel/setup.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
> index 8e3b099..d97de16 100644
> --- a/arch/sh/kernel/setup.c
> +++ b/arch/sh/kernel/setup.c
> @@ -280,6 +280,8 @@ void __init setup_arch(char **cmdline_p)
>  #endif
>  	enable_mmu();
>
> +

    Another empty line hardly needed here.

> +#ifndef CONFIG_OF
>  	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
>
>  	printk(KERN_NOTICE "Boot params:\n"
[...]

MBR, Sergei


^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 05/17] sh: command line passing chosen/bootargs in devicetree
@ 2016-06-12 11:32     ` Sergei Shtylyov
  0 siblings, 0 replies; 68+ messages in thread
From: Sergei Shtylyov @ 2016-06-12 11:32 UTC (permalink / raw)
  To: Yoshinori Sato, linux-sh, linux-kernel

On 6/12/2016 9:54 AM, Yoshinori Sato wrote:

> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  arch/sh/kernel/setup.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
> index 8e3b099..d97de16 100644
> --- a/arch/sh/kernel/setup.c
> +++ b/arch/sh/kernel/setup.c
> @@ -280,6 +280,8 @@ void __init setup_arch(char **cmdline_p)
>  #endif
>  	enable_mmu();
>
> +

    Another empty line hardly needed here.

> +#ifndef CONFIG_OF
>  	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
>
>  	printk(KERN_NOTICE "Boot params:\n"
[...]

MBR, Sergei

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 07/17] sh: Passing FDT address on zImage
  2016-06-12  6:54   ` Yoshinori Sato
@ 2016-06-12 11:38     ` Sergei Shtylyov
  -1 siblings, 0 replies; 68+ messages in thread
From: Sergei Shtylyov @ 2016-06-12 11:38 UTC (permalink / raw)
  To: Yoshinori Sato, linux-sh, linux-kernel

On 6/12/2016 9:54 AM, Yoshinori Sato wrote:

> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  arch/sh/boot/compressed/head_32.S | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S
> index 3e15032..ef70454 100644
> --- a/arch/sh/boot/compressed/head_32.S
> +++ b/arch/sh/boot/compressed/head_32.S
> @@ -11,10 +11,11 @@
>
>  	.global	startup
>  startup:
> +	/* Save FDT address */
> +	mov	r4, r13
>  	/* Load initial status register */
>  	mov.l   init_sr, r1
>  	ldc     r1, sr
> -
>  	/* Move myself to proper location if necessary */
>  	mova	1f, r0
>  	mov.l	1f, r2
> @@ -83,7 +84,7 @@ l1:
>  	/* Jump to the start of the decompressed kernel */
>  	mov.l	kernel_start_addr, r0
>  	jmp	@r0
> -	nop
> +	  mov	r13,r4

    Forgot a space after comma?
    Is it a delay slot BTW (judging by extra indentation)?

[...]

MBR, Sergei


^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 07/17] sh: Passing FDT address on zImage
@ 2016-06-12 11:38     ` Sergei Shtylyov
  0 siblings, 0 replies; 68+ messages in thread
From: Sergei Shtylyov @ 2016-06-12 11:38 UTC (permalink / raw)
  To: Yoshinori Sato, linux-sh, linux-kernel

On 6/12/2016 9:54 AM, Yoshinori Sato wrote:

> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  arch/sh/boot/compressed/head_32.S | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/sh/boot/compressed/head_32.S b/arch/sh/boot/compressed/head_32.S
> index 3e15032..ef70454 100644
> --- a/arch/sh/boot/compressed/head_32.S
> +++ b/arch/sh/boot/compressed/head_32.S
> @@ -11,10 +11,11 @@
>
>  	.global	startup
>  startup:
> +	/* Save FDT address */
> +	mov	r4, r13
>  	/* Load initial status register */
>  	mov.l   init_sr, r1
>  	ldc     r1, sr
> -
>  	/* Move myself to proper location if necessary */
>  	mova	1f, r0
>  	mov.l	1f, r2
> @@ -83,7 +84,7 @@ l1:
>  	/* Jump to the start of the decompressed kernel */
>  	mov.l	kernel_start_addr, r0
>  	jmp	@r0
> -	nop
> +	  mov	r13,r4

    Forgot a space after comma?
    Is it a delay slot BTW (judging by extra indentation)?

[...]

MBR, Sergei

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 13/17] sh: Add PCI definetion
  2016-06-12  6:54   ` Yoshinori Sato
@ 2016-06-13  8:04     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:04 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel

s/definetion/definition/

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 13/17] sh: Add PCI definetion
@ 2016-06-13  8:04     ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:04 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel

s/definetion/definition/

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751
  2016-06-12  6:54   ` Yoshinori Sato
  (?)
@ 2016-06-13  8:04     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:04 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel, linux-pci, devicetree

On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
<ysato@users.sourceforge.jp> wrote:
> This is alternative SH7751 PCI driver.

an alternative

> Existing driver (arch/sh/drivers/pci/pci-sh7751) use SH specific interface.

uses

> But this driver using common PCI interface. It more mordan and generic.

uses ... it is more modern ...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751
@ 2016-06-13  8:04     ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:04 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel, linux-pci, devicetree

On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
<ysato@users.sourceforge.jp> wrote:
> This is alternative SH7751 PCI driver.

an alternative

> Existing driver (arch/sh/drivers/pci/pci-sh7751) use SH specific interface.

uses

> But this driver using common PCI interface. It more mordan and generic.

uses ... it is more modern ...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751
@ 2016-06-13  8:04     ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:04 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel, linux-pci, devicetree

On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
<ysato@users.sourceforge.jp> wrote:
> This is alternative SH7751 PCI driver.

an alternative

> Existing driver (arch/sh/drivers/pci/pci-sh7751) use SH specific interface.

uses

> But this driver using common PCI interface. It more mordan and generic.

uses ... it is more modern ...

Gr{oetje,eeting}s,

                        Geert

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 10/17] sh: convert generic drivers framework
  2016-06-12  6:54   ` Yoshinori Sato
@ 2016-06-13  8:05     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:05 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel, linux-clk

On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
<ysato@users.sourceforge.jp> wrote:
> index 0000000..89e28d8
> --- /dev/null
> +++ b/drivers/clk/sh/Kconfig
> @@ -0,0 +1,2 @@
> +config COMMON_CLK_SH7750
> +       bool "Clcok driver for SH7750/SH7751"

Clock

> diff --git a/drivers/clk/sh/Makefile b/drivers/clk/sh/Makefile
> new file mode 100644
> index 0000000..468eb9d
> --- /dev/null
> +++ b/drivers/clk/sh/Makefile
> @@ -0,0 +1,2 @@
> +obj-y += clk-shdiv.o
> +obj-$(CONFIG_COMMON_CLK_SH7750) += clk-sh7750.o
> \ No newline at end of file

Please add the newline.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 10/17] sh: convert generic drivers framework
@ 2016-06-13  8:05     ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:05 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel, linux-clk

On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
<ysato@users.sourceforge.jp> wrote:
> index 0000000..89e28d8
> --- /dev/null
> +++ b/drivers/clk/sh/Kconfig
> @@ -0,0 +1,2 @@
> +config COMMON_CLK_SH7750
> +       bool "Clcok driver for SH7750/SH7751"

Clock

> diff --git a/drivers/clk/sh/Makefile b/drivers/clk/sh/Makefile
> new file mode 100644
> index 0000000..468eb9d
> --- /dev/null
> +++ b/drivers/clk/sh/Makefile
> @@ -0,0 +1,2 @@
> +obj-y += clk-shdiv.o
> +obj-$(CONFIG_COMMON_CLK_SH7750) += clk-sh7750.o
> \ No newline at end of file

Please add the newline.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 16/17] sh: I/O DATA HDL-U (a.k.a. landisk) Device Tree
  2016-06-12  6:54   ` Yoshinori Sato
@ 2016-06-13  8:13     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:13 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel, devicetree

Hi Sato-san,

On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
<ysato@users.sourceforge.jp> wrote:
> --- /dev/null
> +++ b/arch/sh/boot/dts/landisk.dts
> @@ -0,0 +1,150 @@

> +        pllclk: pllclk {
> +                compatible = "renesas,sh7750-pll-clock";
> +                clocks = <&oclk>;
> +                #clock-cells = <0>;
> +               renesas,mult = <12>;
> +                reg = <0xffc00000 2>, <0xffc00008 4>;
> +        };
> +        iclk: iclk {
> +                compatible = "renesas,sh7750-div-clock";
> +                clocks = <&pllclk>;
> +                #clock-cells = <0>;
> +                reg = <0xffc00000 2>;
> +               renesas,offset = <6>;
> +               clock-output-names = "ick";

clock-output-names is deprecated for clocks providing a single output.

> +        };
> +        bclk: bclk {
> +                compatible = "renesas,sh7750-div-clock";
> +                clocks = <&pllclk>;
> +                #clock-cells = <0>;
> +                reg = <0xffc00000 2>;
> +               renesas,offset = <3>;
> +               clock-output-names = "bck";
> +        };
> +        fclk: fclk {
> +                compatible = "renesas,sh7750-div-clock";
> +                clocks = <&pllclk>;
> +                #clock-cells = <0>;
> +                reg = <0xffc00000 2>;
> +               renesas,offset = <0>;
> +               clock-output-names = "fck";
> +        };

I think it will be much easier for maintenance and code reuse to just have a
single "cpg" node that's compatible with "renesas,sh7750-cpg", covering all
CPG registers. Especially since the various clocks use the same registers.

Cfr. drivers/clk/renesas/cpg-mssr.c.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 16/17] sh: I/O DATA HDL-U (a.k.a. landisk) Device Tree
@ 2016-06-13  8:13     ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:13 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel, devicetree

Hi Sato-san,

On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
<ysato@users.sourceforge.jp> wrote:
> --- /dev/null
> +++ b/arch/sh/boot/dts/landisk.dts
> @@ -0,0 +1,150 @@

> +        pllclk: pllclk {
> +                compatible = "renesas,sh7750-pll-clock";
> +                clocks = <&oclk>;
> +                #clock-cells = <0>;
> +               renesas,mult = <12>;
> +                reg = <0xffc00000 2>, <0xffc00008 4>;
> +        };
> +        iclk: iclk {
> +                compatible = "renesas,sh7750-div-clock";
> +                clocks = <&pllclk>;
> +                #clock-cells = <0>;
> +                reg = <0xffc00000 2>;
> +               renesas,offset = <6>;
> +               clock-output-names = "ick";

clock-output-names is deprecated for clocks providing a single output.

> +        };
> +        bclk: bclk {
> +                compatible = "renesas,sh7750-div-clock";
> +                clocks = <&pllclk>;
> +                #clock-cells = <0>;
> +                reg = <0xffc00000 2>;
> +               renesas,offset = <3>;
> +               clock-output-names = "bck";
> +        };
> +        fclk: fclk {
> +                compatible = "renesas,sh7750-div-clock";
> +                clocks = <&pllclk>;
> +                #clock-cells = <0>;
> +                reg = <0xffc00000 2>;
> +               renesas,offset = <0>;
> +               clock-output-names = "fck";
> +        };

I think it will be much easier for maintenance and code reuse to just have a
single "cpg" node that's compatible with "renesas,sh7750-cpg", covering all
CPG registers. Especially since the various clocks use the same registers.

Cfr. drivers/clk/renesas/cpg-mssr.c.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 11/17] sh: SH7750/51 clock driver
  2016-06-12  6:54   ` Yoshinori Sato
@ 2016-06-13  8:15     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:15 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel, linux-clk

Hi Sato-san,

On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
<ysato@users.sourceforge.jp> wrote:
> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  .../bindings/clock/renesas,sh7750-div-clock.txt    |  27 +++
>  .../bindings/clock/renesas,sh7750-pll-clock.txt    |  26 +++
>  drivers/clk/sh/clk-sh7750.c                        | 240 +++++++++++++++++++++
>  3 files changed, 293 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
>  create mode 100644 drivers/clk/sh/clk-sh7750.c
>
> diff --git a/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt b/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
> new file mode 100644
> index 0000000..8c57ab5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
> @@ -0,0 +1,27 @@
> +* Renesas SH7750/51 divider clock
> +
> +Required Properties:
> +
> +  - compatible: Must be "renesas,sh7750-div-clock"
> +
> +  - clocks: Reference to the parent clocks (mostly PLL)
> +
> +  - #clock-cells: Must be 0
> +
> +  - reg: Base address and length of the divide rate selector
> +
> +  - renesas,offset: bit offset of selector
> +
> +  - clock-output-names: The names of the clocks.
> +
> +Example
> +-------
> +
> +        iclk: iclk {
> +                compatible = "renesas,sh7750-div-clock";
> +                clocks = <&pllclk>;
> +                #clock-cells = <0>;
> +                reg = <0xffc00000 2>;
> +               renesas,offset = <6>;
> +               clock-output-names = "ick";
> +        };
> diff --git a/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt b/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
> new file mode 100644
> index 0000000..06a3d31
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt

> +CLK_OF_DECLARE(sh7750_div_clk, "renesas,sh7750-div-clock",
> +              sh7750_div_clk_setup);
> +CLK_OF_DECLARE(sh7750_pll_clk, "renesas,sh7750-pll-clock",
> +              sh7750_pll_clk_setup);
> +

Cfr. my comment on the .dtsi, which didn't have linux-clk in CC:

I think it will be much easier for maintenance and code reuse to just have a
single "cpg" node that's compatible with "renesas,sh7750-cpg", covering all
CPG registers. Especially since the various clocks use the same registers.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 11/17] sh: SH7750/51 clock driver
@ 2016-06-13  8:15     ` Geert Uytterhoeven
  0 siblings, 0 replies; 68+ messages in thread
From: Geert Uytterhoeven @ 2016-06-13  8:15 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: Linux-sh list, linux-kernel, linux-clk

Hi Sato-san,

On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
<ysato@users.sourceforge.jp> wrote:
> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  .../bindings/clock/renesas,sh7750-div-clock.txt    |  27 +++
>  .../bindings/clock/renesas,sh7750-pll-clock.txt    |  26 +++
>  drivers/clk/sh/clk-sh7750.c                        | 240 +++++++++++++++++++++
>  3 files changed, 293 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
>  create mode 100644 drivers/clk/sh/clk-sh7750.c
>
> diff --git a/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt b/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
> new file mode 100644
> index 0000000..8c57ab5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/renesas,sh7750-div-clock.txt
> @@ -0,0 +1,27 @@
> +* Renesas SH7750/51 divider clock
> +
> +Required Properties:
> +
> +  - compatible: Must be "renesas,sh7750-div-clock"
> +
> +  - clocks: Reference to the parent clocks (mostly PLL)
> +
> +  - #clock-cells: Must be 0
> +
> +  - reg: Base address and length of the divide rate selector
> +
> +  - renesas,offset: bit offset of selector
> +
> +  - clock-output-names: The names of the clocks.
> +
> +Example
> +-------
> +
> +        iclk: iclk {
> +                compatible = "renesas,sh7750-div-clock";
> +                clocks = <&pllclk>;
> +                #clock-cells = <0>;
> +                reg = <0xffc00000 2>;
> +               renesas,offset = <6>;
> +               clock-output-names = "ick";
> +        };
> diff --git a/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt b/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt
> new file mode 100644
> index 0000000..06a3d31
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/renesas,sh7750-pll-clock.txt

> +CLK_OF_DECLARE(sh7750_div_clk, "renesas,sh7750-div-clock",
> +              sh7750_div_clk_setup);
> +CLK_OF_DECLARE(sh7750_pll_clk, "renesas,sh7750-pll-clock",
> +              sh7750_pll_clk_setup);
> +

Cfr. my comment on the .dtsi, which didn't have linux-clk in CC:

I think it will be much easier for maintenance and code reuse to just have a
single "cpg" node that's compatible with "renesas,sh7750-cpg", covering all
CPG registers. Especially since the various clocks use the same registers.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751
  2016-06-12  6:54   ` Yoshinori Sato
@ 2016-06-13  8:38     ` Arnd Bergmann
  -1 siblings, 0 replies; 68+ messages in thread
From: Arnd Bergmann @ 2016-06-13  8:38 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: linux-sh, linux-kernel, linux-pci, devicetree

On Sunday, June 12, 2016 3:54:30 PM CEST Yoshinori Sato wrote:
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/sh7751-pci.txt
> +		ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>,
> +		         <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>;
> +		reg = <0xfe200000 0x0400>,
> +		      <0x0c000000 0x04000000>,
> +		      <0xff800000 0x0030>;
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0x1800 0 7>;
> +		interrupt-map = <0x0000 0 1 &cpldintc evt2irq(0x2a0) 0
> +		                 0x0000 0 2 &cpldintc evt2irq(0x2c0) 0
> +		                 0x0000 0 3 &cpldintc evt2irq(0x2e0) 0
> +		                 0x0000 0 4 &cpldintc evt2irq(0x300) 0
> +
> +		                 0x0800 0 1 &cpldintc evt2irq(0x2c0) 0
> +		                 0x0800 0 2 &cpldintc evt2irq(0x2e0) 0
> +		                 0x0800 0 3 &cpldintc evt2irq(0x300) 0
> +		                 0x0800 0 4 &cpldintc evt2irq(0x2a0) 0

Is this not the default swizzling? I would guess that you can just
list the interrupt once.

The formatting is slightly inconsistent here, my recommendation is
to always enclose each entry in '< >' so you have a comma-separated
list.

> +
> +#define pcic_writel(val, reg) __raw_writel(val, pci_reg_base + (reg))
> +#define pcic_readl(reg) __raw_readl(pci_reg_base + (reg))

We generally try not to use __raw_*() accessors in drivers, because
they are not portable, lack barriers and atomicity, and don't work
when you change endianess.

> +unsigned long PCIBIOS_MIN_IO;
> +unsigned long PCIBIOS_MIN_MEM;

These should probably be in architecture code, otherwise you cannot
build more than one such driver into the kernel.

> +DEFINE_RAW_SPINLOCK(pci_config_lock);

This seems unnecessary, the config operations are always called
under a spinlock already.

> +static __initconst const struct fixups {
> +	char *compatible;
> +	void (*fixup)(void __iomem *, void __iomem *);
> +} fixup_list[] = {
> +	{
> +		.compatible = "iodata,landisk",
> +		.fixup = landisk_fixup,
> +	},
> +};

Just move the fixup pointer into the existing of match table
as the .data pointer, or add a structure to which .data
points.

> +/*
> + * Functions for accessing PCI configuration space with type 1 accesses
> + */
> +static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
> +			   int where, int size, u32 *val)
> +{
> +	struct gen_pci *pci = bus->sysdata;
> +	void __iomem *pci_reg_base;
> +	unsigned long flags;
> +	u32 data;
> +
> +	pci_reg_base = ioremap(pci->cfg.res.start,
> +			       pci->cfg.res.end - pci->cfg.res.start);

You cannot call normally ioremap from pci_read, because it
gets called under a spinlock and ioremap can normally sleep
(that might be architecture specific).

Better map it a probe time, or use fixmap.

> +	/*
> +	 * PCIPDR may only be accessed as 32 bit words,
> +	 * so we must do byte alignment by hand
> +	 */
> +	raw_spin_lock_irqsave(&pci_config_lock, flags);
> +	pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
> +	data = pcic_readl(SH4_PCIPDR);
> +	raw_spin_unlock_irqrestore(&pci_config_lock, flags);

This is shorter to express this using a 'map' function
in pci_ops combined with pci_generic_config_read32
and pci_generic_config_write32.

> +/*
> + * Called after each bus is probed, but before its children
> + * are examined.
> + */
> +void pcibios_fixup_bus(struct pci_bus *bus)
> +{
> +}

This doesn't really belong into the driver.

> +/*
> + * We need to avoid collisions with `mirrored' VGA ports
> + * and other strange ISA hardware, so we always want the
> + * addresses to be allocated in the 0x000-0x0ff region
> + * modulo 0x400.
> + */
> +resource_size_t pcibios_align_resource(void *data,
> +				       const struct resource *res,
> +				       resource_size_t size,
> +				       resource_size_t align)
> +{
> +	resource_size_t start = res->start;
> +
> +	return start;
> +}

The comment does not match what the function does, you should
change one or the other. Also move it to the same file as
pcibios_fixup_bus.

> +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
> +			enum pci_mmap_state mmap_state, int write_combine)
> +{
> +	/*
> +	 * I/O space can be accessed via normal processor loads and stores on
> +	 * this platform but for now we elect not to do this and portable
> +	 * drivers should not do this anyway.
> +	 */
> +
> +	if (mmap_state = pci_mmap_io)
> +		return -EINVAL;
> +
> +	/*
> +	 * Ignore write-combine; for now only return uncached mappings.
> +	 */
> +	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> +
> +	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
> +			       vma->vm_end - vma->vm_start,
> +			       vma->vm_page_prot);
> +}

Do you actually need HAVE_PCI_MMAP? Maybe you can just unset that
and remove the function here.

> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	pci_reg_base = ioremap(res->start, res->end - res->start);
> +	if (IS_ERR(pci_reg_base))
> +		return PTR_ERR(pci_reg_base);
> +
> +	wres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	if (IS_ERR(wres))
> +		return PTR_ERR(wres);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
> +	bcr = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(bcr))


You map three distinct memory resources here, but your
binding just describes one as "reg: base address and
length of the PCI controller registers".

If there are multiple register ranges, please list each
one in the binding and document in which order they
are expected, or use named resources and list the required
names.

	Arnd

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751
@ 2016-06-13  8:38     ` Arnd Bergmann
  0 siblings, 0 replies; 68+ messages in thread
From: Arnd Bergmann @ 2016-06-13  8:38 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: linux-sh, linux-kernel, linux-pci, devicetree

On Sunday, June 12, 2016 3:54:30 PM CEST Yoshinori Sato wrote:
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/sh7751-pci.txt
> +		ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>,
> +		         <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>;
> +		reg = <0xfe200000 0x0400>,
> +		      <0x0c000000 0x04000000>,
> +		      <0xff800000 0x0030>;
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0x1800 0 7>;
> +		interrupt-map = <0x0000 0 1 &cpldintc evt2irq(0x2a0) 0
> +		                 0x0000 0 2 &cpldintc evt2irq(0x2c0) 0
> +		                 0x0000 0 3 &cpldintc evt2irq(0x2e0) 0
> +		                 0x0000 0 4 &cpldintc evt2irq(0x300) 0
> +
> +		                 0x0800 0 1 &cpldintc evt2irq(0x2c0) 0
> +		                 0x0800 0 2 &cpldintc evt2irq(0x2e0) 0
> +		                 0x0800 0 3 &cpldintc evt2irq(0x300) 0
> +		                 0x0800 0 4 &cpldintc evt2irq(0x2a0) 0

Is this not the default swizzling? I would guess that you can just
list the interrupt once.

The formatting is slightly inconsistent here, my recommendation is
to always enclose each entry in '< >' so you have a comma-separated
list.

> +
> +#define pcic_writel(val, reg) __raw_writel(val, pci_reg_base + (reg))
> +#define pcic_readl(reg) __raw_readl(pci_reg_base + (reg))

We generally try not to use __raw_*() accessors in drivers, because
they are not portable, lack barriers and atomicity, and don't work
when you change endianess.

> +unsigned long PCIBIOS_MIN_IO;
> +unsigned long PCIBIOS_MIN_MEM;

These should probably be in architecture code, otherwise you cannot
build more than one such driver into the kernel.

> +DEFINE_RAW_SPINLOCK(pci_config_lock);

This seems unnecessary, the config operations are always called
under a spinlock already.

> +static __initconst const struct fixups {
> +	char *compatible;
> +	void (*fixup)(void __iomem *, void __iomem *);
> +} fixup_list[] = {
> +	{
> +		.compatible = "iodata,landisk",
> +		.fixup = landisk_fixup,
> +	},
> +};

Just move the fixup pointer into the existing of match table
as the .data pointer, or add a structure to which .data
points.

> +/*
> + * Functions for accessing PCI configuration space with type 1 accesses
> + */
> +static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
> +			   int where, int size, u32 *val)
> +{
> +	struct gen_pci *pci = bus->sysdata;
> +	void __iomem *pci_reg_base;
> +	unsigned long flags;
> +	u32 data;
> +
> +	pci_reg_base = ioremap(pci->cfg.res.start,
> +			       pci->cfg.res.end - pci->cfg.res.start);

You cannot call normally ioremap from pci_read, because it
gets called under a spinlock and ioremap can normally sleep
(that might be architecture specific).

Better map it a probe time, or use fixmap.

> +	/*
> +	 * PCIPDR may only be accessed as 32 bit words,
> +	 * so we must do byte alignment by hand
> +	 */
> +	raw_spin_lock_irqsave(&pci_config_lock, flags);
> +	pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
> +	data = pcic_readl(SH4_PCIPDR);
> +	raw_spin_unlock_irqrestore(&pci_config_lock, flags);

This is shorter to express this using a 'map' function
in pci_ops combined with pci_generic_config_read32
and pci_generic_config_write32.

> +/*
> + * Called after each bus is probed, but before its children
> + * are examined.
> + */
> +void pcibios_fixup_bus(struct pci_bus *bus)
> +{
> +}

This doesn't really belong into the driver.

> +/*
> + * We need to avoid collisions with `mirrored' VGA ports
> + * and other strange ISA hardware, so we always want the
> + * addresses to be allocated in the 0x000-0x0ff region
> + * modulo 0x400.
> + */
> +resource_size_t pcibios_align_resource(void *data,
> +				       const struct resource *res,
> +				       resource_size_t size,
> +				       resource_size_t align)
> +{
> +	resource_size_t start = res->start;
> +
> +	return start;
> +}

The comment does not match what the function does, you should
change one or the other. Also move it to the same file as
pcibios_fixup_bus.

> +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
> +			enum pci_mmap_state mmap_state, int write_combine)
> +{
> +	/*
> +	 * I/O space can be accessed via normal processor loads and stores on
> +	 * this platform but for now we elect not to do this and portable
> +	 * drivers should not do this anyway.
> +	 */
> +
> +	if (mmap_state == pci_mmap_io)
> +		return -EINVAL;
> +
> +	/*
> +	 * Ignore write-combine; for now only return uncached mappings.
> +	 */
> +	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> +
> +	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
> +			       vma->vm_end - vma->vm_start,
> +			       vma->vm_page_prot);
> +}

Do you actually need HAVE_PCI_MMAP? Maybe you can just unset that
and remove the function here.

> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	pci_reg_base = ioremap(res->start, res->end - res->start);
> +	if (IS_ERR(pci_reg_base))
> +		return PTR_ERR(pci_reg_base);
> +
> +	wres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	if (IS_ERR(wres))
> +		return PTR_ERR(wres);
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
> +	bcr = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(bcr))


You map three distinct memory resources here, but your
binding just describes one as "reg: base address and
length of the PCI controller registers".

If there are multiple register ranges, please list each
one in the binding and document in which order they
are expected, or use named resources and list the required
names.

	Arnd

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 16/17] sh: I/O DATA HDL-U (a.k.a. landisk) Device Tree
  2016-06-13  8:13     ` Geert Uytterhoeven
@ 2016-06-13 14:23       ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-13 14:23 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Linux-sh list, linux-kernel, devicetree

On Mon, 13 Jun 2016 17:13:37 +0900,
Geert Uytterhoeven wrote:
> 
> Hi Sato-san,
> 
> On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
> <ysato@users.sourceforge.jp> wrote:
> > --- /dev/null
> > +++ b/arch/sh/boot/dts/landisk.dts
> > @@ -0,0 +1,150 @@
> 
> > +        pllclk: pllclk {
> > +                compatible = "renesas,sh7750-pll-clock";
> > +                clocks = <&oclk>;
> > +                #clock-cells = <0>;
> > +               renesas,mult = <12>;
> > +                reg = <0xffc00000 2>, <0xffc00008 4>;
> > +        };
> > +        iclk: iclk {
> > +                compatible = "renesas,sh7750-div-clock";
> > +                clocks = <&pllclk>;
> > +                #clock-cells = <0>;
> > +                reg = <0xffc00000 2>;
> > +               renesas,offset = <6>;
> > +               clock-output-names = "ick";
> 
> clock-output-names is deprecated for clocks providing a single output.
> 
> > +        };
> > +        bclk: bclk {
> > +                compatible = "renesas,sh7750-div-clock";
> > +                clocks = <&pllclk>;
> > +                #clock-cells = <0>;
> > +                reg = <0xffc00000 2>;
> > +               renesas,offset = <3>;
> > +               clock-output-names = "bck";
> > +        };
> > +        fclk: fclk {
> > +                compatible = "renesas,sh7750-div-clock";
> > +                clocks = <&pllclk>;
> > +                #clock-cells = <0>;
> > +                reg = <0xffc00000 2>;
> > +               renesas,offset = <0>;
> > +               clock-output-names = "fck";
> > +        };
> 
> I think it will be much easier for maintenance and code reuse to just have a
> single "cpg" node that's compatible with "renesas,sh7750-cpg", covering all
> CPG registers. Especially since the various clocks use the same registers.
> 
> Cfr. drivers/clk/renesas/cpg-mssr.c.

OK.
I'll try.

> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

-- 
Yoshinori Sato
<ysato@users.sourceforge.jp>

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 16/17] sh: I/O DATA HDL-U (a.k.a. landisk) Device Tree
@ 2016-06-13 14:23       ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-13 14:23 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Linux-sh list, linux-kernel, devicetree

On Mon, 13 Jun 2016 17:13:37 +0900,
Geert Uytterhoeven wrote:
> 
> Hi Sato-san,
> 
> On Sun, Jun 12, 2016 at 8:54 AM, Yoshinori Sato
> <ysato@users.sourceforge.jp> wrote:
> > --- /dev/null
> > +++ b/arch/sh/boot/dts/landisk.dts
> > @@ -0,0 +1,150 @@
> 
> > +        pllclk: pllclk {
> > +                compatible = "renesas,sh7750-pll-clock";
> > +                clocks = <&oclk>;
> > +                #clock-cells = <0>;
> > +               renesas,mult = <12>;
> > +                reg = <0xffc00000 2>, <0xffc00008 4>;
> > +        };
> > +        iclk: iclk {
> > +                compatible = "renesas,sh7750-div-clock";
> > +                clocks = <&pllclk>;
> > +                #clock-cells = <0>;
> > +                reg = <0xffc00000 2>;
> > +               renesas,offset = <6>;
> > +               clock-output-names = "ick";
> 
> clock-output-names is deprecated for clocks providing a single output.
> 
> > +        };
> > +        bclk: bclk {
> > +                compatible = "renesas,sh7750-div-clock";
> > +                clocks = <&pllclk>;
> > +                #clock-cells = <0>;
> > +                reg = <0xffc00000 2>;
> > +               renesas,offset = <3>;
> > +               clock-output-names = "bck";
> > +        };
> > +        fclk: fclk {
> > +                compatible = "renesas,sh7750-div-clock";
> > +                clocks = <&pllclk>;
> > +                #clock-cells = <0>;
> > +                reg = <0xffc00000 2>;
> > +               renesas,offset = <0>;
> > +               clock-output-names = "fck";
> > +        };
> 
> I think it will be much easier for maintenance and code reuse to just have a
> single "cpg" node that's compatible with "renesas,sh7750-cpg", covering all
> CPG registers. Especially since the various clocks use the same registers.
> 
> Cfr. drivers/clk/renesas/cpg-mssr.c.

OK.
I'll try.

> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

-- 
Yoshinori Sato
<ysato@users.sourceforge.jp>

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751
  2016-06-13  8:38     ` Arnd Bergmann
@ 2016-06-13 15:23       ` Yoshinori Sato
  -1 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-13 15:23 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linux-sh, linux-kernel, linux-pci, devicetree

On Mon, 13 Jun 2016 17:38:28 +0900,
Arnd Bergmann wrote:
> 
> On Sunday, June 12, 2016 3:54:30 PM CEST Yoshinori Sato wrote:
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pci/sh7751-pci.txt
> > +		ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>,
> > +		         <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>;
> > +		reg = <0xfe200000 0x0400>,
> > +		      <0x0c000000 0x04000000>,
> > +		      <0xff800000 0x0030>;
> > +		#interrupt-cells = <1>;
> > +		interrupt-map-mask = <0x1800 0 7>;
> > +		interrupt-map = <0x0000 0 1 &cpldintc evt2irq(0x2a0) 0
> > +		                 0x0000 0 2 &cpldintc evt2irq(0x2c0) 0
> > +		                 0x0000 0 3 &cpldintc evt2irq(0x2e0) 0
> > +		                 0x0000 0 4 &cpldintc evt2irq(0x300) 0
> > +
> > +		                 0x0800 0 1 &cpldintc evt2irq(0x2c0) 0
> > +		                 0x0800 0 2 &cpldintc evt2irq(0x2e0) 0
> > +		                 0x0800 0 3 &cpldintc evt2irq(0x300) 0
> > +		                 0x0800 0 4 &cpldintc evt2irq(0x2a0) 0
> 
> Is this not the default swizzling? I would guess that you can just
> list the interrupt once.
> 
> The formatting is slightly inconsistent here, my recommendation is
> to always enclose each entry in '< >' so you have a comma-separated
> list.

OK.
I'll fix this.

> > +
> > +#define pcic_writel(val, reg) __raw_writel(val, pci_reg_base + (reg))
> > +#define pcic_readl(reg) __raw_readl(pci_reg_base + (reg))
> 
> We generally try not to use __raw_*() accessors in drivers, because
> they are not portable, lack barriers and atomicity, and don't work
> when you change endianess.

OK.
It cpied old style driver.
Update ioread/write.

> > +unsigned long PCIBIOS_MIN_IO;
> > +unsigned long PCIBIOS_MIN_MEM;
> 
> These should probably be in architecture code, otherwise you cannot
> build more than one such driver into the kernel.
> 
> > +DEFINE_RAW_SPINLOCK(pci_config_lock);
> 
> This seems unnecessary, the config operations are always called
> under a spinlock already.

OK.
remove it.

> > +static __initconst const struct fixups {
> > +	char *compatible;
> > +	void (*fixup)(void __iomem *, void __iomem *);
> > +} fixup_list[] = {
> > +	{
> > +		.compatible = "iodata,landisk",
> > +		.fixup = landisk_fixup,
> > +	},
> > +};
> 
> Just move the fixup pointer into the existing of match table
> as the .data pointer, or add a structure to which .data
> points.

OK.

> > +/*
> > + * Functions for accessing PCI configuration space with type 1 accesses
> > + */
> > +static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
> > +			   int where, int size, u32 *val)
> > +{
> > +	struct gen_pci *pci = bus->sysdata;
> > +	void __iomem *pci_reg_base;
> > +	unsigned long flags;
> > +	u32 data;
> > +
> > +	pci_reg_base = ioremap(pci->cfg.res.start,
> > +			       pci->cfg.res.end - pci->cfg.res.start);
> 
> You cannot call normally ioremap from pci_read, because it
> gets called under a spinlock and ioremap can normally sleep
> (that might be architecture specific).
> 
> Better map it a probe time, or use fixmap.

OK.

> > +	/*
> > +	 * PCIPDR may only be accessed as 32 bit words,
> > +	 * so we must do byte alignment by hand
> > +	 */
> > +	raw_spin_lock_irqsave(&pci_config_lock, flags);
> > +	pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
> > +	data = pcic_readl(SH4_PCIPDR);
> > +	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
> 
> This is shorter to express this using a 'map' function
> in pci_ops combined with pci_generic_config_read32
> and pci_generic_config_write32.

OK.

> > +/*
> > + * Called after each bus is probed, but before its children
> > + * are examined.
> > + */
> > +void pcibios_fixup_bus(struct pci_bus *bus)
> > +{
> > +}
> 
> This doesn't really belong into the driver.

OK.

> > +/*
> > + * We need to avoid collisions with `mirrored' VGA ports
> > + * and other strange ISA hardware, so we always want the
> > + * addresses to be allocated in the 0x000-0x0ff region
> > + * modulo 0x400.
> > + */
> > +resource_size_t pcibios_align_resource(void *data,
> > +				       const struct resource *res,
> > +				       resource_size_t size,
> > +				       resource_size_t align)
> > +{
> > +	resource_size_t start = res->start;
> > +
> > +	return start;
> > +}
> 
> The comment does not match what the function does, you should
> change one or the other. Also move it to the same file as
> pcibios_fixup_bus.

OK.
This part copied old driver.
I will cleanup.

> > +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
> > +			enum pci_mmap_state mmap_state, int write_combine)
> > +{
> > +	/*
> > +	 * I/O space can be accessed via normal processor loads and stores on
> > +	 * this platform but for now we elect not to do this and portable
> > +	 * drivers should not do this anyway.
> > +	 */
> > +
> > +	if (mmap_state = pci_mmap_io)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * Ignore write-combine; for now only return uncached mappings.
> > +	 */
> > +	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> > +
> > +	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
> > +			       vma->vm_end - vma->vm_start,
> > +			       vma->vm_page_prot);
> > +}
> 
> Do you actually need HAVE_PCI_MMAP? Maybe you can just unset that
> and remove the function here.

Not set this.
Remove function.

> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	pci_reg_base = ioremap(res->start, res->end - res->start);
> > +	if (IS_ERR(pci_reg_base))
> > +		return PTR_ERR(pci_reg_base);
> > +
> > +	wres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +	if (IS_ERR(wres))
> > +		return PTR_ERR(wres);
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
> > +	bcr = devm_ioremap_resource(&pdev->dev, res);
> > +	if (IS_ERR(bcr))
> 
> 
> You map three distinct memory resources here, but your
> binding just describes one as "reg: base address and
> length of the PCI controller registers".

OK.

> If there are multiple register ranges, please list each
> one in the binding and document in which order they
> are expected, or use named resources and list the required
> names.
>

This controller have single register area.
I will fix dts.

Thanks.

> 	Arnd

-- 
Yoshinori Sato
<ysato@users.sourceforge.jp>

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751
@ 2016-06-13 15:23       ` Yoshinori Sato
  0 siblings, 0 replies; 68+ messages in thread
From: Yoshinori Sato @ 2016-06-13 15:23 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linux-sh, linux-kernel, linux-pci, devicetree

On Mon, 13 Jun 2016 17:38:28 +0900,
Arnd Bergmann wrote:
> 
> On Sunday, June 12, 2016 3:54:30 PM CEST Yoshinori Sato wrote:
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pci/sh7751-pci.txt
> > +		ranges = <0x02000000 0x00000000 0xfd000000 0xfd000000 0x00000000 0x01000000>,
> > +		         <0x01000000 0x00000000 0xfe240000 0x00000000 0x00000000 0x00040000>;
> > +		reg = <0xfe200000 0x0400>,
> > +		      <0x0c000000 0x04000000>,
> > +		      <0xff800000 0x0030>;
> > +		#interrupt-cells = <1>;
> > +		interrupt-map-mask = <0x1800 0 7>;
> > +		interrupt-map = <0x0000 0 1 &cpldintc evt2irq(0x2a0) 0
> > +		                 0x0000 0 2 &cpldintc evt2irq(0x2c0) 0
> > +		                 0x0000 0 3 &cpldintc evt2irq(0x2e0) 0
> > +		                 0x0000 0 4 &cpldintc evt2irq(0x300) 0
> > +
> > +		                 0x0800 0 1 &cpldintc evt2irq(0x2c0) 0
> > +		                 0x0800 0 2 &cpldintc evt2irq(0x2e0) 0
> > +		                 0x0800 0 3 &cpldintc evt2irq(0x300) 0
> > +		                 0x0800 0 4 &cpldintc evt2irq(0x2a0) 0
> 
> Is this not the default swizzling? I would guess that you can just
> list the interrupt once.
> 
> The formatting is slightly inconsistent here, my recommendation is
> to always enclose each entry in '< >' so you have a comma-separated
> list.

OK.
I'll fix this.

> > +
> > +#define pcic_writel(val, reg) __raw_writel(val, pci_reg_base + (reg))
> > +#define pcic_readl(reg) __raw_readl(pci_reg_base + (reg))
> 
> We generally try not to use __raw_*() accessors in drivers, because
> they are not portable, lack barriers and atomicity, and don't work
> when you change endianess.

OK.
It cpied old style driver.
Update ioread/write.

> > +unsigned long PCIBIOS_MIN_IO;
> > +unsigned long PCIBIOS_MIN_MEM;
> 
> These should probably be in architecture code, otherwise you cannot
> build more than one such driver into the kernel.
> 
> > +DEFINE_RAW_SPINLOCK(pci_config_lock);
> 
> This seems unnecessary, the config operations are always called
> under a spinlock already.

OK.
remove it.

> > +static __initconst const struct fixups {
> > +	char *compatible;
> > +	void (*fixup)(void __iomem *, void __iomem *);
> > +} fixup_list[] = {
> > +	{
> > +		.compatible = "iodata,landisk",
> > +		.fixup = landisk_fixup,
> > +	},
> > +};
> 
> Just move the fixup pointer into the existing of match table
> as the .data pointer, or add a structure to which .data
> points.

OK.

> > +/*
> > + * Functions for accessing PCI configuration space with type 1 accesses
> > + */
> > +static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
> > +			   int where, int size, u32 *val)
> > +{
> > +	struct gen_pci *pci = bus->sysdata;
> > +	void __iomem *pci_reg_base;
> > +	unsigned long flags;
> > +	u32 data;
> > +
> > +	pci_reg_base = ioremap(pci->cfg.res.start,
> > +			       pci->cfg.res.end - pci->cfg.res.start);
> 
> You cannot call normally ioremap from pci_read, because it
> gets called under a spinlock and ioremap can normally sleep
> (that might be architecture specific).
> 
> Better map it a probe time, or use fixmap.

OK.

> > +	/*
> > +	 * PCIPDR may only be accessed as 32 bit words,
> > +	 * so we must do byte alignment by hand
> > +	 */
> > +	raw_spin_lock_irqsave(&pci_config_lock, flags);
> > +	pcic_writel(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
> > +	data = pcic_readl(SH4_PCIPDR);
> > +	raw_spin_unlock_irqrestore(&pci_config_lock, flags);
> 
> This is shorter to express this using a 'map' function
> in pci_ops combined with pci_generic_config_read32
> and pci_generic_config_write32.

OK.

> > +/*
> > + * Called after each bus is probed, but before its children
> > + * are examined.
> > + */
> > +void pcibios_fixup_bus(struct pci_bus *bus)
> > +{
> > +}
> 
> This doesn't really belong into the driver.

OK.

> > +/*
> > + * We need to avoid collisions with `mirrored' VGA ports
> > + * and other strange ISA hardware, so we always want the
> > + * addresses to be allocated in the 0x000-0x0ff region
> > + * modulo 0x400.
> > + */
> > +resource_size_t pcibios_align_resource(void *data,
> > +				       const struct resource *res,
> > +				       resource_size_t size,
> > +				       resource_size_t align)
> > +{
> > +	resource_size_t start = res->start;
> > +
> > +	return start;
> > +}
> 
> The comment does not match what the function does, you should
> change one or the other. Also move it to the same file as
> pcibios_fixup_bus.

OK.
This part copied old driver.
I will cleanup.

> > +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
> > +			enum pci_mmap_state mmap_state, int write_combine)
> > +{
> > +	/*
> > +	 * I/O space can be accessed via normal processor loads and stores on
> > +	 * this platform but for now we elect not to do this and portable
> > +	 * drivers should not do this anyway.
> > +	 */
> > +
> > +	if (mmap_state == pci_mmap_io)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * Ignore write-combine; for now only return uncached mappings.
> > +	 */
> > +	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> > +
> > +	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
> > +			       vma->vm_end - vma->vm_start,
> > +			       vma->vm_page_prot);
> > +}
> 
> Do you actually need HAVE_PCI_MMAP? Maybe you can just unset that
> and remove the function here.

Not set this.
Remove function.

> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	pci_reg_base = ioremap(res->start, res->end - res->start);
> > +	if (IS_ERR(pci_reg_base))
> > +		return PTR_ERR(pci_reg_base);
> > +
> > +	wres = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +	if (IS_ERR(wres))
> > +		return PTR_ERR(wres);
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
> > +	bcr = devm_ioremap_resource(&pdev->dev, res);
> > +	if (IS_ERR(bcr))
> 
> 
> You map three distinct memory resources here, but your
> binding just describes one as "reg: base address and
> length of the PCI controller registers".

OK.

> If there are multiple register ranges, please list each
> one in the binding and document in which order they
> are expected, or use named resources and list the required
> names.
>

This controller have single register area.
I will fix dts.

Thanks.

> 	Arnd

-- 
Yoshinori Sato
<ysato@users.sourceforge.jp>

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 14/17] sh: SH3/4 Generic IRQCHIP driever
  2016-06-12  7:43     ` Yoshinori Sato
@ 2016-06-14 22:14       ` Rob Herring
  -1 siblings, 0 replies; 68+ messages in thread
From: Rob Herring @ 2016-06-14 22:14 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: linux-sh, linux-kernel, devicetree

On Sun, Jun 12, 2016 at 04:43:46PM +0900, Yoshinori Sato wrote:
> Sorry. I send old patches.
> Please ignore previous files.

Something like this needs to go below the '---' line.

> 
> IPR based IRQ chip driver.
> 
> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  .../interrupt-controller/renesas,sh7751-intc.txt   |  25 ++++

Otherwise,

Acked-by: Rob Herring <robh@kernel.org>

>  arch/sh/Kconfig                                    |   6 +-
>  arch/sh/boards/Kconfig                             |   1 +
>  drivers/irqchip/Kconfig                            |   5 +
>  drivers/irqchip/Makefile                           |   1 +
>  drivers/irqchip/irq-renesas-sh7751.c               | 141 +++++++++++++++++++++
>  6 files changed, 176 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
>  create mode 100644 drivers/irqchip/irq-renesas-sh7751.c

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 14/17] sh: SH3/4 Generic IRQCHIP driever
@ 2016-06-14 22:14       ` Rob Herring
  0 siblings, 0 replies; 68+ messages in thread
From: Rob Herring @ 2016-06-14 22:14 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: linux-sh, linux-kernel, devicetree

On Sun, Jun 12, 2016 at 04:43:46PM +0900, Yoshinori Sato wrote:
> Sorry. I send old patches.
> Please ignore previous files.

Something like this needs to go below the '---' line.

> 
> IPR based IRQ chip driver.
> 
> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  .../interrupt-controller/renesas,sh7751-intc.txt   |  25 ++++

Otherwise,

Acked-by: Rob Herring <robh@kernel.org>

>  arch/sh/Kconfig                                    |   6 +-
>  arch/sh/boards/Kconfig                             |   1 +
>  drivers/irqchip/Kconfig                            |   5 +
>  drivers/irqchip/Makefile                           |   1 +
>  drivers/irqchip/irq-renesas-sh7751.c               | 141 +++++++++++++++++++++
>  6 files changed, 176 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/renesas,sh7751-intc.txt
>  create mode 100644 drivers/irqchip/irq-renesas-sh7751.c

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 17/17] sh: landisk CPLD interrupt controller driver
  2016-06-12  7:44       ` Yoshinori Sato
@ 2016-06-14 22:24         ` Rob Herring
  -1 siblings, 0 replies; 68+ messages in thread
From: Rob Herring @ 2016-06-14 22:24 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: linux-sh, linux-kernel, devicetree

On Sun, Jun 12, 2016 at 04:44:14PM +0900, Yoshinori Sato wrote:
> Sorry. I send old patches.
> Please ignore previous files.

same comment here.

> 
> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  .../interrupt-controller/iodata-landisk.txt        | 28 +++++++++
>  drivers/irqchip/irq-io-landisk.c                   | 72 ++++++++++++++++++++++
>  2 files changed, 100 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
>  create mode 100644 drivers/irqchip/irq-io-landisk.c
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
> new file mode 100644
> index 0000000..d398538
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
> @@ -0,0 +1,28 @@
> +DT bindings for the I/O DATA HDL-U interrupt controller
> +
> +Required properties:
> +
> +  - compatible: has to be "iodata,landisk-intc".
> +
> +  - reg: Base address and length of interrupt controller register.
> +
> +  - interrupt-controller: Identifies the node as an interrupt controller.
> +
> +  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
> +    in interrupts.txt in this directory.
> +
> +  - interrupt-map: Interrupt mapping on parent controller.
> +
> +Example
> +-------
> +
> +	cpldintc: cpld@b0000000 {
> +		compatible = "iodata,landisk-intc";
> +		#interrupt-cells = <2>;
> +		interrupt-controller;
> +		reg = <0xb0000000 8>;
> +		interrupt-map=<0 &shintc 0 0>, <1 &shintc 1 0>,
> +		              <2 &shintc 2 0>, <3 &shintc 3 0>,
> +		              <4 &shintc 4 0>, <5 &shintc 5 0>,
> +		              <6 &shintc 6 0>, <7 &shintc 7 0>;

This is not right. Since this node has 2 interrupt-cells, you need 2 
entries for the child-interrupt specifier. You also need to set 
#address-cells to 0 and set the mask to mask out the 2nd cell.

Then again, there is not any real translation happening here, so perhaps 
you don't need this at all.

Rob

^ permalink raw reply	[flat|nested] 68+ messages in thread

* Re: [PATCH v2 17/17] sh: landisk CPLD interrupt controller driver
@ 2016-06-14 22:24         ` Rob Herring
  0 siblings, 0 replies; 68+ messages in thread
From: Rob Herring @ 2016-06-14 22:24 UTC (permalink / raw)
  To: Yoshinori Sato; +Cc: linux-sh, linux-kernel, devicetree

On Sun, Jun 12, 2016 at 04:44:14PM +0900, Yoshinori Sato wrote:
> Sorry. I send old patches.
> Please ignore previous files.

same comment here.

> 
> Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> ---
>  .../interrupt-controller/iodata-landisk.txt        | 28 +++++++++
>  drivers/irqchip/irq-io-landisk.c                   | 72 ++++++++++++++++++++++
>  2 files changed, 100 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
>  create mode 100644 drivers/irqchip/irq-io-landisk.c
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
> new file mode 100644
> index 0000000..d398538
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/iodata-landisk.txt
> @@ -0,0 +1,28 @@
> +DT bindings for the I/O DATA HDL-U interrupt controller
> +
> +Required properties:
> +
> +  - compatible: has to be "iodata,landisk-intc".
> +
> +  - reg: Base address and length of interrupt controller register.
> +
> +  - interrupt-controller: Identifies the node as an interrupt controller.
> +
> +  - #interrupt-cells: has to be <2>: an interrupt index and flags, as defined
> +    in interrupts.txt in this directory.
> +
> +  - interrupt-map: Interrupt mapping on parent controller.
> +
> +Example
> +-------
> +
> +	cpldintc: cpld@b0000000 {
> +		compatible = "iodata,landisk-intc";
> +		#interrupt-cells = <2>;
> +		interrupt-controller;
> +		reg = <0xb0000000 8>;
> +		interrupt-map=<0 &shintc 0 0>, <1 &shintc 1 0>,
> +		              <2 &shintc 2 0>, <3 &shintc 3 0>,
> +		              <4 &shintc 4 0>, <5 &shintc 5 0>,
> +		              <6 &shintc 6 0>, <7 &shintc 7 0>;

This is not right. Since this node has 2 interrupt-cells, you need 2 
entries for the child-interrupt specifier. You also need to set 
#address-cells to 0 and set the mask to mask out the 2nd cell.

Then again, there is not any real translation happening here, so perhaps 
you don't need this at all.

Rob

^ permalink raw reply	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2016-06-14 22:24 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-12  6:54 [PATCH v2 00/17] sh: LANDISK convert to device tree Yoshinori Sato
2016-06-12  6:54 ` Yoshinori Sato
2016-06-12  6:54 ` [PATCH v2 01/17] sh: Add sh-specific early_init_dt_reserve_memory_arch Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12 11:29   ` Sergei Shtylyov
2016-06-12 11:29     ` Sergei Shtylyov
2016-06-12  6:54 ` [PATCH v2 02/17] sh: More early unflatten device tree Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12  6:54 ` [PATCH v2 03/17] sh: set preset_lpj Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12  6:54 ` [PATCH v2 04/17] sh: Use P1SEGADDR Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12  6:54 ` [PATCH v2 05/17] sh: command line passing chosen/bootargs in devicetree Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12 11:32   ` Sergei Shtylyov
2016-06-12 11:32     ` Sergei Shtylyov
2016-06-12  6:54 ` [PATCH v2 06/17] sh: FDT address save before bank change Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12  6:54 ` [PATCH v2 07/17] sh: Passing FDT address on zImage Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12 11:38   ` Sergei Shtylyov
2016-06-12 11:38     ` Sergei Shtylyov
2016-06-12  6:54 ` [PATCH v2 08/17] sh: Disable board specific code on device tree mode Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12  6:54 ` [PATCH v2 09/17] sh: Use GENERIC_IOMAP " Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12  6:54 ` [PATCH v2 10/17] sh: convert generic drivers framework Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-13  8:05   ` Geert Uytterhoeven
2016-06-13  8:05     ` Geert Uytterhoeven
2016-06-12  6:54 ` [PATCH v2 11/17] sh: SH7750/51 clock driver Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-13  8:15   ` Geert Uytterhoeven
2016-06-13  8:15     ` Geert Uytterhoeven
2016-06-12  6:54 ` [PATCH v2 12/17] sh: Add PCI host bridge driver for SH7751 Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-13  8:04   ` Geert Uytterhoeven
2016-06-13  8:04     ` Geert Uytterhoeven
2016-06-13  8:04     ` Geert Uytterhoeven
2016-06-13  8:38   ` Arnd Bergmann
2016-06-13  8:38     ` Arnd Bergmann
2016-06-13 15:23     ` Yoshinori Sato
2016-06-13 15:23       ` Yoshinori Sato
2016-06-12  6:54 ` [PATCH v2 13/17] sh: Add PCI definetion Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-13  8:04   ` Geert Uytterhoeven
2016-06-13  8:04     ` Geert Uytterhoeven
2016-06-12  6:54 ` [PATCH v2 14/17] sh: SH3/4 Generic IRQCHIP driever Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12  7:43   ` Yoshinori Sato
2016-06-12  7:43     ` Yoshinori Sato
2016-06-14 22:14     ` Rob Herring
2016-06-14 22:14       ` Rob Herring
2016-06-12  6:54 ` [PATCH v2 15/17] sh: SH-INTC helper files Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-12  6:54 ` [PATCH v2 16/17] sh: I/O DATA HDL-U (a.k.a. landisk) Device Tree Yoshinori Sato
2016-06-12  6:54   ` Yoshinori Sato
2016-06-13  8:13   ` Geert Uytterhoeven
2016-06-13  8:13     ` Geert Uytterhoeven
2016-06-13 14:23     ` Yoshinori Sato
2016-06-13 14:23       ` Yoshinori Sato
     [not found] ` <1465714475-24111-1-git-send-email-ysato-Rn4VEauK+AKRv+LV9MX5uooqe+aC9MnS@public.gmane.org>
2016-06-12  6:54   ` [PATCH v2 17/17] sh: landisk CPLD interrupt controller driver Yoshinori Sato
2016-06-12  6:54     ` Yoshinori Sato
2016-06-12  6:54     ` Yoshinori Sato
2016-06-12  7:44     ` Yoshinori Sato
2016-06-12  7:44       ` Yoshinori Sato
2016-06-14 22:24       ` Rob Herring
2016-06-14 22:24         ` Rob Herring

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.