All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH_V2 00/34] jz4780 & CI20 support
@ 2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

Hi,

This series introduces initial support for the Ingenic jz4780 SoC & the
MIPS Creator CI20 board which is based upon it.

The jz4780 shares aspects with jz4740. But jz4740 is platform only.

So, the jz4740 & qi_lb60 (Ben NanoNote) are converted to use DT
for some things in order to ease the process of sharing code.

Series is based on 3.19-rc7.

ACKS from various subsystems are welcome so that the series can
go via mips if that is OK with everyone.

Alternative suggestions welcome.

Changes in V2
- Removed FSF addresses. 
- Removed 2 patches for binding docs that
  were consolidated in the same binding for jz4740.
- Bug fix in error handling in cgu
- Rebase on 3.19-rc7
- Updated defconfig with jz47xx serial and removed initramfs
- Renames in binding from intc to interrupt-controller
- Fix in jz47xx serial for build error on x86 in one config option
- Removed interupt-parent bindings from required bindings
- Fixed imgtec prefix to img
- Added jz47xx config for qi_lb60_defconfig

Regards,
ZubairLK


Paul Burton (34):
  dt: Add Ingenic Semiconductor vendor prefix
  MIPS: jz4740: require & include DT
  MIPS: irq_cpu: declare irqchip table entry
  MIPS: jz4740: probe CPU interrupt controller via DT
  MIPS: jz4740: use generic plat_irq_dispatch
  MIPS: jz4740: move arch_init_irq out of arch/mips/jz4740/irq.c
  dt: interrupt-controller: Add ingenic,jz4740-intc binding doc
  MIPS: jz4740: allow interrupt controller probe via DT
  MIPS: jz4740: probe interrupt controller via DT
  MIPS: jz4740: remove non-DT interrupt controller init
  MIPS: jz4740: register an irq_domain for the interrupt controller
  MIPS: jz4740: call jz4740_clock_init earlier
  MIPS: jz4740: replace use of jz4740_clock_bdata
  clk: jz47xx-cgu: add driver for Ingenic jz47xx series CGU clocks
  dt: clk: Add ingenic,jz4740-cgu binding documentation
  MIPS: clk: migrate jz4740 to common clock framework
  MIPS: clk: move jz4740_clock_set_wait_mode to jz4740-cgu
  MIPS: clk: move jz4740 UDC auto suspend functions to jz4740-cgu
  MIPS: clk: move jz4740 clock suspend, resume functions to jz4740-cgu
  MIPS: jz4740: remove clock.h
  MIPS: jz4740: only detect RAM size if not specified in DT
  MIPS: jz4740: support >32 interrupts
  MIPS: jz4740: define IRQ numbers based on number of intc IRQs
  dt: serial: Add ingenic,jz4740-uart binding
  serial: 8250_jz47xx: support for Ingenic jz47xx UARTs
  MIPS: allow mach-provided serial.h
  MIPS: jz4740: use jz47xx-uart & DT for UART output
  dt: clk: Add ingenic,jz4780-cgu binding documentation
  clk: add Ingenic jz4780 CGU driver
  MIPS: jz4740: add jz4780 interrupt controller support
  MIPS: add jz4780 Ingenic vendor ID
  MIPS: initial Ingenic jz4780 support
  MIPS: initial MIPS Creator CI20 board support
  MIPS: allow jz4780 to be selected in Kconfig

 .../bindings/clock/ingenic,jz4740-cgu.txt          |  52 ++
 .../bindings/clock/ingenic,jz4780-cgu.txt          |  52 ++
 .../interrupt-controller/ingenic,jz4740-intc.txt   |  26 +
 .../bindings/serial/ingenic,jz4740-uart.txt        |  22 +
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/mips/Kconfig                                  |  22 +-
 arch/mips/boot/dts/Makefile                        |   2 +
 arch/mips/boot/dts/ci20.dts                        |  21 +
 arch/mips/boot/dts/jz4740.dtsi                     |  68 ++
 arch/mips/boot/dts/jz4780.dtsi                     | 101 +++
 arch/mips/boot/dts/qi_lb60.dts                     |  15 +
 arch/mips/configs/ci20_defconfig                   | 127 +++
 arch/mips/configs/qi_lb60_defconfig                |   1 +
 arch/mips/include/asm/Kbuild                       |   1 -
 arch/mips/include/asm/cpu.h                        |   1 +
 arch/mips/include/asm/mach-generic/serial.h        |  21 +
 arch/mips/include/asm/mach-jz4740/clock.h          |   3 +
 arch/mips/include/asm/mach-jz4740/irq.h            |  15 +-
 arch/mips/include/asm/mach-jz4740/platform.h       |   2 -
 arch/mips/include/asm/mach-jz4740/serial.h         |  27 +
 arch/mips/include/asm/serial.h                     |  21 +
 arch/mips/jz4740/Kconfig                           |  10 +
 arch/mips/jz4740/Makefile                          |   6 +-
 arch/mips/jz4740/Platform                          |   4 +
 arch/mips/jz4740/board-qi_lb60.c                   |   7 -
 arch/mips/jz4740/clock-debugfs.c                   | 108 ---
 arch/mips/jz4740/clock.c                           | 924 ---------------------
 arch/mips/jz4740/clock.h                           |  76 --
 arch/mips/jz4740/irq.c                             | 103 ++-
 arch/mips/jz4740/platform.c                        |  37 +-
 arch/mips/jz4740/pm.c                              |   2 -
 arch/mips/jz4740/prom.c                            |  13 -
 arch/mips/jz4740/reset.c                           |  13 +-
 arch/mips/jz4740/serial.c                          |  33 -
 arch/mips/jz4740/serial.h                          |  23 -
 arch/mips/jz4740/setup.c                           |  33 +-
 arch/mips/jz4740/time.c                            |  19 +-
 arch/mips/kernel/cpu-probe.c                       |   1 +
 arch/mips/kernel/irq_cpu.c                         |   3 +
 drivers/clk/Makefile                               |   2 +
 drivers/clk/jz47xx/Makefile                        |   3 +
 drivers/clk/jz47xx/jz4740-cgu.c                    | 295 +++++++
 drivers/clk/jz47xx/jz4780-cgu.c                    | 742 +++++++++++++++++
 drivers/clk/jz47xx/jz47xx-cgu.c                    | 723 ++++++++++++++++
 drivers/clk/jz47xx/jz47xx-cgu.h                    | 205 +++++
 drivers/tty/serial/8250/8250_jz47xx.c              | 225 +++++
 drivers/tty/serial/8250/Kconfig                    |   9 +
 drivers/tty/serial/8250/Makefile                   |   1 +
 include/dt-bindings/clock/jz4740-cgu.h             |  37 +
 include/dt-bindings/clock/jz4780-cgu.h             |  88 ++
 50 files changed, 3070 insertions(+), 1276 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
 create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
 create mode 100644 Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt
 create mode 100644 arch/mips/boot/dts/ci20.dts
 create mode 100644 arch/mips/boot/dts/jz4740.dtsi
 create mode 100644 arch/mips/boot/dts/jz4780.dtsi
 create mode 100644 arch/mips/boot/dts/qi_lb60.dts
 create mode 100644 arch/mips/configs/ci20_defconfig
 create mode 100644 arch/mips/include/asm/mach-generic/serial.h
 create mode 100644 arch/mips/include/asm/mach-jz4740/serial.h
 create mode 100644 arch/mips/include/asm/serial.h
 delete mode 100644 arch/mips/jz4740/clock-debugfs.c
 delete mode 100644 arch/mips/jz4740/clock.c
 delete mode 100644 arch/mips/jz4740/clock.h
 delete mode 100644 arch/mips/jz4740/serial.c
 delete mode 100644 arch/mips/jz4740/serial.h
 create mode 100644 drivers/clk/jz47xx/Makefile
 create mode 100644 drivers/clk/jz47xx/jz4740-cgu.c
 create mode 100644 drivers/clk/jz47xx/jz4780-cgu.c
 create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.c
 create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.h
 create mode 100644 drivers/tty/serial/8250/8250_jz47xx.c
 create mode 100644 include/dt-bindings/clock/jz4740-cgu.h
 create mode 100644 include/dt-bindings/clock/jz4780-cgu.h

-- 
1.9.1


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

* [PATCH_V2 00/34] jz4780 & CI20 support
@ 2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

Hi,

This series introduces initial support for the Ingenic jz4780 SoC & the
MIPS Creator CI20 board which is based upon it.

The jz4780 shares aspects with jz4740. But jz4740 is platform only.

So, the jz4740 & qi_lb60 (Ben NanoNote) are converted to use DT
for some things in order to ease the process of sharing code.

Series is based on 3.19-rc7.

ACKS from various subsystems are welcome so that the series can
go via mips if that is OK with everyone.

Alternative suggestions welcome.

Changes in V2
- Removed FSF addresses. 
- Removed 2 patches for binding docs that
  were consolidated in the same binding for jz4740.
- Bug fix in error handling in cgu
- Rebase on 3.19-rc7
- Updated defconfig with jz47xx serial and removed initramfs
- Renames in binding from intc to interrupt-controller
- Fix in jz47xx serial for build error on x86 in one config option
- Removed interupt-parent bindings from required bindings
- Fixed imgtec prefix to img
- Added jz47xx config for qi_lb60_defconfig

Regards,
ZubairLK


Paul Burton (34):
  dt: Add Ingenic Semiconductor vendor prefix
  MIPS: jz4740: require & include DT
  MIPS: irq_cpu: declare irqchip table entry
  MIPS: jz4740: probe CPU interrupt controller via DT
  MIPS: jz4740: use generic plat_irq_dispatch
  MIPS: jz4740: move arch_init_irq out of arch/mips/jz4740/irq.c
  dt: interrupt-controller: Add ingenic,jz4740-intc binding doc
  MIPS: jz4740: allow interrupt controller probe via DT
  MIPS: jz4740: probe interrupt controller via DT
  MIPS: jz4740: remove non-DT interrupt controller init
  MIPS: jz4740: register an irq_domain for the interrupt controller
  MIPS: jz4740: call jz4740_clock_init earlier
  MIPS: jz4740: replace use of jz4740_clock_bdata
  clk: jz47xx-cgu: add driver for Ingenic jz47xx series CGU clocks
  dt: clk: Add ingenic,jz4740-cgu binding documentation
  MIPS: clk: migrate jz4740 to common clock framework
  MIPS: clk: move jz4740_clock_set_wait_mode to jz4740-cgu
  MIPS: clk: move jz4740 UDC auto suspend functions to jz4740-cgu
  MIPS: clk: move jz4740 clock suspend, resume functions to jz4740-cgu
  MIPS: jz4740: remove clock.h
  MIPS: jz4740: only detect RAM size if not specified in DT
  MIPS: jz4740: support >32 interrupts
  MIPS: jz4740: define IRQ numbers based on number of intc IRQs
  dt: serial: Add ingenic,jz4740-uart binding
  serial: 8250_jz47xx: support for Ingenic jz47xx UARTs
  MIPS: allow mach-provided serial.h
  MIPS: jz4740: use jz47xx-uart & DT for UART output
  dt: clk: Add ingenic,jz4780-cgu binding documentation
  clk: add Ingenic jz4780 CGU driver
  MIPS: jz4740: add jz4780 interrupt controller support
  MIPS: add jz4780 Ingenic vendor ID
  MIPS: initial Ingenic jz4780 support
  MIPS: initial MIPS Creator CI20 board support
  MIPS: allow jz4780 to be selected in Kconfig

 .../bindings/clock/ingenic,jz4740-cgu.txt          |  52 ++
 .../bindings/clock/ingenic,jz4780-cgu.txt          |  52 ++
 .../interrupt-controller/ingenic,jz4740-intc.txt   |  26 +
 .../bindings/serial/ingenic,jz4740-uart.txt        |  22 +
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 arch/mips/Kconfig                                  |  22 +-
 arch/mips/boot/dts/Makefile                        |   2 +
 arch/mips/boot/dts/ci20.dts                        |  21 +
 arch/mips/boot/dts/jz4740.dtsi                     |  68 ++
 arch/mips/boot/dts/jz4780.dtsi                     | 101 +++
 arch/mips/boot/dts/qi_lb60.dts                     |  15 +
 arch/mips/configs/ci20_defconfig                   | 127 +++
 arch/mips/configs/qi_lb60_defconfig                |   1 +
 arch/mips/include/asm/Kbuild                       |   1 -
 arch/mips/include/asm/cpu.h                        |   1 +
 arch/mips/include/asm/mach-generic/serial.h        |  21 +
 arch/mips/include/asm/mach-jz4740/clock.h          |   3 +
 arch/mips/include/asm/mach-jz4740/irq.h            |  15 +-
 arch/mips/include/asm/mach-jz4740/platform.h       |   2 -
 arch/mips/include/asm/mach-jz4740/serial.h         |  27 +
 arch/mips/include/asm/serial.h                     |  21 +
 arch/mips/jz4740/Kconfig                           |  10 +
 arch/mips/jz4740/Makefile                          |   6 +-
 arch/mips/jz4740/Platform                          |   4 +
 arch/mips/jz4740/board-qi_lb60.c                   |   7 -
 arch/mips/jz4740/clock-debugfs.c                   | 108 ---
 arch/mips/jz4740/clock.c                           | 924 ---------------------
 arch/mips/jz4740/clock.h                           |  76 --
 arch/mips/jz4740/irq.c                             | 103 ++-
 arch/mips/jz4740/platform.c                        |  37 +-
 arch/mips/jz4740/pm.c                              |   2 -
 arch/mips/jz4740/prom.c                            |  13 -
 arch/mips/jz4740/reset.c                           |  13 +-
 arch/mips/jz4740/serial.c                          |  33 -
 arch/mips/jz4740/serial.h                          |  23 -
 arch/mips/jz4740/setup.c                           |  33 +-
 arch/mips/jz4740/time.c                            |  19 +-
 arch/mips/kernel/cpu-probe.c                       |   1 +
 arch/mips/kernel/irq_cpu.c                         |   3 +
 drivers/clk/Makefile                               |   2 +
 drivers/clk/jz47xx/Makefile                        |   3 +
 drivers/clk/jz47xx/jz4740-cgu.c                    | 295 +++++++
 drivers/clk/jz47xx/jz4780-cgu.c                    | 742 +++++++++++++++++
 drivers/clk/jz47xx/jz47xx-cgu.c                    | 723 ++++++++++++++++
 drivers/clk/jz47xx/jz47xx-cgu.h                    | 205 +++++
 drivers/tty/serial/8250/8250_jz47xx.c              | 225 +++++
 drivers/tty/serial/8250/Kconfig                    |   9 +
 drivers/tty/serial/8250/Makefile                   |   1 +
 include/dt-bindings/clock/jz4740-cgu.h             |  37 +
 include/dt-bindings/clock/jz4780-cgu.h             |  88 ++
 50 files changed, 3070 insertions(+), 1276 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
 create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
 create mode 100644 Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt
 create mode 100644 arch/mips/boot/dts/ci20.dts
 create mode 100644 arch/mips/boot/dts/jz4740.dtsi
 create mode 100644 arch/mips/boot/dts/jz4780.dtsi
 create mode 100644 arch/mips/boot/dts/qi_lb60.dts
 create mode 100644 arch/mips/configs/ci20_defconfig
 create mode 100644 arch/mips/include/asm/mach-generic/serial.h
 create mode 100644 arch/mips/include/asm/mach-jz4740/serial.h
 create mode 100644 arch/mips/include/asm/serial.h
 delete mode 100644 arch/mips/jz4740/clock-debugfs.c
 delete mode 100644 arch/mips/jz4740/clock.c
 delete mode 100644 arch/mips/jz4740/clock.h
 delete mode 100644 arch/mips/jz4740/serial.c
 delete mode 100644 arch/mips/jz4740/serial.h
 create mode 100644 drivers/clk/jz47xx/Makefile
 create mode 100644 drivers/clk/jz47xx/jz4740-cgu.c
 create mode 100644 drivers/clk/jz47xx/jz4780-cgu.c
 create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.c
 create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.h
 create mode 100644 drivers/tty/serial/8250/8250_jz47xx.c
 create mode 100644 include/dt-bindings/clock/jz4740-cgu.h
 create mode 100644 include/dt-bindings/clock/jz4780-cgu.h

-- 
1.9.1

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

* [PATCH_V2 01/34] dt: Add Ingenic Semiconductor vendor prefix
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Simply use 'ingenic'.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: devicetree@vger.kernel.org
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index d443279..d0ea910 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -78,6 +78,7 @@ ibm	International Business Machines (IBM)
 idt	Integrated Device Technologies, Inc.
 iom	Iomega Corporation
 img	Imagination Technologies Ltd.
+ingenic	Ingenic Semiconductor
 innolux	Innolux Corporation
 intel	Intel Corporation
 intercontrol	Inter Control Group
-- 
1.9.1


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

* [PATCH_V2 01/34] dt: Add Ingenic Semiconductor vendor prefix
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips-6z/3iImG2C8G8FEW9MqTrA
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Zubair.Kakakhel-1AXoQHu6uovQT0dZR+AlfA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	mturquette-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	ralf-6z/3iImG2C8G8FEW9MqTrA, jslaby-AlSwsSmVLrQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA,
	lars-Qo5EllUWu/uELgA04lAiVw, paul.burton-1AXoQHu6uovQT0dZR+AlfA

From: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>

Simply use 'ingenic'.

Signed-off-by: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
Cc: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index d443279..d0ea910 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -78,6 +78,7 @@ ibm	International Business Machines (IBM)
 idt	Integrated Device Technologies, Inc.
 iom	Iomega Corporation
 img	Imagination Technologies Ltd.
+ingenic	Ingenic Semiconductor
 innolux	Innolux Corporation
 intel	Intel Corporation
 intercontrol	Inter Control Group
-- 
1.9.1

--
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] 86+ messages in thread

* [PATCH_V2 01/34] dt: Add Ingenic Semiconductor vendor prefix
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Simply use 'ingenic'.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: devicetree@vger.kernel.org
---
 Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index d443279..d0ea910 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -78,6 +78,7 @@ ibm	International Business Machines (IBM)
 idt	Integrated Device Technologies, Inc.
 iom	Iomega Corporation
 img	Imagination Technologies Ltd.
+ingenic	Ingenic Semiconductor
 innolux	Innolux Corporation
 intel	Intel Corporation
 intercontrol	Inter Control Group
-- 
1.9.1

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

* [PATCH_V2 02/34] MIPS: jz4740: require & include DT
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Require a DT for jz4740 based systems, and add a stub one for the
qi_lb60 (Ben NanoNote) board. Devices will be migrated to being probed
via this DT over time.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/Kconfig              |  2 ++
 arch/mips/boot/dts/Makefile    |  1 +
 arch/mips/boot/dts/jz4740.dtsi |  5 +++++
 arch/mips/boot/dts/qi_lb60.dts |  7 +++++++
 arch/mips/jz4740/setup.c       | 19 +++++++++++++++++++
 5 files changed, 34 insertions(+)
 create mode 100644 arch/mips/boot/dts/jz4740.dtsi
 create mode 100644 arch/mips/boot/dts/qi_lb60.dts

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3289969..99d50cd 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -288,6 +288,8 @@ config MACH_JZ4740
 	select SYS_HAS_EARLY_PRINTK
 	select HAVE_CLK
 	select GENERIC_IRQ_CHIP
+	select BUILTIN_DTB
+	select USE_OF
 
 config LANTIQ
 	bool "Lantiq based platforms"
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index 4f49fa4..a1127f3 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -9,6 +9,7 @@ dtb-$(CONFIG_DTB_RT2880_EVAL)		+= rt2880_eval.dtb
 dtb-$(CONFIG_DTB_RT305X_EVAL)		+= rt3052_eval.dtb
 dtb-$(CONFIG_DTB_RT3883_EVAL)		+= rt3883_eval.dtb
 dtb-$(CONFIG_DTB_MT7620A_EVAL)		+= mt7620a_eval.dtb
+dtb-$(CONFIG_JZ4740_QI_LB60)		+= qi_lb60.dtb
 dtb-$(CONFIG_MIPS_SEAD3)		+= sead3.dtb
 
 obj-y		+= $(patsubst %.dtb, %.dtb.o, $(dtb-y))
diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
new file mode 100644
index 0000000..c538691f
--- /dev/null
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -0,0 +1,5 @@
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ingenic,jz4740";
+};
diff --git a/arch/mips/boot/dts/qi_lb60.dts b/arch/mips/boot/dts/qi_lb60.dts
new file mode 100644
index 0000000..0c0f639
--- /dev/null
+++ b/arch/mips/boot/dts/qi_lb60.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+#include "jz4740.dtsi"
+
+/ {
+	compatible = "qi,lb60", "ingenic,jz4740";
+};
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index ef796f9..d6bb7a3 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -17,8 +17,11 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
 
 #include <asm/bootinfo.h>
+#include <asm/prom.h>
 
 #include <asm/mach-jz4740/base.h>
 
@@ -53,8 +56,24 @@ void __init plat_mem_setup(void)
 {
 	jz4740_reset_init();
 	jz4740_detect_mem();
+	__dt_setup_arch(__dtb_start);
 }
 
+void __init device_tree_init(void)
+{
+	if (!initial_boot_params)
+		return;
+
+	unflatten_and_copy_device_tree();
+}
+
+static int __init populate_machine(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+	return 0;
+}
+arch_initcall(populate_machine);
+
 const char *get_system_type(void)
 {
 	return "JZ4740";
-- 
1.9.1


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

* [PATCH_V2 02/34] MIPS: jz4740: require & include DT
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Require a DT for jz4740 based systems, and add a stub one for the
qi_lb60 (Ben NanoNote) board. Devices will be migrated to being probed
via this DT over time.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/Kconfig              |  2 ++
 arch/mips/boot/dts/Makefile    |  1 +
 arch/mips/boot/dts/jz4740.dtsi |  5 +++++
 arch/mips/boot/dts/qi_lb60.dts |  7 +++++++
 arch/mips/jz4740/setup.c       | 19 +++++++++++++++++++
 5 files changed, 34 insertions(+)
 create mode 100644 arch/mips/boot/dts/jz4740.dtsi
 create mode 100644 arch/mips/boot/dts/qi_lb60.dts

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3289969..99d50cd 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -288,6 +288,8 @@ config MACH_JZ4740
 	select SYS_HAS_EARLY_PRINTK
 	select HAVE_CLK
 	select GENERIC_IRQ_CHIP
+	select BUILTIN_DTB
+	select USE_OF
 
 config LANTIQ
 	bool "Lantiq based platforms"
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index 4f49fa4..a1127f3 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -9,6 +9,7 @@ dtb-$(CONFIG_DTB_RT2880_EVAL)		+= rt2880_eval.dtb
 dtb-$(CONFIG_DTB_RT305X_EVAL)		+= rt3052_eval.dtb
 dtb-$(CONFIG_DTB_RT3883_EVAL)		+= rt3883_eval.dtb
 dtb-$(CONFIG_DTB_MT7620A_EVAL)		+= mt7620a_eval.dtb
+dtb-$(CONFIG_JZ4740_QI_LB60)		+= qi_lb60.dtb
 dtb-$(CONFIG_MIPS_SEAD3)		+= sead3.dtb
 
 obj-y		+= $(patsubst %.dtb, %.dtb.o, $(dtb-y))
diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
new file mode 100644
index 0000000..c538691f
--- /dev/null
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -0,0 +1,5 @@
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ingenic,jz4740";
+};
diff --git a/arch/mips/boot/dts/qi_lb60.dts b/arch/mips/boot/dts/qi_lb60.dts
new file mode 100644
index 0000000..0c0f639
--- /dev/null
+++ b/arch/mips/boot/dts/qi_lb60.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+#include "jz4740.dtsi"
+
+/ {
+	compatible = "qi,lb60", "ingenic,jz4740";
+};
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index ef796f9..d6bb7a3 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -17,8 +17,11 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
 
 #include <asm/bootinfo.h>
+#include <asm/prom.h>
 
 #include <asm/mach-jz4740/base.h>
 
@@ -53,8 +56,24 @@ void __init plat_mem_setup(void)
 {
 	jz4740_reset_init();
 	jz4740_detect_mem();
+	__dt_setup_arch(__dtb_start);
 }
 
+void __init device_tree_init(void)
+{
+	if (!initial_boot_params)
+		return;
+
+	unflatten_and_copy_device_tree();
+}
+
+static int __init populate_machine(void)
+{
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+	return 0;
+}
+arch_initcall(populate_machine);
+
 const char *get_system_type(void)
 {
 	return "JZ4740";
-- 
1.9.1

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

* [PATCH_V2 03/34] MIPS: irq_cpu: declare irqchip table entry
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Allow the MIPS CPU interrupt controller to be probed from DT using the
generic __irqchip_of_table for platforms which use irqchip_init. This
will avoid such platforms needing to duplicate the compatible string &
init function pointer.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/kernel/irq_cpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 590c2c9..981d6a3 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -38,6 +38,8 @@
 #include <asm/mipsmtregs.h>
 #include <asm/setup.h>
 
+#include "../../drivers/irqchip/irqchip.h"
+
 static inline void unmask_mips_irq(struct irq_data *d)
 {
 	set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
@@ -163,3 +165,4 @@ int __init mips_cpu_irq_of_init(struct device_node *of_node,
 	__mips_cpu_irq_init(of_node);
 	return 0;
 }
+IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
-- 
1.9.1


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

* [PATCH_V2 03/34] MIPS: irq_cpu: declare irqchip table entry
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Allow the MIPS CPU interrupt controller to be probed from DT using the
generic __irqchip_of_table for platforms which use irqchip_init. This
will avoid such platforms needing to duplicate the compatible string &
init function pointer.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/kernel/irq_cpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index 590c2c9..981d6a3 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -38,6 +38,8 @@
 #include <asm/mipsmtregs.h>
 #include <asm/setup.h>
 
+#include "../../drivers/irqchip/irqchip.h"
+
 static inline void unmask_mips_irq(struct irq_data *d)
 {
 	set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
@@ -163,3 +165,4 @@ int __init mips_cpu_irq_of_init(struct device_node *of_node,
 	__mips_cpu_irq_init(of_node);
 	return 0;
 }
+IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
-- 
1.9.1

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

* [PATCH_V2 04/34] MIPS: jz4740: probe CPU interrupt controller via DT
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Use the generic irqchip_init function to probe irqchip drivers using DT,
and add the appropriate node to the jz4740 devicetree in place of the
call to mips_cpu_irq_init.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/boot/dts/jz4740.dtsi | 7 +++++++
 arch/mips/jz4740/irq.c         | 4 ++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
index c538691f..2d64765c 100644
--- a/arch/mips/boot/dts/jz4740.dtsi
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -2,4 +2,11 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 	compatible = "ingenic,jz4740";
+
+	cpuintc: cpuintc@0 {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
 };
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 2531da1..9c94f7b 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/irqchip.h>
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -27,7 +28,6 @@
 
 #include <asm/io.h>
 #include <asm/mipsregs.h>
-#include <asm/irq_cpu.h>
 
 #include <asm/mach-jz4740/base.h>
 
@@ -81,7 +81,7 @@ void __init arch_init_irq(void)
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 
-	mips_cpu_irq_init();
+	irqchip_init();
 
 	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
 
-- 
1.9.1


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

* [PATCH_V2 04/34] MIPS: jz4740: probe CPU interrupt controller via DT
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Use the generic irqchip_init function to probe irqchip drivers using DT,
and add the appropriate node to the jz4740 devicetree in place of the
call to mips_cpu_irq_init.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/boot/dts/jz4740.dtsi | 7 +++++++
 arch/mips/jz4740/irq.c         | 4 ++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
index c538691f..2d64765c 100644
--- a/arch/mips/boot/dts/jz4740.dtsi
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -2,4 +2,11 @@
 	#address-cells = <1>;
 	#size-cells = <1>;
 	compatible = "ingenic,jz4740";
+
+	cpuintc: cpuintc@0 {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
 };
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 2531da1..9c94f7b 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/irqchip.h>
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -27,7 +28,6 @@
 
 #include <asm/io.h>
 #include <asm/mipsregs.h>
-#include <asm/irq_cpu.h>
 
 #include <asm/mach-jz4740/base.h>
 
@@ -81,7 +81,7 @@ void __init arch_init_irq(void)
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 
-	mips_cpu_irq_init();
+	irqchip_init();
 
 	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
 
-- 
1.9.1

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

* [PATCH_V2 05/34] MIPS: jz4740: use generic plat_irq_dispatch
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Make use of the generic plat_irq_dispatch function introduced by commit
85f7cdacbb81 "MIPS: Provide a generic plat_irq_dispatch", in order to
reduce unnecessary code duplication.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 9c94f7b..999d64b 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -27,7 +27,6 @@
 #include <linux/seq_file.h>
 
 #include <asm/io.h>
-#include <asm/mipsregs.h>
 
 #include <asm/mach-jz4740/base.h>
 
@@ -108,17 +107,6 @@ void __init arch_init_irq(void)
 	setup_irq(2, &jz4740_cascade_action);
 }
 
-asmlinkage void plat_irq_dispatch(void)
-{
-	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
-	if (pending & STATUSF_IP2)
-		do_IRQ(2);
-	else if (pending & STATUSF_IP3)
-		do_IRQ(3);
-	else
-		spurious_interrupt();
-}
-
 #ifdef CONFIG_DEBUG_FS
 
 static inline void intc_seq_reg(struct seq_file *s, const char *name,
-- 
1.9.1


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

* [PATCH_V2 05/34] MIPS: jz4740: use generic plat_irq_dispatch
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Make use of the generic plat_irq_dispatch function introduced by commit
85f7cdacbb81 "MIPS: Provide a generic plat_irq_dispatch", in order to
reduce unnecessary code duplication.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 9c94f7b..999d64b 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -27,7 +27,6 @@
 #include <linux/seq_file.h>
 
 #include <asm/io.h>
-#include <asm/mipsregs.h>
 
 #include <asm/mach-jz4740/base.h>
 
@@ -108,17 +107,6 @@ void __init arch_init_irq(void)
 	setup_irq(2, &jz4740_cascade_action);
 }
 
-asmlinkage void plat_irq_dispatch(void)
-{
-	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
-	if (pending & STATUSF_IP2)
-		do_IRQ(2);
-	else if (pending & STATUSF_IP3)
-		do_IRQ(3);
-	else
-		spurious_interrupt();
-}
-
 #ifdef CONFIG_DEBUG_FS
 
 static inline void intc_seq_reg(struct seq_file *s, const char *name,
-- 
1.9.1

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

* [PATCH_V2 06/34] MIPS: jz4740: move arch_init_irq out of arch/mips/jz4740/irq.c
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

In preparation for moving the jz4740 interrupt controller driver to
drivers/irqchip, move arch_init_irq into setup.c such that everything
remaining in irq.c is related to said jz4740 interrupt controller.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/irq.h | 2 ++
 arch/mips/jz4740/irq.c                  | 5 +----
 arch/mips/jz4740/setup.c                | 8 ++++++++
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
index df50736..5ce4302 100644
--- a/arch/mips/include/asm/mach-jz4740/irq.h
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -54,4 +54,6 @@
 
 #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6)
 
+extern void __init jz4740_intc_init(void);
+
 #endif
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 999d64b..1b742c3 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -18,7 +18,6 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/irqchip.h>
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -75,13 +74,11 @@ static struct irqaction jz4740_cascade_action = {
 	.name = "JZ4740 cascade interrupt",
 };
 
-void __init arch_init_irq(void)
+void __init jz4740_intc_init(void)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 
-	irqchip_init();
-
 	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
 
 	/* Mask all irqs */
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index d6bb7a3..4808730 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -16,6 +16,7 @@
 
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irqchip.h>
 #include <linux/kernel.h>
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
@@ -24,6 +25,7 @@
 #include <asm/prom.h>
 
 #include <asm/mach-jz4740/base.h>
+#include <asm/mach-jz4740/irq.h>
 
 #include "reset.h"
 
@@ -78,3 +80,9 @@ const char *get_system_type(void)
 {
 	return "JZ4740";
 }
+
+void __init arch_init_irq(void)
+{
+	irqchip_init();
+	jz4740_intc_init();
+}
-- 
1.9.1


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

* [PATCH_V2 06/34] MIPS: jz4740: move arch_init_irq out of arch/mips/jz4740/irq.c
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

In preparation for moving the jz4740 interrupt controller driver to
drivers/irqchip, move arch_init_irq into setup.c such that everything
remaining in irq.c is related to said jz4740 interrupt controller.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/irq.h | 2 ++
 arch/mips/jz4740/irq.c                  | 5 +----
 arch/mips/jz4740/setup.c                | 8 ++++++++
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
index df50736..5ce4302 100644
--- a/arch/mips/include/asm/mach-jz4740/irq.h
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -54,4 +54,6 @@
 
 #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6)
 
+extern void __init jz4740_intc_init(void);
+
 #endif
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 999d64b..1b742c3 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -18,7 +18,6 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/irqchip.h>
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -75,13 +74,11 @@ static struct irqaction jz4740_cascade_action = {
 	.name = "JZ4740 cascade interrupt",
 };
 
-void __init arch_init_irq(void)
+void __init jz4740_intc_init(void)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 
-	irqchip_init();
-
 	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
 
 	/* Mask all irqs */
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index d6bb7a3..4808730 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -16,6 +16,7 @@
 
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irqchip.h>
 #include <linux/kernel.h>
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
@@ -24,6 +25,7 @@
 #include <asm/prom.h>
 
 #include <asm/mach-jz4740/base.h>
+#include <asm/mach-jz4740/irq.h>
 
 #include "reset.h"
 
@@ -78,3 +80,9 @@ const char *get_system_type(void)
 {
 	return "JZ4740";
 }
+
+void __init arch_init_irq(void)
+{
+	irqchip_init();
+	jz4740_intc_init();
+}
-- 
1.9.1

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

* [PATCH_V2 07/34] dt: interrupt-controller: Add ingenic,jz4740-intc binding doc
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add binding documentation for the Ingenic jz4740 interrupt controller.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: devicetree@vger.kernel.org
---
 .../interrupt-controller/ingenic,jz4740-intc.txt   | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
new file mode 100644
index 0000000..5e7f4bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
@@ -0,0 +1,26 @@
+Ingenic jz4740 SoC Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ingenic,jz4740-intc" or "ingenic,jz4780-intc"
+- reg : Specifies base physical address and size of the registers.
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+- interrupts - Specifies the CPU interrupt the controller is connected to.
+
+Optional properties:
+- interrupt-parent: phandle of the CPU interrupt controller.
+
+Example:
+
+intc: intc@10001000 {
+	compatible = "ingenic,jz4740-intc";
+	reg = <0x10001000 0x14>;
+
+	interrupt-controller;
+	#interrupt-cells = <1>;
+
+	interrupt-parent = <&cpuintc>;
+	interrupts = <2>;
+};
-- 
1.9.1


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

* [PATCH_V2 07/34] dt: interrupt-controller: Add ingenic,jz4740-intc binding doc
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add binding documentation for the Ingenic jz4740 interrupt controller.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: devicetree@vger.kernel.org
---
 .../interrupt-controller/ingenic,jz4740-intc.txt   | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
new file mode 100644
index 0000000..5e7f4bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
@@ -0,0 +1,26 @@
+Ingenic jz4740 SoC Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ingenic,jz4740-intc" or "ingenic,jz4780-intc"
+- reg : Specifies base physical address and size of the registers.
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+- interrupts - Specifies the CPU interrupt the controller is connected to.
+
+Optional properties:
+- interrupt-parent: phandle of the CPU interrupt controller.
+
+Example:
+
+intc: intc@10001000 {
+	compatible = "ingenic,jz4740-intc";
+	reg = <0x10001000 0x14>;
+
+	interrupt-controller;
+	#interrupt-cells = <1>;
+
+	interrupt-parent = <&cpuintc>;
+	interrupts = <2>;
+};
-- 
1.9.1

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

* [PATCH_V2 08/34] MIPS: jz4740: allow interrupt controller probe via DT
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Declare the interrupt controller for probe via the standard irqchip_init
function.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 1b742c3..a4f0a82 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/of_irq.h>
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -29,6 +30,8 @@
 
 #include <asm/mach-jz4740/base.h>
 
+#include "../../drivers/irqchip/irqchip.h"
+
 static void __iomem *jz_intc_base;
 
 #define JZ_REG_INTC_STATUS	0x00
@@ -74,7 +77,7 @@ static struct irqaction jz4740_cascade_action = {
 	.name = "JZ4740 cascade interrupt",
 };
 
-void __init jz4740_intc_init(void)
+static void __init __jz4740_intc_init(int parent_irq)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
@@ -101,8 +104,27 @@ void __init jz4740_intc_init(void)
 
 	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
 
-	setup_irq(2, &jz4740_cascade_action);
+	setup_irq(parent_irq, &jz4740_cascade_action);
+}
+
+void __init jz4740_intc_init(void)
+{
+	__jz4740_intc_init(2);
+}
+
+static int __init jz4740_intc_of_init(struct device_node *node,
+	struct device_node *parent)
+{
+	int parent_irq;
+
+	parent_irq = irq_of_parse_and_map(node, 0);
+	if (!parent_irq)
+		return -EINVAL;
+
+	__jz4740_intc_init(parent_irq);
+	return 0;
 }
+IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init);
 
 #ifdef CONFIG_DEBUG_FS
 
-- 
1.9.1


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

* [PATCH_V2 08/34] MIPS: jz4740: allow interrupt controller probe via DT
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips-6z/3iImG2C8G8FEW9MqTrA
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Zubair.Kakakhel-1AXoQHu6uovQT0dZR+AlfA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	mturquette-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	ralf-6z/3iImG2C8G8FEW9MqTrA, jslaby-AlSwsSmVLrQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA,
	lars-Qo5EllUWu/uELgA04lAiVw, paul.burton-1AXoQHu6uovQT0dZR+AlfA

From: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>

Declare the interrupt controller for probe via the standard irqchip_init
function.

Signed-off-by: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
Cc: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
---
 arch/mips/jz4740/irq.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 1b742c3..a4f0a82 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/of_irq.h>
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -29,6 +30,8 @@
 
 #include <asm/mach-jz4740/base.h>
 
+#include "../../drivers/irqchip/irqchip.h"
+
 static void __iomem *jz_intc_base;
 
 #define JZ_REG_INTC_STATUS	0x00
@@ -74,7 +77,7 @@ static struct irqaction jz4740_cascade_action = {
 	.name = "JZ4740 cascade interrupt",
 };
 
-void __init jz4740_intc_init(void)
+static void __init __jz4740_intc_init(int parent_irq)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
@@ -101,8 +104,27 @@ void __init jz4740_intc_init(void)
 
 	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
 
-	setup_irq(2, &jz4740_cascade_action);
+	setup_irq(parent_irq, &jz4740_cascade_action);
+}
+
+void __init jz4740_intc_init(void)
+{
+	__jz4740_intc_init(2);
+}
+
+static int __init jz4740_intc_of_init(struct device_node *node,
+	struct device_node *parent)
+{
+	int parent_irq;
+
+	parent_irq = irq_of_parse_and_map(node, 0);
+	if (!parent_irq)
+		return -EINVAL;
+
+	__jz4740_intc_init(parent_irq);
+	return 0;
 }
+IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init);
 
 #ifdef CONFIG_DEBUG_FS
 
-- 
1.9.1

--
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] 86+ messages in thread

* [PATCH_V2 08/34] MIPS: jz4740: allow interrupt controller probe via DT
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Declare the interrupt controller for probe via the standard irqchip_init
function.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 1b742c3..a4f0a82 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -18,6 +18,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/of_irq.h>
 #include <linux/timex.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -29,6 +30,8 @@
 
 #include <asm/mach-jz4740/base.h>
 
+#include "../../drivers/irqchip/irqchip.h"
+
 static void __iomem *jz_intc_base;
 
 #define JZ_REG_INTC_STATUS	0x00
@@ -74,7 +77,7 @@ static struct irqaction jz4740_cascade_action = {
 	.name = "JZ4740 cascade interrupt",
 };
 
-void __init jz4740_intc_init(void)
+static void __init __jz4740_intc_init(int parent_irq)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
@@ -101,8 +104,27 @@ void __init jz4740_intc_init(void)
 
 	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
 
-	setup_irq(2, &jz4740_cascade_action);
+	setup_irq(parent_irq, &jz4740_cascade_action);
+}
+
+void __init jz4740_intc_init(void)
+{
+	__jz4740_intc_init(2);
+}
+
+static int __init jz4740_intc_of_init(struct device_node *node,
+	struct device_node *parent)
+{
+	int parent_irq;
+
+	parent_irq = irq_of_parse_and_map(node, 0);
+	if (!parent_irq)
+		return -EINVAL;
+
+	__jz4740_intc_init(parent_irq);
+	return 0;
 }
+IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init);
 
 #ifdef CONFIG_DEBUG_FS
 
-- 
1.9.1

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

* [PATCH_V2 09/34] MIPS: jz4740: probe interrupt controller via DT
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add the appropriate DT node to probe the interrupt controller driver
using the devicetree, and remove the call to jz4740_intc_init.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/boot/dts/jz4740.dtsi | 11 +++++++++++
 arch/mips/jz4740/setup.c       |  2 --
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
index 2d64765c..3841024 100644
--- a/arch/mips/boot/dts/jz4740.dtsi
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -9,4 +9,15 @@
 		interrupt-controller;
 		compatible = "mti,cpu-interrupt-controller";
 	};
+
+	intc: intc@10001000 {
+		compatible = "ingenic,jz4740-intc";
+		reg = <0x10001000 0x14>;
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <2>;
+	};
 };
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index 4808730..8c08d7d 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -25,7 +25,6 @@
 #include <asm/prom.h>
 
 #include <asm/mach-jz4740/base.h>
-#include <asm/mach-jz4740/irq.h>
 
 #include "reset.h"
 
@@ -84,5 +83,4 @@ const char *get_system_type(void)
 void __init arch_init_irq(void)
 {
 	irqchip_init();
-	jz4740_intc_init();
 }
-- 
1.9.1


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

* [PATCH_V2 09/34] MIPS: jz4740: probe interrupt controller via DT
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add the appropriate DT node to probe the interrupt controller driver
using the devicetree, and remove the call to jz4740_intc_init.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/boot/dts/jz4740.dtsi | 11 +++++++++++
 arch/mips/jz4740/setup.c       |  2 --
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
index 2d64765c..3841024 100644
--- a/arch/mips/boot/dts/jz4740.dtsi
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -9,4 +9,15 @@
 		interrupt-controller;
 		compatible = "mti,cpu-interrupt-controller";
 	};
+
+	intc: intc@10001000 {
+		compatible = "ingenic,jz4740-intc";
+		reg = <0x10001000 0x14>;
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <2>;
+	};
 };
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index 4808730..8c08d7d 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -25,7 +25,6 @@
 #include <asm/prom.h>
 
 #include <asm/mach-jz4740/base.h>
-#include <asm/mach-jz4740/irq.h>
 
 #include "reset.h"
 
@@ -84,5 +83,4 @@ const char *get_system_type(void)
 void __init arch_init_irq(void)
 {
 	irqchip_init();
-	jz4740_intc_init();
 }
-- 
1.9.1

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

* [PATCH_V2 10/34] MIPS: jz4740: remove non-DT interrupt controller init
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The jz4740 now probes the interrupt controller using DT, so remove the
now dead non-DT init code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/irq.h |  2 --
 arch/mips/jz4740/irq.c                  | 25 +++++++------------------
 2 files changed, 7 insertions(+), 20 deletions(-)

diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
index 5ce4302..df50736 100644
--- a/arch/mips/include/asm/mach-jz4740/irq.h
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -54,6 +54,4 @@
 
 #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6)
 
-extern void __init jz4740_intc_init(void);
-
 #endif
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index a4f0a82..9a8bda3 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -77,10 +77,16 @@ static struct irqaction jz4740_cascade_action = {
 	.name = "JZ4740 cascade interrupt",
 };
 
-static void __init __jz4740_intc_init(int parent_irq)
+static int __init jz4740_intc_of_init(struct device_node *node,
+	struct device_node *parent)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
+	int parent_irq;
+
+	parent_irq = irq_of_parse_and_map(node, 0);
+	if (!parent_irq)
+		return -EINVAL;
 
 	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
 
@@ -105,23 +111,6 @@ static void __init __jz4740_intc_init(int parent_irq)
 	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
 
 	setup_irq(parent_irq, &jz4740_cascade_action);
-}
-
-void __init jz4740_intc_init(void)
-{
-	__jz4740_intc_init(2);
-}
-
-static int __init jz4740_intc_of_init(struct device_node *node,
-	struct device_node *parent)
-{
-	int parent_irq;
-
-	parent_irq = irq_of_parse_and_map(node, 0);
-	if (!parent_irq)
-		return -EINVAL;
-
-	__jz4740_intc_init(parent_irq);
 	return 0;
 }
 IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init);
-- 
1.9.1


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

* [PATCH_V2 10/34] MIPS: jz4740: remove non-DT interrupt controller init
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The jz4740 now probes the interrupt controller using DT, so remove the
now dead non-DT init code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/irq.h |  2 --
 arch/mips/jz4740/irq.c                  | 25 +++++++------------------
 2 files changed, 7 insertions(+), 20 deletions(-)

diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
index 5ce4302..df50736 100644
--- a/arch/mips/include/asm/mach-jz4740/irq.h
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -54,6 +54,4 @@
 
 #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6)
 
-extern void __init jz4740_intc_init(void);
-
 #endif
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index a4f0a82..9a8bda3 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -77,10 +77,16 @@ static struct irqaction jz4740_cascade_action = {
 	.name = "JZ4740 cascade interrupt",
 };
 
-static void __init __jz4740_intc_init(int parent_irq)
+static int __init jz4740_intc_of_init(struct device_node *node,
+	struct device_node *parent)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
+	int parent_irq;
+
+	parent_irq = irq_of_parse_and_map(node, 0);
+	if (!parent_irq)
+		return -EINVAL;
 
 	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
 
@@ -105,23 +111,6 @@ static void __init __jz4740_intc_init(int parent_irq)
 	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
 
 	setup_irq(parent_irq, &jz4740_cascade_action);
-}
-
-void __init jz4740_intc_init(void)
-{
-	__jz4740_intc_init(2);
-}
-
-static int __init jz4740_intc_of_init(struct device_node *node,
-	struct device_node *parent)
-{
-	int parent_irq;
-
-	parent_irq = irq_of_parse_and_map(node, 0);
-	if (!parent_irq)
-		return -EINVAL;
-
-	__jz4740_intc_init(parent_irq);
 	return 0;
 }
 IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init);
-- 
1.9.1

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

* [PATCH_V2 11/34] MIPS: jz4740: register an irq_domain for the interrupt controller
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

When probining the interrupt controller, register an IRQ domain such
that the interrupts can be translated by devicetree code & thus used
from devicetree.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 9a8bda3..a620b23 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -82,6 +82,7 @@ static int __init jz4740_intc_of_init(struct device_node *node,
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
+	struct irq_domain *domain;
 	int parent_irq;
 
 	parent_irq = irq_of_parse_and_map(node, 0);
@@ -110,6 +111,11 @@ static int __init jz4740_intc_of_init(struct device_node *node,
 
 	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
 
+	domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0,
+				       &irq_domain_simple_ops, NULL);
+	if (!domain)
+		pr_warn("unable to register IRQ domain\n");
+
 	setup_irq(parent_irq, &jz4740_cascade_action);
 	return 0;
 }
-- 
1.9.1


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

* [PATCH_V2 11/34] MIPS: jz4740: register an irq_domain for the interrupt controller
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

When probining the interrupt controller, register an IRQ domain such
that the interrupts can be translated by devicetree code & thus used
from devicetree.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 9a8bda3..a620b23 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -82,6 +82,7 @@ static int __init jz4740_intc_of_init(struct device_node *node,
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
+	struct irq_domain *domain;
 	int parent_irq;
 
 	parent_irq = irq_of_parse_and_map(node, 0);
@@ -110,6 +111,11 @@ static int __init jz4740_intc_of_init(struct device_node *node,
 
 	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
 
+	domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0,
+				       &irq_domain_simple_ops, NULL);
+	if (!domain)
+		pr_warn("unable to register IRQ domain\n");
+
 	setup_irq(parent_irq, &jz4740_cascade_action);
 	return 0;
 }
-- 
1.9.1

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

* [PATCH_V2 12/34] MIPS: jz4740: call jz4740_clock_init earlier
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Call jz4740_clock_init before any uses of jz4740_clock_bdata occur. This
is in preparation for replacing uses of that struct with calls to
clk_get_rate, which will allow the clocks to be migrated towards common
clock framework & devicetree.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/clock.h | 2 ++
 arch/mips/jz4740/clock.c                  | 3 +--
 arch/mips/jz4740/time.c                   | 2 ++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
index 16659cd..01d8468 100644
--- a/arch/mips/include/asm/mach-jz4740/clock.h
+++ b/arch/mips/include/asm/mach-jz4740/clock.h
@@ -20,6 +20,8 @@ enum jz4740_wait_mode {
 	JZ4740_WAIT_MODE_SLEEP,
 };
 
+int jz4740_clock_init(void);
+
 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
 
 void jz4740_clock_udc_enable_auto_suspend(void);
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
index 1b5f554..c257073 100644
--- a/arch/mips/jz4740/clock.c
+++ b/arch/mips/jz4740/clock.c
@@ -889,7 +889,7 @@ void jz4740_clock_resume(void)
 		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
 }
 
-static int jz4740_clock_init(void)
+int jz4740_clock_init(void)
 {
 	uint32_t val;
 
@@ -921,4 +921,3 @@ static int jz4740_clock_init(void)
 
 	return 0;
 }
-arch_initcall(jz4740_clock_init);
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index 5e430ce..9424344 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -19,6 +19,7 @@
 
 #include <linux/clockchips.h>
 
+#include <asm/mach-jz4740/clock.h>
 #include <asm/mach-jz4740/irq.h>
 #include <asm/mach-jz4740/timer.h>
 #include <asm/time.h>
@@ -109,6 +110,7 @@ void __init plat_time_init(void)
 	uint32_t clk_rate;
 	uint16_t ctrl;
 
+	jz4740_clock_init();
 	jz4740_timer_init();
 
 	clk_rate = jz4740_clock_bdata.ext_rate >> 4;
-- 
1.9.1


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

* [PATCH_V2 12/34] MIPS: jz4740: call jz4740_clock_init earlier
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Call jz4740_clock_init before any uses of jz4740_clock_bdata occur. This
is in preparation for replacing uses of that struct with calls to
clk_get_rate, which will allow the clocks to be migrated towards common
clock framework & devicetree.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/clock.h | 2 ++
 arch/mips/jz4740/clock.c                  | 3 +--
 arch/mips/jz4740/time.c                   | 2 ++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
index 16659cd..01d8468 100644
--- a/arch/mips/include/asm/mach-jz4740/clock.h
+++ b/arch/mips/include/asm/mach-jz4740/clock.h
@@ -20,6 +20,8 @@ enum jz4740_wait_mode {
 	JZ4740_WAIT_MODE_SLEEP,
 };
 
+int jz4740_clock_init(void);
+
 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
 
 void jz4740_clock_udc_enable_auto_suspend(void);
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
index 1b5f554..c257073 100644
--- a/arch/mips/jz4740/clock.c
+++ b/arch/mips/jz4740/clock.c
@@ -889,7 +889,7 @@ void jz4740_clock_resume(void)
 		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
 }
 
-static int jz4740_clock_init(void)
+int jz4740_clock_init(void)
 {
 	uint32_t val;
 
@@ -921,4 +921,3 @@ static int jz4740_clock_init(void)
 
 	return 0;
 }
-arch_initcall(jz4740_clock_init);
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index 5e430ce..9424344 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -19,6 +19,7 @@
 
 #include <linux/clockchips.h>
 
+#include <asm/mach-jz4740/clock.h>
 #include <asm/mach-jz4740/irq.h>
 #include <asm/mach-jz4740/timer.h>
 #include <asm/time.h>
@@ -109,6 +110,7 @@ void __init plat_time_init(void)
 	uint32_t clk_rate;
 	uint16_t ctrl;
 
+	jz4740_clock_init();
 	jz4740_timer_init();
 
 	clk_rate = jz4740_clock_bdata.ext_rate >> 4;
-- 
1.9.1

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

* [PATCH_V2 13/34] MIPS: jz4740: replace use of jz4740_clock_bdata
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Replace uses of the jz4740_clock_bdata struct with calls to clk_get_rate
for the appropriate clock. This is in preparation for migrating the
clocks towards common clock framework & devicetree.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/platform.c | 11 ++++++++++-
 arch/mips/jz4740/reset.c    | 13 +++++++++++--
 arch/mips/jz4740/time.c     |  9 ++++++++-
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index 0b12f27..2a5c7c7 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
@@ -308,9 +309,17 @@ static struct platform_device jz4740_uart_device = {
 void jz4740_serial_device_register(void)
 {
 	struct plat_serial8250_port *p;
+	struct clk *ext_clk;
+	unsigned long ext_rate;
+
+	ext_clk = clk_get(NULL, "ext");
+	if (IS_ERR(ext_clk))
+		panic("unable to get ext clock");
+	ext_rate = clk_get_rate(ext_clk);
+	clk_put(ext_clk);
 
 	for (p = jz4740_uart_data; p->flags != 0; ++p)
-		p->uartclk = jz4740_clock_bdata.ext_rate;
+		p->uartclk = ext_rate;
 
 	platform_device_register(&jz4740_uart_device);
 }
diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c
index b6c6343..954e669 100644
--- a/arch/mips/jz4740/reset.c
+++ b/arch/mips/jz4740/reset.c
@@ -12,6 +12,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/pm.h>
@@ -79,12 +80,20 @@ static void jz4740_power_off(void)
 	void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x38);
 	unsigned long wakeup_filter_ticks;
 	unsigned long reset_counter_ticks;
+	struct clk *rtc_clk;
+	unsigned long rtc_rate;
+
+	rtc_clk = clk_get(NULL, "rtc");
+	if (IS_ERR(rtc_clk))
+		panic("unable to get RTC clock");
+	rtc_rate = clk_get_rate(rtc_clk);
+	clk_put(rtc_clk);
 
 	/*
 	 * Set minimum wakeup pin assertion time: 100 ms.
 	 * Range is 0 to 2 sec if RTC is clocked at 32 kHz.
 	 */
-	wakeup_filter_ticks = (100 * jz4740_clock_bdata.rtc_rate) / 1000;
+	wakeup_filter_ticks = (100 * rtc_rate) / 1000;
 	if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
 		wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
 	else
@@ -96,7 +105,7 @@ static void jz4740_power_off(void)
 	 * Set reset pin low-level assertion time after wakeup: 60 ms.
 	 * Range is 0 to 125 ms if RTC is clocked at 32 kHz.
 	 */
-	reset_counter_ticks = (60 * jz4740_clock_bdata.rtc_rate) / 1000;
+	reset_counter_ticks = (60 * rtc_rate) / 1000;
 	if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK)
 		reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK;
 	else
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index 9424344..bff2ac9 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
@@ -109,11 +110,17 @@ void __init plat_time_init(void)
 	int ret;
 	uint32_t clk_rate;
 	uint16_t ctrl;
+	struct clk *ext_clk;
 
 	jz4740_clock_init();
 	jz4740_timer_init();
 
-	clk_rate = jz4740_clock_bdata.ext_rate >> 4;
+	ext_clk = clk_get(NULL, "ext");
+	if (IS_ERR(ext_clk))
+		panic("unable to get ext clock");
+	clk_rate = clk_get_rate(ext_clk) >> 4;
+	clk_put(ext_clk);
+
 	jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
 
 	clockevent_set_clock(&jz4740_clockevent, clk_rate);
-- 
1.9.1


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

* [PATCH_V2 13/34] MIPS: jz4740: replace use of jz4740_clock_bdata
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Replace uses of the jz4740_clock_bdata struct with calls to clk_get_rate
for the appropriate clock. This is in preparation for migrating the
clocks towards common clock framework & devicetree.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/platform.c | 11 ++++++++++-
 arch/mips/jz4740/reset.c    | 13 +++++++++++--
 arch/mips/jz4740/time.c     |  9 ++++++++-
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index 0b12f27..2a5c7c7 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
@@ -308,9 +309,17 @@ static struct platform_device jz4740_uart_device = {
 void jz4740_serial_device_register(void)
 {
 	struct plat_serial8250_port *p;
+	struct clk *ext_clk;
+	unsigned long ext_rate;
+
+	ext_clk = clk_get(NULL, "ext");
+	if (IS_ERR(ext_clk))
+		panic("unable to get ext clock");
+	ext_rate = clk_get_rate(ext_clk);
+	clk_put(ext_clk);
 
 	for (p = jz4740_uart_data; p->flags != 0; ++p)
-		p->uartclk = jz4740_clock_bdata.ext_rate;
+		p->uartclk = ext_rate;
 
 	platform_device_register(&jz4740_uart_device);
 }
diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c
index b6c6343..954e669 100644
--- a/arch/mips/jz4740/reset.c
+++ b/arch/mips/jz4740/reset.c
@@ -12,6 +12,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/pm.h>
@@ -79,12 +80,20 @@ static void jz4740_power_off(void)
 	void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x38);
 	unsigned long wakeup_filter_ticks;
 	unsigned long reset_counter_ticks;
+	struct clk *rtc_clk;
+	unsigned long rtc_rate;
+
+	rtc_clk = clk_get(NULL, "rtc");
+	if (IS_ERR(rtc_clk))
+		panic("unable to get RTC clock");
+	rtc_rate = clk_get_rate(rtc_clk);
+	clk_put(rtc_clk);
 
 	/*
 	 * Set minimum wakeup pin assertion time: 100 ms.
 	 * Range is 0 to 2 sec if RTC is clocked at 32 kHz.
 	 */
-	wakeup_filter_ticks = (100 * jz4740_clock_bdata.rtc_rate) / 1000;
+	wakeup_filter_ticks = (100 * rtc_rate) / 1000;
 	if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
 		wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
 	else
@@ -96,7 +105,7 @@ static void jz4740_power_off(void)
 	 * Set reset pin low-level assertion time after wakeup: 60 ms.
 	 * Range is 0 to 125 ms if RTC is clocked at 32 kHz.
 	 */
-	reset_counter_ticks = (60 * jz4740_clock_bdata.rtc_rate) / 1000;
+	reset_counter_ticks = (60 * rtc_rate) / 1000;
 	if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK)
 		reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK;
 	else
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index 9424344..bff2ac9 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
@@ -109,11 +110,17 @@ void __init plat_time_init(void)
 	int ret;
 	uint32_t clk_rate;
 	uint16_t ctrl;
+	struct clk *ext_clk;
 
 	jz4740_clock_init();
 	jz4740_timer_init();
 
-	clk_rate = jz4740_clock_bdata.ext_rate >> 4;
+	ext_clk = clk_get(NULL, "ext");
+	if (IS_ERR(ext_clk))
+		panic("unable to get ext clock");
+	clk_rate = clk_get_rate(ext_clk) >> 4;
+	clk_put(ext_clk);
+
 	jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
 
 	clockevent_set_clock(&jz4740_clockevent, clk_rate);
-- 
1.9.1

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

* [PATCH_V2 14/34] clk: jz47xx-cgu: add driver for Ingenic jz47xx series CGU clocks
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

This driver supports the CGU clocks for the Ingenic jz47xx series of
SoCs. It is generic enough to be usable across at least the jz4740 to
the jz4780, as will be done in subsequent commits.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Co-authored-by: Paul Cercueil <paul@crapouillou.net>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>

---
V2
Removed FSF address
Bug fix in error handling
---
 drivers/clk/Makefile            |   1 +
 drivers/clk/jz47xx/Makefile     |   1 +
 drivers/clk/jz47xx/jz47xx-cgu.c | 723 ++++++++++++++++++++++++++++++++++++++++
 drivers/clk/jz47xx/jz47xx-cgu.h | 205 ++++++++++++
 4 files changed, 930 insertions(+)
 create mode 100644 drivers/clk/jz47xx/Makefile
 create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.c
 create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..fc434c0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
 obj-$(CONFIG_ARCH_HI3xxx)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIP04)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIX5HD2)		+= hisilicon/
+obj-$(CONFIG_MACH_JZ4740)		+= jz47xx/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)	+= keystone/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
diff --git a/drivers/clk/jz47xx/Makefile b/drivers/clk/jz47xx/Makefile
new file mode 100644
index 0000000..ac594e5
--- /dev/null
+++ b/drivers/clk/jz47xx/Makefile
@@ -0,0 +1 @@
+obj-y				+= jz47xx-cgu.o
diff --git a/drivers/clk/jz47xx/jz47xx-cgu.c b/drivers/clk/jz47xx/jz47xx-cgu.c
new file mode 100644
index 0000000..85d0592
--- /dev/null
+++ b/drivers/clk/jz47xx/jz47xx-cgu.c
@@ -0,0 +1,723 @@
+/*
+ * Ingenic jz47xx series CGU driver
+ *
+ * Copyright (c) 2013-2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include "jz47xx-cgu.h"
+
+#define REG_CLKGR		0x20
+#define REG_CLKGR_STRIDE	0x8
+
+#define MHZ (1000 * 1000)
+
+/**
+ * jz47xx_cgu_gate_get - get the value of clock gate register bit
+ * @cgu: reference to the CGU whose registers should be read
+ * @idx: index of the gate bit
+ *
+ * Returns 1 if the gate bit is set, else 0. The index begins with 0 being
+ * bit 0 of CLKGR0, continuing from 32 for bit 0 of CLKGR1 etc. For example,
+ * the index of bit 9 of CLKGR1 would be (32+9) == 41.
+ *
+ * The caller must hold cgu->power_lock.
+ */
+static inline unsigned jz47xx_cgu_gate_get(struct jz47xx_cgu *cgu,
+					   unsigned idx)
+{
+	void __iomem *reg;
+	u32 bit, clkgr;
+
+	reg = cgu->base + REG_CLKGR + ((idx / 32) * REG_CLKGR_STRIDE);
+	bit = 1 << (idx % 32);
+	clkgr = readl(reg);
+	return !!(clkgr & bit);
+}
+
+/**
+ * jz47xx_cgu_gate_set - set the value of clock gate register bit
+ * @cgu: reference to the CGU whose registers should be modified
+ * @idx: index of the gate bit
+ * @val: non-zero to gate a clock, otherwise zero
+ *
+ * Sets the given gate bit in order to gate or ungate a clock. See
+ * jz47xx_cgu_gate_get for a description of the idx parameter.
+ *
+ * The caller must hold cgu->power_lock.
+ */
+static inline void jz47xx_cgu_gate_set(struct jz47xx_cgu *cgu,
+				       unsigned idx, unsigned val)
+{
+	void __iomem *reg;
+	u32 bit, clkgr;
+
+	reg = cgu->base + REG_CLKGR + ((idx / 32) * REG_CLKGR_STRIDE);
+	bit = 1 << (idx % 32);
+	clkgr = readl(reg);
+
+	if (val)
+		clkgr |= bit;
+	else
+		clkgr &= ~bit;
+
+	writel(clkgr, reg);
+}
+
+/*
+ * PLL operations
+ */
+
+static unsigned long jz47xx_pll_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	const struct jz47xx_cgu_pll_info *pll_info;
+	unsigned m, n, od_enc, od;
+	bool bypass, enable;
+	unsigned long flags;
+	u32 ctl;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+	BUG_ON(clk_info->type != CGU_CLK_PLL);
+	pll_info = &clk_info->pll;
+
+	spin_lock_irqsave(&cgu->pll_lock, flags);
+	ctl = readl(cgu->base + pll_info->reg);
+	spin_unlock_irqrestore(&cgu->pll_lock, flags);
+
+	m = ((ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0));
+	m += pll_info->m_offset;
+	n = ((ctl >> pll_info->n_shift) & GENMASK(pll_info->n_bits - 1, 0));
+	n += pll_info->n_offset;
+	od_enc = ((ctl >> pll_info->od_shift)
+		 & GENMASK(pll_info->od_bits - 1, 0));
+	bypass = !!(ctl & BIT(pll_info->bypass_bit));
+	enable = !!(ctl & BIT(pll_info->enable_bit));
+
+	if (bypass)
+		return parent_rate;
+
+	if (!enable)
+		return 0;
+
+	for (od = 0; od < pll_info->od_max; od++) {
+		if (pll_info->od_encoding[od] == od_enc)
+			break;
+	}
+	BUG_ON(od == pll_info->od_max);
+	od++;
+
+	return parent_rate * m / (n * od);
+}
+
+static unsigned long jz47xx_pll_calc(const struct jz47xx_cgu_clk_info *clk_info,
+				     unsigned long rate,
+				     unsigned long parent_rate,
+				     unsigned *pm, unsigned *pn, unsigned *pod)
+{
+	unsigned m, n, od;
+
+	/* deal with MHz */
+	rate -= (rate % MHZ);
+
+	m = rate / MHZ;
+	m = min_t(unsigned, m, 1 << clk_info->pll.m_bits);
+	m = max_t(unsigned, m, 1);
+
+	n = parent_rate / MHZ;
+	n = min_t(unsigned, n, 1 << clk_info->pll.n_bits);
+	n = max_t(unsigned, n, 1);
+
+	od = 1;
+
+	if (pm)
+		*pm = m;
+	if (pn)
+		*pn = n;
+	if (pod)
+		*pod = od;
+
+	return parent_rate * m / (n * od);
+}
+
+static long jz47xx_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
+				  unsigned long *prate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+	BUG_ON(clk_info->type != CGU_CLK_PLL);
+
+	return jz47xx_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);
+}
+
+static int jz47xx_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
+			       unsigned long parent_rate)
+{
+	const unsigned timeout = 100;
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	const struct jz47xx_cgu_pll_info *pll_info;
+	unsigned long rate, flags;
+	unsigned m, n, od, i;
+	u32 ctl;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+	BUG_ON(clk_info->type != CGU_CLK_PLL);
+	pll_info = &clk_info->pll;
+
+	rate = jz47xx_pll_calc(clk_info, req_rate, parent_rate,
+			       &m, &n, &od);
+	if (rate != req_rate) {
+		pr_info("jz47xx-cgu: request '%s' rate %luHz, actual %luHz\n",
+			clk_info->name, req_rate, rate);
+	}
+
+	spin_lock_irqsave(&cgu->pll_lock, flags);
+	ctl = readl(cgu->base + pll_info->reg);
+
+	ctl &= ~(GENMASK(pll_info->m_bits - 1, 0) << pll_info->m_shift);
+	ctl |= (m - pll_info->m_offset) << pll_info->m_shift;
+
+	ctl &= ~(GENMASK(pll_info->n_bits - 1, 0) << pll_info->n_shift);
+	ctl |= (n - pll_info->n_offset) << pll_info->n_shift;
+
+	ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift);
+	ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;
+
+	ctl &= ~BIT(pll_info->bypass_bit);
+	ctl |= BIT(pll_info->enable_bit);
+
+	writel(ctl, cgu->base + pll_info->reg);
+
+	/* wait for the PLL to stabilise */
+	for (i = 0; i < timeout; i++) {
+		if (readl(cgu->base + pll_info->reg)
+			 & BIT(pll_info->stable_bit))
+			break;
+		mdelay(1);
+	}
+
+	spin_unlock_irqrestore(&cgu->pll_lock, flags);
+
+	if (i == timeout)
+		return -EBUSY;
+
+	return 0;
+}
+
+static const struct clk_ops jz47xx_pll_ops = {
+	.recalc_rate = jz47xx_pll_recalc_rate,
+	.round_rate = jz47xx_pll_round_rate,
+	.set_rate = jz47xx_pll_set_rate,
+};
+
+/*
+ * Operations for all non-PLL clocks
+ */
+
+static u8 jz47xx_clk_get_parent(struct clk_hw *hw)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	u32 reg;
+	u8 i, hw_idx, idx = 0;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_MUX) {
+		reg = readl(cgu->base + clk_info->mux.reg);
+		hw_idx = (reg >> clk_info->mux.shift) &
+			 ((1 << clk_info->mux.bits) - 1);
+
+		/*
+		 * Convert the hardware index to the parent index by skipping
+		 * over any -1's in the parents array.
+		 */
+		for (i = 0; i < hw_idx; i++) {
+			if (clk_info->parents[i] != -1)
+				idx++;
+		}
+	}
+
+	return idx;
+}
+
+static int jz47xx_clk_set_parent(struct clk_hw *hw, u8 idx)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long flags;
+	u8 curr_idx, hw_idx, num_poss;
+	u32 reg, mask;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_MUX) {
+		/*
+		 * Convert the parent index to the hardware index by adding
+		 * 1 for any -1 in the parents array preceeding the given
+		 * index. That is, we want the index of idx'th entry in
+		 * clk_info->parents which does not equal -1.
+		 */
+		hw_idx = curr_idx = 0;
+		num_poss = 1 << clk_info->mux.bits;
+		for (; (hw_idx < num_poss) && (curr_idx != idx); hw_idx++) {
+			if (clk_info->parents[hw_idx] == -1)
+				continue;
+			curr_idx++;
+		}
+
+		/* idx should always be a valid parent */
+		BUG_ON(curr_idx != idx);
+
+		mask = ((1 << clk_info->mux.bits) - 1) << clk_info->mux.shift;
+
+		spin_lock_irqsave(&cgu->divmux_lock, flags);
+
+		/* write the register */
+		reg = readl(cgu->base + clk_info->mux.reg);
+		reg &= ~mask;
+		reg |= hw_idx << clk_info->mux.shift;
+		writel(reg, cgu->base + clk_info->mux.reg);
+
+		spin_unlock_irqrestore(&cgu->divmux_lock, flags);
+		return 0;
+	}
+
+	return idx ? -EINVAL : 0;
+}
+
+static unsigned long jz47xx_clk_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long rate = parent_rate;
+	u32 div_reg, div;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_DIV) {
+		div_reg = readl(cgu->base + clk_info->div.reg);
+		div = (div_reg >> clk_info->div.shift) &
+		      ((1 << clk_info->div.bits) - 1);
+		div += 1;
+
+		rate /= div;
+	}
+
+	return rate;
+}
+
+static unsigned jz47xx_clk_calc_div(const struct jz47xx_cgu_clk_info *clk_info,
+				    unsigned long parent_rate,
+				    unsigned long req_rate)
+{
+	unsigned div;
+
+	/* calculate the divide that gets us closest */
+	div = DIV_ROUND_CLOSEST(parent_rate, req_rate);
+
+	/* and impose hardware constraints */
+	div = min_t(unsigned, div, 1 << clk_info->div.bits);
+	div = max_t(unsigned, div, 1);
+
+	return div;
+}
+
+static long jz47xx_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
+				  unsigned long *parent_rate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	long rate = req_rate;
+	unsigned div;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_DIV) {
+		div = jz47xx_clk_calc_div(clk_info, *parent_rate, req_rate);
+		rate = *parent_rate / div;
+	}
+
+	return rate;
+}
+
+static int jz47xx_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
+			       unsigned long parent_rate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	const unsigned timeout = 100;
+	unsigned long rate, flags;
+	unsigned div, i;
+	u32 reg, mask;
+	int ret = 0;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_DIV) {
+		div = jz47xx_clk_calc_div(clk_info, parent_rate, req_rate);
+		rate = parent_rate / div;
+
+		if (rate != req_rate)
+			return -EINVAL;
+
+		spin_lock_irqsave(&cgu->divmux_lock, flags);
+		reg = readl(cgu->base + clk_info->div.reg);
+
+		/* update the divide */
+		mask = (1 << clk_info->div.bits) - 1;
+		reg &= ~(mask << clk_info->div.shift);
+		reg |= (div - 1) << clk_info->div.shift;
+
+		/* clear the stop bit */
+		if (clk_info->div.stop_bit != -1)
+			reg &= ~(1 << clk_info->div.stop_bit);
+
+		/* set the change enable bit */
+		if (clk_info->div.ce_bit != -1)
+			reg |= 1 << clk_info->div.ce_bit;
+
+		/* update the hardware */
+		writel(reg, cgu->base + clk_info->div.reg);
+
+		/* wait for the change to take effect */
+		if (clk_info->div.busy_bit != -1) {
+			for (i = 0; i < timeout; i++) {
+				reg = readl(cgu->base + clk_info->div.reg);
+				if (!(reg & (1 << clk_info->div.busy_bit)))
+					break;
+				mdelay(1);
+			}
+			if (i == timeout)
+				ret = -EBUSY;
+		}
+
+		spin_unlock_irqrestore(&cgu->divmux_lock, flags);
+
+		return ret;
+	}
+
+	return -EINVAL;
+}
+
+static int jz47xx_clk_enable(struct clk_hw *hw)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long flags;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_GATE) {
+		/* ungate the clock */
+		spin_lock_irqsave(&cgu->power_lock, flags);
+		jz47xx_cgu_gate_set(cgu, clk_info->gate_bit, 0);
+		spin_unlock_irqrestore(&cgu->power_lock, flags);
+	}
+
+	return 0;
+}
+
+static void jz47xx_clk_disable(struct clk_hw *hw)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long flags;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_GATE) {
+		/* gate the clock */
+		spin_lock_irqsave(&cgu->power_lock, flags);
+		jz47xx_cgu_gate_set(cgu, clk_info->gate_bit, 1);
+		spin_unlock_irqrestore(&cgu->power_lock, flags);
+	}
+}
+
+static int jz47xx_clk_is_enabled(struct clk_hw *hw)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long flags;
+	int enabled = 1;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_GATE) {
+		spin_lock_irqsave(&cgu->power_lock, flags);
+		enabled = !jz47xx_cgu_gate_get(cgu, clk_info->gate_bit);
+		spin_unlock_irqrestore(&cgu->power_lock, flags);
+	}
+
+	return enabled;
+}
+
+static const struct clk_ops jz47xx_clk_ops = {
+	.get_parent = jz47xx_clk_get_parent,
+	.set_parent = jz47xx_clk_set_parent,
+
+	.recalc_rate = jz47xx_clk_recalc_rate,
+	.round_rate = jz47xx_clk_round_rate,
+	.set_rate = jz47xx_clk_set_rate,
+
+	.enable = jz47xx_clk_enable,
+	.disable = jz47xx_clk_disable,
+	.is_enabled = jz47xx_clk_is_enabled,
+};
+
+/*
+ * Setup functions.
+ */
+
+static int register_clock(struct jz47xx_cgu *cgu, unsigned idx)
+{
+	const struct jz47xx_cgu_clk_info *clk_info = &cgu->clock_info[idx];
+	struct clk_init_data clk_init;
+	struct jz47xx_clk *jz_clk = NULL;
+	struct clk *clk, *parent;
+	const char *parent_names[4];
+	unsigned caps, i, num_possible;
+	int err = -EINVAL;
+
+	BUILD_BUG_ON(ARRAY_SIZE(clk_info->parents) > ARRAY_SIZE(parent_names));
+
+	if (clk_info->type == CGU_CLK_EXT) {
+		clk = of_clk_get_by_name(cgu->np, clk_info->name);
+		if (IS_ERR(clk)) {
+			pr_err("%s: no external clock '%s' provided\n",
+			       __func__, clk_info->name);
+			err = -ENODEV;
+			goto out;
+		}
+		err = clk_register_clkdev(clk, clk_info->name, NULL);
+		if (err) {
+			clk_put(clk);
+			goto out;
+		}
+		cgu->clocks.clks[idx] = clk;
+		return 0;
+	}
+
+	if (!clk_info->type) {
+		pr_err("%s: no clock type specified for '%s'\n", __func__,
+		       clk_info->name);
+		goto out;
+	}
+
+	jz_clk = kzalloc(sizeof(*jz_clk), GFP_KERNEL);
+	if (!jz_clk) {
+		pr_err("%s: failed to allocate struct jz47xx_clk\n", __func__);
+		err = -ENOMEM;
+		goto out;
+	}
+
+	jz_clk->hw.init = &clk_init;
+	jz_clk->cgu = cgu;
+	jz_clk->idx = idx;
+
+	clk_init.name = clk_info->name;
+	clk_init.flags = 0;
+	clk_init.parent_names = parent_names;
+
+	caps = clk_info->type;
+
+	if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {
+		clk_init.num_parents = 0;
+
+		if (caps & CGU_CLK_MUX)
+			num_possible = 1 << clk_info->mux.bits;
+		else
+			num_possible = ARRAY_SIZE(clk_info->parents);
+
+		for (i = 0; i < num_possible; i++) {
+			if (clk_info->parents[i] == -1)
+				continue;
+
+			parent = cgu->clocks.clks[clk_info->parents[i]];
+			parent_names[clk_init.num_parents] =
+				__clk_get_name(parent);
+			clk_init.num_parents++;
+		}
+
+		BUG_ON(!clk_init.num_parents);
+		BUG_ON(clk_init.num_parents > ARRAY_SIZE(parent_names));
+	} else {
+		BUG_ON(clk_info->parents[0] == -1);
+		clk_init.num_parents = 1;
+		parent = cgu->clocks.clks[clk_info->parents[0]];
+		parent_names[0] = __clk_get_name(parent);
+	}
+
+	if (caps & CGU_CLK_CUSTOM) {
+		clk_init.ops = clk_info->custom.clk_ops;
+
+		caps &= ~CGU_CLK_CUSTOM;
+
+		if (caps) {
+			pr_err("%s: custom clock may not be combined with type 0x%x\n",
+			       __func__, caps);
+			goto out;
+		}
+	} else if (caps & CGU_CLK_PLL) {
+		clk_init.ops = &jz47xx_pll_ops;
+
+		caps &= ~CGU_CLK_PLL;
+
+		if (caps) {
+			pr_err("%s: PLL may not be combined with type 0x%x\n",
+			       __func__, caps);
+			goto out;
+		}
+	} else {
+		clk_init.ops = &jz47xx_clk_ops;
+	}
+
+	/* nothing to do for gates */
+	caps &= ~CGU_CLK_GATE;
+
+	if (caps & CGU_CLK_MUX) {
+		if (!(caps & CGU_CLK_MUX_GLITCHFREE))
+			clk_init.flags |= CLK_SET_PARENT_GATE;
+
+		caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);
+	}
+
+	if (caps & CGU_CLK_DIV) {
+		caps &= ~CGU_CLK_DIV;
+	} else {
+		/* pass rate changes to the parent clock */
+		clk_init.flags |= CLK_SET_RATE_PARENT;
+	}
+
+	if (caps) {
+		pr_err("%s: unknown clock type 0x%x\n", __func__, caps);
+		goto out;
+	}
+
+	clk = clk_register(NULL, &jz_clk->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register clock '%s'\n", __func__,
+		       clk_info->name);
+		err = PTR_ERR(clk);
+		goto out;
+	}
+
+	err = clk_register_clkdev(clk, clk_info->name, NULL);
+	if (err)
+		goto out;
+
+	cgu->clocks.clks[idx] = clk;
+out:
+	if (err)
+		kfree(jz_clk);
+	return err;
+}
+
+struct jz47xx_cgu *jz47xx_cgu_new(const struct jz47xx_cgu_clk_info *clock_info,
+				  unsigned num_clocks,
+				  struct device_node *np)
+{
+	struct jz47xx_cgu *cgu;
+
+	cgu = kzalloc(sizeof(*cgu), GFP_KERNEL);
+	if (!cgu) {
+		pr_err("%s: failed to allocate struct jz47xx_cgu\n", __func__);
+		goto err_out;
+	}
+
+	cgu->base = of_iomap(np, 0);
+	if (!cgu->base) {
+		pr_err("%s: failed to map CGU registers\n", __func__);
+		goto err_out_free;
+	}
+
+	cgu->np = np;
+	cgu->clock_info = clock_info;
+	cgu->clocks.clk_num = num_clocks;
+
+	spin_lock_init(&cgu->divmux_lock);
+	spin_lock_init(&cgu->power_lock);
+	spin_lock_init(&cgu->pll_lock);
+
+	return cgu;
+
+err_out_free:
+	kfree(cgu);
+err_out:
+	return NULL;
+}
+
+int jz47xx_cgu_register_clocks(struct jz47xx_cgu *cgu)
+{
+	unsigned i;
+	int err = -EINVAL;
+
+	cgu->clocks.clks = kzalloc(sizeof(struct clk *) * cgu->clocks.clk_num,
+				   GFP_KERNEL);
+	if (!cgu->clocks.clks) {
+		pr_err("%s: failed to alloc clock table\n", __func__);
+		goto err_out;
+	}
+
+	for (i = 0; i < cgu->clocks.clk_num; i++) {
+		err = register_clock(cgu, i);
+		if (err)
+			goto err_out_unregister;
+	}
+
+	err = of_clk_add_provider(cgu->np, of_clk_src_onecell_get,
+				  &cgu->clocks);
+	if (err)
+		goto err_out_unregister;
+
+	return 0;
+err_out_unregister:
+	if (cgu) {
+		for (i = 0; i < cgu->clocks.clk_num; i++) {
+			if (!cgu->clocks.clks[i])
+				continue;
+			if (cgu->clock_info[i].type & CGU_CLK_EXT)
+				clk_put(cgu->clocks.clks[i]);
+			else
+				clk_unregister(cgu->clocks.clks[i]);
+		}
+		kfree(cgu->clocks.clks);
+	}
+err_out:
+	return err;
+}
diff --git a/drivers/clk/jz47xx/jz47xx-cgu.h b/drivers/clk/jz47xx/jz47xx-cgu.h
new file mode 100644
index 0000000..ec7fe7d
--- /dev/null
+++ b/drivers/clk/jz47xx/jz47xx-cgu.h
@@ -0,0 +1,205 @@
+/*
+ * Ingenic jz47xx series CGU driver
+ *
+ * Copyright (c) 2013-2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DRIVERS_CLK_JZ47XX_JZ47XX_CGU_H__
+#define __DRIVERS_CLK_JZ47XX_JZ47XX_CGU_H__
+
+#include <linux/of.h>
+#include <linux/spinlock.h>
+
+/**
+ * struct jz47xx_cgu_pll_info - information about a PLL
+ * @reg: the offset of the PLL's control register within the CGU
+ * @m_shift: the number of bits to shift the multiplier value by (ie. the
+ *           index of the lowest bit of the multiplier value in the PLL's
+ *           control register)
+ * @m_bits: the size of the multiplier field in bits
+ * @m_offset: the multiplier value which encodes to 0 in the PLL's control
+ *            register
+ * @n_shift: the number of bits to shift the divider value by (ie. the
+ *           index of the lowest bit of the divider value in the PLL's
+ *           control register)
+ * @n_bits: the size of the divider field in bits
+ * @n_offset: the divider value which encodes to 0 in the PLL's control
+ *            register
+ * @od_shift: the number of bits to shift the post-VCO divider value by (ie.
+ *            the index of the lowest bit of the post-VCO divider value in
+ *            the PLL's control register)
+ * @od_bits: the size of the post-VCO divider field in bits
+ * @od_max: the maximum post-VCO divider value
+ * @od_encoding: a pointer to an array mapping post-VCO divider values to
+ *               their encoded values in the PLL control register, or -1 for
+ *               unsupported values
+ * @bypass_bit: the index of the bypass bit in the PLL control register
+ * @enable_bit: the index of the enable bit in the PLL control register
+ * @stable_bit: the index of the stable bit in the PLL control register
+ */
+struct jz47xx_cgu_pll_info {
+	unsigned reg;
+	unsigned m_shift, m_bits, m_offset;
+	unsigned n_shift, n_bits, n_offset;
+	unsigned od_shift, od_bits, od_max;
+	const s8 *od_encoding;
+	unsigned bypass_bit;
+	unsigned enable_bit;
+	unsigned stable_bit;
+};
+
+/**
+ * struct jz47xx_cgu_mux_info - information about a clock mux
+ * @reg: offset of the mux control register within the CGU
+ * @shift: number of bits to shift the mux value by (ie. the index of
+ *         the lowest bit of the mux value within its control register)
+ * @bits: the size of the mux value in bits
+ */
+struct jz47xx_cgu_mux_info {
+	unsigned reg;
+	unsigned shift:5;
+	unsigned bits:5;
+};
+
+/**
+ * struct jz47xx_cgu_div_info - information about a divider
+ * @reg: offset of the divider control register within the CGU
+ * @shift: number of bits to shift the divide value by (ie. the index of
+ *         the lowest bit of the divide value within its control register)
+ * @bits: the size of the divide value in bits
+ * @ce_bit: the index of the change enable bit within reg, or -1 is there
+ *          isn't one
+ * @busy_bit: the index of the busy bit within reg, or -1 is there isn't one
+ * @stop_bit: the index of the stop bit within reg, or -1 is there isn't one
+ */
+struct jz47xx_cgu_div_info {
+	unsigned reg;
+	unsigned shift:5;
+	unsigned bits:5;
+	int ce_bit:6;
+	int busy_bit:6;
+	int stop_bit:6;
+};
+
+/**
+ * struct jz47xx_cgu_custom_info - information about a custom (SoC) clock
+ */
+struct jz47xx_cgu_custom_info {
+	struct clk_ops *clk_ops;
+};
+
+/**
+ * struct jz47xx_cgu_clk_info - information about a clock
+ * @name: name of the clock
+ * @type: a bitmask formed from CGU_CLK_* values
+ * @parents: an array of the indices of potential parents of this clock
+ *           within the clock_info array of the CGU, or -1 in entries
+ *           which correspond to no valid parent
+ * @pll: information valid if type includes CGU_CLK_PLL
+ * @gate_bit: the index of the gate bit in the CLKGR* registers, valid if
+ *            type includes CGU_CLK_GATE
+ * @mux: information valid if type includes CGU_CLK_MUX
+ * @div: information valid if type includes CGU_CLK_DIV
+ */
+struct jz47xx_cgu_clk_info {
+	const char *name;
+
+	enum {
+		CGU_CLK_NONE		= 0,
+		CGU_CLK_EXT		= (1 << 0),
+		CGU_CLK_PLL		= (1 << 1),
+		CGU_CLK_GATE		= (1 << 2),
+		CGU_CLK_MUX		= (1 << 3),
+		CGU_CLK_MUX_GLITCHFREE	= (1 << 4),
+		CGU_CLK_DIV		= (1 << 5),
+		CGU_CLK_CUSTOM		= (1 << 6),
+	} type;
+
+	int parents[4];
+
+	union {
+		struct jz47xx_cgu_pll_info pll;
+
+		struct {
+			unsigned gate_bit;
+			struct jz47xx_cgu_mux_info mux;
+			struct jz47xx_cgu_div_info div;
+		};
+
+		struct jz47xx_cgu_custom_info custom;
+	};
+};
+
+/**
+ * struct jz47xx_cgu - data about the CGU
+ * @np: the device tree node that caused the CGU to be probed
+ * @base: the ioremap'ed base address of the CGU registers
+ * @clock_info: an array containing information about implemented clocks
+ * @clocks: used to provide clocks to DT, allows lookup of struct clk*
+ * @gate_lock: lock to be held whilst (un)gating a clock
+ * @divmux_lock: lock to be held whilst re-muxing of rate-changing a clock
+ */
+struct jz47xx_cgu {
+	struct device_node *np;
+	void __iomem *base;
+
+	const struct jz47xx_cgu_clk_info *clock_info;
+	struct clk_onecell_data clocks;
+
+	spinlock_t divmux_lock;		/* must be held when changing a divide
+					   or re-muxing a clock */
+	spinlock_t power_lock;		/* must be held when changing a power
+					   manager register */
+	spinlock_t pll_lock;		/* must be held when changing a PLL
+					   control register */
+};
+
+/**
+ * struct jz47xx_clk - private data for a clock
+ * @hw: see Documentation/clk.txt
+ * @cgu: a pointer to the CGU data
+ * @idx: the index of this clock in cgu->clock_info
+ */
+struct jz47xx_clk {
+	struct clk_hw hw;
+	struct jz47xx_cgu *cgu;
+	unsigned idx;
+};
+
+#define to_jz47xx_clk(_hw) container_of(_hw, struct jz47xx_clk, hw)
+
+/**
+ * jz47xx_cgu_new - create a new CGU instance
+ * @clock_info: an array of clock information structures describing the clocks
+ *              which are implemented by the CGU
+ * @num_clocks: the number of entries in clock_info
+ * @np: the device tree node which causes this CGU to be probed
+ *
+ * Returns an opaque pointer to the CGU instance if initialisation & clock
+ * registration is successful, otherwise NULL.
+ */
+struct jz47xx_cgu *jz47xx_cgu_new(const struct jz47xx_cgu_clk_info *clock_info,
+				  unsigned num_clocks,
+				  struct device_node *np);
+
+/**
+ * jz47xx_cgu_register_clocks - Registers the clocks
+ * @cgu: pointer to cgu data
+ *
+ * Returns 1 on success and -EINVAL if unsuccesful.
+ */
+int jz47xx_cgu_register_clocks(struct jz47xx_cgu *cgu);
+
+#endif /* __DRIVERS_CLK_JZ47XX_JZ47XX_CGU_H__ */
-- 
1.9.1


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

* [PATCH_V2 14/34] clk: jz47xx-cgu: add driver for Ingenic jz47xx series CGU clocks
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

This driver supports the CGU clocks for the Ingenic jz47xx series of
SoCs. It is generic enough to be usable across at least the jz4740 to
the jz4780, as will be done in subsequent commits.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Co-authored-by: Paul Cercueil <paul@crapouillou.net>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>

---
V2
Removed FSF address
Bug fix in error handling
---
 drivers/clk/Makefile            |   1 +
 drivers/clk/jz47xx/Makefile     |   1 +
 drivers/clk/jz47xx/jz47xx-cgu.c | 723 ++++++++++++++++++++++++++++++++++++++++
 drivers/clk/jz47xx/jz47xx-cgu.h | 205 ++++++++++++
 4 files changed, 930 insertions(+)
 create mode 100644 drivers/clk/jz47xx/Makefile
 create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.c
 create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.h

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index d5fba5b..fc434c0 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
 obj-$(CONFIG_ARCH_HI3xxx)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIP04)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIX5HD2)		+= hisilicon/
+obj-$(CONFIG_MACH_JZ4740)		+= jz47xx/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)	+= keystone/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
diff --git a/drivers/clk/jz47xx/Makefile b/drivers/clk/jz47xx/Makefile
new file mode 100644
index 0000000..ac594e5
--- /dev/null
+++ b/drivers/clk/jz47xx/Makefile
@@ -0,0 +1 @@
+obj-y				+= jz47xx-cgu.o
diff --git a/drivers/clk/jz47xx/jz47xx-cgu.c b/drivers/clk/jz47xx/jz47xx-cgu.c
new file mode 100644
index 0000000..85d0592
--- /dev/null
+++ b/drivers/clk/jz47xx/jz47xx-cgu.c
@@ -0,0 +1,723 @@
+/*
+ * Ingenic jz47xx series CGU driver
+ *
+ * Copyright (c) 2013-2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include "jz47xx-cgu.h"
+
+#define REG_CLKGR		0x20
+#define REG_CLKGR_STRIDE	0x8
+
+#define MHZ (1000 * 1000)
+
+/**
+ * jz47xx_cgu_gate_get - get the value of clock gate register bit
+ * @cgu: reference to the CGU whose registers should be read
+ * @idx: index of the gate bit
+ *
+ * Returns 1 if the gate bit is set, else 0. The index begins with 0 being
+ * bit 0 of CLKGR0, continuing from 32 for bit 0 of CLKGR1 etc. For example,
+ * the index of bit 9 of CLKGR1 would be (32+9) == 41.
+ *
+ * The caller must hold cgu->power_lock.
+ */
+static inline unsigned jz47xx_cgu_gate_get(struct jz47xx_cgu *cgu,
+					   unsigned idx)
+{
+	void __iomem *reg;
+	u32 bit, clkgr;
+
+	reg = cgu->base + REG_CLKGR + ((idx / 32) * REG_CLKGR_STRIDE);
+	bit = 1 << (idx % 32);
+	clkgr = readl(reg);
+	return !!(clkgr & bit);
+}
+
+/**
+ * jz47xx_cgu_gate_set - set the value of clock gate register bit
+ * @cgu: reference to the CGU whose registers should be modified
+ * @idx: index of the gate bit
+ * @val: non-zero to gate a clock, otherwise zero
+ *
+ * Sets the given gate bit in order to gate or ungate a clock. See
+ * jz47xx_cgu_gate_get for a description of the idx parameter.
+ *
+ * The caller must hold cgu->power_lock.
+ */
+static inline void jz47xx_cgu_gate_set(struct jz47xx_cgu *cgu,
+				       unsigned idx, unsigned val)
+{
+	void __iomem *reg;
+	u32 bit, clkgr;
+
+	reg = cgu->base + REG_CLKGR + ((idx / 32) * REG_CLKGR_STRIDE);
+	bit = 1 << (idx % 32);
+	clkgr = readl(reg);
+
+	if (val)
+		clkgr |= bit;
+	else
+		clkgr &= ~bit;
+
+	writel(clkgr, reg);
+}
+
+/*
+ * PLL operations
+ */
+
+static unsigned long jz47xx_pll_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	const struct jz47xx_cgu_pll_info *pll_info;
+	unsigned m, n, od_enc, od;
+	bool bypass, enable;
+	unsigned long flags;
+	u32 ctl;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+	BUG_ON(clk_info->type != CGU_CLK_PLL);
+	pll_info = &clk_info->pll;
+
+	spin_lock_irqsave(&cgu->pll_lock, flags);
+	ctl = readl(cgu->base + pll_info->reg);
+	spin_unlock_irqrestore(&cgu->pll_lock, flags);
+
+	m = ((ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0));
+	m += pll_info->m_offset;
+	n = ((ctl >> pll_info->n_shift) & GENMASK(pll_info->n_bits - 1, 0));
+	n += pll_info->n_offset;
+	od_enc = ((ctl >> pll_info->od_shift)
+		 & GENMASK(pll_info->od_bits - 1, 0));
+	bypass = !!(ctl & BIT(pll_info->bypass_bit));
+	enable = !!(ctl & BIT(pll_info->enable_bit));
+
+	if (bypass)
+		return parent_rate;
+
+	if (!enable)
+		return 0;
+
+	for (od = 0; od < pll_info->od_max; od++) {
+		if (pll_info->od_encoding[od] == od_enc)
+			break;
+	}
+	BUG_ON(od == pll_info->od_max);
+	od++;
+
+	return parent_rate * m / (n * od);
+}
+
+static unsigned long jz47xx_pll_calc(const struct jz47xx_cgu_clk_info *clk_info,
+				     unsigned long rate,
+				     unsigned long parent_rate,
+				     unsigned *pm, unsigned *pn, unsigned *pod)
+{
+	unsigned m, n, od;
+
+	/* deal with MHz */
+	rate -= (rate % MHZ);
+
+	m = rate / MHZ;
+	m = min_t(unsigned, m, 1 << clk_info->pll.m_bits);
+	m = max_t(unsigned, m, 1);
+
+	n = parent_rate / MHZ;
+	n = min_t(unsigned, n, 1 << clk_info->pll.n_bits);
+	n = max_t(unsigned, n, 1);
+
+	od = 1;
+
+	if (pm)
+		*pm = m;
+	if (pn)
+		*pn = n;
+	if (pod)
+		*pod = od;
+
+	return parent_rate * m / (n * od);
+}
+
+static long jz47xx_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
+				  unsigned long *prate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+	BUG_ON(clk_info->type != CGU_CLK_PLL);
+
+	return jz47xx_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);
+}
+
+static int jz47xx_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
+			       unsigned long parent_rate)
+{
+	const unsigned timeout = 100;
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	const struct jz47xx_cgu_pll_info *pll_info;
+	unsigned long rate, flags;
+	unsigned m, n, od, i;
+	u32 ctl;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+	BUG_ON(clk_info->type != CGU_CLK_PLL);
+	pll_info = &clk_info->pll;
+
+	rate = jz47xx_pll_calc(clk_info, req_rate, parent_rate,
+			       &m, &n, &od);
+	if (rate != req_rate) {
+		pr_info("jz47xx-cgu: request '%s' rate %luHz, actual %luHz\n",
+			clk_info->name, req_rate, rate);
+	}
+
+	spin_lock_irqsave(&cgu->pll_lock, flags);
+	ctl = readl(cgu->base + pll_info->reg);
+
+	ctl &= ~(GENMASK(pll_info->m_bits - 1, 0) << pll_info->m_shift);
+	ctl |= (m - pll_info->m_offset) << pll_info->m_shift;
+
+	ctl &= ~(GENMASK(pll_info->n_bits - 1, 0) << pll_info->n_shift);
+	ctl |= (n - pll_info->n_offset) << pll_info->n_shift;
+
+	ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift);
+	ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;
+
+	ctl &= ~BIT(pll_info->bypass_bit);
+	ctl |= BIT(pll_info->enable_bit);
+
+	writel(ctl, cgu->base + pll_info->reg);
+
+	/* wait for the PLL to stabilise */
+	for (i = 0; i < timeout; i++) {
+		if (readl(cgu->base + pll_info->reg)
+			 & BIT(pll_info->stable_bit))
+			break;
+		mdelay(1);
+	}
+
+	spin_unlock_irqrestore(&cgu->pll_lock, flags);
+
+	if (i == timeout)
+		return -EBUSY;
+
+	return 0;
+}
+
+static const struct clk_ops jz47xx_pll_ops = {
+	.recalc_rate = jz47xx_pll_recalc_rate,
+	.round_rate = jz47xx_pll_round_rate,
+	.set_rate = jz47xx_pll_set_rate,
+};
+
+/*
+ * Operations for all non-PLL clocks
+ */
+
+static u8 jz47xx_clk_get_parent(struct clk_hw *hw)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	u32 reg;
+	u8 i, hw_idx, idx = 0;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_MUX) {
+		reg = readl(cgu->base + clk_info->mux.reg);
+		hw_idx = (reg >> clk_info->mux.shift) &
+			 ((1 << clk_info->mux.bits) - 1);
+
+		/*
+		 * Convert the hardware index to the parent index by skipping
+		 * over any -1's in the parents array.
+		 */
+		for (i = 0; i < hw_idx; i++) {
+			if (clk_info->parents[i] != -1)
+				idx++;
+		}
+	}
+
+	return idx;
+}
+
+static int jz47xx_clk_set_parent(struct clk_hw *hw, u8 idx)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long flags;
+	u8 curr_idx, hw_idx, num_poss;
+	u32 reg, mask;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_MUX) {
+		/*
+		 * Convert the parent index to the hardware index by adding
+		 * 1 for any -1 in the parents array preceeding the given
+		 * index. That is, we want the index of idx'th entry in
+		 * clk_info->parents which does not equal -1.
+		 */
+		hw_idx = curr_idx = 0;
+		num_poss = 1 << clk_info->mux.bits;
+		for (; (hw_idx < num_poss) && (curr_idx != idx); hw_idx++) {
+			if (clk_info->parents[hw_idx] == -1)
+				continue;
+			curr_idx++;
+		}
+
+		/* idx should always be a valid parent */
+		BUG_ON(curr_idx != idx);
+
+		mask = ((1 << clk_info->mux.bits) - 1) << clk_info->mux.shift;
+
+		spin_lock_irqsave(&cgu->divmux_lock, flags);
+
+		/* write the register */
+		reg = readl(cgu->base + clk_info->mux.reg);
+		reg &= ~mask;
+		reg |= hw_idx << clk_info->mux.shift;
+		writel(reg, cgu->base + clk_info->mux.reg);
+
+		spin_unlock_irqrestore(&cgu->divmux_lock, flags);
+		return 0;
+	}
+
+	return idx ? -EINVAL : 0;
+}
+
+static unsigned long jz47xx_clk_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long rate = parent_rate;
+	u32 div_reg, div;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_DIV) {
+		div_reg = readl(cgu->base + clk_info->div.reg);
+		div = (div_reg >> clk_info->div.shift) &
+		      ((1 << clk_info->div.bits) - 1);
+		div += 1;
+
+		rate /= div;
+	}
+
+	return rate;
+}
+
+static unsigned jz47xx_clk_calc_div(const struct jz47xx_cgu_clk_info *clk_info,
+				    unsigned long parent_rate,
+				    unsigned long req_rate)
+{
+	unsigned div;
+
+	/* calculate the divide that gets us closest */
+	div = DIV_ROUND_CLOSEST(parent_rate, req_rate);
+
+	/* and impose hardware constraints */
+	div = min_t(unsigned, div, 1 << clk_info->div.bits);
+	div = max_t(unsigned, div, 1);
+
+	return div;
+}
+
+static long jz47xx_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
+				  unsigned long *parent_rate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	long rate = req_rate;
+	unsigned div;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_DIV) {
+		div = jz47xx_clk_calc_div(clk_info, *parent_rate, req_rate);
+		rate = *parent_rate / div;
+	}
+
+	return rate;
+}
+
+static int jz47xx_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
+			       unsigned long parent_rate)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	const unsigned timeout = 100;
+	unsigned long rate, flags;
+	unsigned div, i;
+	u32 reg, mask;
+	int ret = 0;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_DIV) {
+		div = jz47xx_clk_calc_div(clk_info, parent_rate, req_rate);
+		rate = parent_rate / div;
+
+		if (rate != req_rate)
+			return -EINVAL;
+
+		spin_lock_irqsave(&cgu->divmux_lock, flags);
+		reg = readl(cgu->base + clk_info->div.reg);
+
+		/* update the divide */
+		mask = (1 << clk_info->div.bits) - 1;
+		reg &= ~(mask << clk_info->div.shift);
+		reg |= (div - 1) << clk_info->div.shift;
+
+		/* clear the stop bit */
+		if (clk_info->div.stop_bit != -1)
+			reg &= ~(1 << clk_info->div.stop_bit);
+
+		/* set the change enable bit */
+		if (clk_info->div.ce_bit != -1)
+			reg |= 1 << clk_info->div.ce_bit;
+
+		/* update the hardware */
+		writel(reg, cgu->base + clk_info->div.reg);
+
+		/* wait for the change to take effect */
+		if (clk_info->div.busy_bit != -1) {
+			for (i = 0; i < timeout; i++) {
+				reg = readl(cgu->base + clk_info->div.reg);
+				if (!(reg & (1 << clk_info->div.busy_bit)))
+					break;
+				mdelay(1);
+			}
+			if (i == timeout)
+				ret = -EBUSY;
+		}
+
+		spin_unlock_irqrestore(&cgu->divmux_lock, flags);
+
+		return ret;
+	}
+
+	return -EINVAL;
+}
+
+static int jz47xx_clk_enable(struct clk_hw *hw)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long flags;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_GATE) {
+		/* ungate the clock */
+		spin_lock_irqsave(&cgu->power_lock, flags);
+		jz47xx_cgu_gate_set(cgu, clk_info->gate_bit, 0);
+		spin_unlock_irqrestore(&cgu->power_lock, flags);
+	}
+
+	return 0;
+}
+
+static void jz47xx_clk_disable(struct clk_hw *hw)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long flags;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_GATE) {
+		/* gate the clock */
+		spin_lock_irqsave(&cgu->power_lock, flags);
+		jz47xx_cgu_gate_set(cgu, clk_info->gate_bit, 1);
+		spin_unlock_irqrestore(&cgu->power_lock, flags);
+	}
+}
+
+static int jz47xx_clk_is_enabled(struct clk_hw *hw)
+{
+	struct jz47xx_clk *jz_clk = to_jz47xx_clk(hw);
+	struct jz47xx_cgu *cgu = jz_clk->cgu;
+	const struct jz47xx_cgu_clk_info *clk_info;
+	unsigned long flags;
+	int enabled = 1;
+
+	clk_info = &cgu->clock_info[jz_clk->idx];
+
+	if (clk_info->type & CGU_CLK_GATE) {
+		spin_lock_irqsave(&cgu->power_lock, flags);
+		enabled = !jz47xx_cgu_gate_get(cgu, clk_info->gate_bit);
+		spin_unlock_irqrestore(&cgu->power_lock, flags);
+	}
+
+	return enabled;
+}
+
+static const struct clk_ops jz47xx_clk_ops = {
+	.get_parent = jz47xx_clk_get_parent,
+	.set_parent = jz47xx_clk_set_parent,
+
+	.recalc_rate = jz47xx_clk_recalc_rate,
+	.round_rate = jz47xx_clk_round_rate,
+	.set_rate = jz47xx_clk_set_rate,
+
+	.enable = jz47xx_clk_enable,
+	.disable = jz47xx_clk_disable,
+	.is_enabled = jz47xx_clk_is_enabled,
+};
+
+/*
+ * Setup functions.
+ */
+
+static int register_clock(struct jz47xx_cgu *cgu, unsigned idx)
+{
+	const struct jz47xx_cgu_clk_info *clk_info = &cgu->clock_info[idx];
+	struct clk_init_data clk_init;
+	struct jz47xx_clk *jz_clk = NULL;
+	struct clk *clk, *parent;
+	const char *parent_names[4];
+	unsigned caps, i, num_possible;
+	int err = -EINVAL;
+
+	BUILD_BUG_ON(ARRAY_SIZE(clk_info->parents) > ARRAY_SIZE(parent_names));
+
+	if (clk_info->type == CGU_CLK_EXT) {
+		clk = of_clk_get_by_name(cgu->np, clk_info->name);
+		if (IS_ERR(clk)) {
+			pr_err("%s: no external clock '%s' provided\n",
+			       __func__, clk_info->name);
+			err = -ENODEV;
+			goto out;
+		}
+		err = clk_register_clkdev(clk, clk_info->name, NULL);
+		if (err) {
+			clk_put(clk);
+			goto out;
+		}
+		cgu->clocks.clks[idx] = clk;
+		return 0;
+	}
+
+	if (!clk_info->type) {
+		pr_err("%s: no clock type specified for '%s'\n", __func__,
+		       clk_info->name);
+		goto out;
+	}
+
+	jz_clk = kzalloc(sizeof(*jz_clk), GFP_KERNEL);
+	if (!jz_clk) {
+		pr_err("%s: failed to allocate struct jz47xx_clk\n", __func__);
+		err = -ENOMEM;
+		goto out;
+	}
+
+	jz_clk->hw.init = &clk_init;
+	jz_clk->cgu = cgu;
+	jz_clk->idx = idx;
+
+	clk_init.name = clk_info->name;
+	clk_init.flags = 0;
+	clk_init.parent_names = parent_names;
+
+	caps = clk_info->type;
+
+	if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {
+		clk_init.num_parents = 0;
+
+		if (caps & CGU_CLK_MUX)
+			num_possible = 1 << clk_info->mux.bits;
+		else
+			num_possible = ARRAY_SIZE(clk_info->parents);
+
+		for (i = 0; i < num_possible; i++) {
+			if (clk_info->parents[i] == -1)
+				continue;
+
+			parent = cgu->clocks.clks[clk_info->parents[i]];
+			parent_names[clk_init.num_parents] =
+				__clk_get_name(parent);
+			clk_init.num_parents++;
+		}
+
+		BUG_ON(!clk_init.num_parents);
+		BUG_ON(clk_init.num_parents > ARRAY_SIZE(parent_names));
+	} else {
+		BUG_ON(clk_info->parents[0] == -1);
+		clk_init.num_parents = 1;
+		parent = cgu->clocks.clks[clk_info->parents[0]];
+		parent_names[0] = __clk_get_name(parent);
+	}
+
+	if (caps & CGU_CLK_CUSTOM) {
+		clk_init.ops = clk_info->custom.clk_ops;
+
+		caps &= ~CGU_CLK_CUSTOM;
+
+		if (caps) {
+			pr_err("%s: custom clock may not be combined with type 0x%x\n",
+			       __func__, caps);
+			goto out;
+		}
+	} else if (caps & CGU_CLK_PLL) {
+		clk_init.ops = &jz47xx_pll_ops;
+
+		caps &= ~CGU_CLK_PLL;
+
+		if (caps) {
+			pr_err("%s: PLL may not be combined with type 0x%x\n",
+			       __func__, caps);
+			goto out;
+		}
+	} else {
+		clk_init.ops = &jz47xx_clk_ops;
+	}
+
+	/* nothing to do for gates */
+	caps &= ~CGU_CLK_GATE;
+
+	if (caps & CGU_CLK_MUX) {
+		if (!(caps & CGU_CLK_MUX_GLITCHFREE))
+			clk_init.flags |= CLK_SET_PARENT_GATE;
+
+		caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);
+	}
+
+	if (caps & CGU_CLK_DIV) {
+		caps &= ~CGU_CLK_DIV;
+	} else {
+		/* pass rate changes to the parent clock */
+		clk_init.flags |= CLK_SET_RATE_PARENT;
+	}
+
+	if (caps) {
+		pr_err("%s: unknown clock type 0x%x\n", __func__, caps);
+		goto out;
+	}
+
+	clk = clk_register(NULL, &jz_clk->hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register clock '%s'\n", __func__,
+		       clk_info->name);
+		err = PTR_ERR(clk);
+		goto out;
+	}
+
+	err = clk_register_clkdev(clk, clk_info->name, NULL);
+	if (err)
+		goto out;
+
+	cgu->clocks.clks[idx] = clk;
+out:
+	if (err)
+		kfree(jz_clk);
+	return err;
+}
+
+struct jz47xx_cgu *jz47xx_cgu_new(const struct jz47xx_cgu_clk_info *clock_info,
+				  unsigned num_clocks,
+				  struct device_node *np)
+{
+	struct jz47xx_cgu *cgu;
+
+	cgu = kzalloc(sizeof(*cgu), GFP_KERNEL);
+	if (!cgu) {
+		pr_err("%s: failed to allocate struct jz47xx_cgu\n", __func__);
+		goto err_out;
+	}
+
+	cgu->base = of_iomap(np, 0);
+	if (!cgu->base) {
+		pr_err("%s: failed to map CGU registers\n", __func__);
+		goto err_out_free;
+	}
+
+	cgu->np = np;
+	cgu->clock_info = clock_info;
+	cgu->clocks.clk_num = num_clocks;
+
+	spin_lock_init(&cgu->divmux_lock);
+	spin_lock_init(&cgu->power_lock);
+	spin_lock_init(&cgu->pll_lock);
+
+	return cgu;
+
+err_out_free:
+	kfree(cgu);
+err_out:
+	return NULL;
+}
+
+int jz47xx_cgu_register_clocks(struct jz47xx_cgu *cgu)
+{
+	unsigned i;
+	int err = -EINVAL;
+
+	cgu->clocks.clks = kzalloc(sizeof(struct clk *) * cgu->clocks.clk_num,
+				   GFP_KERNEL);
+	if (!cgu->clocks.clks) {
+		pr_err("%s: failed to alloc clock table\n", __func__);
+		goto err_out;
+	}
+
+	for (i = 0; i < cgu->clocks.clk_num; i++) {
+		err = register_clock(cgu, i);
+		if (err)
+			goto err_out_unregister;
+	}
+
+	err = of_clk_add_provider(cgu->np, of_clk_src_onecell_get,
+				  &cgu->clocks);
+	if (err)
+		goto err_out_unregister;
+
+	return 0;
+err_out_unregister:
+	if (cgu) {
+		for (i = 0; i < cgu->clocks.clk_num; i++) {
+			if (!cgu->clocks.clks[i])
+				continue;
+			if (cgu->clock_info[i].type & CGU_CLK_EXT)
+				clk_put(cgu->clocks.clks[i]);
+			else
+				clk_unregister(cgu->clocks.clks[i]);
+		}
+		kfree(cgu->clocks.clks);
+	}
+err_out:
+	return err;
+}
diff --git a/drivers/clk/jz47xx/jz47xx-cgu.h b/drivers/clk/jz47xx/jz47xx-cgu.h
new file mode 100644
index 0000000..ec7fe7d
--- /dev/null
+++ b/drivers/clk/jz47xx/jz47xx-cgu.h
@@ -0,0 +1,205 @@
+/*
+ * Ingenic jz47xx series CGU driver
+ *
+ * Copyright (c) 2013-2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __DRIVERS_CLK_JZ47XX_JZ47XX_CGU_H__
+#define __DRIVERS_CLK_JZ47XX_JZ47XX_CGU_H__
+
+#include <linux/of.h>
+#include <linux/spinlock.h>
+
+/**
+ * struct jz47xx_cgu_pll_info - information about a PLL
+ * @reg: the offset of the PLL's control register within the CGU
+ * @m_shift: the number of bits to shift the multiplier value by (ie. the
+ *           index of the lowest bit of the multiplier value in the PLL's
+ *           control register)
+ * @m_bits: the size of the multiplier field in bits
+ * @m_offset: the multiplier value which encodes to 0 in the PLL's control
+ *            register
+ * @n_shift: the number of bits to shift the divider value by (ie. the
+ *           index of the lowest bit of the divider value in the PLL's
+ *           control register)
+ * @n_bits: the size of the divider field in bits
+ * @n_offset: the divider value which encodes to 0 in the PLL's control
+ *            register
+ * @od_shift: the number of bits to shift the post-VCO divider value by (ie.
+ *            the index of the lowest bit of the post-VCO divider value in
+ *            the PLL's control register)
+ * @od_bits: the size of the post-VCO divider field in bits
+ * @od_max: the maximum post-VCO divider value
+ * @od_encoding: a pointer to an array mapping post-VCO divider values to
+ *               their encoded values in the PLL control register, or -1 for
+ *               unsupported values
+ * @bypass_bit: the index of the bypass bit in the PLL control register
+ * @enable_bit: the index of the enable bit in the PLL control register
+ * @stable_bit: the index of the stable bit in the PLL control register
+ */
+struct jz47xx_cgu_pll_info {
+	unsigned reg;
+	unsigned m_shift, m_bits, m_offset;
+	unsigned n_shift, n_bits, n_offset;
+	unsigned od_shift, od_bits, od_max;
+	const s8 *od_encoding;
+	unsigned bypass_bit;
+	unsigned enable_bit;
+	unsigned stable_bit;
+};
+
+/**
+ * struct jz47xx_cgu_mux_info - information about a clock mux
+ * @reg: offset of the mux control register within the CGU
+ * @shift: number of bits to shift the mux value by (ie. the index of
+ *         the lowest bit of the mux value within its control register)
+ * @bits: the size of the mux value in bits
+ */
+struct jz47xx_cgu_mux_info {
+	unsigned reg;
+	unsigned shift:5;
+	unsigned bits:5;
+};
+
+/**
+ * struct jz47xx_cgu_div_info - information about a divider
+ * @reg: offset of the divider control register within the CGU
+ * @shift: number of bits to shift the divide value by (ie. the index of
+ *         the lowest bit of the divide value within its control register)
+ * @bits: the size of the divide value in bits
+ * @ce_bit: the index of the change enable bit within reg, or -1 is there
+ *          isn't one
+ * @busy_bit: the index of the busy bit within reg, or -1 is there isn't one
+ * @stop_bit: the index of the stop bit within reg, or -1 is there isn't one
+ */
+struct jz47xx_cgu_div_info {
+	unsigned reg;
+	unsigned shift:5;
+	unsigned bits:5;
+	int ce_bit:6;
+	int busy_bit:6;
+	int stop_bit:6;
+};
+
+/**
+ * struct jz47xx_cgu_custom_info - information about a custom (SoC) clock
+ */
+struct jz47xx_cgu_custom_info {
+	struct clk_ops *clk_ops;
+};
+
+/**
+ * struct jz47xx_cgu_clk_info - information about a clock
+ * @name: name of the clock
+ * @type: a bitmask formed from CGU_CLK_* values
+ * @parents: an array of the indices of potential parents of this clock
+ *           within the clock_info array of the CGU, or -1 in entries
+ *           which correspond to no valid parent
+ * @pll: information valid if type includes CGU_CLK_PLL
+ * @gate_bit: the index of the gate bit in the CLKGR* registers, valid if
+ *            type includes CGU_CLK_GATE
+ * @mux: information valid if type includes CGU_CLK_MUX
+ * @div: information valid if type includes CGU_CLK_DIV
+ */
+struct jz47xx_cgu_clk_info {
+	const char *name;
+
+	enum {
+		CGU_CLK_NONE		= 0,
+		CGU_CLK_EXT		= (1 << 0),
+		CGU_CLK_PLL		= (1 << 1),
+		CGU_CLK_GATE		= (1 << 2),
+		CGU_CLK_MUX		= (1 << 3),
+		CGU_CLK_MUX_GLITCHFREE	= (1 << 4),
+		CGU_CLK_DIV		= (1 << 5),
+		CGU_CLK_CUSTOM		= (1 << 6),
+	} type;
+
+	int parents[4];
+
+	union {
+		struct jz47xx_cgu_pll_info pll;
+
+		struct {
+			unsigned gate_bit;
+			struct jz47xx_cgu_mux_info mux;
+			struct jz47xx_cgu_div_info div;
+		};
+
+		struct jz47xx_cgu_custom_info custom;
+	};
+};
+
+/**
+ * struct jz47xx_cgu - data about the CGU
+ * @np: the device tree node that caused the CGU to be probed
+ * @base: the ioremap'ed base address of the CGU registers
+ * @clock_info: an array containing information about implemented clocks
+ * @clocks: used to provide clocks to DT, allows lookup of struct clk*
+ * @gate_lock: lock to be held whilst (un)gating a clock
+ * @divmux_lock: lock to be held whilst re-muxing of rate-changing a clock
+ */
+struct jz47xx_cgu {
+	struct device_node *np;
+	void __iomem *base;
+
+	const struct jz47xx_cgu_clk_info *clock_info;
+	struct clk_onecell_data clocks;
+
+	spinlock_t divmux_lock;		/* must be held when changing a divide
+					   or re-muxing a clock */
+	spinlock_t power_lock;		/* must be held when changing a power
+					   manager register */
+	spinlock_t pll_lock;		/* must be held when changing a PLL
+					   control register */
+};
+
+/**
+ * struct jz47xx_clk - private data for a clock
+ * @hw: see Documentation/clk.txt
+ * @cgu: a pointer to the CGU data
+ * @idx: the index of this clock in cgu->clock_info
+ */
+struct jz47xx_clk {
+	struct clk_hw hw;
+	struct jz47xx_cgu *cgu;
+	unsigned idx;
+};
+
+#define to_jz47xx_clk(_hw) container_of(_hw, struct jz47xx_clk, hw)
+
+/**
+ * jz47xx_cgu_new - create a new CGU instance
+ * @clock_info: an array of clock information structures describing the clocks
+ *              which are implemented by the CGU
+ * @num_clocks: the number of entries in clock_info
+ * @np: the device tree node which causes this CGU to be probed
+ *
+ * Returns an opaque pointer to the CGU instance if initialisation & clock
+ * registration is successful, otherwise NULL.
+ */
+struct jz47xx_cgu *jz47xx_cgu_new(const struct jz47xx_cgu_clk_info *clock_info,
+				  unsigned num_clocks,
+				  struct device_node *np);
+
+/**
+ * jz47xx_cgu_register_clocks - Registers the clocks
+ * @cgu: pointer to cgu data
+ *
+ * Returns 1 on success and -EINVAL if unsuccesful.
+ */
+int jz47xx_cgu_register_clocks(struct jz47xx_cgu *cgu);
+
+#endif /* __DRIVERS_CLK_JZ47XX_JZ47XX_CGU_H__ */
-- 
1.9.1

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

* [PATCH_V2 15/34] dt: clk: Add ingenic,jz4740-cgu binding documentation
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Document the devicetree binding for the Ingenic jz4740 CGU driver.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: devicetree@vger.kernel.org
---
 .../bindings/clock/ingenic,jz4740-cgu.txt          | 52 ++++++++++++++++++++++
 include/dt-bindings/clock/jz4740-cgu.h             | 37 +++++++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
 create mode 100644 include/dt-bindings/clock/jz4740-cgu.h

diff --git a/Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt b/Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
new file mode 100644
index 0000000..b02e168
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
@@ -0,0 +1,52 @@
+Ingenic jz4740 SoC CGU binding
+
+The CGU in a jz4740 SoC provides all the clocks generated on-chip. It includes
+PLLs, multiplexers, dividers & gates in order to provide a variety of different
+clock signals derived from only 2 external source clocks.
+
+Required properties:
+- compatible: Should be "ingenic,jz4740-cgu"
+- reg: Should be the address & length of the CGU registers
+- clocks: Should contain the phandle & clock specifier for two clocks external
+          to the TCU. First the external crystal "ext" and second the RTC
+          clock source "rtc".
+- clock-names: Should be set to strings naming the clocks specified in the
+               "clocks" property.
+- #clock-cells: Should be 1.
+                Clock consumers specify this argument to identify a clock. The
+                valid values may be found in <dt-bindings/clock/jz4740-cgu.h>.
+
+Example SoC include file:
+
+/ {
+	cgu: jz4740-cgu {
+		compatible = "ingenic,jz4740-cgu";
+		reg = <0x10000000 0x100>;
+		#clock-cells = <1>;
+	};
+
+	uart0: serial@10030000 {
+		clocks = <&cgu JZ4740_CLK_UART0>;
+	};
+};
+
+Example board file:
+
+/ {
+	ext: clock@0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+	};
+
+	rtc: clock@1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	&cgu {
+		clocks = <&ext> <&rtc>;
+		clock-names: "ext", "rtc";
+	};
+};
diff --git a/include/dt-bindings/clock/jz4740-cgu.h b/include/dt-bindings/clock/jz4740-cgu.h
new file mode 100644
index 0000000..43153d3
--- /dev/null
+++ b/include/dt-bindings/clock/jz4740-cgu.h
@@ -0,0 +1,37 @@
+/*
+ * This header provides clock numbers for the ingenic,jz4740-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers in the order they appear in the jz4740 programmers manual
+ *   - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4740_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4740_CGU_H__
+
+#define JZ4740_CLK_EXT		0
+#define JZ4740_CLK_RTC		1
+#define JZ4740_CLK_PLL		2
+#define JZ4740_CLK_PLL_HALF	3
+#define JZ4740_CLK_CCLK		4
+#define JZ4740_CLK_HCLK		5
+#define JZ4740_CLK_PCLK		6
+#define JZ4740_CLK_MCLK		7
+#define JZ4740_CLK_LCD		8
+#define JZ4740_CLK_LCD_PCLK	9
+#define JZ4740_CLK_I2S		10
+#define JZ4740_CLK_SPI		11
+#define JZ4740_CLK_MMC		12
+#define JZ4740_CLK_UHC		13
+#define JZ4740_CLK_UDC		14
+#define JZ4740_CLK_UART0	15
+#define JZ4740_CLK_UART1	16
+#define JZ4740_CLK_DMA		17
+#define JZ4740_CLK_IPU		18
+#define JZ4740_CLK_ADC		19
+#define JZ4740_CLK_I2C		20
+#define JZ4740_CLK_AIC		21
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4740_CGU_H__ */
-- 
1.9.1


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

* [PATCH_V2 15/34] dt: clk: Add ingenic,jz4740-cgu binding documentation
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Document the devicetree binding for the Ingenic jz4740 CGU driver.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: devicetree@vger.kernel.org
---
 .../bindings/clock/ingenic,jz4740-cgu.txt          | 52 ++++++++++++++++++++++
 include/dt-bindings/clock/jz4740-cgu.h             | 37 +++++++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
 create mode 100644 include/dt-bindings/clock/jz4740-cgu.h

diff --git a/Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt b/Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
new file mode 100644
index 0000000..b02e168
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
@@ -0,0 +1,52 @@
+Ingenic jz4740 SoC CGU binding
+
+The CGU in a jz4740 SoC provides all the clocks generated on-chip. It includes
+PLLs, multiplexers, dividers & gates in order to provide a variety of different
+clock signals derived from only 2 external source clocks.
+
+Required properties:
+- compatible: Should be "ingenic,jz4740-cgu"
+- reg: Should be the address & length of the CGU registers
+- clocks: Should contain the phandle & clock specifier for two clocks external
+          to the TCU. First the external crystal "ext" and second the RTC
+          clock source "rtc".
+- clock-names: Should be set to strings naming the clocks specified in the
+               "clocks" property.
+- #clock-cells: Should be 1.
+                Clock consumers specify this argument to identify a clock. The
+                valid values may be found in <dt-bindings/clock/jz4740-cgu.h>.
+
+Example SoC include file:
+
+/ {
+	cgu: jz4740-cgu {
+		compatible = "ingenic,jz4740-cgu";
+		reg = <0x10000000 0x100>;
+		#clock-cells = <1>;
+	};
+
+	uart0: serial@10030000 {
+		clocks = <&cgu JZ4740_CLK_UART0>;
+	};
+};
+
+Example board file:
+
+/ {
+	ext: clock@0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <12000000>;
+	};
+
+	rtc: clock@1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	&cgu {
+		clocks = <&ext> <&rtc>;
+		clock-names: "ext", "rtc";
+	};
+};
diff --git a/include/dt-bindings/clock/jz4740-cgu.h b/include/dt-bindings/clock/jz4740-cgu.h
new file mode 100644
index 0000000..43153d3
--- /dev/null
+++ b/include/dt-bindings/clock/jz4740-cgu.h
@@ -0,0 +1,37 @@
+/*
+ * This header provides clock numbers for the ingenic,jz4740-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers in the order they appear in the jz4740 programmers manual
+ *   - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4740_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4740_CGU_H__
+
+#define JZ4740_CLK_EXT		0
+#define JZ4740_CLK_RTC		1
+#define JZ4740_CLK_PLL		2
+#define JZ4740_CLK_PLL_HALF	3
+#define JZ4740_CLK_CCLK		4
+#define JZ4740_CLK_HCLK		5
+#define JZ4740_CLK_PCLK		6
+#define JZ4740_CLK_MCLK		7
+#define JZ4740_CLK_LCD		8
+#define JZ4740_CLK_LCD_PCLK	9
+#define JZ4740_CLK_I2S		10
+#define JZ4740_CLK_SPI		11
+#define JZ4740_CLK_MMC		12
+#define JZ4740_CLK_UHC		13
+#define JZ4740_CLK_UDC		14
+#define JZ4740_CLK_UART0	15
+#define JZ4740_CLK_UART1	16
+#define JZ4740_CLK_DMA		17
+#define JZ4740_CLK_IPU		18
+#define JZ4740_CLK_ADC		19
+#define JZ4740_CLK_I2C		20
+#define JZ4740_CLK_AIC		21
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4740_CGU_H__ */
-- 
1.9.1

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

* [PATCH_V2 16/34] MIPS: clk: migrate jz4740 to common clock framework
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Migrate the jz4740 & the qi_lb60 board to use common clock framework
via the new jz74xx-cgu driver.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>

---
V2 Removed FSF address
---
 arch/mips/Kconfig                |   2 +-
 arch/mips/boot/dts/jz4740.dtsi   |  23 ++
 arch/mips/boot/dts/qi_lb60.dts   |   4 +
 arch/mips/jz4740/Makefile        |   2 -
 arch/mips/jz4740/board-qi_lb60.c |   5 -
 arch/mips/jz4740/clock-debugfs.c | 108 ------
 arch/mips/jz4740/clock.c         | 801 +--------------------------------------
 arch/mips/jz4740/clock.h         |  53 +--
 arch/mips/jz4740/time.c          |   2 +
 drivers/clk/jz47xx/Makefile      |   1 +
 drivers/clk/jz47xx/jz4740-cgu.c  | 219 +++++++++++
 11 files changed, 252 insertions(+), 968 deletions(-)
 delete mode 100644 arch/mips/jz4740/clock-debugfs.c
 create mode 100644 drivers/clk/jz47xx/jz4740-cgu.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 99d50cd..8b377a7 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -286,7 +286,7 @@ config MACH_JZ4740
 	select IRQ_CPU
 	select ARCH_REQUIRE_GPIOLIB
 	select SYS_HAS_EARLY_PRINTK
-	select HAVE_CLK
+	select COMMON_CLK
 	select GENERIC_IRQ_CHIP
 	select BUILTIN_DTB
 	select USE_OF
diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
index 3841024..ef679b4 100644
--- a/arch/mips/boot/dts/jz4740.dtsi
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -1,3 +1,5 @@
+#include <dt-bindings/clock/jz4740-cgu.h>
+
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
@@ -20,4 +22,25 @@
 		interrupt-parent = <&cpuintc>;
 		interrupts = <2>;
 	};
+
+	ext: ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+	};
+
+	rtc: rtc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	cgu: jz4740-cgu@10000000 {
+		compatible = "ingenic,jz4740-cgu";
+		reg = <0x10000000 0x100>;
+
+		clocks = <&ext>, <&rtc>;
+		clock-names = "ext", "rtc";
+
+		#clock-cells = <1>;
+	};
 };
diff --git a/arch/mips/boot/dts/qi_lb60.dts b/arch/mips/boot/dts/qi_lb60.dts
index 0c0f639..106d13c 100644
--- a/arch/mips/boot/dts/qi_lb60.dts
+++ b/arch/mips/boot/dts/qi_lb60.dts
@@ -5,3 +5,7 @@
 / {
 	compatible = "qi,lb60", "ingenic,jz4740";
 };
+
+&ext {
+	clock-frequency = <12000000>;
+};
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 28e5535..80e326d 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -7,8 +7,6 @@
 obj-y += prom.o irq.o time.o reset.o setup.o \
 	gpio.o clock.o platform.o timer.o serial.o
 
-obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
-
 # board specific support
 
 obj-$(CONFIG_JZ4740_QI_LB60)	+= board-qi_lb60.o
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index c454525..0fbb2d8 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -488,11 +488,6 @@ static int __init qi_lb60_init_platform_devices(void)
 
 }
 
-struct jz4740_clock_board_data jz4740_clock_bdata = {
-	.ext_rate = 12000000,
-	.rtc_rate = 32768,
-};
-
 static __init int board_avt2(char *str)
 {
 	qi_lb60_mmc_pdata.card_detect_active_low = 1;
diff --git a/arch/mips/jz4740/clock-debugfs.c b/arch/mips/jz4740/clock-debugfs.c
deleted file mode 100644
index 325422d0..0000000
--- a/arch/mips/jz4740/clock-debugfs.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC clock support debugfs entries
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General	 Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <linux/debugfs.h>
-#include <linux/uaccess.h>
-
-#include <asm/mach-jz4740/clock.h>
-#include "clock.h"
-
-static struct dentry *jz4740_clock_debugfs;
-
-static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
-{
-	struct clk *clk = data;
-	*value = clk_is_enabled(clk);
-
-	return 0;
-}
-
-static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
-{
-	struct clk *clk = data;
-
-	if (value)
-		return clk_enable(clk);
-	else
-		clk_disable(clk);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
-	jz4740_clock_debugfs_show_enabled,
-	jz4740_clock_debugfs_set_enabled,
-	"%llu\n");
-
-static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
-{
-	struct clk *clk = data;
-	*value = clk_get_rate(clk);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
-	jz4740_clock_debugfs_show_rate,
-	NULL,
-	"%llu\n");
-
-void jz4740_clock_debugfs_add_clk(struct clk *clk)
-{
-	if (!jz4740_clock_debugfs)
-		return;
-
-	clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
-	debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
-				&jz4740_clock_debugfs_ops_rate);
-	debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
-				&jz4740_clock_debugfs_ops_enabled);
-
-	if (clk->parent) {
-		char parent_path[100];
-		snprintf(parent_path, 100, "../%s", clk->parent->name);
-		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
-						clk->debugfs_entry,
-						parent_path);
-	}
-}
-
-/* TODO: Locking */
-void jz4740_clock_debugfs_update_parent(struct clk *clk)
-{
-	debugfs_remove(clk->debugfs_parent_entry);
-
-	if (clk->parent) {
-		char parent_path[100];
-		snprintf(parent_path, 100, "../%s", clk->parent->name);
-		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
-						clk->debugfs_entry,
-						parent_path);
-	} else {
-		clk->debugfs_parent_entry = NULL;
-	}
-}
-
-void jz4740_clock_debugfs_init(void)
-{
-	jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
-	if (IS_ERR(jz4740_clock_debugfs))
-		jz4740_clock_debugfs = NULL;
-}
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
index c257073..dedee7c 100644
--- a/arch/mips/jz4740/clock.c
+++ b/arch/mips/jz4740/clock.c
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -27,820 +28,44 @@
 
 #include "clock.h"
 
-#define JZ_REG_CLOCK_CTRL	0x00
 #define JZ_REG_CLOCK_LOW_POWER	0x04
 #define JZ_REG_CLOCK_PLL	0x10
 #define JZ_REG_CLOCK_GATE	0x20
-#define JZ_REG_CLOCK_SLEEP_CTRL 0x24
-#define JZ_REG_CLOCK_I2S	0x60
-#define JZ_REG_CLOCK_LCD	0x64
-#define JZ_REG_CLOCK_MMC	0x68
-#define JZ_REG_CLOCK_UHC	0x6C
-#define JZ_REG_CLOCK_SPI	0x74
-
-#define JZ_CLOCK_CTRL_I2S_SRC_PLL	BIT(31)
-#define JZ_CLOCK_CTRL_KO_ENABLE		BIT(30)
-#define JZ_CLOCK_CTRL_UDC_SRC_PLL	BIT(29)
-#define JZ_CLOCK_CTRL_UDIV_MASK		0x1f800000
-#define JZ_CLOCK_CTRL_CHANGE_ENABLE	BIT(22)
-#define JZ_CLOCK_CTRL_PLL_HALF		BIT(21)
-#define JZ_CLOCK_CTRL_LDIV_MASK		0x001f0000
-#define JZ_CLOCK_CTRL_UDIV_OFFSET	23
-#define JZ_CLOCK_CTRL_LDIV_OFFSET	16
-#define JZ_CLOCK_CTRL_MDIV_OFFSET	12
-#define JZ_CLOCK_CTRL_PDIV_OFFSET	 8
-#define JZ_CLOCK_CTRL_HDIV_OFFSET	 4
-#define JZ_CLOCK_CTRL_CDIV_OFFSET	 0
 
 #define JZ_CLOCK_GATE_UART0	BIT(0)
 #define JZ_CLOCK_GATE_TCU	BIT(1)
-#define JZ_CLOCK_GATE_RTC	BIT(2)
-#define JZ_CLOCK_GATE_I2C	BIT(3)
-#define JZ_CLOCK_GATE_SPI	BIT(4)
-#define JZ_CLOCK_GATE_AIC	BIT(5)
-#define JZ_CLOCK_GATE_I2S	BIT(6)
-#define JZ_CLOCK_GATE_MMC	BIT(7)
-#define JZ_CLOCK_GATE_ADC	BIT(8)
-#define JZ_CLOCK_GATE_CIM	BIT(9)
-#define JZ_CLOCK_GATE_LCD	BIT(10)
 #define JZ_CLOCK_GATE_UDC	BIT(11)
 #define JZ_CLOCK_GATE_DMAC	BIT(12)
-#define JZ_CLOCK_GATE_IPU	BIT(13)
-#define JZ_CLOCK_GATE_UHC	BIT(14)
-#define JZ_CLOCK_GATE_UART1	BIT(15)
-
-#define JZ_CLOCK_I2S_DIV_MASK		0x01ff
-
-#define JZ_CLOCK_LCD_DIV_MASK		0x01ff
-
-#define JZ_CLOCK_MMC_DIV_MASK		0x001f
 
-#define JZ_CLOCK_UHC_DIV_MASK		0x000f
-
-#define JZ_CLOCK_SPI_SRC_PLL		BIT(31)
-#define JZ_CLOCK_SPI_DIV_MASK		0x000f
-
-#define JZ_CLOCK_PLL_M_MASK		0x01ff
-#define JZ_CLOCK_PLL_N_MASK		0x001f
-#define JZ_CLOCK_PLL_OD_MASK		0x0003
 #define JZ_CLOCK_PLL_STABLE		BIT(10)
-#define JZ_CLOCK_PLL_BYPASS		BIT(9)
 #define JZ_CLOCK_PLL_ENABLED		BIT(8)
-#define JZ_CLOCK_PLL_STABLIZE_MASK	0x000f
-#define JZ_CLOCK_PLL_M_OFFSET		23
-#define JZ_CLOCK_PLL_N_OFFSET		18
-#define JZ_CLOCK_PLL_OD_OFFSET		16
 
 #define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
 #define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
 
-#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
-#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
-
 static void __iomem *jz_clock_base;
-static spinlock_t jz_clock_lock;
-static LIST_HEAD(jz_clocks);
-
-struct main_clk {
-	struct clk clk;
-	uint32_t div_offset;
-};
-
-struct divided_clk {
-	struct clk clk;
-	uint32_t reg;
-	uint32_t mask;
-};
-
-struct static_clk {
-	struct clk clk;
-	unsigned long rate;
-};
 
 static uint32_t jz_clk_reg_read(int reg)
 {
 	return readl(jz_clock_base + reg);
 }
 
-static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
-{
-	uint32_t val2;
-
-	spin_lock(&jz_clock_lock);
-	val2 = readl(jz_clock_base + reg);
-	val2 &= ~mask;
-	val2 |= val;
-	writel(val2, jz_clock_base + reg);
-	spin_unlock(&jz_clock_lock);
-}
-
 static void jz_clk_reg_set_bits(int reg, uint32_t mask)
 {
 	uint32_t val;
 
-	spin_lock(&jz_clock_lock);
 	val = readl(jz_clock_base + reg);
 	val |= mask;
 	writel(val, jz_clock_base + reg);
-	spin_unlock(&jz_clock_lock);
 }
 
 static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
 {
 	uint32_t val;
 
-	spin_lock(&jz_clock_lock);
 	val = readl(jz_clock_base + reg);
 	val &= ~mask;
 	writel(val, jz_clock_base + reg);
-	spin_unlock(&jz_clock_lock);
-}
-
-static int jz_clk_enable_gating(struct clk *clk)
-{
-	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
-		return -EINVAL;
-
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
-	return 0;
-}
-
-static int jz_clk_disable_gating(struct clk *clk)
-{
-	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
-		return -EINVAL;
-
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
-	return 0;
-}
-
-static int jz_clk_is_enabled_gating(struct clk *clk)
-{
-	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
-		return 1;
-
-	return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
-}
-
-static unsigned long jz_clk_static_get_rate(struct clk *clk)
-{
-	return ((struct static_clk *)clk)->rate;
-}
-
-static int jz_clk_ko_enable(struct clk *clk)
-{
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
-	return 0;
-}
-
-static int jz_clk_ko_disable(struct clk *clk)
-{
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
-	return 0;
-}
-
-static int jz_clk_ko_is_enabled(struct clk *clk)
-{
-	return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
-}
-
-static const int pllno[] = {1, 2, 2, 4};
-
-static unsigned long jz_clk_pll_get_rate(struct clk *clk)
-{
-	uint32_t val;
-	int m;
-	int n;
-	int od;
-
-	val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
-
-	if (val & JZ_CLOCK_PLL_BYPASS)
-		return clk_get_rate(clk->parent);
-
-	m = ((val >> 23) & 0x1ff) + 2;
-	n = ((val >> 18) & 0x1f) + 2;
-	od = (val >> 16) & 0x3;
-
-	return ((clk_get_rate(clk->parent) / n) * m) / pllno[od];
-}
-
-static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
-{
-	uint32_t reg;
-
-	reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
-	if (reg & JZ_CLOCK_CTRL_PLL_HALF)
-		return jz_clk_pll_get_rate(clk->parent);
-	return jz_clk_pll_get_rate(clk->parent) >> 1;
-}
-
-static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
-
-static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
-	int div;
-
-	div = parent_rate / rate;
-	if (div > 32)
-		return parent_rate / 32;
-	else if (div < 1)
-		return parent_rate;
-
-	div &= (0x3 << (ffs(div) - 1));
-
-	return parent_rate / div;
-}
-
-static unsigned long jz_clk_main_get_rate(struct clk *clk)
-{
-	struct main_clk *mclk = (struct main_clk *)clk;
-	uint32_t div;
-
-	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
-
-	div >>= mclk->div_offset;
-	div &= 0xf;
-
-	if (div >= ARRAY_SIZE(jz_clk_main_divs))
-		div = ARRAY_SIZE(jz_clk_main_divs) - 1;
-
-	return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
-}
-
-static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
-{
-	struct main_clk *mclk = (struct main_clk *)clk;
-	int i;
-	int div;
-	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
-
-	rate = jz_clk_main_round_rate(clk, rate);
-
-	div = parent_rate / rate;
-
-	i = (ffs(div) - 1) << 1;
-	if (i > 0 && !(div & BIT(i-1)))
-		i -= 1;
-
-	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
-				0xf << mclk->div_offset);
-
-	return 0;
-}
-
-static struct clk_ops jz_clk_static_ops = {
-	.get_rate = jz_clk_static_get_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct static_clk jz_clk_ext = {
-	.clk = {
-		.name = "ext",
-		.gate_bit = JZ4740_CLK_NOT_GATED,
-		.ops = &jz_clk_static_ops,
-	},
-};
-
-static struct clk_ops jz_clk_pll_ops = {
-	.get_rate = jz_clk_pll_get_rate,
-};
-
-static struct clk jz_clk_pll = {
-	.name = "pll",
-	.parent = &jz_clk_ext.clk,
-	.ops = &jz_clk_pll_ops,
-};
-
-static struct clk_ops jz_clk_pll_half_ops = {
-	.get_rate = jz_clk_pll_half_get_rate,
-};
-
-static struct clk jz_clk_pll_half = {
-	.name = "pll half",
-	.parent = &jz_clk_pll,
-	.ops = &jz_clk_pll_half_ops,
-};
-
-static const struct clk_ops jz_clk_main_ops = {
-	.get_rate = jz_clk_main_get_rate,
-	.set_rate = jz_clk_main_set_rate,
-	.round_rate = jz_clk_main_round_rate,
-};
-
-static struct main_clk jz_clk_cpu = {
-	.clk = {
-		.name = "cclk",
-		.parent = &jz_clk_pll,
-		.ops = &jz_clk_main_ops,
-	},
-	.div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
-};
-
-static struct main_clk jz_clk_memory = {
-	.clk = {
-		.name = "mclk",
-		.parent = &jz_clk_pll,
-		.ops = &jz_clk_main_ops,
-	},
-	.div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
-};
-
-static struct main_clk jz_clk_high_speed_peripheral = {
-	.clk = {
-		.name = "hclk",
-		.parent = &jz_clk_pll,
-		.ops = &jz_clk_main_ops,
-	},
-	.div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
-};
-
-
-static struct main_clk jz_clk_low_speed_peripheral = {
-	.clk = {
-		.name = "pclk",
-		.parent = &jz_clk_pll,
-		.ops = &jz_clk_main_ops,
-	},
-	.div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
-};
-
-static const struct clk_ops jz_clk_ko_ops = {
-	.enable = jz_clk_ko_enable,
-	.disable = jz_clk_ko_disable,
-	.is_enabled = jz_clk_ko_is_enabled,
-};
-
-static struct clk jz_clk_ko = {
-	.name = "cko",
-	.parent = &jz_clk_memory.clk,
-	.ops = &jz_clk_ko_ops,
-};
-
-static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
-{
-	if (parent == &jz_clk_pll)
-		jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
-	else if (parent == &jz_clk_ext.clk)
-		jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	return 0;
-}
-
-static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
-{
-	if (parent == &jz_clk_pll_half)
-		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
-	else if (parent == &jz_clk_ext.clk)
-		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	return 0;
-}
-
-static int jz_clk_udc_enable(struct clk *clk)
-{
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
-			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
-
-	return 0;
-}
-
-static int jz_clk_udc_disable(struct clk *clk)
-{
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
-			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
-
-	return 0;
-}
-
-static int jz_clk_udc_is_enabled(struct clk *clk)
-{
-	return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
-			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
-}
-
-static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
-{
-	if (parent == &jz_clk_pll_half)
-		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
-	else if (parent == &jz_clk_ext.clk)
-		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	return 0;
-}
-
-static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
-{
-	int div;
-
-	if (clk->parent == &jz_clk_ext.clk)
-		return -EINVAL;
-
-	div = clk_get_rate(clk->parent) / rate - 1;
-
-	if (div < 0)
-		div = 0;
-	else if (div > 63)
-		div = 63;
-
-	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
-				JZ_CLOCK_CTRL_UDIV_MASK);
-	return 0;
-}
-
-static unsigned long jz_clk_udc_get_rate(struct clk *clk)
-{
-	int div;
-
-	if (clk->parent == &jz_clk_ext.clk)
-		return clk_get_rate(clk->parent);
-
-	div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
-	div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
-	div += 1;
-
-	return clk_get_rate(clk->parent) / div;
-}
-
-static unsigned long jz_clk_divided_get_rate(struct clk *clk)
-{
-	struct divided_clk *dclk = (struct divided_clk *)clk;
-	int div;
-
-	if (clk->parent == &jz_clk_ext.clk)
-		return clk_get_rate(clk->parent);
-
-	div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
-
-	return clk_get_rate(clk->parent) / div;
-}
-
-static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
-{
-	struct divided_clk *dclk = (struct divided_clk *)clk;
-	int div;
-
-	if (clk->parent == &jz_clk_ext.clk)
-		return -EINVAL;
-
-	div = clk_get_rate(clk->parent) / rate - 1;
-
-	if (div < 0)
-		div = 0;
-	else if (div > dclk->mask)
-		div = dclk->mask;
-
-	jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
-
-	return 0;
-}
-
-static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
-{
-	int div;
-	unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
-
-	if (rate > 150000000)
-		return 150000000;
-
-	div = parent_rate / rate;
-	if (div < 1)
-		div = 1;
-	else if (div > 32)
-		div = 32;
-
-	return parent_rate / div;
-}
-
-static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int div;
-
-	if (rate > 150000000)
-		return -EINVAL;
-
-	div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
-	if (div < 0)
-		div = 0;
-	else if (div > 31)
-		div = 31;
-
-	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
-				JZ_CLOCK_CTRL_LDIV_MASK);
-
-	return 0;
-}
-
-static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
-{
-	int div;
-
-	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
-	div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
-
-	return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
-}
-
-static const struct clk_ops jz_clk_ops_ld = {
-	.set_rate = jz_clk_ldclk_set_rate,
-	.get_rate = jz_clk_ldclk_get_rate,
-	.round_rate = jz_clk_ldclk_round_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct clk jz_clk_ld = {
-	.name = "lcd",
-	.gate_bit = JZ_CLOCK_GATE_LCD,
-	.parent = &jz_clk_pll_half,
-	.ops = &jz_clk_ops_ld,
-};
-
-static const struct clk_ops jz_clk_i2s_ops = {
-	.set_rate = jz_clk_divided_set_rate,
-	.get_rate = jz_clk_divided_get_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-	.set_parent = jz_clk_i2s_set_parent,
-};
-
-static const struct clk_ops jz_clk_spi_ops = {
-	.set_rate = jz_clk_divided_set_rate,
-	.get_rate = jz_clk_divided_get_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-	.set_parent = jz_clk_spi_set_parent,
-};
-
-static const struct clk_ops jz_clk_divided_ops = {
-	.set_rate = jz_clk_divided_set_rate,
-	.get_rate = jz_clk_divided_get_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct divided_clk jz4740_clock_divided_clks[] = {
-	[0] = {
-		.clk = {
-			.name = "i2s",
-			.parent = &jz_clk_ext.clk,
-			.gate_bit = JZ_CLOCK_GATE_I2S,
-			.ops = &jz_clk_i2s_ops,
-		},
-		.reg = JZ_REG_CLOCK_I2S,
-		.mask = JZ_CLOCK_I2S_DIV_MASK,
-	},
-	[1] = {
-		.clk = {
-			.name = "spi",
-			.parent = &jz_clk_ext.clk,
-			.gate_bit = JZ_CLOCK_GATE_SPI,
-			.ops = &jz_clk_spi_ops,
-		},
-		.reg = JZ_REG_CLOCK_SPI,
-		.mask = JZ_CLOCK_SPI_DIV_MASK,
-	},
-	[2] = {
-		.clk = {
-			.name = "lcd_pclk",
-			.parent = &jz_clk_pll_half,
-			.gate_bit = JZ4740_CLK_NOT_GATED,
-			.ops = &jz_clk_divided_ops,
-		},
-		.reg = JZ_REG_CLOCK_LCD,
-		.mask = JZ_CLOCK_LCD_DIV_MASK,
-	},
-	[3] = {
-		.clk = {
-			.name = "mmc",
-			.parent = &jz_clk_pll_half,
-			.gate_bit = JZ_CLOCK_GATE_MMC,
-			.ops = &jz_clk_divided_ops,
-		},
-		.reg = JZ_REG_CLOCK_MMC,
-		.mask = JZ_CLOCK_MMC_DIV_MASK,
-	},
-	[4] = {
-		.clk = {
-			.name = "uhc",
-			.parent = &jz_clk_pll_half,
-			.gate_bit = JZ_CLOCK_GATE_UHC,
-			.ops = &jz_clk_divided_ops,
-		},
-		.reg = JZ_REG_CLOCK_UHC,
-		.mask = JZ_CLOCK_UHC_DIV_MASK,
-	},
-};
-
-static const struct clk_ops jz_clk_udc_ops = {
-	.set_parent = jz_clk_udc_set_parent,
-	.set_rate = jz_clk_udc_set_rate,
-	.get_rate = jz_clk_udc_get_rate,
-	.enable = jz_clk_udc_enable,
-	.disable = jz_clk_udc_disable,
-	.is_enabled = jz_clk_udc_is_enabled,
-};
-
-static const struct clk_ops jz_clk_simple_ops = {
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct clk jz4740_clock_simple_clks[] = {
-	[0] = {
-		.name = "udc",
-		.parent = &jz_clk_ext.clk,
-		.ops = &jz_clk_udc_ops,
-	},
-	[1] = {
-		.name = "uart0",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_UART0,
-		.ops = &jz_clk_simple_ops,
-	},
-	[2] = {
-		.name = "uart1",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_UART1,
-		.ops = &jz_clk_simple_ops,
-	},
-	[3] = {
-		.name = "dma",
-		.parent = &jz_clk_high_speed_peripheral.clk,
-		.gate_bit = JZ_CLOCK_GATE_DMAC,
-		.ops = &jz_clk_simple_ops,
-	},
-	[4] = {
-		.name = "ipu",
-		.parent = &jz_clk_high_speed_peripheral.clk,
-		.gate_bit = JZ_CLOCK_GATE_IPU,
-		.ops = &jz_clk_simple_ops,
-	},
-	[5] = {
-		.name = "adc",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_ADC,
-		.ops = &jz_clk_simple_ops,
-	},
-	[6] = {
-		.name = "i2c",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_I2C,
-		.ops = &jz_clk_simple_ops,
-	},
-	[7] = {
-		.name = "aic",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_AIC,
-		.ops = &jz_clk_simple_ops,
-	},
-};
-
-static struct static_clk jz_clk_rtc = {
-	.clk = {
-		.name = "rtc",
-		.gate_bit = JZ_CLOCK_GATE_RTC,
-		.ops = &jz_clk_static_ops,
-	},
-	.rate = 32768,
-};
-
-int clk_enable(struct clk *clk)
-{
-	if (!clk->ops->enable)
-		return -EINVAL;
-
-	return clk->ops->enable(clk);
-}
-EXPORT_SYMBOL_GPL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-	if (clk->ops->disable)
-		clk->ops->disable(clk);
-}
-EXPORT_SYMBOL_GPL(clk_disable);
-
-int clk_is_enabled(struct clk *clk)
-{
-	if (clk->ops->is_enabled)
-		return clk->ops->is_enabled(clk);
-
-	return 1;
-}
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (clk->ops->get_rate)
-		return clk->ops->get_rate(clk);
-	if (clk->parent)
-		return clk_get_rate(clk->parent);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(clk_get_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	if (!clk->ops->set_rate)
-		return -EINVAL;
-	return clk->ops->set_rate(clk, rate);
-}
-EXPORT_SYMBOL_GPL(clk_set_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (clk->ops->round_rate)
-		return clk->ops->round_rate(clk, rate);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(clk_round_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	int ret;
-	int enabled;
-
-	if (!clk->ops->set_parent)
-		return -EINVAL;
-
-	enabled = clk_is_enabled(clk);
-	if (enabled)
-		clk_disable(clk);
-	ret = clk->ops->set_parent(clk, parent);
-	if (enabled)
-		clk_enable(clk);
-
-	jz4740_clock_debugfs_update_parent(clk);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(clk_set_parent);
-
-struct clk *clk_get(struct device *dev, const char *name)
-{
-	struct clk *clk;
-
-	list_for_each_entry(clk, &jz_clocks, list) {
-		if (strcmp(clk->name, name) == 0)
-			return clk;
-	}
-	return ERR_PTR(-ENXIO);
-}
-EXPORT_SYMBOL_GPL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL_GPL(clk_put);
-
-static inline void clk_add(struct clk *clk)
-{
-	list_add_tail(&clk->list, &jz_clocks);
-
-	jz4740_clock_debugfs_add_clk(clk);
-}
-
-static void clk_register_clks(void)
-{
-	size_t i;
-
-	clk_add(&jz_clk_ext.clk);
-	clk_add(&jz_clk_pll);
-	clk_add(&jz_clk_pll_half);
-	clk_add(&jz_clk_cpu.clk);
-	clk_add(&jz_clk_high_speed_peripheral.clk);
-	clk_add(&jz_clk_low_speed_peripheral.clk);
-	clk_add(&jz_clk_ko);
-	clk_add(&jz_clk_ld);
-	clk_add(&jz_clk_rtc.clk);
-
-	for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
-		clk_add(&jz4740_clock_divided_clks[i].clk);
-
-	for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
-		clk_add(&jz4740_clock_simple_clks[i]);
 }
 
 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
@@ -891,33 +116,9 @@ void jz4740_clock_resume(void)
 
 int jz4740_clock_init(void)
 {
-	uint32_t val;
-
 	jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
 	if (!jz_clock_base)
 		return -EBUSY;
 
-	spin_lock_init(&jz_clock_lock);
-
-	jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
-	jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
-
-	val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
-
-	if (val & JZ_CLOCK_SPI_SRC_PLL)
-		jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
-
-	val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
-
-	if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
-		jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
-
-	if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
-		jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
-
-	jz4740_clock_debugfs_init();
-
-	clk_register_clks();
-
 	return 0;
 }
diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
index 5d07499..86a3e01 100644
--- a/arch/mips/jz4740/clock.h
+++ b/arch/mips/jz4740/clock.h
@@ -16,61 +16,10 @@
 #ifndef __MIPS_JZ4740_CLOCK_H__
 #define __MIPS_JZ4740_CLOCK_H__
 
+#include <linux/clk.h>
 #include <linux/list.h>
 
-struct jz4740_clock_board_data {
-	unsigned long ext_rate;
-	unsigned long rtc_rate;
-};
-
-extern struct jz4740_clock_board_data jz4740_clock_bdata;
-
 void jz4740_clock_suspend(void);
 void jz4740_clock_resume(void);
 
-struct clk;
-
-struct clk_ops {
-	unsigned long (*get_rate)(struct clk *clk);
-	unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
-	int (*set_rate)(struct clk *clk, unsigned long rate);
-	int (*enable)(struct clk *clk);
-	int (*disable)(struct clk *clk);
-	int (*is_enabled)(struct clk *clk);
-
-	int (*set_parent)(struct clk *clk, struct clk *parent);
-
-};
-
-struct clk {
-	const char *name;
-	struct clk *parent;
-
-	uint32_t gate_bit;
-
-	const struct clk_ops *ops;
-
-	struct list_head list;
-
-#ifdef CONFIG_DEBUG_FS
-	struct dentry *debugfs_entry;
-	struct dentry *debugfs_parent_entry;
-#endif
-
-};
-
-#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
-
-int clk_is_enabled(struct clk *clk);
-
-#ifdef CONFIG_DEBUG_FS
-void jz4740_clock_debugfs_init(void);
-void jz4740_clock_debugfs_add_clk(struct clk *clk);
-void jz4740_clock_debugfs_update_parent(struct clk *clk);
-#else
-static inline void jz4740_clock_debugfs_init(void) {};
-static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
-static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
-#endif
-
 #endif
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index bff2ac9..caa796d 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -14,6 +14,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
@@ -112,6 +113,7 @@ void __init plat_time_init(void)
 	uint16_t ctrl;
 	struct clk *ext_clk;
 
+	of_clk_init(NULL);
 	jz4740_clock_init();
 	jz4740_timer_init();
 
diff --git a/drivers/clk/jz47xx/Makefile b/drivers/clk/jz47xx/Makefile
index ac594e5..21746fc 100644
--- a/drivers/clk/jz47xx/Makefile
+++ b/drivers/clk/jz47xx/Makefile
@@ -1 +1,2 @@
 obj-y				+= jz47xx-cgu.o
+obj-$(CONFIG_MACH_JZ4740)	+= jz4740-cgu.o
diff --git a/drivers/clk/jz47xx/jz4740-cgu.c b/drivers/clk/jz47xx/jz4740-cgu.c
new file mode 100644
index 0000000..83f1e1f
--- /dev/null
+++ b/drivers/clk/jz47xx/jz4740-cgu.c
@@ -0,0 +1,219 @@
+/*
+ * Ingenic jz4740 SoC CGU driver
+ *
+ * Copyright (c) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <dt-bindings/clock/jz4740-cgu.h>
+#include "jz47xx-cgu.h"
+
+/* CGU register offsets */
+#define CGU_REG_CPCCR		0x00
+#define CGU_REG_CPPCR		0x10
+#define CGU_REG_I2SCDR		0x60
+#define CGU_REG_LPCDR		0x64
+#define CGU_REG_MSCCDR		0x68
+#define CGU_REG_UHCCDR		0x6c
+#define CGU_REG_SSICDR		0x74
+
+/* bits within a PLL control register */
+#define PLLCTL_M_SHIFT		23
+#define PLLCTL_M_MASK		(0x1ff << PLLCTL_M_SHIFT)
+#define PLLCTL_N_SHIFT		18
+#define PLLCTL_N_MASK		(0x1f << PLLCTL_N_SHIFT)
+#define PLLCTL_OD_SHIFT		16
+#define PLLCTL_OD_MASK		(0x3 << PLLCTL_OD_SHIFT)
+#define PLLCTL_STABLE		(1 << 10)
+#define PLLCTL_BYPASS		(1 << 9)
+#define PLLCTL_ENABLE		(1 << 8)
+
+static struct jz47xx_cgu *cgu;
+
+static const s8 pll_od_encoding[4] = {
+	0x0, 0x1, -1, 0x3,
+};
+
+static const struct jz47xx_cgu_clk_info jz4740_cgu_clocks[] = {
+
+	/* External clocks */
+
+	[JZ4740_CLK_EXT] = { "ext", CGU_CLK_EXT },
+	[JZ4740_CLK_RTC] = { "rtc", CGU_CLK_EXT },
+
+	[JZ4740_CLK_PLL] = {
+		"pll", CGU_CLK_PLL,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.pll = {
+			.reg = CGU_REG_CPPCR,
+			.m_shift = 23,
+			.m_bits = 9,
+			.m_offset = 2,
+			.n_shift = 18,
+			.n_bits = 5,
+			.n_offset = 2,
+			.od_shift = 16,
+			.od_bits = 2,
+			.od_max = 4,
+			.od_encoding = pll_od_encoding,
+			.stable_bit = 10,
+			.bypass_bit = 9,
+			.enable_bit = 8,
+		},
+	},
+
+	/* Muxes & dividers */
+
+	[JZ4740_CLK_PLL_HALF] = {
+		"pll half", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 21, 1, -1, -1, -1 },
+	},
+
+	[JZ4740_CLK_CCLK] = {
+		"cclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 0, 4, 22, -1, -1 },
+	},
+
+	[JZ4740_CLK_HCLK] = {
+		"hclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 4, 4, 22, -1, -1 },
+	},
+
+	[JZ4740_CLK_PCLK] = {
+		"pclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 8, 4, 22, -1, -1 },
+	},
+
+	[JZ4740_CLK_MCLK] = {
+		"mclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 12, 4, 22, -1, -1 },
+	},
+
+	[JZ4740_CLK_LCD] = {
+		"lcd", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PLL_HALF, -1 },
+		.div = { CGU_REG_CPCCR, 16, 5, 22, -1, -1 },
+		.gate_bit = 10,
+	},
+
+	[JZ4740_CLK_LCD_PCLK] = {
+		"lcd_pclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL_HALF, -1 },
+		.div = { CGU_REG_LPCDR, 0, 11, -1, -1, -1 },
+	},
+
+	[JZ4740_CLK_I2S] = {
+		"i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1 },
+		.mux = { CGU_REG_CPCCR, 31, 1 },
+		.div = { CGU_REG_I2SCDR, 0, 8, -1, -1, -1 },
+		.gate_bit = 6,
+	},
+
+	[JZ4740_CLK_SPI] = {
+		"spi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL, -1 },
+		.mux = { CGU_REG_SSICDR, 31, 1 },
+		.div = { CGU_REG_SSICDR, 0, 4, -1, -1, -1 },
+		.gate_bit = 4,
+	},
+
+	[JZ4740_CLK_MMC] = {
+		"mmc", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PLL_HALF, -1 },
+		.div = { CGU_REG_MSCCDR, 0, 5, -1, -1, -1 },
+		.gate_bit = 7,
+	},
+
+	[JZ4740_CLK_UHC] = {
+		"uhc", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PLL_HALF, -1 },
+		.div = { CGU_REG_UHCCDR, 0, 4, -1, -1, -1 },
+		.gate_bit = 14,
+	},
+
+	[JZ4740_CLK_UDC] = {
+		"udc", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1 },
+		.mux = { CGU_REG_CPCCR, 29, 1 },
+		.div = { CGU_REG_CPCCR, 23, 6, -1, -1, -1 },
+		/* TODO: gate via SCR */
+	},
+
+	/* Gate-only clocks */
+
+	[JZ4740_CLK_UART0] = {
+		"uart0", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 0,
+	},
+
+	[JZ4740_CLK_UART1] = {
+		"uart1", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 15,
+	},
+
+	[JZ4740_CLK_DMA] = {
+		"dma", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PCLK, -1 },
+		.gate_bit = 12,
+	},
+
+	[JZ4740_CLK_IPU] = {
+		"ipu", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PCLK, -1 },
+		.gate_bit = 13,
+	},
+
+	[JZ4740_CLK_ADC] = {
+		"adc", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 8,
+	},
+
+	[JZ4740_CLK_I2C] = {
+		"i2c", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 3,
+	},
+
+	[JZ4740_CLK_AIC] = {
+		"aic", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 5,
+	},
+};
+
+static void __init jz4740_cgu_init(struct device_node *np)
+{
+	int retval;
+	cgu = jz47xx_cgu_new(jz4740_cgu_clocks, ARRAY_SIZE(jz4740_cgu_clocks),
+			     np);
+	if (!cgu)
+		pr_err("%s: failed to initialise CGU\n", __func__);
+
+	retval = jz47xx_cgu_register_clocks(cgu);
+	if (retval)
+		pr_err("%s: failed to register CGU Clocks\n", __func__);
+}
+CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init);
-- 
1.9.1


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

* [PATCH_V2 16/34] MIPS: clk: migrate jz4740 to common clock framework
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Migrate the jz4740 & the qi_lb60 board to use common clock framework
via the new jz74xx-cgu driver.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>

---
V2 Removed FSF address
---
 arch/mips/Kconfig                |   2 +-
 arch/mips/boot/dts/jz4740.dtsi   |  23 ++
 arch/mips/boot/dts/qi_lb60.dts   |   4 +
 arch/mips/jz4740/Makefile        |   2 -
 arch/mips/jz4740/board-qi_lb60.c |   5 -
 arch/mips/jz4740/clock-debugfs.c | 108 ------
 arch/mips/jz4740/clock.c         | 801 +--------------------------------------
 arch/mips/jz4740/clock.h         |  53 +--
 arch/mips/jz4740/time.c          |   2 +
 drivers/clk/jz47xx/Makefile      |   1 +
 drivers/clk/jz47xx/jz4740-cgu.c  | 219 +++++++++++
 11 files changed, 252 insertions(+), 968 deletions(-)
 delete mode 100644 arch/mips/jz4740/clock-debugfs.c
 create mode 100644 drivers/clk/jz47xx/jz4740-cgu.c

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 99d50cd..8b377a7 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -286,7 +286,7 @@ config MACH_JZ4740
 	select IRQ_CPU
 	select ARCH_REQUIRE_GPIOLIB
 	select SYS_HAS_EARLY_PRINTK
-	select HAVE_CLK
+	select COMMON_CLK
 	select GENERIC_IRQ_CHIP
 	select BUILTIN_DTB
 	select USE_OF
diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
index 3841024..ef679b4 100644
--- a/arch/mips/boot/dts/jz4740.dtsi
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -1,3 +1,5 @@
+#include <dt-bindings/clock/jz4740-cgu.h>
+
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
@@ -20,4 +22,25 @@
 		interrupt-parent = <&cpuintc>;
 		interrupts = <2>;
 	};
+
+	ext: ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+	};
+
+	rtc: rtc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	cgu: jz4740-cgu@10000000 {
+		compatible = "ingenic,jz4740-cgu";
+		reg = <0x10000000 0x100>;
+
+		clocks = <&ext>, <&rtc>;
+		clock-names = "ext", "rtc";
+
+		#clock-cells = <1>;
+	};
 };
diff --git a/arch/mips/boot/dts/qi_lb60.dts b/arch/mips/boot/dts/qi_lb60.dts
index 0c0f639..106d13c 100644
--- a/arch/mips/boot/dts/qi_lb60.dts
+++ b/arch/mips/boot/dts/qi_lb60.dts
@@ -5,3 +5,7 @@
 / {
 	compatible = "qi,lb60", "ingenic,jz4740";
 };
+
+&ext {
+	clock-frequency = <12000000>;
+};
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 28e5535..80e326d 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -7,8 +7,6 @@
 obj-y += prom.o irq.o time.o reset.o setup.o \
 	gpio.o clock.o platform.o timer.o serial.o
 
-obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
-
 # board specific support
 
 obj-$(CONFIG_JZ4740_QI_LB60)	+= board-qi_lb60.o
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index c454525..0fbb2d8 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -488,11 +488,6 @@ static int __init qi_lb60_init_platform_devices(void)
 
 }
 
-struct jz4740_clock_board_data jz4740_clock_bdata = {
-	.ext_rate = 12000000,
-	.rtc_rate = 32768,
-};
-
 static __init int board_avt2(char *str)
 {
 	qi_lb60_mmc_pdata.card_detect_active_low = 1;
diff --git a/arch/mips/jz4740/clock-debugfs.c b/arch/mips/jz4740/clock-debugfs.c
deleted file mode 100644
index 325422d0..0000000
--- a/arch/mips/jz4740/clock-debugfs.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC clock support debugfs entries
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General	 Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <linux/debugfs.h>
-#include <linux/uaccess.h>
-
-#include <asm/mach-jz4740/clock.h>
-#include "clock.h"
-
-static struct dentry *jz4740_clock_debugfs;
-
-static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
-{
-	struct clk *clk = data;
-	*value = clk_is_enabled(clk);
-
-	return 0;
-}
-
-static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
-{
-	struct clk *clk = data;
-
-	if (value)
-		return clk_enable(clk);
-	else
-		clk_disable(clk);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
-	jz4740_clock_debugfs_show_enabled,
-	jz4740_clock_debugfs_set_enabled,
-	"%llu\n");
-
-static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
-{
-	struct clk *clk = data;
-	*value = clk_get_rate(clk);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
-	jz4740_clock_debugfs_show_rate,
-	NULL,
-	"%llu\n");
-
-void jz4740_clock_debugfs_add_clk(struct clk *clk)
-{
-	if (!jz4740_clock_debugfs)
-		return;
-
-	clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
-	debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
-				&jz4740_clock_debugfs_ops_rate);
-	debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
-				&jz4740_clock_debugfs_ops_enabled);
-
-	if (clk->parent) {
-		char parent_path[100];
-		snprintf(parent_path, 100, "../%s", clk->parent->name);
-		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
-						clk->debugfs_entry,
-						parent_path);
-	}
-}
-
-/* TODO: Locking */
-void jz4740_clock_debugfs_update_parent(struct clk *clk)
-{
-	debugfs_remove(clk->debugfs_parent_entry);
-
-	if (clk->parent) {
-		char parent_path[100];
-		snprintf(parent_path, 100, "../%s", clk->parent->name);
-		clk->debugfs_parent_entry = debugfs_create_symlink("parent",
-						clk->debugfs_entry,
-						parent_path);
-	} else {
-		clk->debugfs_parent_entry = NULL;
-	}
-}
-
-void jz4740_clock_debugfs_init(void)
-{
-	jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
-	if (IS_ERR(jz4740_clock_debugfs))
-		jz4740_clock_debugfs = NULL;
-}
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
index c257073..dedee7c 100644
--- a/arch/mips/jz4740/clock.c
+++ b/arch/mips/jz4740/clock.c
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -27,820 +28,44 @@
 
 #include "clock.h"
 
-#define JZ_REG_CLOCK_CTRL	0x00
 #define JZ_REG_CLOCK_LOW_POWER	0x04
 #define JZ_REG_CLOCK_PLL	0x10
 #define JZ_REG_CLOCK_GATE	0x20
-#define JZ_REG_CLOCK_SLEEP_CTRL 0x24
-#define JZ_REG_CLOCK_I2S	0x60
-#define JZ_REG_CLOCK_LCD	0x64
-#define JZ_REG_CLOCK_MMC	0x68
-#define JZ_REG_CLOCK_UHC	0x6C
-#define JZ_REG_CLOCK_SPI	0x74
-
-#define JZ_CLOCK_CTRL_I2S_SRC_PLL	BIT(31)
-#define JZ_CLOCK_CTRL_KO_ENABLE		BIT(30)
-#define JZ_CLOCK_CTRL_UDC_SRC_PLL	BIT(29)
-#define JZ_CLOCK_CTRL_UDIV_MASK		0x1f800000
-#define JZ_CLOCK_CTRL_CHANGE_ENABLE	BIT(22)
-#define JZ_CLOCK_CTRL_PLL_HALF		BIT(21)
-#define JZ_CLOCK_CTRL_LDIV_MASK		0x001f0000
-#define JZ_CLOCK_CTRL_UDIV_OFFSET	23
-#define JZ_CLOCK_CTRL_LDIV_OFFSET	16
-#define JZ_CLOCK_CTRL_MDIV_OFFSET	12
-#define JZ_CLOCK_CTRL_PDIV_OFFSET	 8
-#define JZ_CLOCK_CTRL_HDIV_OFFSET	 4
-#define JZ_CLOCK_CTRL_CDIV_OFFSET	 0
 
 #define JZ_CLOCK_GATE_UART0	BIT(0)
 #define JZ_CLOCK_GATE_TCU	BIT(1)
-#define JZ_CLOCK_GATE_RTC	BIT(2)
-#define JZ_CLOCK_GATE_I2C	BIT(3)
-#define JZ_CLOCK_GATE_SPI	BIT(4)
-#define JZ_CLOCK_GATE_AIC	BIT(5)
-#define JZ_CLOCK_GATE_I2S	BIT(6)
-#define JZ_CLOCK_GATE_MMC	BIT(7)
-#define JZ_CLOCK_GATE_ADC	BIT(8)
-#define JZ_CLOCK_GATE_CIM	BIT(9)
-#define JZ_CLOCK_GATE_LCD	BIT(10)
 #define JZ_CLOCK_GATE_UDC	BIT(11)
 #define JZ_CLOCK_GATE_DMAC	BIT(12)
-#define JZ_CLOCK_GATE_IPU	BIT(13)
-#define JZ_CLOCK_GATE_UHC	BIT(14)
-#define JZ_CLOCK_GATE_UART1	BIT(15)
-
-#define JZ_CLOCK_I2S_DIV_MASK		0x01ff
-
-#define JZ_CLOCK_LCD_DIV_MASK		0x01ff
-
-#define JZ_CLOCK_MMC_DIV_MASK		0x001f
 
-#define JZ_CLOCK_UHC_DIV_MASK		0x000f
-
-#define JZ_CLOCK_SPI_SRC_PLL		BIT(31)
-#define JZ_CLOCK_SPI_DIV_MASK		0x000f
-
-#define JZ_CLOCK_PLL_M_MASK		0x01ff
-#define JZ_CLOCK_PLL_N_MASK		0x001f
-#define JZ_CLOCK_PLL_OD_MASK		0x0003
 #define JZ_CLOCK_PLL_STABLE		BIT(10)
-#define JZ_CLOCK_PLL_BYPASS		BIT(9)
 #define JZ_CLOCK_PLL_ENABLED		BIT(8)
-#define JZ_CLOCK_PLL_STABLIZE_MASK	0x000f
-#define JZ_CLOCK_PLL_M_OFFSET		23
-#define JZ_CLOCK_PLL_N_OFFSET		18
-#define JZ_CLOCK_PLL_OD_OFFSET		16
 
 #define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
 #define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
 
-#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
-#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
-
 static void __iomem *jz_clock_base;
-static spinlock_t jz_clock_lock;
-static LIST_HEAD(jz_clocks);
-
-struct main_clk {
-	struct clk clk;
-	uint32_t div_offset;
-};
-
-struct divided_clk {
-	struct clk clk;
-	uint32_t reg;
-	uint32_t mask;
-};
-
-struct static_clk {
-	struct clk clk;
-	unsigned long rate;
-};
 
 static uint32_t jz_clk_reg_read(int reg)
 {
 	return readl(jz_clock_base + reg);
 }
 
-static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
-{
-	uint32_t val2;
-
-	spin_lock(&jz_clock_lock);
-	val2 = readl(jz_clock_base + reg);
-	val2 &= ~mask;
-	val2 |= val;
-	writel(val2, jz_clock_base + reg);
-	spin_unlock(&jz_clock_lock);
-}
-
 static void jz_clk_reg_set_bits(int reg, uint32_t mask)
 {
 	uint32_t val;
 
-	spin_lock(&jz_clock_lock);
 	val = readl(jz_clock_base + reg);
 	val |= mask;
 	writel(val, jz_clock_base + reg);
-	spin_unlock(&jz_clock_lock);
 }
 
 static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
 {
 	uint32_t val;
 
-	spin_lock(&jz_clock_lock);
 	val = readl(jz_clock_base + reg);
 	val &= ~mask;
 	writel(val, jz_clock_base + reg);
-	spin_unlock(&jz_clock_lock);
-}
-
-static int jz_clk_enable_gating(struct clk *clk)
-{
-	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
-		return -EINVAL;
-
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
-	return 0;
-}
-
-static int jz_clk_disable_gating(struct clk *clk)
-{
-	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
-		return -EINVAL;
-
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
-	return 0;
-}
-
-static int jz_clk_is_enabled_gating(struct clk *clk)
-{
-	if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
-		return 1;
-
-	return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
-}
-
-static unsigned long jz_clk_static_get_rate(struct clk *clk)
-{
-	return ((struct static_clk *)clk)->rate;
-}
-
-static int jz_clk_ko_enable(struct clk *clk)
-{
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
-	return 0;
-}
-
-static int jz_clk_ko_disable(struct clk *clk)
-{
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
-	return 0;
-}
-
-static int jz_clk_ko_is_enabled(struct clk *clk)
-{
-	return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
-}
-
-static const int pllno[] = {1, 2, 2, 4};
-
-static unsigned long jz_clk_pll_get_rate(struct clk *clk)
-{
-	uint32_t val;
-	int m;
-	int n;
-	int od;
-
-	val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
-
-	if (val & JZ_CLOCK_PLL_BYPASS)
-		return clk_get_rate(clk->parent);
-
-	m = ((val >> 23) & 0x1ff) + 2;
-	n = ((val >> 18) & 0x1f) + 2;
-	od = (val >> 16) & 0x3;
-
-	return ((clk_get_rate(clk->parent) / n) * m) / pllno[od];
-}
-
-static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
-{
-	uint32_t reg;
-
-	reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
-	if (reg & JZ_CLOCK_CTRL_PLL_HALF)
-		return jz_clk_pll_get_rate(clk->parent);
-	return jz_clk_pll_get_rate(clk->parent) >> 1;
-}
-
-static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
-
-static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
-	int div;
-
-	div = parent_rate / rate;
-	if (div > 32)
-		return parent_rate / 32;
-	else if (div < 1)
-		return parent_rate;
-
-	div &= (0x3 << (ffs(div) - 1));
-
-	return parent_rate / div;
-}
-
-static unsigned long jz_clk_main_get_rate(struct clk *clk)
-{
-	struct main_clk *mclk = (struct main_clk *)clk;
-	uint32_t div;
-
-	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
-
-	div >>= mclk->div_offset;
-	div &= 0xf;
-
-	if (div >= ARRAY_SIZE(jz_clk_main_divs))
-		div = ARRAY_SIZE(jz_clk_main_divs) - 1;
-
-	return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
-}
-
-static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
-{
-	struct main_clk *mclk = (struct main_clk *)clk;
-	int i;
-	int div;
-	unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
-
-	rate = jz_clk_main_round_rate(clk, rate);
-
-	div = parent_rate / rate;
-
-	i = (ffs(div) - 1) << 1;
-	if (i > 0 && !(div & BIT(i-1)))
-		i -= 1;
-
-	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
-				0xf << mclk->div_offset);
-
-	return 0;
-}
-
-static struct clk_ops jz_clk_static_ops = {
-	.get_rate = jz_clk_static_get_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct static_clk jz_clk_ext = {
-	.clk = {
-		.name = "ext",
-		.gate_bit = JZ4740_CLK_NOT_GATED,
-		.ops = &jz_clk_static_ops,
-	},
-};
-
-static struct clk_ops jz_clk_pll_ops = {
-	.get_rate = jz_clk_pll_get_rate,
-};
-
-static struct clk jz_clk_pll = {
-	.name = "pll",
-	.parent = &jz_clk_ext.clk,
-	.ops = &jz_clk_pll_ops,
-};
-
-static struct clk_ops jz_clk_pll_half_ops = {
-	.get_rate = jz_clk_pll_half_get_rate,
-};
-
-static struct clk jz_clk_pll_half = {
-	.name = "pll half",
-	.parent = &jz_clk_pll,
-	.ops = &jz_clk_pll_half_ops,
-};
-
-static const struct clk_ops jz_clk_main_ops = {
-	.get_rate = jz_clk_main_get_rate,
-	.set_rate = jz_clk_main_set_rate,
-	.round_rate = jz_clk_main_round_rate,
-};
-
-static struct main_clk jz_clk_cpu = {
-	.clk = {
-		.name = "cclk",
-		.parent = &jz_clk_pll,
-		.ops = &jz_clk_main_ops,
-	},
-	.div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
-};
-
-static struct main_clk jz_clk_memory = {
-	.clk = {
-		.name = "mclk",
-		.parent = &jz_clk_pll,
-		.ops = &jz_clk_main_ops,
-	},
-	.div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
-};
-
-static struct main_clk jz_clk_high_speed_peripheral = {
-	.clk = {
-		.name = "hclk",
-		.parent = &jz_clk_pll,
-		.ops = &jz_clk_main_ops,
-	},
-	.div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
-};
-
-
-static struct main_clk jz_clk_low_speed_peripheral = {
-	.clk = {
-		.name = "pclk",
-		.parent = &jz_clk_pll,
-		.ops = &jz_clk_main_ops,
-	},
-	.div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
-};
-
-static const struct clk_ops jz_clk_ko_ops = {
-	.enable = jz_clk_ko_enable,
-	.disable = jz_clk_ko_disable,
-	.is_enabled = jz_clk_ko_is_enabled,
-};
-
-static struct clk jz_clk_ko = {
-	.name = "cko",
-	.parent = &jz_clk_memory.clk,
-	.ops = &jz_clk_ko_ops,
-};
-
-static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
-{
-	if (parent == &jz_clk_pll)
-		jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
-	else if (parent == &jz_clk_ext.clk)
-		jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	return 0;
-}
-
-static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
-{
-	if (parent == &jz_clk_pll_half)
-		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
-	else if (parent == &jz_clk_ext.clk)
-		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	return 0;
-}
-
-static int jz_clk_udc_enable(struct clk *clk)
-{
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
-			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
-
-	return 0;
-}
-
-static int jz_clk_udc_disable(struct clk *clk)
-{
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
-			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
-
-	return 0;
-}
-
-static int jz_clk_udc_is_enabled(struct clk *clk)
-{
-	return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
-			JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
-}
-
-static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
-{
-	if (parent == &jz_clk_pll_half)
-		jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
-	else if (parent == &jz_clk_ext.clk)
-		jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	return 0;
-}
-
-static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
-{
-	int div;
-
-	if (clk->parent == &jz_clk_ext.clk)
-		return -EINVAL;
-
-	div = clk_get_rate(clk->parent) / rate - 1;
-
-	if (div < 0)
-		div = 0;
-	else if (div > 63)
-		div = 63;
-
-	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
-				JZ_CLOCK_CTRL_UDIV_MASK);
-	return 0;
-}
-
-static unsigned long jz_clk_udc_get_rate(struct clk *clk)
-{
-	int div;
-
-	if (clk->parent == &jz_clk_ext.clk)
-		return clk_get_rate(clk->parent);
-
-	div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
-	div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
-	div += 1;
-
-	return clk_get_rate(clk->parent) / div;
-}
-
-static unsigned long jz_clk_divided_get_rate(struct clk *clk)
-{
-	struct divided_clk *dclk = (struct divided_clk *)clk;
-	int div;
-
-	if (clk->parent == &jz_clk_ext.clk)
-		return clk_get_rate(clk->parent);
-
-	div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
-
-	return clk_get_rate(clk->parent) / div;
-}
-
-static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
-{
-	struct divided_clk *dclk = (struct divided_clk *)clk;
-	int div;
-
-	if (clk->parent == &jz_clk_ext.clk)
-		return -EINVAL;
-
-	div = clk_get_rate(clk->parent) / rate - 1;
-
-	if (div < 0)
-		div = 0;
-	else if (div > dclk->mask)
-		div = dclk->mask;
-
-	jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
-
-	return 0;
-}
-
-static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
-{
-	int div;
-	unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
-
-	if (rate > 150000000)
-		return 150000000;
-
-	div = parent_rate / rate;
-	if (div < 1)
-		div = 1;
-	else if (div > 32)
-		div = 32;
-
-	return parent_rate / div;
-}
-
-static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int div;
-
-	if (rate > 150000000)
-		return -EINVAL;
-
-	div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
-	if (div < 0)
-		div = 0;
-	else if (div > 31)
-		div = 31;
-
-	jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
-				JZ_CLOCK_CTRL_LDIV_MASK);
-
-	return 0;
-}
-
-static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
-{
-	int div;
-
-	div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
-	div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
-
-	return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
-}
-
-static const struct clk_ops jz_clk_ops_ld = {
-	.set_rate = jz_clk_ldclk_set_rate,
-	.get_rate = jz_clk_ldclk_get_rate,
-	.round_rate = jz_clk_ldclk_round_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct clk jz_clk_ld = {
-	.name = "lcd",
-	.gate_bit = JZ_CLOCK_GATE_LCD,
-	.parent = &jz_clk_pll_half,
-	.ops = &jz_clk_ops_ld,
-};
-
-static const struct clk_ops jz_clk_i2s_ops = {
-	.set_rate = jz_clk_divided_set_rate,
-	.get_rate = jz_clk_divided_get_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-	.set_parent = jz_clk_i2s_set_parent,
-};
-
-static const struct clk_ops jz_clk_spi_ops = {
-	.set_rate = jz_clk_divided_set_rate,
-	.get_rate = jz_clk_divided_get_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-	.set_parent = jz_clk_spi_set_parent,
-};
-
-static const struct clk_ops jz_clk_divided_ops = {
-	.set_rate = jz_clk_divided_set_rate,
-	.get_rate = jz_clk_divided_get_rate,
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct divided_clk jz4740_clock_divided_clks[] = {
-	[0] = {
-		.clk = {
-			.name = "i2s",
-			.parent = &jz_clk_ext.clk,
-			.gate_bit = JZ_CLOCK_GATE_I2S,
-			.ops = &jz_clk_i2s_ops,
-		},
-		.reg = JZ_REG_CLOCK_I2S,
-		.mask = JZ_CLOCK_I2S_DIV_MASK,
-	},
-	[1] = {
-		.clk = {
-			.name = "spi",
-			.parent = &jz_clk_ext.clk,
-			.gate_bit = JZ_CLOCK_GATE_SPI,
-			.ops = &jz_clk_spi_ops,
-		},
-		.reg = JZ_REG_CLOCK_SPI,
-		.mask = JZ_CLOCK_SPI_DIV_MASK,
-	},
-	[2] = {
-		.clk = {
-			.name = "lcd_pclk",
-			.parent = &jz_clk_pll_half,
-			.gate_bit = JZ4740_CLK_NOT_GATED,
-			.ops = &jz_clk_divided_ops,
-		},
-		.reg = JZ_REG_CLOCK_LCD,
-		.mask = JZ_CLOCK_LCD_DIV_MASK,
-	},
-	[3] = {
-		.clk = {
-			.name = "mmc",
-			.parent = &jz_clk_pll_half,
-			.gate_bit = JZ_CLOCK_GATE_MMC,
-			.ops = &jz_clk_divided_ops,
-		},
-		.reg = JZ_REG_CLOCK_MMC,
-		.mask = JZ_CLOCK_MMC_DIV_MASK,
-	},
-	[4] = {
-		.clk = {
-			.name = "uhc",
-			.parent = &jz_clk_pll_half,
-			.gate_bit = JZ_CLOCK_GATE_UHC,
-			.ops = &jz_clk_divided_ops,
-		},
-		.reg = JZ_REG_CLOCK_UHC,
-		.mask = JZ_CLOCK_UHC_DIV_MASK,
-	},
-};
-
-static const struct clk_ops jz_clk_udc_ops = {
-	.set_parent = jz_clk_udc_set_parent,
-	.set_rate = jz_clk_udc_set_rate,
-	.get_rate = jz_clk_udc_get_rate,
-	.enable = jz_clk_udc_enable,
-	.disable = jz_clk_udc_disable,
-	.is_enabled = jz_clk_udc_is_enabled,
-};
-
-static const struct clk_ops jz_clk_simple_ops = {
-	.enable = jz_clk_enable_gating,
-	.disable = jz_clk_disable_gating,
-	.is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct clk jz4740_clock_simple_clks[] = {
-	[0] = {
-		.name = "udc",
-		.parent = &jz_clk_ext.clk,
-		.ops = &jz_clk_udc_ops,
-	},
-	[1] = {
-		.name = "uart0",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_UART0,
-		.ops = &jz_clk_simple_ops,
-	},
-	[2] = {
-		.name = "uart1",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_UART1,
-		.ops = &jz_clk_simple_ops,
-	},
-	[3] = {
-		.name = "dma",
-		.parent = &jz_clk_high_speed_peripheral.clk,
-		.gate_bit = JZ_CLOCK_GATE_DMAC,
-		.ops = &jz_clk_simple_ops,
-	},
-	[4] = {
-		.name = "ipu",
-		.parent = &jz_clk_high_speed_peripheral.clk,
-		.gate_bit = JZ_CLOCK_GATE_IPU,
-		.ops = &jz_clk_simple_ops,
-	},
-	[5] = {
-		.name = "adc",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_ADC,
-		.ops = &jz_clk_simple_ops,
-	},
-	[6] = {
-		.name = "i2c",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_I2C,
-		.ops = &jz_clk_simple_ops,
-	},
-	[7] = {
-		.name = "aic",
-		.parent = &jz_clk_ext.clk,
-		.gate_bit = JZ_CLOCK_GATE_AIC,
-		.ops = &jz_clk_simple_ops,
-	},
-};
-
-static struct static_clk jz_clk_rtc = {
-	.clk = {
-		.name = "rtc",
-		.gate_bit = JZ_CLOCK_GATE_RTC,
-		.ops = &jz_clk_static_ops,
-	},
-	.rate = 32768,
-};
-
-int clk_enable(struct clk *clk)
-{
-	if (!clk->ops->enable)
-		return -EINVAL;
-
-	return clk->ops->enable(clk);
-}
-EXPORT_SYMBOL_GPL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-	if (clk->ops->disable)
-		clk->ops->disable(clk);
-}
-EXPORT_SYMBOL_GPL(clk_disable);
-
-int clk_is_enabled(struct clk *clk)
-{
-	if (clk->ops->is_enabled)
-		return clk->ops->is_enabled(clk);
-
-	return 1;
-}
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (clk->ops->get_rate)
-		return clk->ops->get_rate(clk);
-	if (clk->parent)
-		return clk_get_rate(clk->parent);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(clk_get_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	if (!clk->ops->set_rate)
-		return -EINVAL;
-	return clk->ops->set_rate(clk, rate);
-}
-EXPORT_SYMBOL_GPL(clk_set_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (clk->ops->round_rate)
-		return clk->ops->round_rate(clk, rate);
-
-	return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(clk_round_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	int ret;
-	int enabled;
-
-	if (!clk->ops->set_parent)
-		return -EINVAL;
-
-	enabled = clk_is_enabled(clk);
-	if (enabled)
-		clk_disable(clk);
-	ret = clk->ops->set_parent(clk, parent);
-	if (enabled)
-		clk_enable(clk);
-
-	jz4740_clock_debugfs_update_parent(clk);
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(clk_set_parent);
-
-struct clk *clk_get(struct device *dev, const char *name)
-{
-	struct clk *clk;
-
-	list_for_each_entry(clk, &jz_clocks, list) {
-		if (strcmp(clk->name, name) == 0)
-			return clk;
-	}
-	return ERR_PTR(-ENXIO);
-}
-EXPORT_SYMBOL_GPL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL_GPL(clk_put);
-
-static inline void clk_add(struct clk *clk)
-{
-	list_add_tail(&clk->list, &jz_clocks);
-
-	jz4740_clock_debugfs_add_clk(clk);
-}
-
-static void clk_register_clks(void)
-{
-	size_t i;
-
-	clk_add(&jz_clk_ext.clk);
-	clk_add(&jz_clk_pll);
-	clk_add(&jz_clk_pll_half);
-	clk_add(&jz_clk_cpu.clk);
-	clk_add(&jz_clk_high_speed_peripheral.clk);
-	clk_add(&jz_clk_low_speed_peripheral.clk);
-	clk_add(&jz_clk_ko);
-	clk_add(&jz_clk_ld);
-	clk_add(&jz_clk_rtc.clk);
-
-	for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
-		clk_add(&jz4740_clock_divided_clks[i].clk);
-
-	for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
-		clk_add(&jz4740_clock_simple_clks[i]);
 }
 
 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
@@ -891,33 +116,9 @@ void jz4740_clock_resume(void)
 
 int jz4740_clock_init(void)
 {
-	uint32_t val;
-
 	jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
 	if (!jz_clock_base)
 		return -EBUSY;
 
-	spin_lock_init(&jz_clock_lock);
-
-	jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
-	jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
-
-	val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
-
-	if (val & JZ_CLOCK_SPI_SRC_PLL)
-		jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
-
-	val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
-
-	if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
-		jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
-
-	if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
-		jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
-
-	jz4740_clock_debugfs_init();
-
-	clk_register_clks();
-
 	return 0;
 }
diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
index 5d07499..86a3e01 100644
--- a/arch/mips/jz4740/clock.h
+++ b/arch/mips/jz4740/clock.h
@@ -16,61 +16,10 @@
 #ifndef __MIPS_JZ4740_CLOCK_H__
 #define __MIPS_JZ4740_CLOCK_H__
 
+#include <linux/clk.h>
 #include <linux/list.h>
 
-struct jz4740_clock_board_data {
-	unsigned long ext_rate;
-	unsigned long rtc_rate;
-};
-
-extern struct jz4740_clock_board_data jz4740_clock_bdata;
-
 void jz4740_clock_suspend(void);
 void jz4740_clock_resume(void);
 
-struct clk;
-
-struct clk_ops {
-	unsigned long (*get_rate)(struct clk *clk);
-	unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
-	int (*set_rate)(struct clk *clk, unsigned long rate);
-	int (*enable)(struct clk *clk);
-	int (*disable)(struct clk *clk);
-	int (*is_enabled)(struct clk *clk);
-
-	int (*set_parent)(struct clk *clk, struct clk *parent);
-
-};
-
-struct clk {
-	const char *name;
-	struct clk *parent;
-
-	uint32_t gate_bit;
-
-	const struct clk_ops *ops;
-
-	struct list_head list;
-
-#ifdef CONFIG_DEBUG_FS
-	struct dentry *debugfs_entry;
-	struct dentry *debugfs_parent_entry;
-#endif
-
-};
-
-#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
-
-int clk_is_enabled(struct clk *clk);
-
-#ifdef CONFIG_DEBUG_FS
-void jz4740_clock_debugfs_init(void);
-void jz4740_clock_debugfs_add_clk(struct clk *clk);
-void jz4740_clock_debugfs_update_parent(struct clk *clk);
-#else
-static inline void jz4740_clock_debugfs_init(void) {};
-static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
-static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
-#endif
-
 #endif
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index bff2ac9..caa796d 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -14,6 +14,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
@@ -112,6 +113,7 @@ void __init plat_time_init(void)
 	uint16_t ctrl;
 	struct clk *ext_clk;
 
+	of_clk_init(NULL);
 	jz4740_clock_init();
 	jz4740_timer_init();
 
diff --git a/drivers/clk/jz47xx/Makefile b/drivers/clk/jz47xx/Makefile
index ac594e5..21746fc 100644
--- a/drivers/clk/jz47xx/Makefile
+++ b/drivers/clk/jz47xx/Makefile
@@ -1 +1,2 @@
 obj-y				+= jz47xx-cgu.o
+obj-$(CONFIG_MACH_JZ4740)	+= jz4740-cgu.o
diff --git a/drivers/clk/jz47xx/jz4740-cgu.c b/drivers/clk/jz47xx/jz4740-cgu.c
new file mode 100644
index 0000000..83f1e1f
--- /dev/null
+++ b/drivers/clk/jz47xx/jz4740-cgu.c
@@ -0,0 +1,219 @@
+/*
+ * Ingenic jz4740 SoC CGU driver
+ *
+ * Copyright (c) 2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <dt-bindings/clock/jz4740-cgu.h>
+#include "jz47xx-cgu.h"
+
+/* CGU register offsets */
+#define CGU_REG_CPCCR		0x00
+#define CGU_REG_CPPCR		0x10
+#define CGU_REG_I2SCDR		0x60
+#define CGU_REG_LPCDR		0x64
+#define CGU_REG_MSCCDR		0x68
+#define CGU_REG_UHCCDR		0x6c
+#define CGU_REG_SSICDR		0x74
+
+/* bits within a PLL control register */
+#define PLLCTL_M_SHIFT		23
+#define PLLCTL_M_MASK		(0x1ff << PLLCTL_M_SHIFT)
+#define PLLCTL_N_SHIFT		18
+#define PLLCTL_N_MASK		(0x1f << PLLCTL_N_SHIFT)
+#define PLLCTL_OD_SHIFT		16
+#define PLLCTL_OD_MASK		(0x3 << PLLCTL_OD_SHIFT)
+#define PLLCTL_STABLE		(1 << 10)
+#define PLLCTL_BYPASS		(1 << 9)
+#define PLLCTL_ENABLE		(1 << 8)
+
+static struct jz47xx_cgu *cgu;
+
+static const s8 pll_od_encoding[4] = {
+	0x0, 0x1, -1, 0x3,
+};
+
+static const struct jz47xx_cgu_clk_info jz4740_cgu_clocks[] = {
+
+	/* External clocks */
+
+	[JZ4740_CLK_EXT] = { "ext", CGU_CLK_EXT },
+	[JZ4740_CLK_RTC] = { "rtc", CGU_CLK_EXT },
+
+	[JZ4740_CLK_PLL] = {
+		"pll", CGU_CLK_PLL,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.pll = {
+			.reg = CGU_REG_CPPCR,
+			.m_shift = 23,
+			.m_bits = 9,
+			.m_offset = 2,
+			.n_shift = 18,
+			.n_bits = 5,
+			.n_offset = 2,
+			.od_shift = 16,
+			.od_bits = 2,
+			.od_max = 4,
+			.od_encoding = pll_od_encoding,
+			.stable_bit = 10,
+			.bypass_bit = 9,
+			.enable_bit = 8,
+		},
+	},
+
+	/* Muxes & dividers */
+
+	[JZ4740_CLK_PLL_HALF] = {
+		"pll half", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 21, 1, -1, -1, -1 },
+	},
+
+	[JZ4740_CLK_CCLK] = {
+		"cclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 0, 4, 22, -1, -1 },
+	},
+
+	[JZ4740_CLK_HCLK] = {
+		"hclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 4, 4, 22, -1, -1 },
+	},
+
+	[JZ4740_CLK_PCLK] = {
+		"pclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 8, 4, 22, -1, -1 },
+	},
+
+	[JZ4740_CLK_MCLK] = {
+		"mclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL, -1 },
+		.div = { CGU_REG_CPCCR, 12, 4, 22, -1, -1 },
+	},
+
+	[JZ4740_CLK_LCD] = {
+		"lcd", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PLL_HALF, -1 },
+		.div = { CGU_REG_CPCCR, 16, 5, 22, -1, -1 },
+		.gate_bit = 10,
+	},
+
+	[JZ4740_CLK_LCD_PCLK] = {
+		"lcd_pclk", CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_PLL_HALF, -1 },
+		.div = { CGU_REG_LPCDR, 0, 11, -1, -1, -1 },
+	},
+
+	[JZ4740_CLK_I2S] = {
+		"i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1 },
+		.mux = { CGU_REG_CPCCR, 31, 1 },
+		.div = { CGU_REG_I2SCDR, 0, 8, -1, -1, -1 },
+		.gate_bit = 6,
+	},
+
+	[JZ4740_CLK_SPI] = {
+		"spi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL, -1 },
+		.mux = { CGU_REG_SSICDR, 31, 1 },
+		.div = { CGU_REG_SSICDR, 0, 4, -1, -1, -1 },
+		.gate_bit = 4,
+	},
+
+	[JZ4740_CLK_MMC] = {
+		"mmc", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PLL_HALF, -1 },
+		.div = { CGU_REG_MSCCDR, 0, 5, -1, -1, -1 },
+		.gate_bit = 7,
+	},
+
+	[JZ4740_CLK_UHC] = {
+		"uhc", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PLL_HALF, -1 },
+		.div = { CGU_REG_UHCCDR, 0, 4, -1, -1, -1 },
+		.gate_bit = 14,
+	},
+
+	[JZ4740_CLK_UDC] = {
+		"udc", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1 },
+		.mux = { CGU_REG_CPCCR, 29, 1 },
+		.div = { CGU_REG_CPCCR, 23, 6, -1, -1, -1 },
+		/* TODO: gate via SCR */
+	},
+
+	/* Gate-only clocks */
+
+	[JZ4740_CLK_UART0] = {
+		"uart0", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 0,
+	},
+
+	[JZ4740_CLK_UART1] = {
+		"uart1", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 15,
+	},
+
+	[JZ4740_CLK_DMA] = {
+		"dma", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PCLK, -1 },
+		.gate_bit = 12,
+	},
+
+	[JZ4740_CLK_IPU] = {
+		"ipu", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_PCLK, -1 },
+		.gate_bit = 13,
+	},
+
+	[JZ4740_CLK_ADC] = {
+		"adc", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 8,
+	},
+
+	[JZ4740_CLK_I2C] = {
+		"i2c", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 3,
+	},
+
+	[JZ4740_CLK_AIC] = {
+		"aic", CGU_CLK_GATE,
+		.parents = { JZ4740_CLK_EXT, -1 },
+		.gate_bit = 5,
+	},
+};
+
+static void __init jz4740_cgu_init(struct device_node *np)
+{
+	int retval;
+	cgu = jz47xx_cgu_new(jz4740_cgu_clocks, ARRAY_SIZE(jz4740_cgu_clocks),
+			     np);
+	if (!cgu)
+		pr_err("%s: failed to initialise CGU\n", __func__);
+
+	retval = jz47xx_cgu_register_clocks(cgu);
+	if (retval)
+		pr_err("%s: failed to register CGU Clocks\n", __func__);
+}
+CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init);
-- 
1.9.1

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

* [PATCH_V2 17/34] MIPS: clk: move jz4740_clock_set_wait_mode to jz4740-cgu
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The jz4740-cgu driver already has access to the CGU, so it makes sense
to move the few remaining accesses to the CGU from arch/mips/jz4740
there too. Move jz4740_clock_set_wait_mode for such consistency.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
---
 arch/mips/jz4740/clock.c        | 16 ----------------
 drivers/clk/jz47xx/jz4740-cgu.c | 22 ++++++++++++++++++++++
 2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
index dedee7c..90b44d7 100644
--- a/arch/mips/jz4740/clock.c
+++ b/arch/mips/jz4740/clock.c
@@ -28,7 +28,6 @@
 
 #include "clock.h"
 
-#define JZ_REG_CLOCK_LOW_POWER	0x04
 #define JZ_REG_CLOCK_PLL	0x10
 #define JZ_REG_CLOCK_GATE	0x20
 
@@ -40,9 +39,6 @@
 #define JZ_CLOCK_PLL_STABLE		BIT(10)
 #define JZ_CLOCK_PLL_ENABLED		BIT(8)
 
-#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
-#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
-
 static void __iomem *jz_clock_base;
 
 static uint32_t jz_clk_reg_read(int reg)
@@ -68,18 +64,6 @@ static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
 	writel(val, jz_clock_base + reg);
 }
 
-void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
-{
-	switch (mode) {
-	case JZ4740_WAIT_MODE_IDLE:
-		jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
-		break;
-	case JZ4740_WAIT_MODE_SLEEP:
-		jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
-		break;
-	}
-}
-
 void jz4740_clock_udc_disable_auto_suspend(void)
 {
 	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
diff --git a/drivers/clk/jz47xx/jz4740-cgu.c b/drivers/clk/jz47xx/jz4740-cgu.c
index 83f1e1f..ef559e7 100644
--- a/drivers/clk/jz47xx/jz4740-cgu.c
+++ b/drivers/clk/jz47xx/jz4740-cgu.c
@@ -20,10 +20,12 @@
 #include <linux/delay.h>
 #include <linux/of.h>
 #include <dt-bindings/clock/jz4740-cgu.h>
+#include <asm/mach-jz4740/clock.h>
 #include "jz47xx-cgu.h"
 
 /* CGU register offsets */
 #define CGU_REG_CPCCR		0x00
+#define CGU_REG_LCR		0x04
 #define CGU_REG_CPPCR		0x10
 #define CGU_REG_I2SCDR		0x60
 #define CGU_REG_LPCDR		0x64
@@ -42,6 +44,9 @@
 #define PLLCTL_BYPASS		(1 << 9)
 #define PLLCTL_ENABLE		(1 << 8)
 
+/* bits within the LCR register */
+#define LCR_SLEEP		(1 << 0)
+
 static struct jz47xx_cgu *cgu;
 
 static const s8 pll_od_encoding[4] = {
@@ -217,3 +222,20 @@ static void __init jz4740_cgu_init(struct device_node *np)
 		pr_err("%s: failed to register CGU Clocks\n", __func__);
 }
 CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init);
+
+void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
+{
+	uint32_t lcr = readl(cgu->base + CGU_REG_LCR);
+
+	switch (mode) {
+	case JZ4740_WAIT_MODE_IDLE:
+		lcr &= ~LCR_SLEEP;
+		break;
+
+	case JZ4740_WAIT_MODE_SLEEP:
+		lcr |= LCR_SLEEP;
+		break;
+	}
+
+	writel(lcr, cgu->base + CGU_REG_LCR);
+}
-- 
1.9.1


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

* [PATCH_V2 17/34] MIPS: clk: move jz4740_clock_set_wait_mode to jz4740-cgu
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The jz4740-cgu driver already has access to the CGU, so it makes sense
to move the few remaining accesses to the CGU from arch/mips/jz4740
there too. Move jz4740_clock_set_wait_mode for such consistency.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
---
 arch/mips/jz4740/clock.c        | 16 ----------------
 drivers/clk/jz47xx/jz4740-cgu.c | 22 ++++++++++++++++++++++
 2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
index dedee7c..90b44d7 100644
--- a/arch/mips/jz4740/clock.c
+++ b/arch/mips/jz4740/clock.c
@@ -28,7 +28,6 @@
 
 #include "clock.h"
 
-#define JZ_REG_CLOCK_LOW_POWER	0x04
 #define JZ_REG_CLOCK_PLL	0x10
 #define JZ_REG_CLOCK_GATE	0x20
 
@@ -40,9 +39,6 @@
 #define JZ_CLOCK_PLL_STABLE		BIT(10)
 #define JZ_CLOCK_PLL_ENABLED		BIT(8)
 
-#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
-#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
-
 static void __iomem *jz_clock_base;
 
 static uint32_t jz_clk_reg_read(int reg)
@@ -68,18 +64,6 @@ static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
 	writel(val, jz_clock_base + reg);
 }
 
-void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
-{
-	switch (mode) {
-	case JZ4740_WAIT_MODE_IDLE:
-		jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
-		break;
-	case JZ4740_WAIT_MODE_SLEEP:
-		jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
-		break;
-	}
-}
-
 void jz4740_clock_udc_disable_auto_suspend(void)
 {
 	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
diff --git a/drivers/clk/jz47xx/jz4740-cgu.c b/drivers/clk/jz47xx/jz4740-cgu.c
index 83f1e1f..ef559e7 100644
--- a/drivers/clk/jz47xx/jz4740-cgu.c
+++ b/drivers/clk/jz47xx/jz4740-cgu.c
@@ -20,10 +20,12 @@
 #include <linux/delay.h>
 #include <linux/of.h>
 #include <dt-bindings/clock/jz4740-cgu.h>
+#include <asm/mach-jz4740/clock.h>
 #include "jz47xx-cgu.h"
 
 /* CGU register offsets */
 #define CGU_REG_CPCCR		0x00
+#define CGU_REG_LCR		0x04
 #define CGU_REG_CPPCR		0x10
 #define CGU_REG_I2SCDR		0x60
 #define CGU_REG_LPCDR		0x64
@@ -42,6 +44,9 @@
 #define PLLCTL_BYPASS		(1 << 9)
 #define PLLCTL_ENABLE		(1 << 8)
 
+/* bits within the LCR register */
+#define LCR_SLEEP		(1 << 0)
+
 static struct jz47xx_cgu *cgu;
 
 static const s8 pll_od_encoding[4] = {
@@ -217,3 +222,20 @@ static void __init jz4740_cgu_init(struct device_node *np)
 		pr_err("%s: failed to register CGU Clocks\n", __func__);
 }
 CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init);
+
+void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
+{
+	uint32_t lcr = readl(cgu->base + CGU_REG_LCR);
+
+	switch (mode) {
+	case JZ4740_WAIT_MODE_IDLE:
+		lcr &= ~LCR_SLEEP;
+		break;
+
+	case JZ4740_WAIT_MODE_SLEEP:
+		lcr |= LCR_SLEEP;
+		break;
+	}
+
+	writel(lcr, cgu->base + CGU_REG_LCR);
+}
-- 
1.9.1

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

* [PATCH_V2 18/34] MIPS: clk: move jz4740 UDC auto suspend functions to jz4740-cgu
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The jz4740-cgu driver already has access to the CGU, so it makes sense
to move the few remaining accesses to the CGU from arch/mips/jz4740
there too. Move the jz4740_clock_udc_{dis,en}able_auto_suspend functions
there for such consistency.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
---
 arch/mips/jz4740/clock.c        | 13 -------------
 drivers/clk/jz47xx/jz4740-cgu.c | 20 ++++++++++++++++++++
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
index 90b44d7..2a10829 100644
--- a/arch/mips/jz4740/clock.c
+++ b/arch/mips/jz4740/clock.c
@@ -33,7 +33,6 @@
 
 #define JZ_CLOCK_GATE_UART0	BIT(0)
 #define JZ_CLOCK_GATE_TCU	BIT(1)
-#define JZ_CLOCK_GATE_UDC	BIT(11)
 #define JZ_CLOCK_GATE_DMAC	BIT(12)
 
 #define JZ_CLOCK_PLL_STABLE		BIT(10)
@@ -64,18 +63,6 @@ static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
 	writel(val, jz_clock_base + reg);
 }
 
-void jz4740_clock_udc_disable_auto_suspend(void)
-{
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
-}
-EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
-
-void jz4740_clock_udc_enable_auto_suspend(void)
-{
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
-}
-EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
-
 void jz4740_clock_suspend(void)
 {
 	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
diff --git a/drivers/clk/jz47xx/jz4740-cgu.c b/drivers/clk/jz47xx/jz4740-cgu.c
index ef559e7..46b6c1a 100644
--- a/drivers/clk/jz47xx/jz4740-cgu.c
+++ b/drivers/clk/jz47xx/jz4740-cgu.c
@@ -27,6 +27,7 @@
 #define CGU_REG_CPCCR		0x00
 #define CGU_REG_LCR		0x04
 #define CGU_REG_CPPCR		0x10
+#define CGU_REG_CLKGR		0x20
 #define CGU_REG_I2SCDR		0x60
 #define CGU_REG_LPCDR		0x64
 #define CGU_REG_MSCCDR		0x68
@@ -47,6 +48,9 @@
 /* bits within the LCR register */
 #define LCR_SLEEP		(1 << 0)
 
+/* bits within the CLKGR register */
+#define CLKGR_UDC		(1 << 11)
+
 static struct jz47xx_cgu *cgu;
 
 static const s8 pll_od_encoding[4] = {
@@ -239,3 +243,19 @@ void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
 
 	writel(lcr, cgu->base + CGU_REG_LCR);
 }
+
+void jz4740_clock_udc_disable_auto_suspend(void)
+{
+	uint32_t clkgr = readl(cgu->base + CGU_REG_CLKGR);
+	clkgr &= ~CLKGR_UDC;
+	writel(clkgr, cgu->base + CGU_REG_CLKGR);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
+
+void jz4740_clock_udc_enable_auto_suspend(void)
+{
+	uint32_t clkgr = readl(cgu->base + CGU_REG_CLKGR);
+	clkgr |= CLKGR_UDC;
+	writel(clkgr, cgu->base + CGU_REG_CLKGR);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
-- 
1.9.1


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

* [PATCH_V2 18/34] MIPS: clk: move jz4740 UDC auto suspend functions to jz4740-cgu
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The jz4740-cgu driver already has access to the CGU, so it makes sense
to move the few remaining accesses to the CGU from arch/mips/jz4740
there too. Move the jz4740_clock_udc_{dis,en}able_auto_suspend functions
there for such consistency.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
---
 arch/mips/jz4740/clock.c        | 13 -------------
 drivers/clk/jz47xx/jz4740-cgu.c | 20 ++++++++++++++++++++
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
index 90b44d7..2a10829 100644
--- a/arch/mips/jz4740/clock.c
+++ b/arch/mips/jz4740/clock.c
@@ -33,7 +33,6 @@
 
 #define JZ_CLOCK_GATE_UART0	BIT(0)
 #define JZ_CLOCK_GATE_TCU	BIT(1)
-#define JZ_CLOCK_GATE_UDC	BIT(11)
 #define JZ_CLOCK_GATE_DMAC	BIT(12)
 
 #define JZ_CLOCK_PLL_STABLE		BIT(10)
@@ -64,18 +63,6 @@ static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
 	writel(val, jz_clock_base + reg);
 }
 
-void jz4740_clock_udc_disable_auto_suspend(void)
-{
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
-}
-EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
-
-void jz4740_clock_udc_enable_auto_suspend(void)
-{
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
-}
-EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
-
 void jz4740_clock_suspend(void)
 {
 	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
diff --git a/drivers/clk/jz47xx/jz4740-cgu.c b/drivers/clk/jz47xx/jz4740-cgu.c
index ef559e7..46b6c1a 100644
--- a/drivers/clk/jz47xx/jz4740-cgu.c
+++ b/drivers/clk/jz47xx/jz4740-cgu.c
@@ -27,6 +27,7 @@
 #define CGU_REG_CPCCR		0x00
 #define CGU_REG_LCR		0x04
 #define CGU_REG_CPPCR		0x10
+#define CGU_REG_CLKGR		0x20
 #define CGU_REG_I2SCDR		0x60
 #define CGU_REG_LPCDR		0x64
 #define CGU_REG_MSCCDR		0x68
@@ -47,6 +48,9 @@
 /* bits within the LCR register */
 #define LCR_SLEEP		(1 << 0)
 
+/* bits within the CLKGR register */
+#define CLKGR_UDC		(1 << 11)
+
 static struct jz47xx_cgu *cgu;
 
 static const s8 pll_od_encoding[4] = {
@@ -239,3 +243,19 @@ void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
 
 	writel(lcr, cgu->base + CGU_REG_LCR);
 }
+
+void jz4740_clock_udc_disable_auto_suspend(void)
+{
+	uint32_t clkgr = readl(cgu->base + CGU_REG_CLKGR);
+	clkgr &= ~CLKGR_UDC;
+	writel(clkgr, cgu->base + CGU_REG_CLKGR);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
+
+void jz4740_clock_udc_enable_auto_suspend(void)
+{
+	uint32_t clkgr = readl(cgu->base + CGU_REG_CLKGR);
+	clkgr |= CLKGR_UDC;
+	writel(clkgr, cgu->base + CGU_REG_CLKGR);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
-- 
1.9.1

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

* [PATCH_V2 19/34] MIPS: clk: move jz4740 clock suspend, resume functions to jz4740-cgu
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The jz4740-cgu driver already has access to the CGU, so it makes sense
to move the few remaining accesses to the CGU from arch/mips/jz4740
there too. Move the jz4740_clock_{suspend,resume} functions there for
such consistency. The arch/mips/jz4740/clock.c file now contains nothing
more of use & so is removed.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
---
 arch/mips/include/asm/mach-jz4740/clock.h |  2 -
 arch/mips/jz4740/Makefile                 |  2 +-
 arch/mips/jz4740/clock.c                  | 95 -------------------------------
 arch/mips/jz4740/time.c                   |  1 -
 drivers/clk/jz47xx/jz4740-cgu.c           | 34 +++++++++++
 5 files changed, 35 insertions(+), 99 deletions(-)
 delete mode 100644 arch/mips/jz4740/clock.c

diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
index 01d8468..16659cd 100644
--- a/arch/mips/include/asm/mach-jz4740/clock.h
+++ b/arch/mips/include/asm/mach-jz4740/clock.h
@@ -20,8 +20,6 @@ enum jz4740_wait_mode {
 	JZ4740_WAIT_MODE_SLEEP,
 };
 
-int jz4740_clock_init(void);
-
 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
 
 void jz4740_clock_udc_enable_auto_suspend(void);
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 80e326d..61168a2 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -5,7 +5,7 @@
 # Object file lists.
 
 obj-y += prom.o irq.o time.o reset.o setup.o \
-	gpio.o clock.o platform.o timer.o serial.o
+	gpio.o platform.o timer.o serial.o
 
 # board specific support
 
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
deleted file mode 100644
index 2a10829..0000000
--- a/arch/mips/jz4740/clock.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC clock support
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General	 Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/list.h>
-#include <linux/err.h>
-
-#include <asm/mach-jz4740/clock.h>
-#include <asm/mach-jz4740/base.h>
-
-#include "clock.h"
-
-#define JZ_REG_CLOCK_PLL	0x10
-#define JZ_REG_CLOCK_GATE	0x20
-
-#define JZ_CLOCK_GATE_UART0	BIT(0)
-#define JZ_CLOCK_GATE_TCU	BIT(1)
-#define JZ_CLOCK_GATE_DMAC	BIT(12)
-
-#define JZ_CLOCK_PLL_STABLE		BIT(10)
-#define JZ_CLOCK_PLL_ENABLED		BIT(8)
-
-static void __iomem *jz_clock_base;
-
-static uint32_t jz_clk_reg_read(int reg)
-{
-	return readl(jz_clock_base + reg);
-}
-
-static void jz_clk_reg_set_bits(int reg, uint32_t mask)
-{
-	uint32_t val;
-
-	val = readl(jz_clock_base + reg);
-	val |= mask;
-	writel(val, jz_clock_base + reg);
-}
-
-static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
-{
-	uint32_t val;
-
-	val = readl(jz_clock_base + reg);
-	val &= ~mask;
-	writel(val, jz_clock_base + reg);
-}
-
-void jz4740_clock_suspend(void)
-{
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
-		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
-
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
-}
-
-void jz4740_clock_resume(void)
-{
-	uint32_t pll;
-
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
-
-	do {
-		pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
-	} while (!(pll & JZ_CLOCK_PLL_STABLE));
-
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
-		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
-}
-
-int jz4740_clock_init(void)
-{
-	jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
-	if (!jz_clock_base)
-		return -EBUSY;
-
-	return 0;
-}
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index caa796d..121ec3a 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -114,7 +114,6 @@ void __init plat_time_init(void)
 	struct clk *ext_clk;
 
 	of_clk_init(NULL);
-	jz4740_clock_init();
 	jz4740_timer_init();
 
 	ext_clk = clk_get(NULL, "ext");
diff --git a/drivers/clk/jz47xx/jz4740-cgu.c b/drivers/clk/jz47xx/jz4740-cgu.c
index 46b6c1a..3325bd8 100644
--- a/drivers/clk/jz47xx/jz4740-cgu.c
+++ b/drivers/clk/jz47xx/jz4740-cgu.c
@@ -259,3 +259,37 @@ void jz4740_clock_udc_enable_auto_suspend(void)
 	writel(clkgr, cgu->base + CGU_REG_CLKGR);
 }
 EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
+
+#define JZ_CLOCK_GATE_UART0	BIT(0)
+#define JZ_CLOCK_GATE_TCU	BIT(1)
+#define JZ_CLOCK_GATE_DMAC	BIT(12)
+
+void jz4740_clock_suspend(void)
+{
+	uint32_t clkgr, cppcr;
+
+	clkgr = readl(cgu->base + CGU_REG_CLKGR);
+	clkgr |= JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0;
+	writel(clkgr, cgu->base + CGU_REG_CLKGR);
+
+	cppcr = readl(cgu->base + CGU_REG_CPPCR);
+	cppcr &= ~BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit);
+	writel(cppcr, cgu->base + CGU_REG_CPPCR);
+}
+
+void jz4740_clock_resume(void)
+{
+	uint32_t clkgr, cppcr;
+
+	cppcr = readl(cgu->base + CGU_REG_CPPCR);
+	cppcr |= BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit);
+	writel(cppcr, cgu->base + CGU_REG_CPPCR);
+
+	do {
+		cppcr = readl(cgu->base + CGU_REG_CPPCR);
+	} while (!(cppcr & BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.stable_bit)));
+
+	clkgr = readl(cgu->base + CGU_REG_CLKGR);
+	clkgr &= ~(JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+	writel(clkgr, cgu->base + CGU_REG_CLKGR);
+}
-- 
1.9.1


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

* [PATCH_V2 19/34] MIPS: clk: move jz4740 clock suspend, resume functions to jz4740-cgu
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The jz4740-cgu driver already has access to the CGU, so it makes sense
to move the few remaining accesses to the CGU from arch/mips/jz4740
there too. Move the jz4740_clock_{suspend,resume} functions there for
such consistency. The arch/mips/jz4740/clock.c file now contains nothing
more of use & so is removed.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
---
 arch/mips/include/asm/mach-jz4740/clock.h |  2 -
 arch/mips/jz4740/Makefile                 |  2 +-
 arch/mips/jz4740/clock.c                  | 95 -------------------------------
 arch/mips/jz4740/time.c                   |  1 -
 drivers/clk/jz47xx/jz4740-cgu.c           | 34 +++++++++++
 5 files changed, 35 insertions(+), 99 deletions(-)
 delete mode 100644 arch/mips/jz4740/clock.c

diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
index 01d8468..16659cd 100644
--- a/arch/mips/include/asm/mach-jz4740/clock.h
+++ b/arch/mips/include/asm/mach-jz4740/clock.h
@@ -20,8 +20,6 @@ enum jz4740_wait_mode {
 	JZ4740_WAIT_MODE_SLEEP,
 };
 
-int jz4740_clock_init(void);
-
 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
 
 void jz4740_clock_udc_enable_auto_suspend(void);
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 80e326d..61168a2 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -5,7 +5,7 @@
 # Object file lists.
 
 obj-y += prom.o irq.o time.o reset.o setup.o \
-	gpio.o clock.o platform.o timer.o serial.o
+	gpio.o platform.o timer.o serial.o
 
 # board specific support
 
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
deleted file mode 100644
index 2a10829..0000000
--- a/arch/mips/jz4740/clock.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC clock support
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General	 Public License as published by the
- *  Free Software Foundation;  either version 2 of the License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/list.h>
-#include <linux/err.h>
-
-#include <asm/mach-jz4740/clock.h>
-#include <asm/mach-jz4740/base.h>
-
-#include "clock.h"
-
-#define JZ_REG_CLOCK_PLL	0x10
-#define JZ_REG_CLOCK_GATE	0x20
-
-#define JZ_CLOCK_GATE_UART0	BIT(0)
-#define JZ_CLOCK_GATE_TCU	BIT(1)
-#define JZ_CLOCK_GATE_DMAC	BIT(12)
-
-#define JZ_CLOCK_PLL_STABLE		BIT(10)
-#define JZ_CLOCK_PLL_ENABLED		BIT(8)
-
-static void __iomem *jz_clock_base;
-
-static uint32_t jz_clk_reg_read(int reg)
-{
-	return readl(jz_clock_base + reg);
-}
-
-static void jz_clk_reg_set_bits(int reg, uint32_t mask)
-{
-	uint32_t val;
-
-	val = readl(jz_clock_base + reg);
-	val |= mask;
-	writel(val, jz_clock_base + reg);
-}
-
-static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
-{
-	uint32_t val;
-
-	val = readl(jz_clock_base + reg);
-	val &= ~mask;
-	writel(val, jz_clock_base + reg);
-}
-
-void jz4740_clock_suspend(void)
-{
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
-		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
-
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
-}
-
-void jz4740_clock_resume(void)
-{
-	uint32_t pll;
-
-	jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
-
-	do {
-		pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
-	} while (!(pll & JZ_CLOCK_PLL_STABLE));
-
-	jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
-		JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
-}
-
-int jz4740_clock_init(void)
-{
-	jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
-	if (!jz_clock_base)
-		return -EBUSY;
-
-	return 0;
-}
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index caa796d..121ec3a 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -114,7 +114,6 @@ void __init plat_time_init(void)
 	struct clk *ext_clk;
 
 	of_clk_init(NULL);
-	jz4740_clock_init();
 	jz4740_timer_init();
 
 	ext_clk = clk_get(NULL, "ext");
diff --git a/drivers/clk/jz47xx/jz4740-cgu.c b/drivers/clk/jz47xx/jz4740-cgu.c
index 46b6c1a..3325bd8 100644
--- a/drivers/clk/jz47xx/jz4740-cgu.c
+++ b/drivers/clk/jz47xx/jz4740-cgu.c
@@ -259,3 +259,37 @@ void jz4740_clock_udc_enable_auto_suspend(void)
 	writel(clkgr, cgu->base + CGU_REG_CLKGR);
 }
 EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
+
+#define JZ_CLOCK_GATE_UART0	BIT(0)
+#define JZ_CLOCK_GATE_TCU	BIT(1)
+#define JZ_CLOCK_GATE_DMAC	BIT(12)
+
+void jz4740_clock_suspend(void)
+{
+	uint32_t clkgr, cppcr;
+
+	clkgr = readl(cgu->base + CGU_REG_CLKGR);
+	clkgr |= JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0;
+	writel(clkgr, cgu->base + CGU_REG_CLKGR);
+
+	cppcr = readl(cgu->base + CGU_REG_CPPCR);
+	cppcr &= ~BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit);
+	writel(cppcr, cgu->base + CGU_REG_CPPCR);
+}
+
+void jz4740_clock_resume(void)
+{
+	uint32_t clkgr, cppcr;
+
+	cppcr = readl(cgu->base + CGU_REG_CPPCR);
+	cppcr |= BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit);
+	writel(cppcr, cgu->base + CGU_REG_CPPCR);
+
+	do {
+		cppcr = readl(cgu->base + CGU_REG_CPPCR);
+	} while (!(cppcr & BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.stable_bit)));
+
+	clkgr = readl(cgu->base + CGU_REG_CLKGR);
+	clkgr &= ~(JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
+	writel(clkgr, cgu->base + CGU_REG_CLKGR);
+}
-- 
1.9.1

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

* [PATCH_V2 20/34] MIPS: jz4740: remove clock.h
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The only thing remaining in arch/mips/jz4740/clock.h is declarations of
the jz4780_clock_{suspend,resume} functions. Move these to
arch/mips/include/asm/mach-jz4740/clock.h for consistency with similar
functions, and remove the redundant arch/mips/jz4740/clock.h header.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/clock.h |  3 +++
 arch/mips/jz4740/clock.h                  | 25 -------------------------
 arch/mips/jz4740/pm.c                     |  2 --
 3 files changed, 3 insertions(+), 27 deletions(-)
 delete mode 100644 arch/mips/jz4740/clock.h

diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
index 16659cd..104d2df 100644
--- a/arch/mips/include/asm/mach-jz4740/clock.h
+++ b/arch/mips/include/asm/mach-jz4740/clock.h
@@ -22,6 +22,9 @@ enum jz4740_wait_mode {
 
 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
 
+void jz4740_clock_suspend(void);
+void jz4740_clock_resume(void);
+
 void jz4740_clock_udc_enable_auto_suspend(void);
 void jz4740_clock_udc_disable_auto_suspend(void);
 
diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
deleted file mode 100644
index 86a3e01..0000000
--- a/arch/mips/jz4740/clock.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC clock support
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the	License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __MIPS_JZ4740_CLOCK_H__
-#define __MIPS_JZ4740_CLOCK_H__
-
-#include <linux/clk.h>
-#include <linux/list.h>
-
-void jz4740_clock_suspend(void);
-void jz4740_clock_resume(void);
-
-#endif
diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c
index d8e2130..2d8653f 100644
--- a/arch/mips/jz4740/pm.c
+++ b/arch/mips/jz4740/pm.c
@@ -20,8 +20,6 @@
 
 #include <asm/mach-jz4740/clock.h>
 
-#include "clock.h"
-
 static int jz4740_pm_enter(suspend_state_t state)
 {
 	jz4740_clock_suspend();
-- 
1.9.1


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

* [PATCH_V2 20/34] MIPS: jz4740: remove clock.h
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

The only thing remaining in arch/mips/jz4740/clock.h is declarations of
the jz4780_clock_{suspend,resume} functions. Move these to
arch/mips/include/asm/mach-jz4740/clock.h for consistency with similar
functions, and remove the redundant arch/mips/jz4740/clock.h header.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/clock.h |  3 +++
 arch/mips/jz4740/clock.h                  | 25 -------------------------
 arch/mips/jz4740/pm.c                     |  2 --
 3 files changed, 3 insertions(+), 27 deletions(-)
 delete mode 100644 arch/mips/jz4740/clock.h

diff --git a/arch/mips/include/asm/mach-jz4740/clock.h b/arch/mips/include/asm/mach-jz4740/clock.h
index 16659cd..104d2df 100644
--- a/arch/mips/include/asm/mach-jz4740/clock.h
+++ b/arch/mips/include/asm/mach-jz4740/clock.h
@@ -22,6 +22,9 @@ enum jz4740_wait_mode {
 
 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
 
+void jz4740_clock_suspend(void);
+void jz4740_clock_resume(void);
+
 void jz4740_clock_udc_enable_auto_suspend(void);
 void jz4740_clock_udc_disable_auto_suspend(void);
 
diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
deleted file mode 100644
index 86a3e01..0000000
--- a/arch/mips/jz4740/clock.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC clock support
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the	License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __MIPS_JZ4740_CLOCK_H__
-#define __MIPS_JZ4740_CLOCK_H__
-
-#include <linux/clk.h>
-#include <linux/list.h>
-
-void jz4740_clock_suspend(void);
-void jz4740_clock_resume(void);
-
-#endif
diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c
index d8e2130..2d8653f 100644
--- a/arch/mips/jz4740/pm.c
+++ b/arch/mips/jz4740/pm.c
@@ -20,8 +20,6 @@
 
 #include <asm/mach-jz4740/clock.h>
 
-#include "clock.h"
-
 static int jz4740_pm_enter(suspend_state_t state)
 {
 	jz4740_clock_suspend();
-- 
1.9.1

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

* [PATCH_V2 21/34] MIPS: jz4740: only detect RAM size if not specified in DT
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Allow a devicetree to specify the memory present in the system rather
than probing it from the memory controller. This both saves the probing
for systems where the amount of memory is fixed, and will simplify the
bringup of later jz47xx series SoCs where the memory controller register
layout differs.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/Kconfig         | 1 +
 arch/mips/jz4740/Makefile | 2 ++
 arch/mips/jz4740/setup.c  | 8 +++++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 8b377a7..ef82cd3 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -290,6 +290,7 @@ config MACH_JZ4740
 	select GENERIC_IRQ_CHIP
 	select BUILTIN_DTB
 	select USE_OF
+	select LIBFDT
 
 config LANTIQ
 	bool "Lantiq based platforms"
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 61168a2..340dc16 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -7,6 +7,8 @@
 obj-y += prom.o irq.o time.o reset.o setup.o \
 	gpio.o platform.o timer.o serial.o
 
+CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
+
 # board specific support
 
 obj-$(CONFIG_JZ4740_QI_LB60)	+= board-qi_lb60.o
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index 8c08d7d..1bed3cb 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/irqchip.h>
 #include <linux/kernel.h>
+#include <linux/libfdt.h>
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
 
@@ -55,9 +56,14 @@ static void __init jz4740_detect_mem(void)
 
 void __init plat_mem_setup(void)
 {
+	int offset;
+
 	jz4740_reset_init();
-	jz4740_detect_mem();
 	__dt_setup_arch(__dtb_start);
+
+	offset = fdt_path_offset(__dtb_start, "/memory");
+	if (offset < 0)
+		jz4740_detect_mem();
 }
 
 void __init device_tree_init(void)
-- 
1.9.1


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

* [PATCH_V2 21/34] MIPS: jz4740: only detect RAM size if not specified in DT
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips-6z/3iImG2C8G8FEW9MqTrA
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	Zubair.Kakakhel-1AXoQHu6uovQT0dZR+AlfA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	mturquette-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	ralf-6z/3iImG2C8G8FEW9MqTrA, jslaby-AlSwsSmVLrQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA,
	lars-Qo5EllUWu/uELgA04lAiVw, paul.burton-1AXoQHu6uovQT0dZR+AlfA

From: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>

Allow a devicetree to specify the memory present in the system rather
than probing it from the memory controller. This both saves the probing
for systems where the amount of memory is fixed, and will simplify the
bringup of later jz47xx series SoCs where the memory controller register
layout differs.

Signed-off-by: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
Cc: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
---
 arch/mips/Kconfig         | 1 +
 arch/mips/jz4740/Makefile | 2 ++
 arch/mips/jz4740/setup.c  | 8 +++++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 8b377a7..ef82cd3 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -290,6 +290,7 @@ config MACH_JZ4740
 	select GENERIC_IRQ_CHIP
 	select BUILTIN_DTB
 	select USE_OF
+	select LIBFDT
 
 config LANTIQ
 	bool "Lantiq based platforms"
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 61168a2..340dc16 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -7,6 +7,8 @@
 obj-y += prom.o irq.o time.o reset.o setup.o \
 	gpio.o platform.o timer.o serial.o
 
+CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
+
 # board specific support
 
 obj-$(CONFIG_JZ4740_QI_LB60)	+= board-qi_lb60.o
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index 8c08d7d..1bed3cb 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/irqchip.h>
 #include <linux/kernel.h>
+#include <linux/libfdt.h>
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
 
@@ -55,9 +56,14 @@ static void __init jz4740_detect_mem(void)
 
 void __init plat_mem_setup(void)
 {
+	int offset;
+
 	jz4740_reset_init();
-	jz4740_detect_mem();
 	__dt_setup_arch(__dtb_start);
+
+	offset = fdt_path_offset(__dtb_start, "/memory");
+	if (offset < 0)
+		jz4740_detect_mem();
 }
 
 void __init device_tree_init(void)
-- 
1.9.1

--
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] 86+ messages in thread

* [PATCH_V2 21/34] MIPS: jz4740: only detect RAM size if not specified in DT
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Allow a devicetree to specify the memory present in the system rather
than probing it from the memory controller. This both saves the probing
for systems where the amount of memory is fixed, and will simplify the
bringup of later jz47xx series SoCs where the memory controller register
layout differs.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/Kconfig         | 1 +
 arch/mips/jz4740/Makefile | 2 ++
 arch/mips/jz4740/setup.c  | 8 +++++++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 8b377a7..ef82cd3 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -290,6 +290,7 @@ config MACH_JZ4740
 	select GENERIC_IRQ_CHIP
 	select BUILTIN_DTB
 	select USE_OF
+	select LIBFDT
 
 config LANTIQ
 	bool "Lantiq based platforms"
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 61168a2..340dc16 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -7,6 +7,8 @@
 obj-y += prom.o irq.o time.o reset.o setup.o \
 	gpio.o platform.o timer.o serial.o
 
+CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
+
 # board specific support
 
 obj-$(CONFIG_JZ4740_QI_LB60)	+= board-qi_lb60.o
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index 8c08d7d..1bed3cb 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/irqchip.h>
 #include <linux/kernel.h>
+#include <linux/libfdt.h>
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
 
@@ -55,9 +56,14 @@ static void __init jz4740_detect_mem(void)
 
 void __init plat_mem_setup(void)
 {
+	int offset;
+
 	jz4740_reset_init();
-	jz4740_detect_mem();
 	__dt_setup_arch(__dtb_start);
+
+	offset = fdt_path_offset(__dtb_start, "/memory");
+	if (offset < 0)
+		jz4740_detect_mem();
 }
 
 void __init device_tree_init(void)
-- 
1.9.1

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

* [PATCH_V2 22/34] MIPS: jz4740: support >32 interrupts
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

On later jz47xx series SoCs the interrupt controller supports more than
32 interrupts, which it does by duplicating the registers at intervals
of 0x20 bytes within its address space. Add support for an arbitrary
number of interrupts using multiple generic chips, and provide the
number of chips to register from the SoC-specific probe function.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 58 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index a620b23..3e53a32 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -33,21 +33,27 @@
 #include "../../drivers/irqchip/irqchip.h"
 
 static void __iomem *jz_intc_base;
+static unsigned jz_num_chips;
 
 #define JZ_REG_INTC_STATUS	0x00
 #define JZ_REG_INTC_MASK	0x04
 #define JZ_REG_INTC_SET_MASK	0x08
 #define JZ_REG_INTC_CLEAR_MASK	0x0c
 #define JZ_REG_INTC_PENDING	0x10
+#define CHIP_SIZE		0x20
 
 static irqreturn_t jz4740_cascade(int irq, void *data)
 {
 	uint32_t irq_reg;
+	unsigned i;
 
-	irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
+	for (i = 0; i < jz_num_chips; i++) {
+		irq_reg = readl(jz_intc_base + (i * CHIP_SIZE) + JZ_REG_INTC_PENDING);
+		if (!irq_reg)
+			continue;
 
-	if (irq_reg)
-		generic_handle_irq(__fls(irq_reg) + JZ4740_IRQ_BASE);
+		generic_handle_irq(__fls(irq_reg) + (i * 32) + JZ4740_IRQ_BASE);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -77,39 +83,43 @@ static struct irqaction jz4740_cascade_action = {
 	.name = "JZ4740 cascade interrupt",
 };
 
-static int __init jz4740_intc_of_init(struct device_node *node,
-	struct device_node *parent)
+static int __init jz47xx_intc_of_init(struct device_node *node, unsigned num_chips)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 	struct irq_domain *domain;
 	int parent_irq;
+	unsigned i;
 
 	parent_irq = irq_of_parse_and_map(node, 0);
 	if (!parent_irq)
 		return -EINVAL;
 
-	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
+	jz_num_chips = num_chips;
+	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR,
+			       ((num_chips - 1) * CHIP_SIZE) + 0x14);
 
-	/* Mask all irqs */
-	writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK);
+	for (i = 0; i < num_chips; i++) {
+		/* Mask all irqs */
+		writel(0xffffffff, jz_intc_base + (i * CHIP_SIZE) + JZ_REG_INTC_SET_MASK);
 
-	gc = irq_alloc_generic_chip("INTC", 1, JZ4740_IRQ_BASE, jz_intc_base,
-		handle_level_irq);
+		gc = irq_alloc_generic_chip("INTC", 1, JZ4740_IRQ_BASE + (i * 32),
+					    jz_intc_base + (i * CHIP_SIZE), handle_level_irq);
 
-	gc->wake_enabled = IRQ_MSK(32);
+		gc->wake_enabled = IRQ_MSK(32);
 
-	ct = gc->chip_types;
-	ct->regs.enable = JZ_REG_INTC_CLEAR_MASK;
-	ct->regs.disable = JZ_REG_INTC_SET_MASK;
-	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
-	ct->chip.irq_mask = irq_gc_mask_disable_reg;
-	ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
-	ct->chip.irq_set_wake = irq_gc_set_wake;
-	ct->chip.irq_suspend = jz4740_irq_suspend;
-	ct->chip.irq_resume = jz4740_irq_resume;
+		ct = gc->chip_types;
+		ct->regs.enable = JZ_REG_INTC_CLEAR_MASK;
+		ct->regs.disable = JZ_REG_INTC_SET_MASK;
+		ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
+		ct->chip.irq_mask = irq_gc_mask_disable_reg;
+		ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
+		ct->chip.irq_set_wake = irq_gc_set_wake;
+		ct->chip.irq_suspend = jz4740_irq_suspend;
+		ct->chip.irq_resume = jz4740_irq_resume;
 
-	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
+		irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
+	}
 
 	domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0,
 				       &irq_domain_simple_ops, NULL);
@@ -119,6 +129,12 @@ static int __init jz4740_intc_of_init(struct device_node *node,
 	setup_irq(parent_irq, &jz4740_cascade_action);
 	return 0;
 }
+
+static int __init jz4740_intc_of_init(struct device_node *node,
+	struct device_node *parent)
+{
+	return jz47xx_intc_of_init(node, 1);
+}
 IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init);
 
 #ifdef CONFIG_DEBUG_FS
-- 
1.9.1


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

* [PATCH_V2 22/34] MIPS: jz4740: support >32 interrupts
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

On later jz47xx series SoCs the interrupt controller supports more than
32 interrupts, which it does by duplicating the registers at intervals
of 0x20 bytes within its address space. Add support for an arbitrary
number of interrupts using multiple generic chips, and provide the
number of chips to register from the SoC-specific probe function.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 58 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index a620b23..3e53a32 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -33,21 +33,27 @@
 #include "../../drivers/irqchip/irqchip.h"
 
 static void __iomem *jz_intc_base;
+static unsigned jz_num_chips;
 
 #define JZ_REG_INTC_STATUS	0x00
 #define JZ_REG_INTC_MASK	0x04
 #define JZ_REG_INTC_SET_MASK	0x08
 #define JZ_REG_INTC_CLEAR_MASK	0x0c
 #define JZ_REG_INTC_PENDING	0x10
+#define CHIP_SIZE		0x20
 
 static irqreturn_t jz4740_cascade(int irq, void *data)
 {
 	uint32_t irq_reg;
+	unsigned i;
 
-	irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
+	for (i = 0; i < jz_num_chips; i++) {
+		irq_reg = readl(jz_intc_base + (i * CHIP_SIZE) + JZ_REG_INTC_PENDING);
+		if (!irq_reg)
+			continue;
 
-	if (irq_reg)
-		generic_handle_irq(__fls(irq_reg) + JZ4740_IRQ_BASE);
+		generic_handle_irq(__fls(irq_reg) + (i * 32) + JZ4740_IRQ_BASE);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -77,39 +83,43 @@ static struct irqaction jz4740_cascade_action = {
 	.name = "JZ4740 cascade interrupt",
 };
 
-static int __init jz4740_intc_of_init(struct device_node *node,
-	struct device_node *parent)
+static int __init jz47xx_intc_of_init(struct device_node *node, unsigned num_chips)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 	struct irq_domain *domain;
 	int parent_irq;
+	unsigned i;
 
 	parent_irq = irq_of_parse_and_map(node, 0);
 	if (!parent_irq)
 		return -EINVAL;
 
-	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
+	jz_num_chips = num_chips;
+	jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR,
+			       ((num_chips - 1) * CHIP_SIZE) + 0x14);
 
-	/* Mask all irqs */
-	writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK);
+	for (i = 0; i < num_chips; i++) {
+		/* Mask all irqs */
+		writel(0xffffffff, jz_intc_base + (i * CHIP_SIZE) + JZ_REG_INTC_SET_MASK);
 
-	gc = irq_alloc_generic_chip("INTC", 1, JZ4740_IRQ_BASE, jz_intc_base,
-		handle_level_irq);
+		gc = irq_alloc_generic_chip("INTC", 1, JZ4740_IRQ_BASE + (i * 32),
+					    jz_intc_base + (i * CHIP_SIZE), handle_level_irq);
 
-	gc->wake_enabled = IRQ_MSK(32);
+		gc->wake_enabled = IRQ_MSK(32);
 
-	ct = gc->chip_types;
-	ct->regs.enable = JZ_REG_INTC_CLEAR_MASK;
-	ct->regs.disable = JZ_REG_INTC_SET_MASK;
-	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
-	ct->chip.irq_mask = irq_gc_mask_disable_reg;
-	ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
-	ct->chip.irq_set_wake = irq_gc_set_wake;
-	ct->chip.irq_suspend = jz4740_irq_suspend;
-	ct->chip.irq_resume = jz4740_irq_resume;
+		ct = gc->chip_types;
+		ct->regs.enable = JZ_REG_INTC_CLEAR_MASK;
+		ct->regs.disable = JZ_REG_INTC_SET_MASK;
+		ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
+		ct->chip.irq_mask = irq_gc_mask_disable_reg;
+		ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
+		ct->chip.irq_set_wake = irq_gc_set_wake;
+		ct->chip.irq_suspend = jz4740_irq_suspend;
+		ct->chip.irq_resume = jz4740_irq_resume;
 
-	irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
+		irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
+	}
 
 	domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0,
 				       &irq_domain_simple_ops, NULL);
@@ -119,6 +129,12 @@ static int __init jz4740_intc_of_init(struct device_node *node,
 	setup_irq(parent_irq, &jz4740_cascade_action);
 	return 0;
 }
+
+static int __init jz4740_intc_of_init(struct device_node *node,
+	struct device_node *parent)
+{
+	return jz47xx_intc_of_init(node, 1);
+}
 IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init);
 
 #ifdef CONFIG_DEBUG_FS
-- 
1.9.1

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

* [PATCH_V2 23/34] MIPS: jz4740: define IRQ numbers based on number of intc IRQs
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

For interrupts numbered after those of the interrupt controller, define
their numbers based upon the number of interrupts provided by the SoC
interrupt controller. This is in preparation for supporting later jz47xx
series SoCs which provide more interrupts.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/irq.h | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
index df50736..b218f76 100644
--- a/arch/mips/include/asm/mach-jz4740/irq.h
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -19,6 +19,10 @@
 #define MIPS_CPU_IRQ_BASE 0
 #define JZ4740_IRQ_BASE 8
 
+#ifdef CONFIG_MACH_JZ4740
+# define NR_INTC_IRQS	32
+#endif
+
 /* 1st-level interrupts */
 #define JZ4740_IRQ(x)		(JZ4740_IRQ_BASE + (x))
 #define JZ4740_IRQ_I2C		JZ4740_IRQ(1)
@@ -45,12 +49,12 @@
 #define JZ4740_IRQ_LCD		JZ4740_IRQ(30)
 
 /* 2nd-level interrupts */
-#define JZ4740_IRQ_DMA(x)	(JZ4740_IRQ(32) + (x))
+#define JZ4740_IRQ_DMA(x)	(JZ4740_IRQ(NR_INTC_IRQS) + (x))
 
 #define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x))
-#define JZ4740_IRQ_GPIO(x)	(JZ4740_IRQ(48) + (x))
+#define JZ4740_IRQ_GPIO(x)	(JZ4740_IRQ(NR_INTC_IRQS + 16) + (x))
 
-#define JZ4740_IRQ_ADC_BASE	JZ4740_IRQ(176)
+#define JZ4740_IRQ_ADC_BASE	JZ4740_IRQ(NR_INTC_IRQS + 144)
 
 #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6)
 
-- 
1.9.1


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

* [PATCH_V2 23/34] MIPS: jz4740: define IRQ numbers based on number of intc IRQs
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

For interrupts numbered after those of the interrupt controller, define
their numbers based upon the number of interrupts provided by the SoC
interrupt controller. This is in preparation for supporting later jz47xx
series SoCs which provide more interrupts.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/mach-jz4740/irq.h | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
index df50736..b218f76 100644
--- a/arch/mips/include/asm/mach-jz4740/irq.h
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -19,6 +19,10 @@
 #define MIPS_CPU_IRQ_BASE 0
 #define JZ4740_IRQ_BASE 8
 
+#ifdef CONFIG_MACH_JZ4740
+# define NR_INTC_IRQS	32
+#endif
+
 /* 1st-level interrupts */
 #define JZ4740_IRQ(x)		(JZ4740_IRQ_BASE + (x))
 #define JZ4740_IRQ_I2C		JZ4740_IRQ(1)
@@ -45,12 +49,12 @@
 #define JZ4740_IRQ_LCD		JZ4740_IRQ(30)
 
 /* 2nd-level interrupts */
-#define JZ4740_IRQ_DMA(x)	(JZ4740_IRQ(32) + (x))
+#define JZ4740_IRQ_DMA(x)	(JZ4740_IRQ(NR_INTC_IRQS) + (x))
 
 #define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x))
-#define JZ4740_IRQ_GPIO(x)	(JZ4740_IRQ(48) + (x))
+#define JZ4740_IRQ_GPIO(x)	(JZ4740_IRQ(NR_INTC_IRQS + 16) + (x))
 
-#define JZ4740_IRQ_ADC_BASE	JZ4740_IRQ(176)
+#define JZ4740_IRQ_ADC_BASE	JZ4740_IRQ(NR_INTC_IRQS + 144)
 
 #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6)
 
-- 
1.9.1

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

* [PATCH_V2 24/34] dt: serial: Add ingenic,jz4740-uart binding
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add binding documentation for Ingenic jz4740 UARTs.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: devicetree@vger.kernel.org
---
 .../bindings/serial/ingenic,jz4740-uart.txt        | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt

diff --git a/Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt b/Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt
new file mode 100644
index 0000000..9e12de6
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt
@@ -0,0 +1,22 @@
+* Ingenic jz4740 UART
+
+Required properties:
+- compatible : "ingenic,jz4740-uart" or "ingenic,jz4780-uart"
+- reg : offset and length of the register set for the device.
+- interrupts : should contain uart interrupt.
+- clocks : phandles to the module & baud clocks.
+- clock-names: tuple listing input clock names.
+	Required elements: "baud", "module"
+
+Example:
+
+uart0: serial@10030000 {
+	compatible = "ingenic,jz4740-uart";
+	reg = <0x10030000 0x100>;
+
+	interrupt-parent = <&intc>;
+	interrupts = <9>;
+
+	clocks = <&ext>, <&cgu JZ4740_CLK_UART0>;
+	clock-names = "baud", "module";
+};
-- 
1.9.1


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

* [PATCH_V2 24/34] dt: serial: Add ingenic,jz4740-uart binding
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add binding documentation for Ingenic jz4740 UARTs.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: devicetree@vger.kernel.org
---
 .../bindings/serial/ingenic,jz4740-uart.txt        | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt

diff --git a/Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt b/Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt
new file mode 100644
index 0000000..9e12de6
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt
@@ -0,0 +1,22 @@
+* Ingenic jz4740 UART
+
+Required properties:
+- compatible : "ingenic,jz4740-uart" or "ingenic,jz4780-uart"
+- reg : offset and length of the register set for the device.
+- interrupts : should contain uart interrupt.
+- clocks : phandles to the module & baud clocks.
+- clock-names: tuple listing input clock names.
+	Required elements: "baud", "module"
+
+Example:
+
+uart0: serial@10030000 {
+	compatible = "ingenic,jz4740-uart";
+	reg = <0x10030000 0x100>;
+
+	interrupt-parent = <&intc>;
+	interrupts = <9>;
+
+	clocks = <&ext>, <&cgu JZ4740_CLK_UART0>;
+	clock-names = "baud", "module";
+};
-- 
1.9.1

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

* [PATCH_V2 25/34] serial: 8250_jz47xx: support for Ingenic jz47xx UARTs
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Introduce a driver suitable for use with the UARTs present in
Ingenic jz47xx series SoCs. These are described as being ns16550
compatible but aren't quite - they require the setting of an extra bit
in the FCR register to enable the UART module. The serial_out
implementation is the same as that in arch/mips/jz4740/serial.c - which
will shortly be removed.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: linux-serial@vger.kernel.org

---
V2 changes
Removed FSF address
Added select SERIAL_CORE_CONSOLE to fix a build error
---
 drivers/tty/serial/8250/8250_jz47xx.c | 225 ++++++++++++++++++++++++++++++++++
 drivers/tty/serial/8250/Kconfig       |   9 ++
 drivers/tty/serial/8250/Makefile      |   1 +
 3 files changed, 235 insertions(+)
 create mode 100644 drivers/tty/serial/8250/8250_jz47xx.c

diff --git a/drivers/tty/serial/8250/8250_jz47xx.c b/drivers/tty/serial/8250/8250_jz47xx.c
new file mode 100644
index 0000000..49a63ce
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_jz47xx.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2010 Lars-Peter Clausen <lars@metafoo.de>
+ * Copyright (C) 2015 Imagination Technologies
+ *
+ * Ingenic jz47xx series UART support
+ *
+ * This program is free software; you can redistribute	 it and/or modify it
+ * under  the terms of	 the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the	License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+struct jz47xx_uart_data {
+	struct clk	*clk_module;
+	struct clk	*clk_baud;
+	int		line;
+};
+
+#define UART_FCR_UME	BIT(4)
+
+static struct earlycon_device *early_device;
+
+static uint8_t __init early_in(struct uart_port *port, int offset)
+{
+	return readl(port->membase + (offset << 2));
+}
+
+static void __init early_out(struct uart_port *port, int offset, uint8_t value)
+{
+	writel(value, port->membase + (offset << 2));
+}
+
+static void __init jz47xx_early_console_putc(struct uart_port *port, int c)
+{
+	uint8_t lsr;
+
+	do {
+		lsr = early_in(port, UART_LSR);
+	} while ((lsr & UART_LSR_TEMT) == 0);
+
+	early_out(port, UART_TX, c);
+}
+
+static void __init jz47xx_early_console_write(struct console *console,
+					      const char *s, unsigned int count)
+{
+	uart_console_write(&early_device->port, s, count, jz47xx_early_console_putc);
+}
+
+static int __init jz47xx_early_console_setup(struct earlycon_device *dev,
+					     const char *opt)
+{
+	struct uart_port *port = &dev->port;
+	unsigned int baud, divisor;
+
+	if (!dev->port.membase)
+		return -ENODEV;
+
+	baud = dev->baud ?: 115200;
+	divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud);
+
+	early_out(port, UART_IER, 0);
+	early_out(port, UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
+	early_out(port, UART_DLL, 0);
+	early_out(port, UART_DLM, 0);
+	early_out(port, UART_LCR, UART_LCR_WLEN8);
+	early_out(port, UART_FCR, UART_FCR_UME | UART_FCR_CLEAR_XMIT |
+			UART_FCR_CLEAR_RCVR | UART_FCR_ENABLE_FIFO);
+	early_out(port, UART_MCR, UART_MCR_RTS | UART_MCR_DTR);
+
+	early_out(port, UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
+	early_out(port, UART_DLL, divisor & 0xff);
+	early_out(port, UART_DLM, (divisor >> 8) & 0xff);
+	early_out(port, UART_LCR, UART_LCR_WLEN8);
+
+	early_device = dev;
+	dev->con->write = jz47xx_early_console_write;
+
+	return 0;
+}
+EARLYCON_DECLARE(jz4740_uart, jz47xx_early_console_setup);
+OF_EARLYCON_DECLARE(jz4740_uart, "ingenic,jz4740-uart", jz47xx_early_console_setup);
+EARLYCON_DECLARE(jz4780_uart, jz47xx_early_console_setup);
+OF_EARLYCON_DECLARE(jz4780_uart, "ingenic,jz4780-uart", jz47xx_early_console_setup);
+
+static void jz47xx_serial_out(struct uart_port *p, int offset, int value)
+{
+	switch (offset) {
+	case UART_FCR:
+		/* UART module enable */
+		value |= UART_FCR_UME;
+		break;
+
+	case UART_IER:
+		value |= (value & 0x4) << 2;
+		break;
+
+	default:
+		break;
+	}
+
+	writeb(value, p->membase + (offset << p->regshift));
+}
+
+static int jz47xx_probe(struct platform_device *pdev)
+{
+	struct uart_8250_port uart = {};
+	struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	struct jz47xx_uart_data *data;
+	int err;
+
+	if (!regs || !irq) {
+		dev_err(&pdev->dev, "no registers/irq defined\n");
+		return -EINVAL;
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	spin_lock_init(&uart.port.lock);
+	uart.port.type = PORT_16550;
+	uart.port.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE;
+	uart.port.iotype = UPIO_MEM;
+	uart.port.mapbase = regs->start;
+	uart.port.regshift = 2;
+	uart.port.serial_out = jz47xx_serial_out;
+	uart.port.irq = irq->start;
+	uart.port.dev = &pdev->dev;
+
+	uart.port.membase = devm_ioremap(&pdev->dev, regs->start,
+					 resource_size(regs));
+	if (!uart.port.membase)
+		return -ENOMEM;
+
+	data->clk_module = devm_clk_get(&pdev->dev, "module");
+	if (IS_ERR(data->clk_module)) {
+		err = PTR_ERR(data->clk_module);
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "unable to get module clock: %d\n", err);
+		return err;
+	}
+
+	data->clk_baud = devm_clk_get(&pdev->dev, "baud");
+	if (IS_ERR(data->clk_baud)) {
+		err = PTR_ERR(data->clk_baud);
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "unable to get baud clock: %d\n", err);
+		return err;
+	}
+
+	err = clk_prepare_enable(data->clk_module);
+	if (err) {
+		dev_err(&pdev->dev, "could not enable module clock: %d\n", err);
+		goto out;
+	}
+
+	err = clk_prepare_enable(data->clk_baud);
+	if (err) {
+		dev_err(&pdev->dev, "could not enable baud clock: %d\n", err);
+		goto out_disable_moduleclk;
+	}
+	uart.port.uartclk = clk_get_rate(data->clk_baud);
+
+	data->line = serial8250_register_8250_port(&uart);
+	if (data->line < 0) {
+		err = data->line;
+		goto out_disable_baudclk;
+	}
+
+	platform_set_drvdata(pdev, data);
+	return 0;
+
+out_disable_baudclk:
+	clk_disable_unprepare(data->clk_baud);
+out_disable_moduleclk:
+	clk_disable_unprepare(data->clk_module);
+out:
+	return err;
+}
+
+static int jz47xx_remove(struct platform_device *pdev)
+{
+	struct jz47xx_uart_data *data = platform_get_drvdata(pdev);
+
+	serial8250_unregister_port(data->line);
+	clk_disable_unprepare(data->clk_module);
+	clk_disable_unprepare(data->clk_baud);
+	return 0;
+}
+
+static const struct of_device_id jz47xx_of_match[] = {
+	{ .compatible = "ingenic,jz4740-uart" },
+	{ .compatible = "ingenic,jz4780-uart" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jz47xx_of_match);
+
+static struct platform_driver jz47xx_platform_driver = {
+	.driver = {
+		.name		= "jz47xx-uart",
+		.owner		= THIS_MODULE,
+		.of_match_table	= jz47xx_of_match,
+	},
+	.probe			= jz47xx_probe,
+	.remove			= jz47xx_remove,
+};
+
+module_platform_driver(jz47xx_platform_driver);
+
+MODULE_AUTHOR("Paul Burton");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Ingenic jz47xx SoC series UART driver");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 0fcbcd2..ebb298e 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -322,3 +322,12 @@ config SERIAL_8250_MT6577
 	help
 	  If you have a Mediatek based board and want to use the
 	  serial port, say Y to this option. If unsure, say N.
+
+config SERIAL_8250_JZ47XX
+	tristate "Support for Ingenic jz47xx series serial ports"
+	depends on SERIAL_8250
+	select SERIAL_EARLYCON
+	select SERIAL_CORE_CONSOLE
+	help
+	  If you have a system using an Ingenic jz47xx series SoC and wish to
+	  make use of its UARTs, say Y to this option. If unsure, say N.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 31e7cdc..ddbcb7a 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_SERIAL_8250_EM)		+= 8250_em.o
 obj-$(CONFIG_SERIAL_8250_OMAP)		+= 8250_omap.o
 obj-$(CONFIG_SERIAL_8250_FINTEK)	+= 8250_fintek.o
 obj-$(CONFIG_SERIAL_8250_MT6577)	+= 8250_mtk.o
+obj-$(CONFIG_SERIAL_8250_JZ47XX)	+= 8250_jz47xx.o
-- 
1.9.1


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

* [PATCH_V2 25/34] serial: 8250_jz47xx: support for Ingenic jz47xx UARTs
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Introduce a driver suitable for use with the UARTs present in
Ingenic jz47xx series SoCs. These are described as being ns16550
compatible but aren't quite - they require the setting of an extra bit
in the FCR register to enable the UART module. The serial_out
implementation is the same as that in arch/mips/jz4740/serial.c - which
will shortly be removed.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: linux-serial@vger.kernel.org

---
V2 changes
Removed FSF address
Added select SERIAL_CORE_CONSOLE to fix a build error
---
 drivers/tty/serial/8250/8250_jz47xx.c | 225 ++++++++++++++++++++++++++++++++++
 drivers/tty/serial/8250/Kconfig       |   9 ++
 drivers/tty/serial/8250/Makefile      |   1 +
 3 files changed, 235 insertions(+)
 create mode 100644 drivers/tty/serial/8250/8250_jz47xx.c

diff --git a/drivers/tty/serial/8250/8250_jz47xx.c b/drivers/tty/serial/8250/8250_jz47xx.c
new file mode 100644
index 0000000..49a63ce
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_jz47xx.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2010 Lars-Peter Clausen <lars@metafoo.de>
+ * Copyright (C) 2015 Imagination Technologies
+ *
+ * Ingenic jz47xx series UART support
+ *
+ * This program is free software; you can redistribute	 it and/or modify it
+ * under  the terms of	 the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the	License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+struct jz47xx_uart_data {
+	struct clk	*clk_module;
+	struct clk	*clk_baud;
+	int		line;
+};
+
+#define UART_FCR_UME	BIT(4)
+
+static struct earlycon_device *early_device;
+
+static uint8_t __init early_in(struct uart_port *port, int offset)
+{
+	return readl(port->membase + (offset << 2));
+}
+
+static void __init early_out(struct uart_port *port, int offset, uint8_t value)
+{
+	writel(value, port->membase + (offset << 2));
+}
+
+static void __init jz47xx_early_console_putc(struct uart_port *port, int c)
+{
+	uint8_t lsr;
+
+	do {
+		lsr = early_in(port, UART_LSR);
+	} while ((lsr & UART_LSR_TEMT) == 0);
+
+	early_out(port, UART_TX, c);
+}
+
+static void __init jz47xx_early_console_write(struct console *console,
+					      const char *s, unsigned int count)
+{
+	uart_console_write(&early_device->port, s, count, jz47xx_early_console_putc);
+}
+
+static int __init jz47xx_early_console_setup(struct earlycon_device *dev,
+					     const char *opt)
+{
+	struct uart_port *port = &dev->port;
+	unsigned int baud, divisor;
+
+	if (!dev->port.membase)
+		return -ENODEV;
+
+	baud = dev->baud ?: 115200;
+	divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud);
+
+	early_out(port, UART_IER, 0);
+	early_out(port, UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
+	early_out(port, UART_DLL, 0);
+	early_out(port, UART_DLM, 0);
+	early_out(port, UART_LCR, UART_LCR_WLEN8);
+	early_out(port, UART_FCR, UART_FCR_UME | UART_FCR_CLEAR_XMIT |
+			UART_FCR_CLEAR_RCVR | UART_FCR_ENABLE_FIFO);
+	early_out(port, UART_MCR, UART_MCR_RTS | UART_MCR_DTR);
+
+	early_out(port, UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
+	early_out(port, UART_DLL, divisor & 0xff);
+	early_out(port, UART_DLM, (divisor >> 8) & 0xff);
+	early_out(port, UART_LCR, UART_LCR_WLEN8);
+
+	early_device = dev;
+	dev->con->write = jz47xx_early_console_write;
+
+	return 0;
+}
+EARLYCON_DECLARE(jz4740_uart, jz47xx_early_console_setup);
+OF_EARLYCON_DECLARE(jz4740_uart, "ingenic,jz4740-uart", jz47xx_early_console_setup);
+EARLYCON_DECLARE(jz4780_uart, jz47xx_early_console_setup);
+OF_EARLYCON_DECLARE(jz4780_uart, "ingenic,jz4780-uart", jz47xx_early_console_setup);
+
+static void jz47xx_serial_out(struct uart_port *p, int offset, int value)
+{
+	switch (offset) {
+	case UART_FCR:
+		/* UART module enable */
+		value |= UART_FCR_UME;
+		break;
+
+	case UART_IER:
+		value |= (value & 0x4) << 2;
+		break;
+
+	default:
+		break;
+	}
+
+	writeb(value, p->membase + (offset << p->regshift));
+}
+
+static int jz47xx_probe(struct platform_device *pdev)
+{
+	struct uart_8250_port uart = {};
+	struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	struct jz47xx_uart_data *data;
+	int err;
+
+	if (!regs || !irq) {
+		dev_err(&pdev->dev, "no registers/irq defined\n");
+		return -EINVAL;
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	spin_lock_init(&uart.port.lock);
+	uart.port.type = PORT_16550;
+	uart.port.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE;
+	uart.port.iotype = UPIO_MEM;
+	uart.port.mapbase = regs->start;
+	uart.port.regshift = 2;
+	uart.port.serial_out = jz47xx_serial_out;
+	uart.port.irq = irq->start;
+	uart.port.dev = &pdev->dev;
+
+	uart.port.membase = devm_ioremap(&pdev->dev, regs->start,
+					 resource_size(regs));
+	if (!uart.port.membase)
+		return -ENOMEM;
+
+	data->clk_module = devm_clk_get(&pdev->dev, "module");
+	if (IS_ERR(data->clk_module)) {
+		err = PTR_ERR(data->clk_module);
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "unable to get module clock: %d\n", err);
+		return err;
+	}
+
+	data->clk_baud = devm_clk_get(&pdev->dev, "baud");
+	if (IS_ERR(data->clk_baud)) {
+		err = PTR_ERR(data->clk_baud);
+		if (err != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "unable to get baud clock: %d\n", err);
+		return err;
+	}
+
+	err = clk_prepare_enable(data->clk_module);
+	if (err) {
+		dev_err(&pdev->dev, "could not enable module clock: %d\n", err);
+		goto out;
+	}
+
+	err = clk_prepare_enable(data->clk_baud);
+	if (err) {
+		dev_err(&pdev->dev, "could not enable baud clock: %d\n", err);
+		goto out_disable_moduleclk;
+	}
+	uart.port.uartclk = clk_get_rate(data->clk_baud);
+
+	data->line = serial8250_register_8250_port(&uart);
+	if (data->line < 0) {
+		err = data->line;
+		goto out_disable_baudclk;
+	}
+
+	platform_set_drvdata(pdev, data);
+	return 0;
+
+out_disable_baudclk:
+	clk_disable_unprepare(data->clk_baud);
+out_disable_moduleclk:
+	clk_disable_unprepare(data->clk_module);
+out:
+	return err;
+}
+
+static int jz47xx_remove(struct platform_device *pdev)
+{
+	struct jz47xx_uart_data *data = platform_get_drvdata(pdev);
+
+	serial8250_unregister_port(data->line);
+	clk_disable_unprepare(data->clk_module);
+	clk_disable_unprepare(data->clk_baud);
+	return 0;
+}
+
+static const struct of_device_id jz47xx_of_match[] = {
+	{ .compatible = "ingenic,jz4740-uart" },
+	{ .compatible = "ingenic,jz4780-uart" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, jz47xx_of_match);
+
+static struct platform_driver jz47xx_platform_driver = {
+	.driver = {
+		.name		= "jz47xx-uart",
+		.owner		= THIS_MODULE,
+		.of_match_table	= jz47xx_of_match,
+	},
+	.probe			= jz47xx_probe,
+	.remove			= jz47xx_remove,
+};
+
+module_platform_driver(jz47xx_platform_driver);
+
+MODULE_AUTHOR("Paul Burton");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Ingenic jz47xx SoC series UART driver");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index 0fcbcd2..ebb298e 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -322,3 +322,12 @@ config SERIAL_8250_MT6577
 	help
 	  If you have a Mediatek based board and want to use the
 	  serial port, say Y to this option. If unsure, say N.
+
+config SERIAL_8250_JZ47XX
+	tristate "Support for Ingenic jz47xx series serial ports"
+	depends on SERIAL_8250
+	select SERIAL_EARLYCON
+	select SERIAL_CORE_CONSOLE
+	help
+	  If you have a system using an Ingenic jz47xx series SoC and wish to
+	  make use of its UARTs, say Y to this option. If unsure, say N.
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 31e7cdc..ddbcb7a 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_SERIAL_8250_EM)		+= 8250_em.o
 obj-$(CONFIG_SERIAL_8250_OMAP)		+= 8250_omap.o
 obj-$(CONFIG_SERIAL_8250_FINTEK)	+= 8250_fintek.o
 obj-$(CONFIG_SERIAL_8250_MT6577)	+= 8250_mtk.o
+obj-$(CONFIG_SERIAL_8250_JZ47XX)	+= 8250_jz47xx.o
-- 
1.9.1

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

* [PATCH_V2 26/34] MIPS: allow mach-provided serial.h
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Allow platforms to set BAUD_BASE, which is used by earlycon to calculate
the baud clock.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>

---
V2 Removed FSF address
---
 arch/mips/include/asm/Kbuild                |  1 -
 arch/mips/include/asm/mach-generic/serial.h | 21 +++++++++++++++++++++
 arch/mips/include/asm/serial.h              | 21 +++++++++++++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 arch/mips/include/asm/mach-generic/serial.h
 create mode 100644 arch/mips/include/asm/serial.h

diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 200efea..3cd9114 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -13,7 +13,6 @@ generic-y += preempt.h
 generic-y += scatterlist.h
 generic-y += sections.h
 generic-y += segment.h
-generic-y += serial.h
 generic-y += trace_clock.h
 generic-y += ucontext.h
 generic-y += user.h
diff --git a/arch/mips/include/asm/mach-generic/serial.h b/arch/mips/include/asm/mach-generic/serial.h
new file mode 100644
index 0000000..25932bb
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/serial.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Imagination Technologies
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_GENERIC_SERIAL_H__
+#define __MACH_GENERIC_SERIAL_H__
+
+#include <asm-generic/serial.h>
+
+#endif /* __MACH_GENERIC_SERIAL_H__ */
diff --git a/arch/mips/include/asm/serial.h b/arch/mips/include/asm/serial.h
new file mode 100644
index 0000000..a50e7b0
--- /dev/null
+++ b/arch/mips/include/asm/serial.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Imagination Technologies
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_SERIAL_H__
+#define __ASM_SERIAL_H__
+
+#include_next <serial.h>
+
+#endif /* __ASM_SERIAL_H__ */
-- 
1.9.1


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

* [PATCH_V2 26/34] MIPS: allow mach-provided serial.h
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Allow platforms to set BAUD_BASE, which is used by earlycon to calculate
the baud clock.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>

---
V2 Removed FSF address
---
 arch/mips/include/asm/Kbuild                |  1 -
 arch/mips/include/asm/mach-generic/serial.h | 21 +++++++++++++++++++++
 arch/mips/include/asm/serial.h              | 21 +++++++++++++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 arch/mips/include/asm/mach-generic/serial.h
 create mode 100644 arch/mips/include/asm/serial.h

diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 200efea..3cd9114 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -13,7 +13,6 @@ generic-y += preempt.h
 generic-y += scatterlist.h
 generic-y += sections.h
 generic-y += segment.h
-generic-y += serial.h
 generic-y += trace_clock.h
 generic-y += ucontext.h
 generic-y += user.h
diff --git a/arch/mips/include/asm/mach-generic/serial.h b/arch/mips/include/asm/mach-generic/serial.h
new file mode 100644
index 0000000..25932bb
--- /dev/null
+++ b/arch/mips/include/asm/mach-generic/serial.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Imagination Technologies
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_GENERIC_SERIAL_H__
+#define __MACH_GENERIC_SERIAL_H__
+
+#include <asm-generic/serial.h>
+
+#endif /* __MACH_GENERIC_SERIAL_H__ */
diff --git a/arch/mips/include/asm/serial.h b/arch/mips/include/asm/serial.h
new file mode 100644
index 0000000..a50e7b0
--- /dev/null
+++ b/arch/mips/include/asm/serial.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2015 Imagination Technologies
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __ASM_SERIAL_H__
+#define __ASM_SERIAL_H__
+
+#include_next <serial.h>
+
+#endif /* __ASM_SERIAL_H__ */
-- 
1.9.1

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

* [PATCH_V2 27/34] MIPS: jz4740: use jz47xx-uart & DT for UART output
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Remove the serial support from arch/mips/jz4740 & make use of the new
jz47xx-uart driver. This is done for both regular & early console
output.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>

---
V2 Removed FSF header
---
 arch/mips/Kconfig                            |  1 -
 arch/mips/boot/dts/jz4740.dtsi               | 22 ++++++++++++++
 arch/mips/boot/dts/qi_lb60.dts               |  4 +++
 arch/mips/configs/qi_lb60_defconfig          |  1 +
 arch/mips/include/asm/mach-jz4740/platform.h |  2 --
 arch/mips/include/asm/mach-jz4740/serial.h   | 21 +++++++++++++
 arch/mips/jz4740/Makefile                    |  2 +-
 arch/mips/jz4740/board-qi_lb60.c             |  2 --
 arch/mips/jz4740/platform.c                  | 44 ----------------------------
 arch/mips/jz4740/prom.c                      | 13 --------
 arch/mips/jz4740/serial.c                    | 33 ---------------------
 arch/mips/jz4740/serial.h                    | 23 ---------------
 12 files changed, 49 insertions(+), 119 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-jz4740/serial.h
 delete mode 100644 arch/mips/jz4740/serial.c
 delete mode 100644 arch/mips/jz4740/serial.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ef82cd3..622d0aa 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -285,7 +285,6 @@ config MACH_JZ4740
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select ARCH_REQUIRE_GPIOLIB
-	select SYS_HAS_EARLY_PRINTK
 	select COMMON_CLK
 	select GENERIC_IRQ_CHIP
 	select BUILTIN_DTB
diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
index ef679b4..c52d92d 100644
--- a/arch/mips/boot/dts/jz4740.dtsi
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -43,4 +43,26 @@
 
 		#clock-cells = <1>;
 	};
+
+	uart0: serial@10030000 {
+		compatible = "ingenic,jz4740-uart";
+		reg = <0x10030000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <9>;
+
+		clocks = <&ext>, <&cgu JZ4740_CLK_UART0>;
+		clock-names = "baud", "module";
+	};
+
+	uart1: serial@10031000 {
+		compatible = "ingenic,jz4740-uart";
+		reg = <0x10031000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <8>;
+
+		clocks = <&ext>, <&cgu JZ4740_CLK_UART1>;
+		clock-names = "baud", "module";
+	};
 };
diff --git a/arch/mips/boot/dts/qi_lb60.dts b/arch/mips/boot/dts/qi_lb60.dts
index 106d13c..2414d63 100644
--- a/arch/mips/boot/dts/qi_lb60.dts
+++ b/arch/mips/boot/dts/qi_lb60.dts
@@ -4,6 +4,10 @@
 
 / {
 	compatible = "qi,lb60", "ingenic,jz4740";
+
+	chosen {
+		stdout-path = &uart0;
+	};
 };
 
 &ext {
diff --git a/arch/mips/configs/qi_lb60_defconfig b/arch/mips/configs/qi_lb60_defconfig
index 2b96547..04371ab 100644
--- a/arch/mips/configs/qi_lb60_defconfig
+++ b/arch/mips/configs/qi_lb60_defconfig
@@ -66,6 +66,7 @@ CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_DMA is not set
 CONFIG_SERIAL_8250_NR_UARTS=2
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_JZ47XX=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=y
diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h
index 069b43a..32cfbe6 100644
--- a/arch/mips/include/asm/mach-jz4740/platform.h
+++ b/arch/mips/include/asm/mach-jz4740/platform.h
@@ -35,6 +35,4 @@ extern struct platform_device jz4740_wdt_device;
 extern struct platform_device jz4740_pwm_device;
 extern struct platform_device jz4740_dma_device;
 
-void jz4740_serial_device_register(void);
-
 #endif
diff --git a/arch/mips/include/asm/mach-jz4740/serial.h b/arch/mips/include/asm/mach-jz4740/serial.h
new file mode 100644
index 0000000..9f93563
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/serial.h
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2015 Imagination Technologies
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+
+#ifndef __JZ4740_SERIAL_H__
+#define __JZ4740_SERIAL_H__
+
+#define BASE_BAUD (12000000 / 16)
+
+#endif /* __JZ4740_SERIAL_H__ */
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 340dc16..ae72346 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -5,7 +5,7 @@
 # Object file lists.
 
 obj-y += prom.o irq.o time.o reset.o setup.o \
-	gpio.o platform.o timer.o serial.o
+	gpio.o platform.o timer.o
 
 CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
 
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 0fbb2d8..f84526d 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -473,8 +473,6 @@ static int __init qi_lb60_init_platform_devices(void)
 
 	gpiod_add_lookup_table(&qi_lb60_audio_gpio_table);
 
-	jz4740_serial_device_register();
-
 	spi_register_board_info(qi_lb60_spi_board_info,
 				ARRAY_SIZE(qi_lb60_spi_board_info));
 
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index 2a5c7c7..8226a36 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -280,50 +280,6 @@ struct platform_device jz4740_adc_device = {
 	.resource	= jz4740_adc_resources,
 };
 
-/* Serial */
-#define JZ4740_UART_DATA(_id) \
-	{ \
-		.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE, \
-		.iotype = UPIO_MEM, \
-		.regshift = 2, \
-		.serial_out = jz4740_serial_out, \
-		.type = PORT_16550, \
-		.mapbase = JZ4740_UART ## _id ## _BASE_ADDR, \
-		.irq = JZ4740_IRQ_UART ## _id, \
-	}
-
-static struct plat_serial8250_port jz4740_uart_data[] = {
-	JZ4740_UART_DATA(0),
-	JZ4740_UART_DATA(1),
-	{},
-};
-
-static struct platform_device jz4740_uart_device = {
-	.name = "serial8250",
-	.id = 0,
-	.dev = {
-		.platform_data = jz4740_uart_data,
-	},
-};
-
-void jz4740_serial_device_register(void)
-{
-	struct plat_serial8250_port *p;
-	struct clk *ext_clk;
-	unsigned long ext_rate;
-
-	ext_clk = clk_get(NULL, "ext");
-	if (IS_ERR(ext_clk))
-		panic("unable to get ext clock");
-	ext_rate = clk_get_rate(ext_clk);
-	clk_put(ext_clk);
-
-	for (p = jz4740_uart_data; p->flags != 0; ++p)
-		p->uartclk = ext_rate;
-
-	platform_device_register(&jz4740_uart_device);
-}
-
 /* Watchdog */
 static struct resource jz4740_wdt_resources[] = {
 	{
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
index 5a93f38..6984683 100644
--- a/arch/mips/jz4740/prom.c
+++ b/arch/mips/jz4740/prom.c
@@ -53,16 +53,3 @@ void __init prom_init(void)
 void __init prom_free_prom_memory(void)
 {
 }
-
-#define UART_REG(_reg) ((void __iomem *)CKSEG1ADDR(JZ4740_UART0_BASE_ADDR + (_reg << 2)))
-
-void prom_putchar(char c)
-{
-	uint8_t lsr;
-
-	do {
-		lsr = readb(UART_REG(UART_LSR));
-	} while ((lsr & UART_LSR_TEMT) == 0);
-
-	writeb(c, UART_REG(UART_TX));
-}
diff --git a/arch/mips/jz4740/serial.c b/arch/mips/jz4740/serial.c
deleted file mode 100644
index d23de45..0000000
--- a/arch/mips/jz4740/serial.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 serial support
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the	License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/io.h>
-#include <linux/serial_core.h>
-#include <linux/serial_reg.h>
-
-void jz4740_serial_out(struct uart_port *p, int offset, int value)
-{
-	switch (offset) {
-	case UART_FCR:
-		value |= 0x10; /* Enable uart module */
-		break;
-	case UART_IER:
-		value |= (value & 0x4) << 2;
-		break;
-	default:
-		break;
-	}
-	writeb(value, p->membase + (offset << p->regshift));
-}
diff --git a/arch/mips/jz4740/serial.h b/arch/mips/jz4740/serial.h
deleted file mode 100644
index 8eb715b..0000000
--- a/arch/mips/jz4740/serial.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 serial support
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the	License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __MIPS_JZ4740_SERIAL_H__
-#define __MIPS_JZ4740_SERIAL_H__
-
-struct uart_port;
-
-void jz4740_serial_out(struct uart_port *p, int offset, int value);
-
-#endif
-- 
1.9.1


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

* [PATCH_V2 27/34] MIPS: jz4740: use jz47xx-uart & DT for UART output
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Remove the serial support from arch/mips/jz4740 & make use of the new
jz47xx-uart driver. This is done for both regular & early console
output.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>

---
V2 Removed FSF header
---
 arch/mips/Kconfig                            |  1 -
 arch/mips/boot/dts/jz4740.dtsi               | 22 ++++++++++++++
 arch/mips/boot/dts/qi_lb60.dts               |  4 +++
 arch/mips/configs/qi_lb60_defconfig          |  1 +
 arch/mips/include/asm/mach-jz4740/platform.h |  2 --
 arch/mips/include/asm/mach-jz4740/serial.h   | 21 +++++++++++++
 arch/mips/jz4740/Makefile                    |  2 +-
 arch/mips/jz4740/board-qi_lb60.c             |  2 --
 arch/mips/jz4740/platform.c                  | 44 ----------------------------
 arch/mips/jz4740/prom.c                      | 13 --------
 arch/mips/jz4740/serial.c                    | 33 ---------------------
 arch/mips/jz4740/serial.h                    | 23 ---------------
 12 files changed, 49 insertions(+), 119 deletions(-)
 create mode 100644 arch/mips/include/asm/mach-jz4740/serial.h
 delete mode 100644 arch/mips/jz4740/serial.c
 delete mode 100644 arch/mips/jz4740/serial.h

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ef82cd3..622d0aa 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -285,7 +285,6 @@ config MACH_JZ4740
 	select DMA_NONCOHERENT
 	select IRQ_CPU
 	select ARCH_REQUIRE_GPIOLIB
-	select SYS_HAS_EARLY_PRINTK
 	select COMMON_CLK
 	select GENERIC_IRQ_CHIP
 	select BUILTIN_DTB
diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
index ef679b4..c52d92d 100644
--- a/arch/mips/boot/dts/jz4740.dtsi
+++ b/arch/mips/boot/dts/jz4740.dtsi
@@ -43,4 +43,26 @@
 
 		#clock-cells = <1>;
 	};
+
+	uart0: serial@10030000 {
+		compatible = "ingenic,jz4740-uart";
+		reg = <0x10030000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <9>;
+
+		clocks = <&ext>, <&cgu JZ4740_CLK_UART0>;
+		clock-names = "baud", "module";
+	};
+
+	uart1: serial@10031000 {
+		compatible = "ingenic,jz4740-uart";
+		reg = <0x10031000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <8>;
+
+		clocks = <&ext>, <&cgu JZ4740_CLK_UART1>;
+		clock-names = "baud", "module";
+	};
 };
diff --git a/arch/mips/boot/dts/qi_lb60.dts b/arch/mips/boot/dts/qi_lb60.dts
index 106d13c..2414d63 100644
--- a/arch/mips/boot/dts/qi_lb60.dts
+++ b/arch/mips/boot/dts/qi_lb60.dts
@@ -4,6 +4,10 @@
 
 / {
 	compatible = "qi,lb60", "ingenic,jz4740";
+
+	chosen {
+		stdout-path = &uart0;
+	};
 };
 
 &ext {
diff --git a/arch/mips/configs/qi_lb60_defconfig b/arch/mips/configs/qi_lb60_defconfig
index 2b96547..04371ab 100644
--- a/arch/mips/configs/qi_lb60_defconfig
+++ b/arch/mips/configs/qi_lb60_defconfig
@@ -66,6 +66,7 @@ CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_DMA is not set
 CONFIG_SERIAL_8250_NR_UARTS=2
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_JZ47XX=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=y
diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h
index 069b43a..32cfbe6 100644
--- a/arch/mips/include/asm/mach-jz4740/platform.h
+++ b/arch/mips/include/asm/mach-jz4740/platform.h
@@ -35,6 +35,4 @@ extern struct platform_device jz4740_wdt_device;
 extern struct platform_device jz4740_pwm_device;
 extern struct platform_device jz4740_dma_device;
 
-void jz4740_serial_device_register(void);
-
 #endif
diff --git a/arch/mips/include/asm/mach-jz4740/serial.h b/arch/mips/include/asm/mach-jz4740/serial.h
new file mode 100644
index 0000000..9f93563
--- /dev/null
+++ b/arch/mips/include/asm/mach-jz4740/serial.h
@@ -0,0 +1,21 @@
+/*
+* Copyright (c) 2015 Imagination Technologies
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+*/
+
+#ifndef __JZ4740_SERIAL_H__
+#define __JZ4740_SERIAL_H__
+
+#define BASE_BAUD (12000000 / 16)
+
+#endif /* __JZ4740_SERIAL_H__ */
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index 340dc16..ae72346 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -5,7 +5,7 @@
 # Object file lists.
 
 obj-y += prom.o irq.o time.o reset.o setup.o \
-	gpio.o platform.o timer.o serial.o
+	gpio.o platform.o timer.o
 
 CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
 
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 0fbb2d8..f84526d 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -473,8 +473,6 @@ static int __init qi_lb60_init_platform_devices(void)
 
 	gpiod_add_lookup_table(&qi_lb60_audio_gpio_table);
 
-	jz4740_serial_device_register();
-
 	spi_register_board_info(qi_lb60_spi_board_info,
 				ARRAY_SIZE(qi_lb60_spi_board_info));
 
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index 2a5c7c7..8226a36 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -280,50 +280,6 @@ struct platform_device jz4740_adc_device = {
 	.resource	= jz4740_adc_resources,
 };
 
-/* Serial */
-#define JZ4740_UART_DATA(_id) \
-	{ \
-		.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE, \
-		.iotype = UPIO_MEM, \
-		.regshift = 2, \
-		.serial_out = jz4740_serial_out, \
-		.type = PORT_16550, \
-		.mapbase = JZ4740_UART ## _id ## _BASE_ADDR, \
-		.irq = JZ4740_IRQ_UART ## _id, \
-	}
-
-static struct plat_serial8250_port jz4740_uart_data[] = {
-	JZ4740_UART_DATA(0),
-	JZ4740_UART_DATA(1),
-	{},
-};
-
-static struct platform_device jz4740_uart_device = {
-	.name = "serial8250",
-	.id = 0,
-	.dev = {
-		.platform_data = jz4740_uart_data,
-	},
-};
-
-void jz4740_serial_device_register(void)
-{
-	struct plat_serial8250_port *p;
-	struct clk *ext_clk;
-	unsigned long ext_rate;
-
-	ext_clk = clk_get(NULL, "ext");
-	if (IS_ERR(ext_clk))
-		panic("unable to get ext clock");
-	ext_rate = clk_get_rate(ext_clk);
-	clk_put(ext_clk);
-
-	for (p = jz4740_uart_data; p->flags != 0; ++p)
-		p->uartclk = ext_rate;
-
-	platform_device_register(&jz4740_uart_device);
-}
-
 /* Watchdog */
 static struct resource jz4740_wdt_resources[] = {
 	{
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
index 5a93f38..6984683 100644
--- a/arch/mips/jz4740/prom.c
+++ b/arch/mips/jz4740/prom.c
@@ -53,16 +53,3 @@ void __init prom_init(void)
 void __init prom_free_prom_memory(void)
 {
 }
-
-#define UART_REG(_reg) ((void __iomem *)CKSEG1ADDR(JZ4740_UART0_BASE_ADDR + (_reg << 2)))
-
-void prom_putchar(char c)
-{
-	uint8_t lsr;
-
-	do {
-		lsr = readb(UART_REG(UART_LSR));
-	} while ((lsr & UART_LSR_TEMT) == 0);
-
-	writeb(c, UART_REG(UART_TX));
-}
diff --git a/arch/mips/jz4740/serial.c b/arch/mips/jz4740/serial.c
deleted file mode 100644
index d23de45..0000000
--- a/arch/mips/jz4740/serial.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 serial support
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the	License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/io.h>
-#include <linux/serial_core.h>
-#include <linux/serial_reg.h>
-
-void jz4740_serial_out(struct uart_port *p, int offset, int value)
-{
-	switch (offset) {
-	case UART_FCR:
-		value |= 0x10; /* Enable uart module */
-		break;
-	case UART_IER:
-		value |= (value & 0x4) << 2;
-		break;
-	default:
-		break;
-	}
-	writeb(value, p->membase + (offset << p->regshift));
-}
diff --git a/arch/mips/jz4740/serial.h b/arch/mips/jz4740/serial.h
deleted file mode 100644
index 8eb715b..0000000
--- a/arch/mips/jz4740/serial.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 serial support
- *
- *  This program is free software; you can redistribute	 it and/or modify it
- *  under  the terms of	 the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the	License, or (at your
- *  option) any later version.
- *
- *  You should have received a copy of the  GNU General Public License along
- *  with this program; if not, write  to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __MIPS_JZ4740_SERIAL_H__
-#define __MIPS_JZ4740_SERIAL_H__
-
-struct uart_port;
-
-void jz4740_serial_out(struct uart_port *p, int offset, int value);
-
-#endif
-- 
1.9.1

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

* [PATCH_V2 28/34] dt: clk: Add ingenic,jz4780-cgu binding documentation
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Document the devictree binding for the Ingenic jz4780 CGU driver.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: devicetree@vger.kernel.org
---
 .../bindings/clock/ingenic,jz4780-cgu.txt          | 52 +++++++++++++
 include/dt-bindings/clock/jz4780-cgu.h             | 88 ++++++++++++++++++++++
 2 files changed, 140 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
 create mode 100644 include/dt-bindings/clock/jz4780-cgu.h

diff --git a/Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt b/Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
new file mode 100644
index 0000000..2432a49
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
@@ -0,0 +1,52 @@
+Ingenic jz4780 SoC CGU binding
+
+The CGU in a jz4780 SoC provides all the clocks generated on-chip. It includes
+PLLs, multiplexers, dividers & gates in order to provide a variety of different
+clock signals derived from only 2 external source clocks.
+
+Required properties:
+- compatible: Should be "ingenic,jz4780-cgu"
+- reg: Should be the address & length of the CGU registers
+- clocks: Should contain the phandle & clock specifier for two clocks external
+          to the TCU. First the external crystal "ext" and second the RTC
+          clock source "rtc".
+- clock-names: Should be set to strings naming the clocks specified in the
+               "clocks" property.
+- #clock-cells: Should be 1.
+                Clock consumers specify this argument to identify a clock. The
+                valid values may be found in <dt-bindings/clock/jz4780-cgu.h>.
+
+Example SoC include file:
+
+/ {
+	cgu: jz4780-cgu {
+		compatible = "ingenic,jz4780-cgu";
+		reg = <0x10000000 0x100>;
+		#clock-cells = <1>;
+	};
+
+	uart0: serial@10030000 {
+		clocks = <&cgu JZ4780_CLK_UART0>;
+	};
+};
+
+Example board file:
+
+/ {
+	ext: clock@0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <48000000>;
+	};
+
+	rtc: clock@1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	&cgu {
+		clocks = <&ext> <&rtc>;
+		clock-names: "ext", "rtc";
+	};
+};
diff --git a/include/dt-bindings/clock/jz4780-cgu.h b/include/dt-bindings/clock/jz4780-cgu.h
new file mode 100644
index 0000000..467165e
--- /dev/null
+++ b/include/dt-bindings/clock/jz4780-cgu.h
@@ -0,0 +1,88 @@
+/*
+ * This header provides clock numbers for the ingenic,jz4780-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers in the order they appear in the jz4780 programmers manual
+ *   - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+
+#define JZ4780_CLK_EXCLK	0
+#define JZ4780_CLK_RTCLK	1
+#define JZ4780_CLK_APLL		2
+#define JZ4780_CLK_MPLL		3
+#define JZ4780_CLK_EPLL		4
+#define JZ4780_CLK_VPLL		5
+#define JZ4780_CLK_OTGPHY	6
+#define JZ4780_CLK_SCLKA	7
+#define JZ4780_CLK_CPUMUX	8
+#define JZ4780_CLK_CPU		9
+#define JZ4780_CLK_L2CACHE	10
+#define JZ4780_CLK_AHB0		11
+#define JZ4780_CLK_AHB2PMUX	12
+#define JZ4780_CLK_AHB2		13
+#define JZ4780_CLK_PCLK		14
+#define JZ4780_CLK_DDR		15
+#define JZ4780_CLK_VPU		16
+#define JZ4780_CLK_I2SPLL	17
+#define JZ4780_CLK_I2S		18
+#define JZ4780_CLK_LCD0PIXCLK	19
+#define JZ4780_CLK_LCD1PIXCLK	20
+#define JZ4780_CLK_MSCMUX	21
+#define JZ4780_CLK_MSC0		22
+#define JZ4780_CLK_MSC1		23
+#define JZ4780_CLK_MSC2		24
+#define JZ4780_CLK_UHC		25
+#define JZ4780_CLK_SSIPLL	26
+#define JZ4780_CLK_SSI		27
+#define JZ4780_CLK_CIMMCLK	28
+#define JZ4780_CLK_PCMPLL	29
+#define JZ4780_CLK_PCM		30
+#define JZ4780_CLK_GPU		31
+#define JZ4780_CLK_HDMI		32
+#define JZ4780_CLK_BCH		33
+#define JZ4780_CLK_NEMC		34
+#define JZ4780_CLK_OTG0		35
+#define JZ4780_CLK_SSI0		36
+#define JZ4780_CLK_SMB0		37
+#define JZ4780_CLK_SMB1		38
+#define JZ4780_CLK_SCC		39
+#define JZ4780_CLK_AIC		40
+#define JZ4780_CLK_TSSI0	41
+#define JZ4780_CLK_OWI		42
+#define JZ4780_CLK_KBC		43
+#define JZ4780_CLK_SADC		44
+#define JZ4780_CLK_UART0	45
+#define JZ4780_CLK_UART1	46
+#define JZ4780_CLK_UART2	47
+#define JZ4780_CLK_UART3	48
+#define JZ4780_CLK_SSI1		49
+#define JZ4780_CLK_SSI2		50
+#define JZ4780_CLK_PDMA		51
+#define JZ4780_CLK_GPS		52
+#define JZ4780_CLK_MAC		53
+#define JZ4780_CLK_SMB2		54
+#define JZ4780_CLK_CIM		55
+#define JZ4780_CLK_LCD		56
+#define JZ4780_CLK_TVE		57
+#define JZ4780_CLK_IPU		58
+#define JZ4780_CLK_DDR0		59
+#define JZ4780_CLK_DDR1		60
+#define JZ4780_CLK_SMB3		61
+#define JZ4780_CLK_TSSI1	62
+#define JZ4780_CLK_COMPRESS	63
+#define JZ4780_CLK_AIC1		64
+#define JZ4780_CLK_GPVLC	65
+#define JZ4780_CLK_OTG1		66
+#define JZ4780_CLK_UART4	67
+#define JZ4780_CLK_AHBMON	68
+#define JZ4780_CLK_SMB4		69
+#define JZ4780_CLK_DES		70
+#define JZ4780_CLK_X2D		71
+#define JZ4780_CLK_CORE1	72
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */
-- 
1.9.1


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

* [PATCH_V2 28/34] dt: clk: Add ingenic,jz4780-cgu binding documentation
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Document the devictree binding for the Ingenic jz4780 CGU driver.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: devicetree@vger.kernel.org
---
 .../bindings/clock/ingenic,jz4780-cgu.txt          | 52 +++++++++++++
 include/dt-bindings/clock/jz4780-cgu.h             | 88 ++++++++++++++++++++++
 2 files changed, 140 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
 create mode 100644 include/dt-bindings/clock/jz4780-cgu.h

diff --git a/Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt b/Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
new file mode 100644
index 0000000..2432a49
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
@@ -0,0 +1,52 @@
+Ingenic jz4780 SoC CGU binding
+
+The CGU in a jz4780 SoC provides all the clocks generated on-chip. It includes
+PLLs, multiplexers, dividers & gates in order to provide a variety of different
+clock signals derived from only 2 external source clocks.
+
+Required properties:
+- compatible: Should be "ingenic,jz4780-cgu"
+- reg: Should be the address & length of the CGU registers
+- clocks: Should contain the phandle & clock specifier for two clocks external
+          to the TCU. First the external crystal "ext" and second the RTC
+          clock source "rtc".
+- clock-names: Should be set to strings naming the clocks specified in the
+               "clocks" property.
+- #clock-cells: Should be 1.
+                Clock consumers specify this argument to identify a clock. The
+                valid values may be found in <dt-bindings/clock/jz4780-cgu.h>.
+
+Example SoC include file:
+
+/ {
+	cgu: jz4780-cgu {
+		compatible = "ingenic,jz4780-cgu";
+		reg = <0x10000000 0x100>;
+		#clock-cells = <1>;
+	};
+
+	uart0: serial@10030000 {
+		clocks = <&cgu JZ4780_CLK_UART0>;
+	};
+};
+
+Example board file:
+
+/ {
+	ext: clock@0 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <48000000>;
+	};
+
+	rtc: clock@1 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	&cgu {
+		clocks = <&ext> <&rtc>;
+		clock-names: "ext", "rtc";
+	};
+};
diff --git a/include/dt-bindings/clock/jz4780-cgu.h b/include/dt-bindings/clock/jz4780-cgu.h
new file mode 100644
index 0000000..467165e
--- /dev/null
+++ b/include/dt-bindings/clock/jz4780-cgu.h
@@ -0,0 +1,88 @@
+/*
+ * This header provides clock numbers for the ingenic,jz4780-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers in the order they appear in the jz4780 programmers manual
+ *   - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+
+#define JZ4780_CLK_EXCLK	0
+#define JZ4780_CLK_RTCLK	1
+#define JZ4780_CLK_APLL		2
+#define JZ4780_CLK_MPLL		3
+#define JZ4780_CLK_EPLL		4
+#define JZ4780_CLK_VPLL		5
+#define JZ4780_CLK_OTGPHY	6
+#define JZ4780_CLK_SCLKA	7
+#define JZ4780_CLK_CPUMUX	8
+#define JZ4780_CLK_CPU		9
+#define JZ4780_CLK_L2CACHE	10
+#define JZ4780_CLK_AHB0		11
+#define JZ4780_CLK_AHB2PMUX	12
+#define JZ4780_CLK_AHB2		13
+#define JZ4780_CLK_PCLK		14
+#define JZ4780_CLK_DDR		15
+#define JZ4780_CLK_VPU		16
+#define JZ4780_CLK_I2SPLL	17
+#define JZ4780_CLK_I2S		18
+#define JZ4780_CLK_LCD0PIXCLK	19
+#define JZ4780_CLK_LCD1PIXCLK	20
+#define JZ4780_CLK_MSCMUX	21
+#define JZ4780_CLK_MSC0		22
+#define JZ4780_CLK_MSC1		23
+#define JZ4780_CLK_MSC2		24
+#define JZ4780_CLK_UHC		25
+#define JZ4780_CLK_SSIPLL	26
+#define JZ4780_CLK_SSI		27
+#define JZ4780_CLK_CIMMCLK	28
+#define JZ4780_CLK_PCMPLL	29
+#define JZ4780_CLK_PCM		30
+#define JZ4780_CLK_GPU		31
+#define JZ4780_CLK_HDMI		32
+#define JZ4780_CLK_BCH		33
+#define JZ4780_CLK_NEMC		34
+#define JZ4780_CLK_OTG0		35
+#define JZ4780_CLK_SSI0		36
+#define JZ4780_CLK_SMB0		37
+#define JZ4780_CLK_SMB1		38
+#define JZ4780_CLK_SCC		39
+#define JZ4780_CLK_AIC		40
+#define JZ4780_CLK_TSSI0	41
+#define JZ4780_CLK_OWI		42
+#define JZ4780_CLK_KBC		43
+#define JZ4780_CLK_SADC		44
+#define JZ4780_CLK_UART0	45
+#define JZ4780_CLK_UART1	46
+#define JZ4780_CLK_UART2	47
+#define JZ4780_CLK_UART3	48
+#define JZ4780_CLK_SSI1		49
+#define JZ4780_CLK_SSI2		50
+#define JZ4780_CLK_PDMA		51
+#define JZ4780_CLK_GPS		52
+#define JZ4780_CLK_MAC		53
+#define JZ4780_CLK_SMB2		54
+#define JZ4780_CLK_CIM		55
+#define JZ4780_CLK_LCD		56
+#define JZ4780_CLK_TVE		57
+#define JZ4780_CLK_IPU		58
+#define JZ4780_CLK_DDR0		59
+#define JZ4780_CLK_DDR1		60
+#define JZ4780_CLK_SMB3		61
+#define JZ4780_CLK_TSSI1	62
+#define JZ4780_CLK_COMPRESS	63
+#define JZ4780_CLK_AIC1		64
+#define JZ4780_CLK_GPVLC	65
+#define JZ4780_CLK_OTG1		66
+#define JZ4780_CLK_UART4	67
+#define JZ4780_CLK_AHBMON	68
+#define JZ4780_CLK_SMB4		69
+#define JZ4780_CLK_DES		70
+#define JZ4780_CLK_X2D		71
+#define JZ4780_CLK_CORE1	72
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */
-- 
1.9.1

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

* [PATCH_V2 29/34] clk: add Ingenic jz4780 CGU driver
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add support for the clocks provided by the CGU in the Ingenic jz4780
SoC, making use of the jz47xx-cgu code to do the heavy lifting.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>

---
V2 Removed FSF header
---
 drivers/clk/Makefile            |   1 +
 drivers/clk/jz47xx/Makefile     |   1 +
 drivers/clk/jz47xx/jz4780-cgu.c | 742 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 744 insertions(+)
 create mode 100644 drivers/clk/jz47xx/jz4780-cgu.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index fc434c0..3eac9e2 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_ARCH_HI3xxx)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIP04)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIX5HD2)		+= hisilicon/
 obj-$(CONFIG_MACH_JZ4740)		+= jz47xx/
+obj-$(CONFIG_MACH_JZ4780)		+= jz47xx/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)	+= keystone/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
diff --git a/drivers/clk/jz47xx/Makefile b/drivers/clk/jz47xx/Makefile
index 21746fc..5e0b845 100644
--- a/drivers/clk/jz47xx/Makefile
+++ b/drivers/clk/jz47xx/Makefile
@@ -1,2 +1,3 @@
 obj-y				+= jz47xx-cgu.o
 obj-$(CONFIG_MACH_JZ4740)	+= jz4740-cgu.o
+obj-$(CONFIG_MACH_JZ4780)	+= jz4780-cgu.o
diff --git a/drivers/clk/jz47xx/jz4780-cgu.c b/drivers/clk/jz47xx/jz4780-cgu.c
new file mode 100644
index 0000000..054db6e
--- /dev/null
+++ b/drivers/clk/jz47xx/jz4780-cgu.c
@@ -0,0 +1,742 @@
+/*
+ * Ingenic jz4780 SoC CGU driver
+ *
+ * Copyright (c) 2013-2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <dt-bindings/clock/jz4780-cgu.h>
+#include "jz47xx-cgu.h"
+
+/* CGU register offsets */
+#define CGU_REG_CLOCKCONTROL	0x00
+#define CGU_REG_PLLCONTROL	0x0c
+#define CGU_REG_APLL		0x10
+#define CGU_REG_MPLL		0x14
+#define CGU_REG_EPLL		0x18
+#define CGU_REG_VPLL		0x1c
+#define CGU_REG_OPCR		0x24
+#define CGU_REG_DDRCDR		0x2c
+#define CGU_REG_VPUCDR		0x30
+#define CGU_REG_USBPCR		0x3c
+#define CGU_REG_USBRDT		0x40
+#define CGU_REG_USBVBFIL	0x44
+#define CGU_REG_USBPCR1		0x48
+#define CGU_REG_LP0CDR		0x54
+#define CGU_REG_I2SCDR		0x60
+#define CGU_REG_LP1CDR		0x64
+#define CGU_REG_MSC0CDR		0x68
+#define CGU_REG_UHCCDR		0x6c
+#define CGU_REG_SSICDR		0x74
+#define CGU_REG_CIMCDR		0x7c
+#define CGU_REG_PCMCDR		0x84
+#define CGU_REG_GPUCDR		0x88
+#define CGU_REG_HDMICDR		0x8c
+#define CGU_REG_MSC1CDR		0xa4
+#define CGU_REG_MSC2CDR		0xa8
+#define CGU_REG_BCHCDR		0xac
+#define CGU_REG_CLOCKSTATUS	0xd4
+
+/* bits within a PLL control register */
+#define PLLCTL_M_SHIFT		19
+#define PLLCTL_M_MASK		(0x1fff << PLLCTL_M_SHIFT)
+#define PLLCTL_N_SHIFT		13
+#define PLLCTL_N_MASK		(0x3f << PLLCTL_N_SHIFT)
+#define PLLCTL_OD_SHIFT		9
+#define PLLCTL_OD_MASK		(0xf << PLLCTL_OD_SHIFT)
+#define PLLCTL_ON		(1 << 4)
+#define PLLCTL_BYPASS		(1 << 1)
+#define PLLCTL_ENABLE		(1 << 0)
+
+/* bits within the OPCR register */
+#define OPCR_SPENDN0		(1 << 7)
+#define OPCR_SPENDN1		(1 << 6)
+
+/* bits within the USBPCR register */
+#define USBPCR_USB_MODE		BIT(31)
+#define USBPCR_IDPULLUP_MASK	(0x3 << 28)
+#define USBPCR_COMMONONN	BIT(25)
+#define USBPCR_VBUSVLDEXT	BIT(24)
+#define USBPCR_VBUSVLDEXTSEL	BIT(23)
+#define USBPCR_POR		BIT(22)
+#define USBPCR_OTG_DISABLE	BIT(20)
+#define USBPCR_COMPDISTUNE_MASK	(0x7 << 17)
+#define USBPCR_OTGTUNE_MASK	(0x7 << 14)
+#define USBPCR_SQRXTUNE_MASK	(0x7 << 11)
+#define USBPCR_TXFSLSTUNE_MASK	(0xf << 7)
+#define USBPCR_TXPREEMPHTUNE	BIT(6)
+#define USBPCR_TXHSXVTUNE_MASK	(0x3 << 4)
+#define USBPCR_TXVREFTUNE_MASK	0xf
+
+/* bits within the USBPCR1 register */
+#define USBPCR1_REFCLKSEL_SHIFT	26
+#define USBPCR1_REFCLKSEL_MASK	(0x3 << USBPCR1_REFCLKSEL_SHIFT)
+#define USBPCR1_REFCLKSEL_CORE	(0x2 << USBPCR1_REFCLKSEL_SHIFT)
+#define USBPCR1_REFCLKDIV_SHIFT	24
+#define USBPCR1_REFCLKDIV_MASK	(0x3 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_19_2	(0x3 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_48	(0x2 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_24	(0x1 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_12	(0x0 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_USB_SEL		BIT(28)
+#define USBPCR1_WORD_IF0	BIT(19)
+#define USBPCR1_WORD_IF1	BIT(18)
+
+/* bits within the USBRDT register */
+#define USBRDT_VBFIL_LD_EN	BIT(25)
+#define USBRDT_USBRDT_MASK	0x7fffff
+
+/* bits within the USBVBFIL register */
+#define USBVBFIL_IDDIGFIL_SHIFT	16
+#define USBVBFIL_IDDIGFIL_MASK	(0xffff << USBVBFIL_IDDIGFIL_SHIFT)
+#define USBVBFIL_USBVBFIL_MASK	(0xffff)
+
+static struct jz47xx_cgu *cgu;
+
+static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw)
+{
+	/* we only use CLKCORE, revisit if that ever changes */
+	return 0;
+}
+
+static int jz4780_otg_phy_set_parent(struct clk_hw *hw, u8 idx)
+{
+	unsigned long flags;
+	u32 usbpcr1;
+
+	if (idx > 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&cgu->power_lock, flags);
+
+	usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+	usbpcr1 &= ~USBPCR1_REFCLKSEL_MASK;
+	/* we only use CLKCORE */
+	usbpcr1 |= USBPCR1_REFCLKSEL_CORE;
+	writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
+
+	spin_unlock_irqrestore(&cgu->power_lock, flags);
+	return 0;
+}
+
+static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	u32 usbpcr1;
+	unsigned refclk_div;
+
+	usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+	refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK;
+
+	switch (refclk_div) {
+	case USBPCR1_REFCLKDIV_12:
+		return 12000000;
+
+	case USBPCR1_REFCLKDIV_24:
+		return 24000000;
+
+	case USBPCR1_REFCLKDIV_48:
+		return 48000000;
+
+	case USBPCR1_REFCLKDIV_19_2:
+		return 19200000;
+	}
+
+	BUG();
+	return parent_rate;
+}
+
+static long jz4780_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate,
+				      unsigned long *parent_rate)
+{
+	if (req_rate < 15600000)
+		return 12000000;
+
+	if (req_rate < 21600000)
+		return 19200000;
+
+	if (req_rate < 36000000)
+		return 24000000;
+
+	return 48000000;
+}
+
+static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
+				   unsigned long parent_rate)
+{
+	unsigned long flags;
+	u32 usbpcr1, div_bits;
+
+	switch (req_rate) {
+	case 12000000:
+		div_bits = USBPCR1_REFCLKDIV_12;
+		break;
+
+	case 19200000:
+		div_bits = USBPCR1_REFCLKDIV_19_2;
+		break;
+
+	case 24000000:
+		div_bits = USBPCR1_REFCLKDIV_24;
+		break;
+
+	case 48000000:
+		div_bits = USBPCR1_REFCLKDIV_48;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&cgu->power_lock, flags);
+
+	usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+	usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK;
+	usbpcr1 |= div_bits;
+	writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
+
+	spin_unlock_irqrestore(&cgu->power_lock, flags);
+	return 0;
+}
+
+struct clk_ops jz4780_otg_phy_ops = {
+	.get_parent = jz4780_otg_phy_get_parent,
+	.set_parent = jz4780_otg_phy_set_parent,
+
+	.recalc_rate = jz4780_otg_phy_recalc_rate,
+	.round_rate = jz4780_otg_phy_round_rate,
+	.set_rate = jz4780_otg_phy_set_rate,
+};
+
+static const s8 pll_od_encoding[16] = {
+	0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+	0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+};
+
+static const struct jz47xx_cgu_clk_info jz4780_cgu_clocks[] = {
+
+	/* External clocks */
+
+	[JZ4780_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
+	[JZ4780_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
+
+	/* PLLs */
+
+#define DEF_PLL(name) { \
+	.reg = CGU_REG_ ## name, \
+	.m_shift = 19, \
+	.m_bits = 13, \
+	.m_offset = 1, \
+	.n_shift = 13, \
+	.n_bits = 6, \
+	.n_offset = 1, \
+	.od_shift = 9, \
+	.od_bits = 4, \
+	.od_max = 16, \
+	.od_encoding = pll_od_encoding, \
+	.stable_bit = 6, \
+	.bypass_bit = 1, \
+	.enable_bit = 0, \
+}
+
+	[JZ4780_CLK_APLL] = {
+		"apll", CGU_CLK_PLL,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.pll = DEF_PLL(APLL),
+	},
+
+	[JZ4780_CLK_MPLL] = {
+		"mpll", CGU_CLK_PLL,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.pll = DEF_PLL(MPLL),
+	},
+
+	[JZ4780_CLK_EPLL] = {
+		"epll", CGU_CLK_PLL,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.pll = DEF_PLL(EPLL),
+	},
+
+	[JZ4780_CLK_VPLL] = {
+		"vpll", CGU_CLK_PLL,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.pll = DEF_PLL(VPLL),
+	},
+
+#undef DEF_PLL
+
+	/* Custom (SoC-specific) OTG PHY */
+
+	[JZ4780_CLK_OTGPHY] = {
+		"otg_phy", CGU_CLK_CUSTOM,
+		.parents = { -1, -1, JZ4780_CLK_EXCLK, -1 },
+		.custom = { &jz4780_otg_phy_ops },
+	},
+
+	/* Muxes & dividers */
+
+	[JZ4780_CLK_SCLKA] = {
+		"sclk_a", CGU_CLK_MUX,
+		.parents = { -1, JZ4780_CLK_APLL, JZ4780_CLK_EXCLK,
+			     JZ4780_CLK_RTCLK },
+		.mux = { CGU_REG_CLOCKCONTROL, 30, 2 },
+	},
+
+	[JZ4780_CLK_CPUMUX] = {
+		"cpumux", CGU_CLK_MUX,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL },
+		.mux = { CGU_REG_CLOCKCONTROL, 28, 2 },
+	},
+
+	[JZ4780_CLK_CPU] = {
+		"cpu", CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_CPUMUX, -1 },
+		.div = { CGU_REG_CLOCKCONTROL, 0, 4, 22, -1, -1 },
+	},
+
+	[JZ4780_CLK_L2CACHE] = {
+		"l2cache", CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_CPUMUX, -1 },
+		.div = { CGU_REG_CLOCKCONTROL, 4, 4, -1, -1, -1 },
+	},
+
+	[JZ4780_CLK_AHB0] = {
+		"ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL },
+		.mux = { CGU_REG_CLOCKCONTROL, 26, 2 },
+		.div = { CGU_REG_CLOCKCONTROL, 8, 4, 21, -1, -1 },
+	},
+
+	[JZ4780_CLK_AHB2PMUX] = {
+		"ahb2_apb_mux", CGU_CLK_MUX,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_RTCLK },
+		.mux = { CGU_REG_CLOCKCONTROL, 24, 2 },
+	},
+
+	[JZ4780_CLK_AHB2] = {
+		"ahb2", CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_AHB2PMUX, -1 },
+		.div = { CGU_REG_CLOCKCONTROL, 12, 4, 20, -1, -1 },
+	},
+
+	[JZ4780_CLK_PCLK] = {
+		"pclk", CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_AHB2PMUX, -1 },
+		.div = { CGU_REG_CLOCKCONTROL, 16, 4, 20, -1, -1 },
+	},
+
+	[JZ4780_CLK_DDR] = {
+		"ddr", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+		.mux = { CGU_REG_DDRCDR, 30, 2 },
+		.div = { CGU_REG_DDRCDR, 0, 4, 29, 28, 27 },
+	},
+
+	[JZ4780_CLK_VPU] = {
+		"vpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL, -1 },
+		.mux = { CGU_REG_VPUCDR, 30, 2 },
+		.div = { CGU_REG_VPUCDR, 0, 4, 29, 28, 27 },
+		.gate_bit = 32 + 2,
+	},
+
+	[JZ4780_CLK_I2SPLL] = {
+		"i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1 },
+		.mux = { CGU_REG_I2SCDR, 30, 1 },
+		.div = { CGU_REG_I2SCDR, 0, 8, 29, 28, 27 },
+	},
+
+	[JZ4780_CLK_I2S] = {
+		"i2s", CGU_CLK_MUX,
+		.parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_I2SPLL, -1 },
+		.mux = { CGU_REG_I2SCDR, 31, 1 },
+	},
+
+	[JZ4780_CLK_LCD0PIXCLK] = {
+		"lcd0pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_VPLL, -1 },
+		.mux = { CGU_REG_LP0CDR, 30, 2 },
+		.div = { CGU_REG_LP0CDR, 0, 8, 28, 27, 26 },
+	},
+
+	[JZ4780_CLK_LCD1PIXCLK] = {
+		"lcd1pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_VPLL, -1 },
+		.mux = { CGU_REG_LP1CDR, 30, 2 },
+		.div = { CGU_REG_LP1CDR, 0, 8, 28, 27, 26 },
+	},
+
+	[JZ4780_CLK_MSCMUX] = {
+		"msc_mux", CGU_CLK_MUX,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+		.mux = { CGU_REG_MSC0CDR, 30, 2 },
+	},
+
+	[JZ4780_CLK_MSC0] = {
+		"msc0", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_MSCMUX, -1 },
+		.div = { CGU_REG_MSC0CDR, 0, 8, 29, 28, 27 },
+		.gate_bit = 3,
+	},
+
+	[JZ4780_CLK_MSC1] = {
+		"msc1", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_MSCMUX, -1 },
+		.div = { CGU_REG_MSC1CDR, 0, 8, 29, 28, 27 },
+		.gate_bit = 11,
+	},
+
+	[JZ4780_CLK_MSC2] = {
+		"msc2", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_MSCMUX, -1 },
+		.div = { CGU_REG_MSC2CDR, 0, 8, 29, 28, 27 },
+		.gate_bit = 12,
+	},
+
+	[JZ4780_CLK_UHC] = {
+		"uhc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY },
+		.mux = { CGU_REG_UHCCDR, 30, 2 },
+		.div = { CGU_REG_UHCCDR, 0, 8, 29, 28, 27 },
+		.gate_bit = 24,
+	},
+
+	[JZ4780_CLK_SSIPLL] = {
+		"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+		.mux = { CGU_REG_SSICDR, 30, 1 },
+		.div = { CGU_REG_SSICDR, 0, 8, 29, 28, 27 },
+	},
+
+	[JZ4780_CLK_SSI] = {
+		"ssi", CGU_CLK_MUX,
+		.parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_SSIPLL, -1 },
+		.mux = { CGU_REG_SSICDR, 31, 1 },
+	},
+
+	[JZ4780_CLK_CIMMCLK] = {
+		"cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+		.mux = { CGU_REG_CIMCDR, 31, 1 },
+		.div = { CGU_REG_CIMCDR, 0, 8, 30, 29, 28 },
+	},
+
+	[JZ4780_CLK_PCMPLL] = {
+		"pcm_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL, JZ4780_CLK_VPLL },
+		.mux = { CGU_REG_PCMCDR, 29, 2 },
+		.div = { CGU_REG_PCMCDR, 0, 8, 28, 27, 26 },
+	},
+
+	[JZ4780_CLK_PCM] = {
+		"pcm", CGU_CLK_MUX | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_PCMPLL, -1 },
+		.mux = { CGU_REG_PCMCDR, 31, 1 },
+		.gate_bit = 32 + 3,
+	},
+
+	[JZ4780_CLK_GPU] = {
+		"gpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL },
+		.mux = { CGU_REG_GPUCDR, 30, 2 },
+		.div = { CGU_REG_GPUCDR, 0, 4, 29, 28, 27 },
+		.gate_bit = 32 + 4,
+	},
+
+	[JZ4780_CLK_HDMI] = {
+		"hdmi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_VPLL, -1 },
+		.mux = { CGU_REG_HDMICDR, 30, 2 },
+		.div = { CGU_REG_HDMICDR, 0, 8, 29, 28, 26 },
+		.gate_bit = 32 + 9,
+	},
+
+	[JZ4780_CLK_BCH] = {
+		"bch", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL },
+		.mux = { CGU_REG_BCHCDR, 30, 2 },
+		.div = { CGU_REG_BCHCDR, 0, 4, 29, 28, 27 },
+		.gate_bit = 1,
+	},
+
+	/* Gate-only clocks */
+
+	[JZ4780_CLK_NEMC] = {
+		"nemc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_AHB2, -1 },
+		.gate_bit = 0,
+	},
+
+	[JZ4780_CLK_OTG0] = {
+		"otg0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 2,
+	},
+
+	[JZ4780_CLK_SSI0] = {
+		"ssi0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SSI, -1 },
+		.gate_bit = 4,
+	},
+
+	[JZ4780_CLK_SMB0] = {
+		"smb0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 5,
+	},
+
+	[JZ4780_CLK_SMB1] = {
+		"smb1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 6,
+	},
+
+	[JZ4780_CLK_SCC] = {
+		"scc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 7,
+	},
+
+	[JZ4780_CLK_AIC] = {
+		"aic", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 8,
+	},
+
+	[JZ4780_CLK_TSSI0] = {
+		"tssi0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 9,
+	},
+
+	[JZ4780_CLK_OWI] = {
+		"owi", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 10,
+	},
+
+	[JZ4780_CLK_KBC] = {
+		"kbc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 13,
+	},
+
+	[JZ4780_CLK_SADC] = {
+		"sadc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 14,
+	},
+
+	[JZ4780_CLK_UART0] = {
+		"uart0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 15,
+	},
+
+	[JZ4780_CLK_UART1] = {
+		"uart1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 16,
+	},
+
+	[JZ4780_CLK_UART2] = {
+		"uart2", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 17,
+	},
+
+	[JZ4780_CLK_UART3] = {
+		"uart3", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 18,
+	},
+
+	[JZ4780_CLK_SSI1] = {
+		"ssi1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SSI, -1 },
+		.gate_bit = 19,
+	},
+
+	[JZ4780_CLK_SSI2] = {
+		"ssi2", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SSI, -1 },
+		.gate_bit = 20,
+	},
+
+	[JZ4780_CLK_PDMA] = {
+		"pdma", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 21,
+	},
+
+	[JZ4780_CLK_GPS] = {
+		"gps", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 22,
+	},
+
+	[JZ4780_CLK_MAC] = {
+		"mac", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 23,
+	},
+
+	[JZ4780_CLK_SMB2] = {
+		"smb2", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 25,
+	},
+
+	[JZ4780_CLK_CIM] = {
+		"cim", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 26,
+	},
+
+	[JZ4780_CLK_LCD] = {
+		"lcd", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 28,
+	},
+
+	[JZ4780_CLK_TVE] = {
+		"tve", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_LCD, -1 },
+		.gate_bit = 27,
+	},
+
+	[JZ4780_CLK_IPU] = {
+		"ipu", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 29,
+	},
+
+	[JZ4780_CLK_DDR0] = {
+		"ddr0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_DDR, -1 },
+		.gate_bit = 30,
+	},
+
+	[JZ4780_CLK_DDR1] = {
+		"ddr1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_DDR, -1 },
+		.gate_bit = 31,
+	},
+
+	[JZ4780_CLK_SMB3] = {
+		"smb3", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 32 + 0,
+	},
+
+	[JZ4780_CLK_TSSI1] = {
+		"tssi1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 1,
+	},
+
+	[JZ4780_CLK_COMPRESS] = {
+		"compress", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 5,
+	},
+
+	[JZ4780_CLK_AIC1] = {
+		"aic1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 6,
+	},
+
+	[JZ4780_CLK_GPVLC] = {
+		"gpvlc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 7,
+	},
+
+	[JZ4780_CLK_OTG1] = {
+		"otg1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 8,
+	},
+
+	[JZ4780_CLK_UART4] = {
+		"uart4", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 10,
+	},
+
+	[JZ4780_CLK_AHBMON] = {
+		"ahb_mon", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 11,
+	},
+
+	[JZ4780_CLK_SMB4] = {
+		"smb4", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 32 + 12,
+	},
+
+	[JZ4780_CLK_DES] = {
+		"des", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 13,
+	},
+
+	[JZ4780_CLK_X2D] = {
+		"x2d", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 14,
+	},
+
+	[JZ4780_CLK_CORE1] = {
+		"core1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_CPU, -1 },
+		.gate_bit = 32 + 15,
+	},
+
+};
+
+static void __init jz4780_cgu_init(struct device_node *np)
+{
+	int retval;
+
+	cgu = jz47xx_cgu_new(jz4780_cgu_clocks, ARRAY_SIZE(jz4780_cgu_clocks),
+			     np);
+	if (!cgu)
+		pr_err("%s: failed to initialise CGU\n", __func__);
+
+	retval = jz47xx_cgu_register_clocks(cgu);
+	if (retval)
+		pr_err("%s: failed to register CGU Clocks\n", __func__);
+
+	clk_set_parent(cgu->clocks.clks[JZ4780_CLK_UHC],
+		       cgu->clocks.clks[JZ4780_CLK_MPLL]);
+}
+CLK_OF_DECLARE(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);
-- 
1.9.1


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

* [PATCH_V2 29/34] clk: add Ingenic jz4780 CGU driver
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add support for the clocks provided by the CGU in the Ingenic jz4780
SoC, making use of the jz47xx-cgu code to do the heavy lifting.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Cc: Mike Turquette <mturquette@linaro.org>

---
V2 Removed FSF header
---
 drivers/clk/Makefile            |   1 +
 drivers/clk/jz47xx/Makefile     |   1 +
 drivers/clk/jz47xx/jz4780-cgu.c | 742 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 744 insertions(+)
 create mode 100644 drivers/clk/jz47xx/jz4780-cgu.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index fc434c0..3eac9e2 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_ARCH_HI3xxx)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIP04)		+= hisilicon/
 obj-$(CONFIG_ARCH_HIX5HD2)		+= hisilicon/
 obj-$(CONFIG_MACH_JZ4740)		+= jz47xx/
+obj-$(CONFIG_MACH_JZ4780)		+= jz47xx/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)	+= keystone/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)			+= mmp/
diff --git a/drivers/clk/jz47xx/Makefile b/drivers/clk/jz47xx/Makefile
index 21746fc..5e0b845 100644
--- a/drivers/clk/jz47xx/Makefile
+++ b/drivers/clk/jz47xx/Makefile
@@ -1,2 +1,3 @@
 obj-y				+= jz47xx-cgu.o
 obj-$(CONFIG_MACH_JZ4740)	+= jz4740-cgu.o
+obj-$(CONFIG_MACH_JZ4780)	+= jz4780-cgu.o
diff --git a/drivers/clk/jz47xx/jz4780-cgu.c b/drivers/clk/jz47xx/jz4780-cgu.c
new file mode 100644
index 0000000..054db6e
--- /dev/null
+++ b/drivers/clk/jz47xx/jz4780-cgu.c
@@ -0,0 +1,742 @@
+/*
+ * Ingenic jz4780 SoC CGU driver
+ *
+ * Copyright (c) 2013-2015 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <dt-bindings/clock/jz4780-cgu.h>
+#include "jz47xx-cgu.h"
+
+/* CGU register offsets */
+#define CGU_REG_CLOCKCONTROL	0x00
+#define CGU_REG_PLLCONTROL	0x0c
+#define CGU_REG_APLL		0x10
+#define CGU_REG_MPLL		0x14
+#define CGU_REG_EPLL		0x18
+#define CGU_REG_VPLL		0x1c
+#define CGU_REG_OPCR		0x24
+#define CGU_REG_DDRCDR		0x2c
+#define CGU_REG_VPUCDR		0x30
+#define CGU_REG_USBPCR		0x3c
+#define CGU_REG_USBRDT		0x40
+#define CGU_REG_USBVBFIL	0x44
+#define CGU_REG_USBPCR1		0x48
+#define CGU_REG_LP0CDR		0x54
+#define CGU_REG_I2SCDR		0x60
+#define CGU_REG_LP1CDR		0x64
+#define CGU_REG_MSC0CDR		0x68
+#define CGU_REG_UHCCDR		0x6c
+#define CGU_REG_SSICDR		0x74
+#define CGU_REG_CIMCDR		0x7c
+#define CGU_REG_PCMCDR		0x84
+#define CGU_REG_GPUCDR		0x88
+#define CGU_REG_HDMICDR		0x8c
+#define CGU_REG_MSC1CDR		0xa4
+#define CGU_REG_MSC2CDR		0xa8
+#define CGU_REG_BCHCDR		0xac
+#define CGU_REG_CLOCKSTATUS	0xd4
+
+/* bits within a PLL control register */
+#define PLLCTL_M_SHIFT		19
+#define PLLCTL_M_MASK		(0x1fff << PLLCTL_M_SHIFT)
+#define PLLCTL_N_SHIFT		13
+#define PLLCTL_N_MASK		(0x3f << PLLCTL_N_SHIFT)
+#define PLLCTL_OD_SHIFT		9
+#define PLLCTL_OD_MASK		(0xf << PLLCTL_OD_SHIFT)
+#define PLLCTL_ON		(1 << 4)
+#define PLLCTL_BYPASS		(1 << 1)
+#define PLLCTL_ENABLE		(1 << 0)
+
+/* bits within the OPCR register */
+#define OPCR_SPENDN0		(1 << 7)
+#define OPCR_SPENDN1		(1 << 6)
+
+/* bits within the USBPCR register */
+#define USBPCR_USB_MODE		BIT(31)
+#define USBPCR_IDPULLUP_MASK	(0x3 << 28)
+#define USBPCR_COMMONONN	BIT(25)
+#define USBPCR_VBUSVLDEXT	BIT(24)
+#define USBPCR_VBUSVLDEXTSEL	BIT(23)
+#define USBPCR_POR		BIT(22)
+#define USBPCR_OTG_DISABLE	BIT(20)
+#define USBPCR_COMPDISTUNE_MASK	(0x7 << 17)
+#define USBPCR_OTGTUNE_MASK	(0x7 << 14)
+#define USBPCR_SQRXTUNE_MASK	(0x7 << 11)
+#define USBPCR_TXFSLSTUNE_MASK	(0xf << 7)
+#define USBPCR_TXPREEMPHTUNE	BIT(6)
+#define USBPCR_TXHSXVTUNE_MASK	(0x3 << 4)
+#define USBPCR_TXVREFTUNE_MASK	0xf
+
+/* bits within the USBPCR1 register */
+#define USBPCR1_REFCLKSEL_SHIFT	26
+#define USBPCR1_REFCLKSEL_MASK	(0x3 << USBPCR1_REFCLKSEL_SHIFT)
+#define USBPCR1_REFCLKSEL_CORE	(0x2 << USBPCR1_REFCLKSEL_SHIFT)
+#define USBPCR1_REFCLKDIV_SHIFT	24
+#define USBPCR1_REFCLKDIV_MASK	(0x3 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_19_2	(0x3 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_48	(0x2 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_24	(0x1 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_12	(0x0 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_USB_SEL		BIT(28)
+#define USBPCR1_WORD_IF0	BIT(19)
+#define USBPCR1_WORD_IF1	BIT(18)
+
+/* bits within the USBRDT register */
+#define USBRDT_VBFIL_LD_EN	BIT(25)
+#define USBRDT_USBRDT_MASK	0x7fffff
+
+/* bits within the USBVBFIL register */
+#define USBVBFIL_IDDIGFIL_SHIFT	16
+#define USBVBFIL_IDDIGFIL_MASK	(0xffff << USBVBFIL_IDDIGFIL_SHIFT)
+#define USBVBFIL_USBVBFIL_MASK	(0xffff)
+
+static struct jz47xx_cgu *cgu;
+
+static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw)
+{
+	/* we only use CLKCORE, revisit if that ever changes */
+	return 0;
+}
+
+static int jz4780_otg_phy_set_parent(struct clk_hw *hw, u8 idx)
+{
+	unsigned long flags;
+	u32 usbpcr1;
+
+	if (idx > 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&cgu->power_lock, flags);
+
+	usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+	usbpcr1 &= ~USBPCR1_REFCLKSEL_MASK;
+	/* we only use CLKCORE */
+	usbpcr1 |= USBPCR1_REFCLKSEL_CORE;
+	writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
+
+	spin_unlock_irqrestore(&cgu->power_lock, flags);
+	return 0;
+}
+
+static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	u32 usbpcr1;
+	unsigned refclk_div;
+
+	usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+	refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK;
+
+	switch (refclk_div) {
+	case USBPCR1_REFCLKDIV_12:
+		return 12000000;
+
+	case USBPCR1_REFCLKDIV_24:
+		return 24000000;
+
+	case USBPCR1_REFCLKDIV_48:
+		return 48000000;
+
+	case USBPCR1_REFCLKDIV_19_2:
+		return 19200000;
+	}
+
+	BUG();
+	return parent_rate;
+}
+
+static long jz4780_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate,
+				      unsigned long *parent_rate)
+{
+	if (req_rate < 15600000)
+		return 12000000;
+
+	if (req_rate < 21600000)
+		return 19200000;
+
+	if (req_rate < 36000000)
+		return 24000000;
+
+	return 48000000;
+}
+
+static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
+				   unsigned long parent_rate)
+{
+	unsigned long flags;
+	u32 usbpcr1, div_bits;
+
+	switch (req_rate) {
+	case 12000000:
+		div_bits = USBPCR1_REFCLKDIV_12;
+		break;
+
+	case 19200000:
+		div_bits = USBPCR1_REFCLKDIV_19_2;
+		break;
+
+	case 24000000:
+		div_bits = USBPCR1_REFCLKDIV_24;
+		break;
+
+	case 48000000:
+		div_bits = USBPCR1_REFCLKDIV_48;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&cgu->power_lock, flags);
+
+	usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+	usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK;
+	usbpcr1 |= div_bits;
+	writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
+
+	spin_unlock_irqrestore(&cgu->power_lock, flags);
+	return 0;
+}
+
+struct clk_ops jz4780_otg_phy_ops = {
+	.get_parent = jz4780_otg_phy_get_parent,
+	.set_parent = jz4780_otg_phy_set_parent,
+
+	.recalc_rate = jz4780_otg_phy_recalc_rate,
+	.round_rate = jz4780_otg_phy_round_rate,
+	.set_rate = jz4780_otg_phy_set_rate,
+};
+
+static const s8 pll_od_encoding[16] = {
+	0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+	0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+};
+
+static const struct jz47xx_cgu_clk_info jz4780_cgu_clocks[] = {
+
+	/* External clocks */
+
+	[JZ4780_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
+	[JZ4780_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
+
+	/* PLLs */
+
+#define DEF_PLL(name) { \
+	.reg = CGU_REG_ ## name, \
+	.m_shift = 19, \
+	.m_bits = 13, \
+	.m_offset = 1, \
+	.n_shift = 13, \
+	.n_bits = 6, \
+	.n_offset = 1, \
+	.od_shift = 9, \
+	.od_bits = 4, \
+	.od_max = 16, \
+	.od_encoding = pll_od_encoding, \
+	.stable_bit = 6, \
+	.bypass_bit = 1, \
+	.enable_bit = 0, \
+}
+
+	[JZ4780_CLK_APLL] = {
+		"apll", CGU_CLK_PLL,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.pll = DEF_PLL(APLL),
+	},
+
+	[JZ4780_CLK_MPLL] = {
+		"mpll", CGU_CLK_PLL,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.pll = DEF_PLL(MPLL),
+	},
+
+	[JZ4780_CLK_EPLL] = {
+		"epll", CGU_CLK_PLL,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.pll = DEF_PLL(EPLL),
+	},
+
+	[JZ4780_CLK_VPLL] = {
+		"vpll", CGU_CLK_PLL,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.pll = DEF_PLL(VPLL),
+	},
+
+#undef DEF_PLL
+
+	/* Custom (SoC-specific) OTG PHY */
+
+	[JZ4780_CLK_OTGPHY] = {
+		"otg_phy", CGU_CLK_CUSTOM,
+		.parents = { -1, -1, JZ4780_CLK_EXCLK, -1 },
+		.custom = { &jz4780_otg_phy_ops },
+	},
+
+	/* Muxes & dividers */
+
+	[JZ4780_CLK_SCLKA] = {
+		"sclk_a", CGU_CLK_MUX,
+		.parents = { -1, JZ4780_CLK_APLL, JZ4780_CLK_EXCLK,
+			     JZ4780_CLK_RTCLK },
+		.mux = { CGU_REG_CLOCKCONTROL, 30, 2 },
+	},
+
+	[JZ4780_CLK_CPUMUX] = {
+		"cpumux", CGU_CLK_MUX,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL },
+		.mux = { CGU_REG_CLOCKCONTROL, 28, 2 },
+	},
+
+	[JZ4780_CLK_CPU] = {
+		"cpu", CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_CPUMUX, -1 },
+		.div = { CGU_REG_CLOCKCONTROL, 0, 4, 22, -1, -1 },
+	},
+
+	[JZ4780_CLK_L2CACHE] = {
+		"l2cache", CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_CPUMUX, -1 },
+		.div = { CGU_REG_CLOCKCONTROL, 4, 4, -1, -1, -1 },
+	},
+
+	[JZ4780_CLK_AHB0] = {
+		"ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL },
+		.mux = { CGU_REG_CLOCKCONTROL, 26, 2 },
+		.div = { CGU_REG_CLOCKCONTROL, 8, 4, 21, -1, -1 },
+	},
+
+	[JZ4780_CLK_AHB2PMUX] = {
+		"ahb2_apb_mux", CGU_CLK_MUX,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_RTCLK },
+		.mux = { CGU_REG_CLOCKCONTROL, 24, 2 },
+	},
+
+	[JZ4780_CLK_AHB2] = {
+		"ahb2", CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_AHB2PMUX, -1 },
+		.div = { CGU_REG_CLOCKCONTROL, 12, 4, 20, -1, -1 },
+	},
+
+	[JZ4780_CLK_PCLK] = {
+		"pclk", CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_AHB2PMUX, -1 },
+		.div = { CGU_REG_CLOCKCONTROL, 16, 4, 20, -1, -1 },
+	},
+
+	[JZ4780_CLK_DDR] = {
+		"ddr", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+		.mux = { CGU_REG_DDRCDR, 30, 2 },
+		.div = { CGU_REG_DDRCDR, 0, 4, 29, 28, 27 },
+	},
+
+	[JZ4780_CLK_VPU] = {
+		"vpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL, -1 },
+		.mux = { CGU_REG_VPUCDR, 30, 2 },
+		.div = { CGU_REG_VPUCDR, 0, 4, 29, 28, 27 },
+		.gate_bit = 32 + 2,
+	},
+
+	[JZ4780_CLK_I2SPLL] = {
+		"i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1 },
+		.mux = { CGU_REG_I2SCDR, 30, 1 },
+		.div = { CGU_REG_I2SCDR, 0, 8, 29, 28, 27 },
+	},
+
+	[JZ4780_CLK_I2S] = {
+		"i2s", CGU_CLK_MUX,
+		.parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_I2SPLL, -1 },
+		.mux = { CGU_REG_I2SCDR, 31, 1 },
+	},
+
+	[JZ4780_CLK_LCD0PIXCLK] = {
+		"lcd0pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_VPLL, -1 },
+		.mux = { CGU_REG_LP0CDR, 30, 2 },
+		.div = { CGU_REG_LP0CDR, 0, 8, 28, 27, 26 },
+	},
+
+	[JZ4780_CLK_LCD1PIXCLK] = {
+		"lcd1pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_VPLL, -1 },
+		.mux = { CGU_REG_LP1CDR, 30, 2 },
+		.div = { CGU_REG_LP1CDR, 0, 8, 28, 27, 26 },
+	},
+
+	[JZ4780_CLK_MSCMUX] = {
+		"msc_mux", CGU_CLK_MUX,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+		.mux = { CGU_REG_MSC0CDR, 30, 2 },
+	},
+
+	[JZ4780_CLK_MSC0] = {
+		"msc0", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_MSCMUX, -1 },
+		.div = { CGU_REG_MSC0CDR, 0, 8, 29, 28, 27 },
+		.gate_bit = 3,
+	},
+
+	[JZ4780_CLK_MSC1] = {
+		"msc1", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_MSCMUX, -1 },
+		.div = { CGU_REG_MSC1CDR, 0, 8, 29, 28, 27 },
+		.gate_bit = 11,
+	},
+
+	[JZ4780_CLK_MSC2] = {
+		"msc2", CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_MSCMUX, -1 },
+		.div = { CGU_REG_MSC2CDR, 0, 8, 29, 28, 27 },
+		.gate_bit = 12,
+	},
+
+	[JZ4780_CLK_UHC] = {
+		"uhc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY },
+		.mux = { CGU_REG_UHCCDR, 30, 2 },
+		.div = { CGU_REG_UHCCDR, 0, 8, 29, 28, 27 },
+		.gate_bit = 24,
+	},
+
+	[JZ4780_CLK_SSIPLL] = {
+		"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+		.mux = { CGU_REG_SSICDR, 30, 1 },
+		.div = { CGU_REG_SSICDR, 0, 8, 29, 28, 27 },
+	},
+
+	[JZ4780_CLK_SSI] = {
+		"ssi", CGU_CLK_MUX,
+		.parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_SSIPLL, -1 },
+		.mux = { CGU_REG_SSICDR, 31, 1 },
+	},
+
+	[JZ4780_CLK_CIMMCLK] = {
+		"cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+		.mux = { CGU_REG_CIMCDR, 31, 1 },
+		.div = { CGU_REG_CIMCDR, 0, 8, 30, 29, 28 },
+	},
+
+	[JZ4780_CLK_PCMPLL] = {
+		"pcm_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL, JZ4780_CLK_VPLL },
+		.mux = { CGU_REG_PCMCDR, 29, 2 },
+		.div = { CGU_REG_PCMCDR, 0, 8, 28, 27, 26 },
+	},
+
+	[JZ4780_CLK_PCM] = {
+		"pcm", CGU_CLK_MUX | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_PCMPLL, -1 },
+		.mux = { CGU_REG_PCMCDR, 31, 1 },
+		.gate_bit = 32 + 3,
+	},
+
+	[JZ4780_CLK_GPU] = {
+		"gpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL },
+		.mux = { CGU_REG_GPUCDR, 30, 2 },
+		.div = { CGU_REG_GPUCDR, 0, 4, 29, 28, 27 },
+		.gate_bit = 32 + 4,
+	},
+
+	[JZ4780_CLK_HDMI] = {
+		"hdmi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_VPLL, -1 },
+		.mux = { CGU_REG_HDMICDR, 30, 2 },
+		.div = { CGU_REG_HDMICDR, 0, 8, 29, 28, 26 },
+		.gate_bit = 32 + 9,
+	},
+
+	[JZ4780_CLK_BCH] = {
+		"bch", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+		.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+			     JZ4780_CLK_EPLL },
+		.mux = { CGU_REG_BCHCDR, 30, 2 },
+		.div = { CGU_REG_BCHCDR, 0, 4, 29, 28, 27 },
+		.gate_bit = 1,
+	},
+
+	/* Gate-only clocks */
+
+	[JZ4780_CLK_NEMC] = {
+		"nemc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_AHB2, -1 },
+		.gate_bit = 0,
+	},
+
+	[JZ4780_CLK_OTG0] = {
+		"otg0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 2,
+	},
+
+	[JZ4780_CLK_SSI0] = {
+		"ssi0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SSI, -1 },
+		.gate_bit = 4,
+	},
+
+	[JZ4780_CLK_SMB0] = {
+		"smb0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 5,
+	},
+
+	[JZ4780_CLK_SMB1] = {
+		"smb1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 6,
+	},
+
+	[JZ4780_CLK_SCC] = {
+		"scc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 7,
+	},
+
+	[JZ4780_CLK_AIC] = {
+		"aic", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 8,
+	},
+
+	[JZ4780_CLK_TSSI0] = {
+		"tssi0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 9,
+	},
+
+	[JZ4780_CLK_OWI] = {
+		"owi", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 10,
+	},
+
+	[JZ4780_CLK_KBC] = {
+		"kbc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 13,
+	},
+
+	[JZ4780_CLK_SADC] = {
+		"sadc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 14,
+	},
+
+	[JZ4780_CLK_UART0] = {
+		"uart0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 15,
+	},
+
+	[JZ4780_CLK_UART1] = {
+		"uart1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 16,
+	},
+
+	[JZ4780_CLK_UART2] = {
+		"uart2", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 17,
+	},
+
+	[JZ4780_CLK_UART3] = {
+		"uart3", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 18,
+	},
+
+	[JZ4780_CLK_SSI1] = {
+		"ssi1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SSI, -1 },
+		.gate_bit = 19,
+	},
+
+	[JZ4780_CLK_SSI2] = {
+		"ssi2", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_SSI, -1 },
+		.gate_bit = 20,
+	},
+
+	[JZ4780_CLK_PDMA] = {
+		"pdma", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 21,
+	},
+
+	[JZ4780_CLK_GPS] = {
+		"gps", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 22,
+	},
+
+	[JZ4780_CLK_MAC] = {
+		"mac", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 23,
+	},
+
+	[JZ4780_CLK_SMB2] = {
+		"smb2", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 25,
+	},
+
+	[JZ4780_CLK_CIM] = {
+		"cim", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 26,
+	},
+
+	[JZ4780_CLK_LCD] = {
+		"lcd", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 28,
+	},
+
+	[JZ4780_CLK_TVE] = {
+		"tve", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_LCD, -1 },
+		.gate_bit = 27,
+	},
+
+	[JZ4780_CLK_IPU] = {
+		"ipu", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 29,
+	},
+
+	[JZ4780_CLK_DDR0] = {
+		"ddr0", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_DDR, -1 },
+		.gate_bit = 30,
+	},
+
+	[JZ4780_CLK_DDR1] = {
+		"ddr1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_DDR, -1 },
+		.gate_bit = 31,
+	},
+
+	[JZ4780_CLK_SMB3] = {
+		"smb3", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 32 + 0,
+	},
+
+	[JZ4780_CLK_TSSI1] = {
+		"tssi1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 1,
+	},
+
+	[JZ4780_CLK_COMPRESS] = {
+		"compress", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 5,
+	},
+
+	[JZ4780_CLK_AIC1] = {
+		"aic1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 6,
+	},
+
+	[JZ4780_CLK_GPVLC] = {
+		"gpvlc", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 7,
+	},
+
+	[JZ4780_CLK_OTG1] = {
+		"otg1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 8,
+	},
+
+	[JZ4780_CLK_UART4] = {
+		"uart4", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 10,
+	},
+
+	[JZ4780_CLK_AHBMON] = {
+		"ahb_mon", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 11,
+	},
+
+	[JZ4780_CLK_SMB4] = {
+		"smb4", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_PCLK, -1 },
+		.gate_bit = 32 + 12,
+	},
+
+	[JZ4780_CLK_DES] = {
+		"des", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 13,
+	},
+
+	[JZ4780_CLK_X2D] = {
+		"x2d", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_EXCLK, -1 },
+		.gate_bit = 32 + 14,
+	},
+
+	[JZ4780_CLK_CORE1] = {
+		"core1", CGU_CLK_GATE,
+		.parents = { JZ4780_CLK_CPU, -1 },
+		.gate_bit = 32 + 15,
+	},
+
+};
+
+static void __init jz4780_cgu_init(struct device_node *np)
+{
+	int retval;
+
+	cgu = jz47xx_cgu_new(jz4780_cgu_clocks, ARRAY_SIZE(jz4780_cgu_clocks),
+			     np);
+	if (!cgu)
+		pr_err("%s: failed to initialise CGU\n", __func__);
+
+	retval = jz47xx_cgu_register_clocks(cgu);
+	if (retval)
+		pr_err("%s: failed to register CGU Clocks\n", __func__);
+
+	clk_set_parent(cgu->clocks.clks[JZ4780_CLK_UHC],
+		       cgu->clocks.clks[JZ4780_CLK_MPLL]);
+}
+CLK_OF_DECLARE(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);
-- 
1.9.1

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

* [PATCH_V2 30/34] MIPS: jz4740: add jz4780 interrupt controller support
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Allow the jz4780 interrupt controller to be probed from devicetree,
supporting the 64 interrupts it provides.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 3e53a32..de1c03e 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -137,6 +137,13 @@ static int __init jz4740_intc_of_init(struct device_node *node,
 }
 IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init);
 
+static int __init jz4780_intc_of_init(struct device_node *node,
+	struct device_node *parent)
+{
+	return jz47xx_intc_of_init(node, 2);
+}
+IRQCHIP_DECLARE(jz4780_intc, "ingenic,jz4780-intc", jz4780_intc_of_init);
+
 #ifdef CONFIG_DEBUG_FS
 
 static inline void intc_seq_reg(struct seq_file *s, const char *name,
-- 
1.9.1


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

* [PATCH_V2 30/34] MIPS: jz4740: add jz4780 interrupt controller support
@ 2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:21 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Allow the jz4780 interrupt controller to be probed from devicetree,
supporting the 64 interrupts it provides.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/jz4740/irq.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index 3e53a32..de1c03e 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -137,6 +137,13 @@ static int __init jz4740_intc_of_init(struct device_node *node,
 }
 IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", jz4740_intc_of_init);
 
+static int __init jz4780_intc_of_init(struct device_node *node,
+	struct device_node *parent)
+{
+	return jz47xx_intc_of_init(node, 2);
+}
+IRQCHIP_DECLARE(jz4780_intc, "ingenic,jz4780-intc", jz4780_intc_of_init);
+
 #ifdef CONFIG_DEBUG_FS
 
 static inline void intc_seq_reg(struct seq_file *s, const char *name,
-- 
1.9.1

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

* [PATCH_V2 31/34] MIPS: add jz4780 Ingenic vendor ID
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:22 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

With the jz4780, Ingenic switched to use a different vendor ID in the
coprocessor 0 PRID register (whilst keeping the product ID & revision
the same as the jz4740 & jz4770...). Add a definition for the new
vendor ID & handle it in the same way as the older one.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/cpu.h  | 1 +
 arch/mips/kernel/cpu-probe.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 33866fc..ab00d3b 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -43,6 +43,7 @@
 #define PRID_COMP_NETLOGIC	0x0c0000
 #define PRID_COMP_CAVIUM	0x0d0000
 #define PRID_COMP_INGENIC	0xd00000
+#define PRID_COMP_INGENIC_4780	0xe10000
 
 /*
  * Assigned Processor ID (implementation) values for bits 15:8 of the PRId
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 5342674..ca98c4a 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -1313,6 +1313,7 @@ void cpu_probe(void)
 		cpu_probe_cavium(c, cpu);
 		break;
 	case PRID_COMP_INGENIC:
+	case PRID_COMP_INGENIC_4780:
 		cpu_probe_ingenic(c, cpu);
 		break;
 	case PRID_COMP_NETLOGIC:
-- 
1.9.1


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

* [PATCH_V2 31/34] MIPS: add jz4780 Ingenic vendor ID
@ 2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:22 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

With the jz4780, Ingenic switched to use a different vendor ID in the
coprocessor 0 PRID register (whilst keeping the product ID & revision
the same as the jz4740 & jz4770...). Add a definition for the new
vendor ID & handle it in the same way as the older one.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/include/asm/cpu.h  | 1 +
 arch/mips/kernel/cpu-probe.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 33866fc..ab00d3b 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -43,6 +43,7 @@
 #define PRID_COMP_NETLOGIC	0x0c0000
 #define PRID_COMP_CAVIUM	0x0d0000
 #define PRID_COMP_INGENIC	0xd00000
+#define PRID_COMP_INGENIC_4780	0xe10000
 
 /*
  * Assigned Processor ID (implementation) values for bits 15:8 of the PRId
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 5342674..ca98c4a 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -1313,6 +1313,7 @@ void cpu_probe(void)
 		cpu_probe_cavium(c, cpu);
 		break;
 	case PRID_COMP_INGENIC:
+	case PRID_COMP_INGENIC_4780:
 		cpu_probe_ingenic(c, cpu);
 		break;
 	case PRID_COMP_NETLOGIC:
-- 
1.9.1

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

* [PATCH_V2 32/34] MIPS: initial Ingenic jz4780 support
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:22 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Support the Ingenic jz4780 SoC using the code under arch/mips/jz4740 now
that it has been generalised sufficiently. This is left unselectable in
Kconfig until a jz4780 based board is added in a later commit.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/Kconfig                          |  16 +++++
 arch/mips/boot/dts/jz4780.dtsi             | 101 +++++++++++++++++++++++++++++
 arch/mips/include/asm/mach-jz4740/irq.h    |   5 ++
 arch/mips/include/asm/mach-jz4740/serial.h |   8 ++-
 arch/mips/jz4740/Makefile                  |   4 +-
 arch/mips/jz4740/Platform                  |   4 ++
 arch/mips/jz4740/time.c                    |   7 +-
 7 files changed, 142 insertions(+), 3 deletions(-)
 create mode 100644 arch/mips/boot/dts/jz4780.dtsi

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 622d0aa..296bafb 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -291,6 +291,22 @@ config MACH_JZ4740
 	select USE_OF
 	select LIBFDT
 
+config MACH_JZ4780
+	bool
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_SUPPORTS_ZBOOT_UART16550
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select ARCH_REQUIRE_GPIOLIB
+	select COMMON_CLK
+	select GENERIC_IRQ_CHIP
+	select BUILTIN_DTB
+	select USE_OF
+	select LIBFDT
+	select MIPS_CPU_SCACHE
+
 config LANTIQ
 	bool "Lantiq based platforms"
 	select DMA_NONCOHERENT
diff --git a/arch/mips/boot/dts/jz4780.dtsi b/arch/mips/boot/dts/jz4780.dtsi
new file mode 100644
index 0000000..d9b696f
--- /dev/null
+++ b/arch/mips/boot/dts/jz4780.dtsi
@@ -0,0 +1,101 @@
+#include <dt-bindings/clock/jz4780-cgu.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ingenic,jz4780";
+
+	cpuintc: cpuintc@0 {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	intc: intc@10001000 {
+		compatible = "ingenic,jz4780-intc";
+		reg = <0x10001000 0x50>;
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <2>;
+	};
+
+	ext: ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+	};
+
+	rtc: rtc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	cgu: jz4780-cgu@10000000 {
+		compatible = "ingenic,jz4780-cgu";
+		reg = <0x10000000 0x100>;
+
+		clocks = <&ext>, <&rtc>;
+		clock-names = "ext", "rtc";
+
+		#clock-cells = <1>;
+	};
+
+	uart0: serial@10030000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10030000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <51>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART0>;
+		clock-names = "baud", "module";
+	};
+
+	uart1: serial@10031000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10031000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <50>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART1>;
+		clock-names = "baud", "module";
+	};
+
+	uart2: serial@10032000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10032000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <49>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART2>;
+		clock-names = "baud", "module";
+	};
+
+	uart3: serial@10033000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10033000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <48>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART3>;
+		clock-names = "baud", "module";
+	};
+
+	uart4: serial@10034000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10034000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <34>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART4>;
+		clock-names = "baud", "module";
+	};
+};
diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
index b218f76..7e4ec21 100644
--- a/arch/mips/include/asm/mach-jz4740/irq.h
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -22,6 +22,9 @@
 #ifdef CONFIG_MACH_JZ4740
 # define NR_INTC_IRQS	32
 #endif
+#ifdef CONFIG_MACH_JZ4780
+# define NR_INTC_IRQS	64
+#endif
 
 /* 1st-level interrupts */
 #define JZ4740_IRQ(x)		(JZ4740_IRQ_BASE + (x))
@@ -48,6 +51,8 @@
 #define JZ4740_IRQ_IPU		JZ4740_IRQ(29)
 #define JZ4740_IRQ_LCD		JZ4740_IRQ(30)
 
+#define JZ4780_IRQ_TCU2		JZ4740_IRQ(25)
+
 /* 2nd-level interrupts */
 #define JZ4740_IRQ_DMA(x)	(JZ4740_IRQ(NR_INTC_IRQS) + (x))
 
diff --git a/arch/mips/include/asm/mach-jz4740/serial.h b/arch/mips/include/asm/mach-jz4740/serial.h
index 9f93563..5001d34 100644
--- a/arch/mips/include/asm/mach-jz4740/serial.h
+++ b/arch/mips/include/asm/mach-jz4740/serial.h
@@ -16,6 +16,12 @@
 #ifndef __JZ4740_SERIAL_H__
 #define __JZ4740_SERIAL_H__
 
-#define BASE_BAUD (12000000 / 16)
+#ifdef CONFIG_MACH_JZ4740
+# define BASE_BAUD (12000000 / 16)
+#endif
+
+#ifdef CONFIG_MACH_JZ4780
+# define BASE_BAUD (48000000 / 16)
+#endif
 
 #endif /* __JZ4740_SERIAL_H__ */
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index ae72346..03e9f0a 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -5,7 +5,9 @@
 # Object file lists.
 
 obj-y += prom.o irq.o time.o reset.o setup.o \
-	gpio.o platform.o timer.o
+	platform.o timer.o
+
+obj-$(CONFIG_MACH_JZ4740) += gpio.o
 
 CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
 
diff --git a/arch/mips/jz4740/Platform b/arch/mips/jz4740/Platform
index ba91be9..ad1b443 100644
--- a/arch/mips/jz4740/Platform
+++ b/arch/mips/jz4740/Platform
@@ -1,3 +1,7 @@
 platform-$(CONFIG_MACH_JZ4740)	+= jz4740/
 cflags-$(CONFIG_MACH_JZ4740)	+= -I$(srctree)/arch/mips/include/asm/mach-jz4740
 load-$(CONFIG_MACH_JZ4740)	+= 0xffffffff80010000
+
+platform-$(CONFIG_MACH_JZ4780)	+= jz4740/
+cflags-$(CONFIG_MACH_JZ4780)	+= -I$(srctree)/arch/mips/include/asm/mach-jz4740
+load-$(CONFIG_MACH_JZ4780)	+= 0xffffffff80010000
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index 121ec3a..e4e440d 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -96,7 +96,12 @@ static struct clock_event_device jz4740_clockevent = {
 	.set_next_event = jz4740_clockevent_set_next,
 	.set_mode = jz4740_clockevent_set_mode,
 	.rating = 200,
+#ifdef CONFIG_MACH_JZ4740
 	.irq = JZ4740_IRQ_TCU0,
+#endif
+#ifdef CONFIG_MACH_JZ4780
+	.irq = JZ4780_IRQ_TCU2,
+#endif
 };
 
 static struct irqaction timer_irqaction = {
@@ -136,7 +141,7 @@ void __init plat_time_init(void)
 	if (ret)
 		printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
 
-	setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
+	setup_irq(jz4740_clockevent.irq, &timer_irqaction);
 
 	ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
 
-- 
1.9.1


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

* [PATCH_V2 32/34] MIPS: initial Ingenic jz4780 support
@ 2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:22 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Support the Ingenic jz4780 SoC using the code under arch/mips/jz4740 now
that it has been generalised sufficiently. This is left unselectable in
Kconfig until a jz4780 based board is added in a later commit.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/Kconfig                          |  16 +++++
 arch/mips/boot/dts/jz4780.dtsi             | 101 +++++++++++++++++++++++++++++
 arch/mips/include/asm/mach-jz4740/irq.h    |   5 ++
 arch/mips/include/asm/mach-jz4740/serial.h |   8 ++-
 arch/mips/jz4740/Makefile                  |   4 +-
 arch/mips/jz4740/Platform                  |   4 ++
 arch/mips/jz4740/time.c                    |   7 +-
 7 files changed, 142 insertions(+), 3 deletions(-)
 create mode 100644 arch/mips/boot/dts/jz4780.dtsi

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 622d0aa..296bafb 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -291,6 +291,22 @@ config MACH_JZ4740
 	select USE_OF
 	select LIBFDT
 
+config MACH_JZ4780
+	bool
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_SUPPORTS_ZBOOT_UART16550
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select ARCH_REQUIRE_GPIOLIB
+	select COMMON_CLK
+	select GENERIC_IRQ_CHIP
+	select BUILTIN_DTB
+	select USE_OF
+	select LIBFDT
+	select MIPS_CPU_SCACHE
+
 config LANTIQ
 	bool "Lantiq based platforms"
 	select DMA_NONCOHERENT
diff --git a/arch/mips/boot/dts/jz4780.dtsi b/arch/mips/boot/dts/jz4780.dtsi
new file mode 100644
index 0000000..d9b696f
--- /dev/null
+++ b/arch/mips/boot/dts/jz4780.dtsi
@@ -0,0 +1,101 @@
+#include <dt-bindings/clock/jz4780-cgu.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "ingenic,jz4780";
+
+	cpuintc: cpuintc@0 {
+		#address-cells = <0>;
+		#interrupt-cells = <1>;
+		interrupt-controller;
+		compatible = "mti,cpu-interrupt-controller";
+	};
+
+	intc: intc@10001000 {
+		compatible = "ingenic,jz4780-intc";
+		reg = <0x10001000 0x50>;
+
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		interrupt-parent = <&cpuintc>;
+		interrupts = <2>;
+	};
+
+	ext: ext {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+	};
+
+	rtc: rtc {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+	};
+
+	cgu: jz4780-cgu@10000000 {
+		compatible = "ingenic,jz4780-cgu";
+		reg = <0x10000000 0x100>;
+
+		clocks = <&ext>, <&rtc>;
+		clock-names = "ext", "rtc";
+
+		#clock-cells = <1>;
+	};
+
+	uart0: serial@10030000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10030000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <51>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART0>;
+		clock-names = "baud", "module";
+	};
+
+	uart1: serial@10031000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10031000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <50>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART1>;
+		clock-names = "baud", "module";
+	};
+
+	uart2: serial@10032000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10032000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <49>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART2>;
+		clock-names = "baud", "module";
+	};
+
+	uart3: serial@10033000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10033000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <48>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART3>;
+		clock-names = "baud", "module";
+	};
+
+	uart4: serial@10034000 {
+		compatible = "ingenic,jz4780-uart";
+		reg = <0x10034000 0x100>;
+
+		interrupt-parent = <&intc>;
+		interrupts = <34>;
+
+		clocks = <&ext>, <&cgu JZ4780_CLK_UART4>;
+		clock-names = "baud", "module";
+	};
+};
diff --git a/arch/mips/include/asm/mach-jz4740/irq.h b/arch/mips/include/asm/mach-jz4740/irq.h
index b218f76..7e4ec21 100644
--- a/arch/mips/include/asm/mach-jz4740/irq.h
+++ b/arch/mips/include/asm/mach-jz4740/irq.h
@@ -22,6 +22,9 @@
 #ifdef CONFIG_MACH_JZ4740
 # define NR_INTC_IRQS	32
 #endif
+#ifdef CONFIG_MACH_JZ4780
+# define NR_INTC_IRQS	64
+#endif
 
 /* 1st-level interrupts */
 #define JZ4740_IRQ(x)		(JZ4740_IRQ_BASE + (x))
@@ -48,6 +51,8 @@
 #define JZ4740_IRQ_IPU		JZ4740_IRQ(29)
 #define JZ4740_IRQ_LCD		JZ4740_IRQ(30)
 
+#define JZ4780_IRQ_TCU2		JZ4740_IRQ(25)
+
 /* 2nd-level interrupts */
 #define JZ4740_IRQ_DMA(x)	(JZ4740_IRQ(NR_INTC_IRQS) + (x))
 
diff --git a/arch/mips/include/asm/mach-jz4740/serial.h b/arch/mips/include/asm/mach-jz4740/serial.h
index 9f93563..5001d34 100644
--- a/arch/mips/include/asm/mach-jz4740/serial.h
+++ b/arch/mips/include/asm/mach-jz4740/serial.h
@@ -16,6 +16,12 @@
 #ifndef __JZ4740_SERIAL_H__
 #define __JZ4740_SERIAL_H__
 
-#define BASE_BAUD (12000000 / 16)
+#ifdef CONFIG_MACH_JZ4740
+# define BASE_BAUD (12000000 / 16)
+#endif
+
+#ifdef CONFIG_MACH_JZ4780
+# define BASE_BAUD (48000000 / 16)
+#endif
 
 #endif /* __JZ4740_SERIAL_H__ */
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index ae72346..03e9f0a 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -5,7 +5,9 @@
 # Object file lists.
 
 obj-y += prom.o irq.o time.o reset.o setup.o \
-	gpio.o platform.o timer.o
+	platform.o timer.o
+
+obj-$(CONFIG_MACH_JZ4740) += gpio.o
 
 CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
 
diff --git a/arch/mips/jz4740/Platform b/arch/mips/jz4740/Platform
index ba91be9..ad1b443 100644
--- a/arch/mips/jz4740/Platform
+++ b/arch/mips/jz4740/Platform
@@ -1,3 +1,7 @@
 platform-$(CONFIG_MACH_JZ4740)	+= jz4740/
 cflags-$(CONFIG_MACH_JZ4740)	+= -I$(srctree)/arch/mips/include/asm/mach-jz4740
 load-$(CONFIG_MACH_JZ4740)	+= 0xffffffff80010000
+
+platform-$(CONFIG_MACH_JZ4780)	+= jz4740/
+cflags-$(CONFIG_MACH_JZ4780)	+= -I$(srctree)/arch/mips/include/asm/mach-jz4740
+load-$(CONFIG_MACH_JZ4780)	+= 0xffffffff80010000
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index 121ec3a..e4e440d 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -96,7 +96,12 @@ static struct clock_event_device jz4740_clockevent = {
 	.set_next_event = jz4740_clockevent_set_next,
 	.set_mode = jz4740_clockevent_set_mode,
 	.rating = 200,
+#ifdef CONFIG_MACH_JZ4740
 	.irq = JZ4740_IRQ_TCU0,
+#endif
+#ifdef CONFIG_MACH_JZ4780
+	.irq = JZ4780_IRQ_TCU2,
+#endif
 };
 
 static struct irqaction timer_irqaction = {
@@ -136,7 +141,7 @@ void __init plat_time_init(void)
 	if (ret)
 		printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
 
-	setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
+	setup_irq(jz4740_clockevent.irq, &timer_irqaction);
 
 	ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
 
-- 
1.9.1

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

* [PATCH_V2 33/34] MIPS: initial MIPS Creator CI20 board support
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:22 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add a device tree for the Ingenic jz4780 based MIPS Creator CI20 board.
Note that this is unselectable via Kconfig until the jz4780 SoC is made
selectable in a later commit.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/boot/dts/Makefile      |   1 +
 arch/mips/boot/dts/ci20.dts      |  21 +++++++
 arch/mips/configs/ci20_defconfig | 127 +++++++++++++++++++++++++++++++++++++++
 arch/mips/jz4740/Kconfig         |  10 +++
 4 files changed, 159 insertions(+)
 create mode 100644 arch/mips/boot/dts/ci20.dts
 create mode 100644 arch/mips/configs/ci20_defconfig

diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index a1127f3..28e6a21 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -10,6 +10,7 @@ dtb-$(CONFIG_DTB_RT305X_EVAL)		+= rt3052_eval.dtb
 dtb-$(CONFIG_DTB_RT3883_EVAL)		+= rt3883_eval.dtb
 dtb-$(CONFIG_DTB_MT7620A_EVAL)		+= mt7620a_eval.dtb
 dtb-$(CONFIG_JZ4740_QI_LB60)		+= qi_lb60.dtb
+dtb-$(CONFIG_JZ4780_CI20)		+= ci20.dtb
 dtb-$(CONFIG_MIPS_SEAD3)		+= sead3.dtb
 
 obj-y		+= $(patsubst %.dtb, %.dtb.o, $(dtb-y))
diff --git a/arch/mips/boot/dts/ci20.dts b/arch/mips/boot/dts/ci20.dts
new file mode 100644
index 0000000..4f882ef
--- /dev/null
+++ b/arch/mips/boot/dts/ci20.dts
@@ -0,0 +1,21 @@
+/dts-v1/;
+
+#include "jz4780.dtsi"
+
+/ {
+	compatible = "img,ci20", "ingenic,jz4780";
+
+	chosen {
+		stdout-path = &uart4;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x10000000
+		       0x30000000 0x30000000>;
+	};
+};
+
+&ext {
+	clock-frequency = <48000000>;
+};
diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig
new file mode 100644
index 0000000..6562d28
--- /dev/null
+++ b/arch/mips/configs/ci20_defconfig
@@ -0,0 +1,127 @@
+CONFIG_MACH_JZ4780=y
+# CONFIG_COMPACTION is not set
+CONFIG_HZ_100=y
+CONFIG_PREEMPT=y
+# CONFIG_SECCOMP is not set
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_XZ=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_KMEM=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+# CONFIG_RD_GZIP is not set
+CONFIG_RD_XZ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_LEGACY_PTY_COUNT=2
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=5
+CONFIG_SERIAL_8250_RUNTIME_UARTS=5
+CONFIG_SERIAL_8250_JZ47XX=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PANIC_ON_OOPS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_STACKTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS4,115200 clk_ignore_unused"
diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
index 4689030..72ac174 100644
--- a/arch/mips/jz4740/Kconfig
+++ b/arch/mips/jz4740/Kconfig
@@ -7,3 +7,13 @@ config JZ4740_QI_LB60
 	bool "Qi Hardware Ben NanoNote"
 
 endchoice
+
+choice
+	prompt "Machine type"
+	depends on MACH_JZ4780
+	default JZ4780_CI20
+
+config JZ4780_CI20
+	bool "MIPS Creator CI20"
+
+endchoice
-- 
1.9.1


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

* [PATCH_V2 33/34] MIPS: initial MIPS Creator CI20 board support
@ 2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:22 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Add a device tree for the Ingenic jz4780 based MIPS Creator CI20 board.
Note that this is unselectable via Kconfig until the jz4780 SoC is made
selectable in a later commit.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/boot/dts/Makefile      |   1 +
 arch/mips/boot/dts/ci20.dts      |  21 +++++++
 arch/mips/configs/ci20_defconfig | 127 +++++++++++++++++++++++++++++++++++++++
 arch/mips/jz4740/Kconfig         |  10 +++
 4 files changed, 159 insertions(+)
 create mode 100644 arch/mips/boot/dts/ci20.dts
 create mode 100644 arch/mips/configs/ci20_defconfig

diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile
index a1127f3..28e6a21 100644
--- a/arch/mips/boot/dts/Makefile
+++ b/arch/mips/boot/dts/Makefile
@@ -10,6 +10,7 @@ dtb-$(CONFIG_DTB_RT305X_EVAL)		+= rt3052_eval.dtb
 dtb-$(CONFIG_DTB_RT3883_EVAL)		+= rt3883_eval.dtb
 dtb-$(CONFIG_DTB_MT7620A_EVAL)		+= mt7620a_eval.dtb
 dtb-$(CONFIG_JZ4740_QI_LB60)		+= qi_lb60.dtb
+dtb-$(CONFIG_JZ4780_CI20)		+= ci20.dtb
 dtb-$(CONFIG_MIPS_SEAD3)		+= sead3.dtb
 
 obj-y		+= $(patsubst %.dtb, %.dtb.o, $(dtb-y))
diff --git a/arch/mips/boot/dts/ci20.dts b/arch/mips/boot/dts/ci20.dts
new file mode 100644
index 0000000..4f882ef
--- /dev/null
+++ b/arch/mips/boot/dts/ci20.dts
@@ -0,0 +1,21 @@
+/dts-v1/;
+
+#include "jz4780.dtsi"
+
+/ {
+	compatible = "img,ci20", "ingenic,jz4780";
+
+	chosen {
+		stdout-path = &uart4;
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x10000000
+		       0x30000000 0x30000000>;
+	};
+};
+
+&ext {
+	clock-frequency = <48000000>;
+};
diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig
new file mode 100644
index 0000000..6562d28
--- /dev/null
+++ b/arch/mips/configs/ci20_defconfig
@@ -0,0 +1,127 @@
+CONFIG_MACH_JZ4780=y
+# CONFIG_COMPACTION is not set
+CONFIG_HZ_100=y
+CONFIG_PREEMPT=y
+# CONFIG_SECCOMP is not set
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_XZ=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_KMEM=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+# CONFIG_RD_GZIP is not set
+CONFIG_RD_XZ=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_LEGACY_PTY_COUNT=2
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=5
+CONFIG_SERIAL_8250_RUNTIME_UARTS=5
+CONFIG_SERIAL_8250_JZ47XX=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PANIC_ON_OOPS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_STACKTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS4,115200 clk_ignore_unused"
diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
index 4689030..72ac174 100644
--- a/arch/mips/jz4740/Kconfig
+++ b/arch/mips/jz4740/Kconfig
@@ -7,3 +7,13 @@ config JZ4740_QI_LB60
 	bool "Qi Hardware Ben NanoNote"
 
 endchoice
+
+choice
+	prompt "Machine type"
+	depends on MACH_JZ4780
+	default JZ4780_CI20
+
+config JZ4780_CI20
+	bool "MIPS Creator CI20"
+
+endchoice
-- 
1.9.1

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

* [PATCH_V2 34/34] MIPS: allow jz4780 to be selected in Kconfig
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
  -1 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:22 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Now that a jz4780 based board (the MIPS Creator CI20) is present, allow
the jz4780 SoC to be selected as the machine type via Kconfig.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 296bafb..6bd77f1 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -292,7 +292,7 @@ config MACH_JZ4740
 	select LIBFDT
 
 config MACH_JZ4780
-	bool
+	bool "Ingenic JZ4780 based machines"
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
-- 
1.9.1


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

* [PATCH_V2 34/34] MIPS: allow jz4780 to be selected in Kconfig
@ 2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
  0 siblings, 0 replies; 86+ messages in thread
From: Zubair Lutfullah Kakakhel @ 2015-02-04 15:22 UTC (permalink / raw)
  To: linux-mips
  Cc: devicetree, linux-serial, linux-kernel, Zubair.Kakakhel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

From: Paul Burton <paul.burton@imgtec.com>

Now that a jz4780 based board (the MIPS Creator CI20) is present, allow
the jz4780 SoC to be selected as the machine type via Kconfig.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Lars-Peter Clausen <lars@metafoo.de>
---
 arch/mips/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 296bafb..6bd77f1 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -292,7 +292,7 @@ config MACH_JZ4740
 	select LIBFDT
 
 config MACH_JZ4780
-	bool
+	bool "Ingenic JZ4780 based machines"
 	select SYS_HAS_CPU_MIPS32_R2
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
-- 
1.9.1

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

* Re: [PATCH_V2 11/34] MIPS: jz4740: register an irq_domain for the interrupt controller
@ 2015-02-04 16:19     ` Arnd Bergmann
  0 siblings, 0 replies; 86+ messages in thread
From: Arnd Bergmann @ 2015-02-04 16:19 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips, devicetree, linux-serial, linux-kernel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

On Wednesday 04 February 2015 15:21:40 Zubair Lutfullah Kakakhel wrote:
> +       domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0,
> +                                      &irq_domain_simple_ops, NULL);
> +       if (!domain)
> +               pr_warn("unable to register IRQ domain\n");
> +
>         setup_irq(parent_irq, &jz4740_cascade_action);

Can you use the linear domain instead, or do you still require devices
that are hardcoded in the platform code rather than DT?

	Arnd

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

* Re: [PATCH_V2 11/34] MIPS: jz4740: register an irq_domain for the interrupt controller
@ 2015-02-04 16:19     ` Arnd Bergmann
  0 siblings, 0 replies; 86+ messages in thread
From: Arnd Bergmann @ 2015-02-04 16:19 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	mturquette-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	ralf-6z/3iImG2C8G8FEW9MqTrA, jslaby-AlSwsSmVLrQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA,
	lars-Qo5EllUWu/uELgA04lAiVw, paul.burton-1AXoQHu6uovQT0dZR+AlfA

On Wednesday 04 February 2015 15:21:40 Zubair Lutfullah Kakakhel wrote:
> +       domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0,
> +                                      &irq_domain_simple_ops, NULL);
> +       if (!domain)
> +               pr_warn("unable to register IRQ domain\n");
> +
>         setup_irq(parent_irq, &jz4740_cascade_action);

Can you use the linear domain instead, or do you still require devices
that are hardcoded in the platform code rather than DT?

	Arnd
--
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	[flat|nested] 86+ messages in thread

* Re: [PATCH_V2 15/34] dt: clk: Add ingenic,jz4740-cgu binding documentation
  2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  (?)
@ 2015-02-04 16:27   ` Arnd Bergmann
  -1 siblings, 0 replies; 86+ messages in thread
From: Arnd Bergmann @ 2015-02-04 16:27 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips, devicetree, linux-serial, linux-kernel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

On Wednesday 04 February 2015 15:21:44 Zubair Lutfullah Kakakhel wrote:
> 
> +/ {
> +       ext: clock@0 {
> +               compatible = "fixed-clock";
> +               #clock-cells = <0>;
> +               clock-frequency = <12000000>;
> +       };
> +
> +       rtc: clock@1 {
> +               compatible = "fixed-clock";
> +               #clock-cells = <0>;
> +               clock-frequency = <32768>;
> +       };
> +
> +       &cgu {
> +               clocks = <&ext> <&rtc>;
> +               clock-names: "ext", "rtc";
> +       };
> +};
> diff --git a/include/dt-bindings/clock/jz4740-cgu.h b/include/dt-bindings/clock/jz4740-cgu.h
> new file mode 100644
> index 0000000..43153d3
> --- /dev/null
> +++ b/include/dt-bindings/clock/jz4740-cgu.h
> @@ -0,0 +1,37 @@
> +/*
> + * This header provides clock numbers for the ingenic,jz4740-cgu DT binding.
> + *
> + * They are roughly ordered as:
> + *   - external clocks
> + *   - PLLs
> + *   - muxes/dividers in the order they appear in the jz4740 programmers manual
> + *   - gates in order of their bit in the CLKGR* registers
> + */
> +
> +#ifndef __DT_BINDINGS_CLOCK_JZ4740_CGU_H__
> +#define __DT_BINDINGS_CLOCK_JZ4740_CGU_H__
> +
> +#define JZ4740_CLK_EXT         0
> +#define JZ4740_CLK_RTC         1
> +#define JZ4740_CLK_PLL         2
> +#define JZ4740_CLK_PLL_HALF    3

So there are fixed clocks for ext and rtc that are used as inputs
to the cgu, but also outputs with the same name. How do these relate?

	Arnd

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

* Re: [PATCH_V2 27/34] MIPS: jz4740: use jz47xx-uart & DT for UART output
@ 2015-02-04 16:32     ` Arnd Bergmann
  0 siblings, 0 replies; 86+ messages in thread
From: Arnd Bergmann @ 2015-02-04 16:32 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips, devicetree, linux-serial, linux-kernel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

On Wednesday 04 February 2015 15:21:56 Zubair Lutfullah Kakakhel wrote:
> +#ifndef __JZ4740_SERIAL_H__
> +#define __JZ4740_SERIAL_H__
> +
> +#define BASE_BAUD (12000000 / 16)
> +
> +#endif /* __JZ4740_SERIAL_H__ */
> 

This looks wrong: You should not need to hardcode this number when
you can get it from DT.

	Arnd

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

* Re: [PATCH_V2 27/34] MIPS: jz4740: use jz47xx-uart & DT for UART output
@ 2015-02-04 16:32     ` Arnd Bergmann
  0 siblings, 0 replies; 86+ messages in thread
From: Arnd Bergmann @ 2015-02-04 16:32 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	mturquette-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	ralf-6z/3iImG2C8G8FEW9MqTrA, jslaby-AlSwsSmVLrQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA,
	lars-Qo5EllUWu/uELgA04lAiVw, paul.burton-1AXoQHu6uovQT0dZR+AlfA

On Wednesday 04 February 2015 15:21:56 Zubair Lutfullah Kakakhel wrote:
> +#ifndef __JZ4740_SERIAL_H__
> +#define __JZ4740_SERIAL_H__
> +
> +#define BASE_BAUD (12000000 / 16)
> +
> +#endif /* __JZ4740_SERIAL_H__ */
> 

This looks wrong: You should not need to hardcode this number when
you can get it from DT.

	Arnd
--
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	[flat|nested] 86+ messages in thread

* Re: [PATCH_V2 00/34] jz4780 & CI20 support
  2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
@ 2015-02-04 16:47   ` Paul Burton
  -1 siblings, 0 replies; 86+ messages in thread
From: Paul Burton @ 2015-02-04 16:47 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips, devicetree, linux-serial, linux-kernel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars

On Wed, Feb 04, 2015 at 03:21:29PM +0000, Zubair Lutfullah Kakakhel wrote:
> Hi,
> 
> This series introduces initial support for the Ingenic jz4780 SoC & the
> MIPS Creator CI20 board which is based upon it.
> 
> The jz4780 shares aspects with jz4740. But jz4740 is platform only.
> 
> So, the jz4740 & qi_lb60 (Ben NanoNote) are converted to use DT
> for some things in order to ease the process of sharing code.
> 
> Series is based on 3.19-rc7.
> 
> ACKS from various subsystems are welcome so that the series can
> go via mips if that is OK with everyone.
> 
> Alternative suggestions welcome.
> 
> Changes in V2
> - Removed FSF addresses. 
> - Removed 2 patches for binding docs that
>   were consolidated in the same binding for jz4740.
> - Bug fix in error handling in cgu
> - Rebase on 3.19-rc7
> - Updated defconfig with jz47xx serial and removed initramfs
> - Renames in binding from intc to interrupt-controller
> - Fix in jz47xx serial for build error on x86 in one config option
> - Removed interupt-parent bindings from required bindings
> - Fixed imgtec prefix to img
> - Added jz47xx config for qi_lb60_defconfig
> 
> Regards,
> ZubairLK

Hi Zubair,

So first of all, thanks. I've been rather busy & haven't had time to
revise this patchset myself yet so I appreciate your effort.

Having said that, I do find it at best rather rude to take someone elses
patches, modify them & submit them without first:

  - Asking the author if that's ok.

  - Allowing the author to look over the changes you've made to their
    patches.

  - Making it clear in the commit message for each patch which
    modifications you have made.

As is I now have to go and retroactively check each patch against mine
to find out what's different, since you didn't indicate that in each
patch, and then hope I agree with the changes that you made but which
the patches indicate I authored.

So please, if you should see fit to modify any of my patches in the
future, do the above things first.

Thanks,
    Paul

> Paul Burton (34):
>   dt: Add Ingenic Semiconductor vendor prefix
>   MIPS: jz4740: require & include DT
>   MIPS: irq_cpu: declare irqchip table entry
>   MIPS: jz4740: probe CPU interrupt controller via DT
>   MIPS: jz4740: use generic plat_irq_dispatch
>   MIPS: jz4740: move arch_init_irq out of arch/mips/jz4740/irq.c
>   dt: interrupt-controller: Add ingenic,jz4740-intc binding doc
>   MIPS: jz4740: allow interrupt controller probe via DT
>   MIPS: jz4740: probe interrupt controller via DT
>   MIPS: jz4740: remove non-DT interrupt controller init
>   MIPS: jz4740: register an irq_domain for the interrupt controller
>   MIPS: jz4740: call jz4740_clock_init earlier
>   MIPS: jz4740: replace use of jz4740_clock_bdata
>   clk: jz47xx-cgu: add driver for Ingenic jz47xx series CGU clocks
>   dt: clk: Add ingenic,jz4740-cgu binding documentation
>   MIPS: clk: migrate jz4740 to common clock framework
>   MIPS: clk: move jz4740_clock_set_wait_mode to jz4740-cgu
>   MIPS: clk: move jz4740 UDC auto suspend functions to jz4740-cgu
>   MIPS: clk: move jz4740 clock suspend, resume functions to jz4740-cgu
>   MIPS: jz4740: remove clock.h
>   MIPS: jz4740: only detect RAM size if not specified in DT
>   MIPS: jz4740: support >32 interrupts
>   MIPS: jz4740: define IRQ numbers based on number of intc IRQs
>   dt: serial: Add ingenic,jz4740-uart binding
>   serial: 8250_jz47xx: support for Ingenic jz47xx UARTs
>   MIPS: allow mach-provided serial.h
>   MIPS: jz4740: use jz47xx-uart & DT for UART output
>   dt: clk: Add ingenic,jz4780-cgu binding documentation
>   clk: add Ingenic jz4780 CGU driver
>   MIPS: jz4740: add jz4780 interrupt controller support
>   MIPS: add jz4780 Ingenic vendor ID
>   MIPS: initial Ingenic jz4780 support
>   MIPS: initial MIPS Creator CI20 board support
>   MIPS: allow jz4780 to be selected in Kconfig
> 
>  .../bindings/clock/ingenic,jz4740-cgu.txt          |  52 ++
>  .../bindings/clock/ingenic,jz4780-cgu.txt          |  52 ++
>  .../interrupt-controller/ingenic,jz4740-intc.txt   |  26 +
>  .../bindings/serial/ingenic,jz4740-uart.txt        |  22 +
>  .../devicetree/bindings/vendor-prefixes.txt        |   1 +
>  arch/mips/Kconfig                                  |  22 +-
>  arch/mips/boot/dts/Makefile                        |   2 +
>  arch/mips/boot/dts/ci20.dts                        |  21 +
>  arch/mips/boot/dts/jz4740.dtsi                     |  68 ++
>  arch/mips/boot/dts/jz4780.dtsi                     | 101 +++
>  arch/mips/boot/dts/qi_lb60.dts                     |  15 +
>  arch/mips/configs/ci20_defconfig                   | 127 +++
>  arch/mips/configs/qi_lb60_defconfig                |   1 +
>  arch/mips/include/asm/Kbuild                       |   1 -
>  arch/mips/include/asm/cpu.h                        |   1 +
>  arch/mips/include/asm/mach-generic/serial.h        |  21 +
>  arch/mips/include/asm/mach-jz4740/clock.h          |   3 +
>  arch/mips/include/asm/mach-jz4740/irq.h            |  15 +-
>  arch/mips/include/asm/mach-jz4740/platform.h       |   2 -
>  arch/mips/include/asm/mach-jz4740/serial.h         |  27 +
>  arch/mips/include/asm/serial.h                     |  21 +
>  arch/mips/jz4740/Kconfig                           |  10 +
>  arch/mips/jz4740/Makefile                          |   6 +-
>  arch/mips/jz4740/Platform                          |   4 +
>  arch/mips/jz4740/board-qi_lb60.c                   |   7 -
>  arch/mips/jz4740/clock-debugfs.c                   | 108 ---
>  arch/mips/jz4740/clock.c                           | 924 ---------------------
>  arch/mips/jz4740/clock.h                           |  76 --
>  arch/mips/jz4740/irq.c                             | 103 ++-
>  arch/mips/jz4740/platform.c                        |  37 +-
>  arch/mips/jz4740/pm.c                              |   2 -
>  arch/mips/jz4740/prom.c                            |  13 -
>  arch/mips/jz4740/reset.c                           |  13 +-
>  arch/mips/jz4740/serial.c                          |  33 -
>  arch/mips/jz4740/serial.h                          |  23 -
>  arch/mips/jz4740/setup.c                           |  33 +-
>  arch/mips/jz4740/time.c                            |  19 +-
>  arch/mips/kernel/cpu-probe.c                       |   1 +
>  arch/mips/kernel/irq_cpu.c                         |   3 +
>  drivers/clk/Makefile                               |   2 +
>  drivers/clk/jz47xx/Makefile                        |   3 +
>  drivers/clk/jz47xx/jz4740-cgu.c                    | 295 +++++++
>  drivers/clk/jz47xx/jz4780-cgu.c                    | 742 +++++++++++++++++
>  drivers/clk/jz47xx/jz47xx-cgu.c                    | 723 ++++++++++++++++
>  drivers/clk/jz47xx/jz47xx-cgu.h                    | 205 +++++
>  drivers/tty/serial/8250/8250_jz47xx.c              | 225 +++++
>  drivers/tty/serial/8250/Kconfig                    |   9 +
>  drivers/tty/serial/8250/Makefile                   |   1 +
>  include/dt-bindings/clock/jz4740-cgu.h             |  37 +
>  include/dt-bindings/clock/jz4780-cgu.h             |  88 ++
>  50 files changed, 3070 insertions(+), 1276 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
>  create mode 100644 Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt
>  create mode 100644 arch/mips/boot/dts/ci20.dts
>  create mode 100644 arch/mips/boot/dts/jz4740.dtsi
>  create mode 100644 arch/mips/boot/dts/jz4780.dtsi
>  create mode 100644 arch/mips/boot/dts/qi_lb60.dts
>  create mode 100644 arch/mips/configs/ci20_defconfig
>  create mode 100644 arch/mips/include/asm/mach-generic/serial.h
>  create mode 100644 arch/mips/include/asm/mach-jz4740/serial.h
>  create mode 100644 arch/mips/include/asm/serial.h
>  delete mode 100644 arch/mips/jz4740/clock-debugfs.c
>  delete mode 100644 arch/mips/jz4740/clock.c
>  delete mode 100644 arch/mips/jz4740/clock.h
>  delete mode 100644 arch/mips/jz4740/serial.c
>  delete mode 100644 arch/mips/jz4740/serial.h
>  create mode 100644 drivers/clk/jz47xx/Makefile
>  create mode 100644 drivers/clk/jz47xx/jz4740-cgu.c
>  create mode 100644 drivers/clk/jz47xx/jz4780-cgu.c
>  create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.c
>  create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.h
>  create mode 100644 drivers/tty/serial/8250/8250_jz47xx.c
>  create mode 100644 include/dt-bindings/clock/jz4740-cgu.h
>  create mode 100644 include/dt-bindings/clock/jz4780-cgu.h
> 
> -- 
> 1.9.1
> 

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

* Re: [PATCH_V2 00/34] jz4780 & CI20 support
@ 2015-02-04 16:47   ` Paul Burton
  0 siblings, 0 replies; 86+ messages in thread
From: Paul Burton @ 2015-02-04 16:47 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips, devicetree, linux-serial, linux-kernel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars

On Wed, Feb 04, 2015 at 03:21:29PM +0000, Zubair Lutfullah Kakakhel wrote:
> Hi,
> 
> This series introduces initial support for the Ingenic jz4780 SoC & the
> MIPS Creator CI20 board which is based upon it.
> 
> The jz4780 shares aspects with jz4740. But jz4740 is platform only.
> 
> So, the jz4740 & qi_lb60 (Ben NanoNote) are converted to use DT
> for some things in order to ease the process of sharing code.
> 
> Series is based on 3.19-rc7.
> 
> ACKS from various subsystems are welcome so that the series can
> go via mips if that is OK with everyone.
> 
> Alternative suggestions welcome.
> 
> Changes in V2
> - Removed FSF addresses. 
> - Removed 2 patches for binding docs that
>   were consolidated in the same binding for jz4740.
> - Bug fix in error handling in cgu
> - Rebase on 3.19-rc7
> - Updated defconfig with jz47xx serial and removed initramfs
> - Renames in binding from intc to interrupt-controller
> - Fix in jz47xx serial for build error on x86 in one config option
> - Removed interupt-parent bindings from required bindings
> - Fixed imgtec prefix to img
> - Added jz47xx config for qi_lb60_defconfig
> 
> Regards,
> ZubairLK

Hi Zubair,

So first of all, thanks. I've been rather busy & haven't had time to
revise this patchset myself yet so I appreciate your effort.

Having said that, I do find it at best rather rude to take someone elses
patches, modify them & submit them without first:

  - Asking the author if that's ok.

  - Allowing the author to look over the changes you've made to their
    patches.

  - Making it clear in the commit message for each patch which
    modifications you have made.

As is I now have to go and retroactively check each patch against mine
to find out what's different, since you didn't indicate that in each
patch, and then hope I agree with the changes that you made but which
the patches indicate I authored.

So please, if you should see fit to modify any of my patches in the
future, do the above things first.

Thanks,
    Paul

> Paul Burton (34):
>   dt: Add Ingenic Semiconductor vendor prefix
>   MIPS: jz4740: require & include DT
>   MIPS: irq_cpu: declare irqchip table entry
>   MIPS: jz4740: probe CPU interrupt controller via DT
>   MIPS: jz4740: use generic plat_irq_dispatch
>   MIPS: jz4740: move arch_init_irq out of arch/mips/jz4740/irq.c
>   dt: interrupt-controller: Add ingenic,jz4740-intc binding doc
>   MIPS: jz4740: allow interrupt controller probe via DT
>   MIPS: jz4740: probe interrupt controller via DT
>   MIPS: jz4740: remove non-DT interrupt controller init
>   MIPS: jz4740: register an irq_domain for the interrupt controller
>   MIPS: jz4740: call jz4740_clock_init earlier
>   MIPS: jz4740: replace use of jz4740_clock_bdata
>   clk: jz47xx-cgu: add driver for Ingenic jz47xx series CGU clocks
>   dt: clk: Add ingenic,jz4740-cgu binding documentation
>   MIPS: clk: migrate jz4740 to common clock framework
>   MIPS: clk: move jz4740_clock_set_wait_mode to jz4740-cgu
>   MIPS: clk: move jz4740 UDC auto suspend functions to jz4740-cgu
>   MIPS: clk: move jz4740 clock suspend, resume functions to jz4740-cgu
>   MIPS: jz4740: remove clock.h
>   MIPS: jz4740: only detect RAM size if not specified in DT
>   MIPS: jz4740: support >32 interrupts
>   MIPS: jz4740: define IRQ numbers based on number of intc IRQs
>   dt: serial: Add ingenic,jz4740-uart binding
>   serial: 8250_jz47xx: support for Ingenic jz47xx UARTs
>   MIPS: allow mach-provided serial.h
>   MIPS: jz4740: use jz47xx-uart & DT for UART output
>   dt: clk: Add ingenic,jz4780-cgu binding documentation
>   clk: add Ingenic jz4780 CGU driver
>   MIPS: jz4740: add jz4780 interrupt controller support
>   MIPS: add jz4780 Ingenic vendor ID
>   MIPS: initial Ingenic jz4780 support
>   MIPS: initial MIPS Creator CI20 board support
>   MIPS: allow jz4780 to be selected in Kconfig
> 
>  .../bindings/clock/ingenic,jz4740-cgu.txt          |  52 ++
>  .../bindings/clock/ingenic,jz4780-cgu.txt          |  52 ++
>  .../interrupt-controller/ingenic,jz4740-intc.txt   |  26 +
>  .../bindings/serial/ingenic,jz4740-uart.txt        |  22 +
>  .../devicetree/bindings/vendor-prefixes.txt        |   1 +
>  arch/mips/Kconfig                                  |  22 +-
>  arch/mips/boot/dts/Makefile                        |   2 +
>  arch/mips/boot/dts/ci20.dts                        |  21 +
>  arch/mips/boot/dts/jz4740.dtsi                     |  68 ++
>  arch/mips/boot/dts/jz4780.dtsi                     | 101 +++
>  arch/mips/boot/dts/qi_lb60.dts                     |  15 +
>  arch/mips/configs/ci20_defconfig                   | 127 +++
>  arch/mips/configs/qi_lb60_defconfig                |   1 +
>  arch/mips/include/asm/Kbuild                       |   1 -
>  arch/mips/include/asm/cpu.h                        |   1 +
>  arch/mips/include/asm/mach-generic/serial.h        |  21 +
>  arch/mips/include/asm/mach-jz4740/clock.h          |   3 +
>  arch/mips/include/asm/mach-jz4740/irq.h            |  15 +-
>  arch/mips/include/asm/mach-jz4740/platform.h       |   2 -
>  arch/mips/include/asm/mach-jz4740/serial.h         |  27 +
>  arch/mips/include/asm/serial.h                     |  21 +
>  arch/mips/jz4740/Kconfig                           |  10 +
>  arch/mips/jz4740/Makefile                          |   6 +-
>  arch/mips/jz4740/Platform                          |   4 +
>  arch/mips/jz4740/board-qi_lb60.c                   |   7 -
>  arch/mips/jz4740/clock-debugfs.c                   | 108 ---
>  arch/mips/jz4740/clock.c                           | 924 ---------------------
>  arch/mips/jz4740/clock.h                           |  76 --
>  arch/mips/jz4740/irq.c                             | 103 ++-
>  arch/mips/jz4740/platform.c                        |  37 +-
>  arch/mips/jz4740/pm.c                              |   2 -
>  arch/mips/jz4740/prom.c                            |  13 -
>  arch/mips/jz4740/reset.c                           |  13 +-
>  arch/mips/jz4740/serial.c                          |  33 -
>  arch/mips/jz4740/serial.h                          |  23 -
>  arch/mips/jz4740/setup.c                           |  33 +-
>  arch/mips/jz4740/time.c                            |  19 +-
>  arch/mips/kernel/cpu-probe.c                       |   1 +
>  arch/mips/kernel/irq_cpu.c                         |   3 +
>  drivers/clk/Makefile                               |   2 +
>  drivers/clk/jz47xx/Makefile                        |   3 +
>  drivers/clk/jz47xx/jz4740-cgu.c                    | 295 +++++++
>  drivers/clk/jz47xx/jz4780-cgu.c                    | 742 +++++++++++++++++
>  drivers/clk/jz47xx/jz47xx-cgu.c                    | 723 ++++++++++++++++
>  drivers/clk/jz47xx/jz47xx-cgu.h                    | 205 +++++
>  drivers/tty/serial/8250/8250_jz47xx.c              | 225 +++++
>  drivers/tty/serial/8250/Kconfig                    |   9 +
>  drivers/tty/serial/8250/Makefile                   |   1 +
>  include/dt-bindings/clock/jz4740-cgu.h             |  37 +
>  include/dt-bindings/clock/jz4780-cgu.h             |  88 ++
>  50 files changed, 3070 insertions(+), 1276 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4740-cgu.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/ingenic,jz4780-cgu.txt
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
>  create mode 100644 Documentation/devicetree/bindings/serial/ingenic,jz4740-uart.txt
>  create mode 100644 arch/mips/boot/dts/ci20.dts
>  create mode 100644 arch/mips/boot/dts/jz4740.dtsi
>  create mode 100644 arch/mips/boot/dts/jz4780.dtsi
>  create mode 100644 arch/mips/boot/dts/qi_lb60.dts
>  create mode 100644 arch/mips/configs/ci20_defconfig
>  create mode 100644 arch/mips/include/asm/mach-generic/serial.h
>  create mode 100644 arch/mips/include/asm/mach-jz4740/serial.h
>  create mode 100644 arch/mips/include/asm/serial.h
>  delete mode 100644 arch/mips/jz4740/clock-debugfs.c
>  delete mode 100644 arch/mips/jz4740/clock.c
>  delete mode 100644 arch/mips/jz4740/clock.h
>  delete mode 100644 arch/mips/jz4740/serial.c
>  delete mode 100644 arch/mips/jz4740/serial.h
>  create mode 100644 drivers/clk/jz47xx/Makefile
>  create mode 100644 drivers/clk/jz47xx/jz4740-cgu.c
>  create mode 100644 drivers/clk/jz47xx/jz4780-cgu.c
>  create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.c
>  create mode 100644 drivers/clk/jz47xx/jz47xx-cgu.h
>  create mode 100644 drivers/tty/serial/8250/8250_jz47xx.c
>  create mode 100644 include/dt-bindings/clock/jz4740-cgu.h
>  create mode 100644 include/dt-bindings/clock/jz4780-cgu.h
> 
> -- 
> 1.9.1
> 

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

* Re: [PATCH_V2 04/34] MIPS: jz4740: probe CPU interrupt controller via DT
  2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  (?)
@ 2015-02-04 17:05   ` Sergei Shtylyov
  -1 siblings, 0 replies; 86+ messages in thread
From: Sergei Shtylyov @ 2015-02-04 17:05 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, linux-mips
  Cc: devicetree, linux-serial, linux-kernel, gregkh, mturquette,
	sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

Hello.

On 02/04/2015 06:21 PM, Zubair Lutfullah Kakakhel wrote:

> From: Paul Burton <paul.burton@imgtec.com>

> Use the generic irqchip_init function to probe irqchip drivers using DT,
> and add the appropriate node to the jz4740 devicetree in place of the
> call to mips_cpu_irq_init.

> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> ---
>   arch/mips/boot/dts/jz4740.dtsi | 7 +++++++
>   arch/mips/jz4740/irq.c         | 4 ++--
>   2 files changed, 9 insertions(+), 2 deletions(-)

> diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
> index c538691f..2d64765c 100644
> --- a/arch/mips/boot/dts/jz4740.dtsi
> +++ b/arch/mips/boot/dts/jz4740.dtsi
> @@ -2,4 +2,11 @@
>   	#address-cells = <1>;
>   	#size-cells = <1>;
>   	compatible = "ingenic,jz4740";
> +
> +	cpuintc: cpuintc@0 {

    Please name it "interrupt-controller". And why there's <unit-address> if 
there's no "reg" prop?

> +		#address-cells = <0>;
> +		#interrupt-cells = <1>;
> +		interrupt-controller;
> +		compatible = "mti,cpu-interrupt-controller";
> +	};
>   };
[...]

WBR, Sergei


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

* Re: [PATCH_V2 07/34] dt: interrupt-controller: Add ingenic,jz4740-intc binding doc
  2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  (?)
@ 2015-02-04 17:07   ` Sergei Shtylyov
  -1 siblings, 0 replies; 86+ messages in thread
From: Sergei Shtylyov @ 2015-02-04 17:07 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, linux-mips
  Cc: devicetree, linux-serial, linux-kernel, gregkh, mturquette,
	sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

Hello.

On 02/04/2015 06:21 PM, Zubair Lutfullah Kakakhel wrote:

> From: Paul Burton <paul.burton@imgtec.com>

> Add binding documentation for the Ingenic jz4740 interrupt controller.

> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: devicetree@vger.kernel.org
> ---
>   .../interrupt-controller/ingenic,jz4740-intc.txt   | 26 ++++++++++++++++++++++
>   1 file changed, 26 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt

> diff --git a/Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
> new file mode 100644
> index 0000000..5e7f4bb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/ingenic,jz4740-intc.txt
> @@ -0,0 +1,26 @@
> +Ingenic jz4740 SoC Interrupt Controller

    JZ4740?

> +
> +Required properties:
> +
> +- compatible : should be "ingenic,jz4740-intc" or "ingenic,jz4780-intc"
> +- reg : Specifies base physical address and size of the registers.
> +- interrupt-controller : Identifies the node as an interrupt controller
> +- #interrupt-cells : Specifies the number of cells needed to encode an
> +  interrupt source. The value shall be 1.
> +- interrupts - Specifies the CPU interrupt the controller is connected to.
> +
> +Optional properties:
> +- interrupt-parent: phandle of the CPU interrupt controller.
> +
> +Example:
> +
> +intc: intc@10001000 {

    Name it "interrupt-controller@10001000", please.

> +	compatible = "ingenic,jz4740-intc";
> +	reg = <0x10001000 0x14>;
> +
> +	interrupt-controller;
> +	#interrupt-cells = <1>;
> +
> +	interrupt-parent = <&cpuintc>;
> +	interrupts = <2>;
> +};

WBR, Sergei


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

* Re: [PATCH_V2 09/34] MIPS: jz4740: probe interrupt controller via DT
  2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  (?)
@ 2015-02-04 17:09   ` Sergei Shtylyov
  -1 siblings, 0 replies; 86+ messages in thread
From: Sergei Shtylyov @ 2015-02-04 17:09 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel, linux-mips
  Cc: devicetree, linux-serial, linux-kernel, gregkh, mturquette,
	sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

On 02/04/2015 06:21 PM, Zubair Lutfullah Kakakhel wrote:

> From: Paul Burton <paul.burton@imgtec.com>

> Add the appropriate DT node to probe the interrupt controller driver
> using the devicetree, and remove the call to jz4740_intc_init.

> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> ---
>   arch/mips/boot/dts/jz4740.dtsi | 11 +++++++++++
>   arch/mips/jz4740/setup.c       |  2 --
>   2 files changed, 11 insertions(+), 2 deletions(-)

> diff --git a/arch/mips/boot/dts/jz4740.dtsi b/arch/mips/boot/dts/jz4740.dtsi
> index 2d64765c..3841024 100644
> --- a/arch/mips/boot/dts/jz4740.dtsi
> +++ b/arch/mips/boot/dts/jz4740.dtsi
> @@ -9,4 +9,15 @@
>   		interrupt-controller;
>   		compatible = "mti,cpu-interrupt-controller";
>   	};
> +
> +	intc: intc@10001000 {

    Name it "interrupt-controller@10001000", please. I have faint memories of 
already telling you to do this...

> +		compatible = "ingenic,jz4740-intc";
> +		reg = <0x10001000 0x14>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <1>;
> +
> +		interrupt-parent = <&cpuintc>;
> +		interrupts = <2>;
> +	};
>   };
[...]

WBR, Sergei


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

* Re: [PATCH_V2 33/34] MIPS: initial MIPS Creator CI20 board support
@ 2015-02-04 20:56     ` Paul Bolle
  0 siblings, 0 replies; 86+ messages in thread
From: Paul Bolle @ 2015-02-04 20:56 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips, devicetree, linux-serial, linux-kernel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

On Wed, 2015-02-04 at 15:22 +0000, Zubair Lutfullah Kakakhel wrote:
> From: Paul Burton <paul.burton@imgtec.com>
> 
> Add a device tree for the Ingenic jz4780 based MIPS Creator CI20 board.
> Note that this is unselectable via Kconfig until the jz4780 SoC is made
> selectable in a later commit.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/mips/boot/dts/Makefile      |   1 +
>  arch/mips/boot/dts/ci20.dts      |  21 +++++++
>  arch/mips/configs/ci20_defconfig | 127 +++++++++++++++++++++++++++++++++++++++
>  arch/mips/jz4740/Kconfig         |  10 +++
>  4 files changed, 159 insertions(+)
>  create mode 100644 arch/mips/boot/dts/ci20.dts
>  create mode 100644 arch/mips/configs/ci20_defconfig
>[...]
> diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
> index 4689030..72ac174 100644
> --- a/arch/mips/jz4740/Kconfig
> +++ b/arch/mips/jz4740/Kconfig
> @@ -7,3 +7,13 @@ config JZ4740_QI_LB60
>  	bool "Qi Hardware Ben NanoNote"
>  
>  endchoice
> +
> +choice
> +	prompt "Machine type"
> +	depends on MACH_JZ4780
> +	default JZ4780_CI20
> +
> +config JZ4780_CI20
> +	bool "MIPS Creator CI20"
> +
> +endchoice

This adds a choice with a single entry. What's the point?


Paul Bolle


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

* Re: [PATCH_V2 33/34] MIPS: initial MIPS Creator CI20 board support
@ 2015-02-04 20:56     ` Paul Bolle
  0 siblings, 0 replies; 86+ messages in thread
From: Paul Bolle @ 2015-02-04 20:56 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	mturquette-QSEj5FYQhm4dnm+yROfE0A, sboyd-sgV2jX0FEOL9JmXXK+q4OQ,
	ralf-6z/3iImG2C8G8FEW9MqTrA, jslaby-AlSwsSmVLrQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ, jason-NLaQJdtUoK4Be96aLqz0jA,
	lars-Qo5EllUWu/uELgA04lAiVw, paul.burton-1AXoQHu6uovQT0dZR+AlfA

On Wed, 2015-02-04 at 15:22 +0000, Zubair Lutfullah Kakakhel wrote:
> From: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
> 
> Add a device tree for the Ingenic jz4780 based MIPS Creator CI20 board.
> Note that this is unselectable via Kconfig until the jz4780 SoC is made
> selectable in a later commit.
> 
> Signed-off-by: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>
> Cc: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
> ---
>  arch/mips/boot/dts/Makefile      |   1 +
>  arch/mips/boot/dts/ci20.dts      |  21 +++++++
>  arch/mips/configs/ci20_defconfig | 127 +++++++++++++++++++++++++++++++++++++++
>  arch/mips/jz4740/Kconfig         |  10 +++
>  4 files changed, 159 insertions(+)
>  create mode 100644 arch/mips/boot/dts/ci20.dts
>  create mode 100644 arch/mips/configs/ci20_defconfig
>[...]
> diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
> index 4689030..72ac174 100644
> --- a/arch/mips/jz4740/Kconfig
> +++ b/arch/mips/jz4740/Kconfig
> @@ -7,3 +7,13 @@ config JZ4740_QI_LB60
>  	bool "Qi Hardware Ben NanoNote"
>  
>  endchoice
> +
> +choice
> +	prompt "Machine type"
> +	depends on MACH_JZ4780
> +	default JZ4780_CI20
> +
> +config JZ4780_CI20
> +	bool "MIPS Creator CI20"
> +
> +endchoice

This adds a choice with a single entry. What's the point?


Paul Bolle

--
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	[flat|nested] 86+ messages in thread

* Re: [PATCH_V2 25/34] serial: 8250_jz47xx: support for Ingenic jz47xx UARTs
  2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
  (?)
@ 2015-02-04 21:02   ` Paul Bolle
  -1 siblings, 0 replies; 86+ messages in thread
From: Paul Bolle @ 2015-02-04 21:02 UTC (permalink / raw)
  To: Zubair Lutfullah Kakakhel
  Cc: linux-mips, devicetree, linux-serial, linux-kernel, gregkh,
	mturquette, sboyd, ralf, jslaby, tglx, jason, lars, paul.burton

On Wed, 2015-02-04 at 15:21 +0000, Zubair Lutfullah Kakakhel wrote:
> From: Paul Burton <paul.burton@imgtec.com>
> 
> Introduce a driver suitable for use with the UARTs present in
> Ingenic jz47xx series SoCs. These are described as being ns16550
> compatible but aren't quite - they require the setting of an extra bit
> in the FCR register to enable the UART module. The serial_out
> implementation is the same as that in arch/mips/jz4740/serial.c - which
> will shortly be removed.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Lars-Peter Clausen <lars@metafoo.de>
> Cc: linux-serial@vger.kernel.org
> 
> ---
> V2 changes
> Removed FSF address
> Added select SERIAL_CORE_CONSOLE to fix a build error
> ---
>  drivers/tty/serial/8250/8250_jz47xx.c | 225 ++++++++++++++++++++++++++++++++++
>  drivers/tty/serial/8250/Kconfig       |   9 ++
>  drivers/tty/serial/8250/Makefile      |   1 +
>  3 files changed, 235 insertions(+)
>  create mode 100644 drivers/tty/serial/8250/8250_jz47xx.c
> 
>[...]
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index 0fcbcd2..ebb298e 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -322,3 +322,12 @@ config SERIAL_8250_MT6577
>  	help
>  	  If you have a Mediatek based board and want to use the
>  	  serial port, say Y to this option. If unsure, say N.
> +
> +config SERIAL_8250_JZ47XX
> +	tristate "Support for Ingenic jz47xx series serial ports"
> +	depends on SERIAL_8250
> +	select SERIAL_EARLYCON
> +	select SERIAL_CORE_CONSOLE
> +	help
> +	  If you have a system using an Ingenic jz47xx series SoC and wish to
> +	  make use of its UARTs, say Y to this option. If unsure, say N.

Nit: should people never say M?


Paul Bolle


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

end of thread, other threads:[~2015-02-04 21:03 UTC | newest]

Thread overview: 86+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-04 15:21 [PATCH_V2 00/34] jz4780 & CI20 support Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 01/34] dt: Add Ingenic Semiconductor vendor prefix Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 02/34] MIPS: jz4740: require & include DT Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 03/34] MIPS: irq_cpu: declare irqchip table entry Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 04/34] MIPS: jz4740: probe CPU interrupt controller via DT Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 17:05   ` Sergei Shtylyov
2015-02-04 15:21 ` [PATCH_V2 05/34] MIPS: jz4740: use generic plat_irq_dispatch Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 06/34] MIPS: jz4740: move arch_init_irq out of arch/mips/jz4740/irq.c Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 07/34] dt: interrupt-controller: Add ingenic,jz4740-intc binding doc Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 17:07   ` Sergei Shtylyov
2015-02-04 15:21 ` [PATCH_V2 08/34] MIPS: jz4740: allow interrupt controller probe via DT Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 09/34] MIPS: jz4740: probe interrupt controller " Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 17:09   ` Sergei Shtylyov
2015-02-04 15:21 ` [PATCH_V2 10/34] MIPS: jz4740: remove non-DT interrupt controller init Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 11/34] MIPS: jz4740: register an irq_domain for the interrupt controller Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 16:19   ` Arnd Bergmann
2015-02-04 16:19     ` Arnd Bergmann
2015-02-04 15:21 ` [PATCH_V2 12/34] MIPS: jz4740: call jz4740_clock_init earlier Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 13/34] MIPS: jz4740: replace use of jz4740_clock_bdata Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 14/34] clk: jz47xx-cgu: add driver for Ingenic jz47xx series CGU clocks Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 15/34] dt: clk: Add ingenic,jz4740-cgu binding documentation Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 16:27   ` Arnd Bergmann
2015-02-04 15:21 ` [PATCH_V2 16/34] MIPS: clk: migrate jz4740 to common clock framework Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 17/34] MIPS: clk: move jz4740_clock_set_wait_mode to jz4740-cgu Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 18/34] MIPS: clk: move jz4740 UDC auto suspend functions " Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 19/34] MIPS: clk: move jz4740 clock suspend, resume " Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 20/34] MIPS: jz4740: remove clock.h Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 21/34] MIPS: jz4740: only detect RAM size if not specified in DT Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 22/34] MIPS: jz4740: support >32 interrupts Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 23/34] MIPS: jz4740: define IRQ numbers based on number of intc IRQs Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 24/34] dt: serial: Add ingenic,jz4740-uart binding Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 25/34] serial: 8250_jz47xx: support for Ingenic jz47xx UARTs Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 21:02   ` Paul Bolle
2015-02-04 15:21 ` [PATCH_V2 26/34] MIPS: allow mach-provided serial.h Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 27/34] MIPS: jz4740: use jz47xx-uart & DT for UART output Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 16:32   ` Arnd Bergmann
2015-02-04 16:32     ` Arnd Bergmann
2015-02-04 15:21 ` [PATCH_V2 28/34] dt: clk: Add ingenic,jz4780-cgu binding documentation Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 29/34] clk: add Ingenic jz4780 CGU driver Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:21 ` [PATCH_V2 30/34] MIPS: jz4740: add jz4780 interrupt controller support Zubair Lutfullah Kakakhel
2015-02-04 15:21   ` Zubair Lutfullah Kakakhel
2015-02-04 15:22 ` [PATCH_V2 31/34] MIPS: add jz4780 Ingenic vendor ID Zubair Lutfullah Kakakhel
2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
2015-02-04 15:22 ` [PATCH_V2 32/34] MIPS: initial Ingenic jz4780 support Zubair Lutfullah Kakakhel
2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
2015-02-04 15:22 ` [PATCH_V2 33/34] MIPS: initial MIPS Creator CI20 board support Zubair Lutfullah Kakakhel
2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
2015-02-04 20:56   ` Paul Bolle
2015-02-04 20:56     ` Paul Bolle
2015-02-04 15:22 ` [PATCH_V2 34/34] MIPS: allow jz4780 to be selected in Kconfig Zubair Lutfullah Kakakhel
2015-02-04 15:22   ` Zubair Lutfullah Kakakhel
2015-02-04 16:47 ` [PATCH_V2 00/34] jz4780 & CI20 support Paul Burton
2015-02-04 16:47   ` Paul Burton

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.