All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx
@ 2015-11-20  1:05 ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

This changeset adds common clock framework driver for NXP LPC32xx
boards.

The changeset has dependencies on the recent updates to LPC32xx DTS:
  http://permalink.gmane.org/gmane.linux.ports.arm.kernel/456304

The RFC version of CCF driver 9/11 can be found here:
  http://www.spinics.net/lists/devicetree/msg100583.html

Changes from RFC to v1:
* added definitions of a missed IRDA clock,
* renamed compatible property from lpc32xx-scb to lpc32xx-clk
* switched to regmap interface instead of mmio, this is required to
  secure access to registers shared between pinmux, dma and clock
  driver, unfortunately this change has to pull some code snippets
  from common gate, divider and mux helpers rebased on regmap API,
* split clock definitions from the driver to be able to update
  dts files separately from CCF driver.

The driver is written from scratch, here are main functional
differences with the legacy driver arch/arm/mach-lpc32xx/clock.c:
* serialized access to SCB registers,
* reworked routines to select PLL parameters,
* now the clock driver has detailed description of all clocks,
  the original driver misses several clock entries and most of fine
  grained clock controls, here every mux and divider are accounted,
* now clocks and clock hierarchies can be described in board DT file,
* sophisticated management of USB clocks, for example now USB device
  controller needs only one clock instead of USB PLL, USB OTG and USB
  device clocks,
* other benefits from a driver powered by CCF.

Patch 9/11 may produce false positives from checkpatch, the fix
to checkpatch can be found in Andrew's tree.

Vladimir Zapolskiy (11):
  dt-bindings: clock: add description of LPC32xx clock controller
  dt-bindings: clock: add description of LPC32xx USB clock controller
  dt-bindings: clock: add NXP LPC32xx clock list for consumers
  arm: dts: lpc32xx: add device nodes for external oscillators
  arm: dts: lpc32xx: add clock controller device node
  arm: dts: lpc32xx: add clock properties to device nodes
  arm: dts: lpc32xx: add USB clock controller
  clk: lpc18xx: add NXP specific common clock framework selection
  clk: lpc32xx: add common clock framework driver
  arm: lpc32xx: switch to common clock framework
  arm: dts: lpc32xx: remove clock frequency property from UART device
    nodes

 .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  |   30 +
 .../bindings/clock/nxp,lpc3220-usb-clk.txt         |   22 +
 arch/arm/Kconfig                                   |    4 +-
 arch/arm/boot/dts/lpc32xx.dtsi                     |   87 +-
 arch/arm/mach-lpc32xx/Makefile                     |    3 +-
 arch/arm/mach-lpc32xx/clock.c                      | 1284 ----------------
 arch/arm/mach-lpc32xx/phy3250.c                    |    1 -
 arch/arm/mach-lpc32xx/serial.c                     |    3 -
 arch/arm/mach-lpc32xx/timer.c                      |  144 --
 drivers/clk/Kconfig                                |    6 +
 drivers/clk/Makefile                               |    2 +-
 drivers/clk/nxp/Makefile                           |    1 +
 drivers/clk/nxp/clk-lpc32xx.c                      | 1562 ++++++++++++++++++++
 include/dt-bindings/clock/lpc32xx-clock.h          |   56 +
 14 files changed, 1765 insertions(+), 1440 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
 delete mode 100644 arch/arm/mach-lpc32xx/clock.c
 delete mode 100644 arch/arm/mach-lpc32xx/timer.c
 create mode 100644 drivers/clk/nxp/clk-lpc32xx.c
 create mode 100644 include/dt-bindings/clock/lpc32xx-clock.h

-- 
2.1.4

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

* [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx
@ 2015-11-20  1:05 ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

This changeset adds common clock framework driver for NXP LPC32xx
boards.

The changeset has dependencies on the recent updates to LPC32xx DTS:
  http://permalink.gmane.org/gmane.linux.ports.arm.kernel/456304

The RFC version of CCF driver 9/11 can be found here:
  http://www.spinics.net/lists/devicetree/msg100583.html

Changes from RFC to v1:
* added definitions of a missed IRDA clock,
* renamed compatible property from lpc32xx-scb to lpc32xx-clk
* switched to regmap interface instead of mmio, this is required to
  secure access to registers shared between pinmux, dma and clock
  driver, unfortunately this change has to pull some code snippets
  from common gate, divider and mux helpers rebased on regmap API,
* split clock definitions from the driver to be able to update
  dts files separately from CCF driver.

The driver is written from scratch, here are main functional
differences with the legacy driver arch/arm/mach-lpc32xx/clock.c:
* serialized access to SCB registers,
* reworked routines to select PLL parameters,
* now the clock driver has detailed description of all clocks,
  the original driver misses several clock entries and most of fine
  grained clock controls, here every mux and divider are accounted,
* now clocks and clock hierarchies can be described in board DT file,
* sophisticated management of USB clocks, for example now USB device
  controller needs only one clock instead of USB PLL, USB OTG and USB
  device clocks,
* other benefits from a driver powered by CCF.

Patch 9/11 may produce false positives from checkpatch, the fix
to checkpatch can be found in Andrew's tree.

Vladimir Zapolskiy (11):
  dt-bindings: clock: add description of LPC32xx clock controller
  dt-bindings: clock: add description of LPC32xx USB clock controller
  dt-bindings: clock: add NXP LPC32xx clock list for consumers
  arm: dts: lpc32xx: add device nodes for external oscillators
  arm: dts: lpc32xx: add clock controller device node
  arm: dts: lpc32xx: add clock properties to device nodes
  arm: dts: lpc32xx: add USB clock controller
  clk: lpc18xx: add NXP specific common clock framework selection
  clk: lpc32xx: add common clock framework driver
  arm: lpc32xx: switch to common clock framework
  arm: dts: lpc32xx: remove clock frequency property from UART device
    nodes

 .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  |   30 +
 .../bindings/clock/nxp,lpc3220-usb-clk.txt         |   22 +
 arch/arm/Kconfig                                   |    4 +-
 arch/arm/boot/dts/lpc32xx.dtsi                     |   87 +-
 arch/arm/mach-lpc32xx/Makefile                     |    3 +-
 arch/arm/mach-lpc32xx/clock.c                      | 1284 ----------------
 arch/arm/mach-lpc32xx/phy3250.c                    |    1 -
 arch/arm/mach-lpc32xx/serial.c                     |    3 -
 arch/arm/mach-lpc32xx/timer.c                      |  144 --
 drivers/clk/Kconfig                                |    6 +
 drivers/clk/Makefile                               |    2 +-
 drivers/clk/nxp/Makefile                           |    1 +
 drivers/clk/nxp/clk-lpc32xx.c                      | 1562 ++++++++++++++++++++
 include/dt-bindings/clock/lpc32xx-clock.h          |   56 +
 14 files changed, 1765 insertions(+), 1440 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
 delete mode 100644 arch/arm/mach-lpc32xx/clock.c
 delete mode 100644 arch/arm/mach-lpc32xx/timer.c
 create mode 100644 drivers/clk/nxp/clk-lpc32xx.c
 create mode 100644 include/dt-bindings/clock/lpc32xx-clock.h

-- 
2.1.4

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

* [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx
@ 2015-11-20  1:05 ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

This changeset adds common clock framework driver for NXP LPC32xx
boards.

The changeset has dependencies on the recent updates to LPC32xx DTS:
  http://permalink.gmane.org/gmane.linux.ports.arm.kernel/456304

The RFC version of CCF driver 9/11 can be found here:
  http://www.spinics.net/lists/devicetree/msg100583.html

Changes from RFC to v1:
* added definitions of a missed IRDA clock,
* renamed compatible property from lpc32xx-scb to lpc32xx-clk
* switched to regmap interface instead of mmio, this is required to
  secure access to registers shared between pinmux, dma and clock
  driver, unfortunately this change has to pull some code snippets
  from common gate, divider and mux helpers rebased on regmap API,
* split clock definitions from the driver to be able to update
  dts files separately from CCF driver.

The driver is written from scratch, here are main functional
differences with the legacy driver arch/arm/mach-lpc32xx/clock.c:
* serialized access to SCB registers,
* reworked routines to select PLL parameters,
* now the clock driver has detailed description of all clocks,
  the original driver misses several clock entries and most of fine
  grained clock controls, here every mux and divider are accounted,
* now clocks and clock hierarchies can be described in board DT file,
* sophisticated management of USB clocks, for example now USB device
  controller needs only one clock instead of USB PLL, USB OTG and USB
  device clocks,
* other benefits from a driver powered by CCF.

Patch 9/11 may produce false positives from checkpatch, the fix
to checkpatch can be found in Andrew's tree.

Vladimir Zapolskiy (11):
  dt-bindings: clock: add description of LPC32xx clock controller
  dt-bindings: clock: add description of LPC32xx USB clock controller
  dt-bindings: clock: add NXP LPC32xx clock list for consumers
  arm: dts: lpc32xx: add device nodes for external oscillators
  arm: dts: lpc32xx: add clock controller device node
  arm: dts: lpc32xx: add clock properties to device nodes
  arm: dts: lpc32xx: add USB clock controller
  clk: lpc18xx: add NXP specific common clock framework selection
  clk: lpc32xx: add common clock framework driver
  arm: lpc32xx: switch to common clock framework
  arm: dts: lpc32xx: remove clock frequency property from UART device
    nodes

 .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  |   30 +
 .../bindings/clock/nxp,lpc3220-usb-clk.txt         |   22 +
 arch/arm/Kconfig                                   |    4 +-
 arch/arm/boot/dts/lpc32xx.dtsi                     |   87 +-
 arch/arm/mach-lpc32xx/Makefile                     |    3 +-
 arch/arm/mach-lpc32xx/clock.c                      | 1284 ----------------
 arch/arm/mach-lpc32xx/phy3250.c                    |    1 -
 arch/arm/mach-lpc32xx/serial.c                     |    3 -
 arch/arm/mach-lpc32xx/timer.c                      |  144 --
 drivers/clk/Kconfig                                |    6 +
 drivers/clk/Makefile                               |    2 +-
 drivers/clk/nxp/Makefile                           |    1 +
 drivers/clk/nxp/clk-lpc32xx.c                      | 1562 ++++++++++++++++++++
 include/dt-bindings/clock/lpc32xx-clock.h          |   56 +
 14 files changed, 1765 insertions(+), 1440 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
 delete mode 100644 arch/arm/mach-lpc32xx/clock.c
 delete mode 100644 arch/arm/mach-lpc32xx/timer.c
 create mode 100644 drivers/clk/nxp/clk-lpc32xx.c
 create mode 100644 include/dt-bindings/clock/lpc32xx-clock.h

-- 
2.1.4

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

* [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
  2015-11-20  1:05 ` Vladimir Zapolskiy
  (?)
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
of system control block (SCB). CPC is supplied by two external
oscillators and it manages core and most of peripheral
clocks, the change adds description of DT bindings for clock
controller found on LPC32xx SoC series.

Signed-off-by: Vladimir Zapolskiy <vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
---
 .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
new file mode 100644
index 0000000..20cbca3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
@@ -0,0 +1,30 @@
+NXP LPC32xx Clock Controller
+
+Required properties:
+- compatible: should be "nxp,lpc3220-clk"
+- reg:  should contain clock controller registers location and length
+- #clock-cells: must be 1, the cell holds id of a clock provided by the
+  clock controller
+- clocks: phandles of external oscillators, the list must contain one
+  32768 Hz oscillator and may have one optional high frequency oscillator
+- clock-names: list of external oscillator clock names, must contain
+  "xtal_32k" and may have optional "xtal"
+
+Examples:
+
+	/* System Control Block */
+	scb {
+		compatible = "simple-bus";
+		ranges = <0x0 0x040004000 0x00001000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		clk: clock-controller@0 {
+			compatible = "nxp,lpc3220-clk";
+			reg = <0x00 0x114>;
+			#clock-cells = <1>;
+
+			clocks = <&xtal_32k>, <&xtal>;
+			clock-names = "xtal_32k", "xtal";
+		};
+	};
-- 
2.1.4

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

* [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
of system control block (SCB). CPC is supplied by two external
oscillators and it manages core and most of peripheral
clocks, the change adds description of DT bindings for clock
controller found on LPC32xx SoC series.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
new file mode 100644
index 0000000..20cbca3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
@@ -0,0 +1,30 @@
+NXP LPC32xx Clock Controller
+
+Required properties:
+- compatible: should be "nxp,lpc3220-clk"
+- reg:  should contain clock controller registers location and length
+- #clock-cells: must be 1, the cell holds id of a clock provided by the
+  clock controller
+- clocks: phandles of external oscillators, the list must contain one
+  32768 Hz oscillator and may have one optional high frequency oscillator
+- clock-names: list of external oscillator clock names, must contain
+  "xtal_32k" and may have optional "xtal"
+
+Examples:
+
+	/* System Control Block */
+	scb {
+		compatible = "simple-bus";
+		ranges = <0x0 0x040004000 0x00001000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		clk: clock-controller@0 {
+			compatible = "nxp,lpc3220-clk";
+			reg = <0x00 0x114>;
+			#clock-cells = <1>;
+
+			clocks = <&xtal_32k>, <&xtal>;
+			clock-names = "xtal_32k", "xtal";
+		};
+	};
-- 
2.1.4

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

* [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
of system control block (SCB). CPC is supplied by two external
oscillators and it manages core and most of peripheral
clocks, the change adds description of DT bindings for clock
controller found on LPC32xx SoC series.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
new file mode 100644
index 0000000..20cbca3
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
@@ -0,0 +1,30 @@
+NXP LPC32xx Clock Controller
+
+Required properties:
+- compatible: should be "nxp,lpc3220-clk"
+- reg:  should contain clock controller registers location and length
+- #clock-cells: must be 1, the cell holds id of a clock provided by the
+  clock controller
+- clocks: phandles of external oscillators, the list must contain one
+  32768 Hz oscillator and may have one optional high frequency oscillator
+- clock-names: list of external oscillator clock names, must contain
+  "xtal_32k" and may have optional "xtal"
+
+Examples:
+
+	/* System Control Block */
+	scb {
+		compatible = "simple-bus";
+		ranges = <0x0 0x040004000 0x00001000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		clk: clock-controller at 0 {
+			compatible = "nxp,lpc3220-clk";
+			reg = <0x00 0x114>;
+			#clock-cells = <1>;
+
+			clocks = <&xtal_32k>, <&xtal>;
+			clock-names = "xtal_32k", "xtal";
+		};
+	};
-- 
2.1.4

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

* [PATCH 02/11] dt-bindings: clock: add description of LPC32xx USB clock controller
  2015-11-20  1:05 ` Vladimir Zapolskiy
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

NXP LPC32xx USB controller has a subdevice, which controls USB AHB
slave, USB OTG, USB OHCI, USB device and I2C controller to USB phy
clocks, this change adds description of the clock controller, for more
details reference LPC32xx User's Manual, namely USB control, OTG clock
control and OTG clock status registers.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 .../bindings/clock/nxp,lpc3220-usb-clk.txt         | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
new file mode 100644
index 0000000..67fba7f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
@@ -0,0 +1,22 @@
+NXP LPC32xx USB Clock Controller
+
+Required properties:
+- compatible: should be "nxp,lpc3220-usb-clk"
+- reg:  should contain clock controller registers location and length
+- #clock-cells: must be 1, the cell holds id of a clock provided by the
+  USB clock controller
+
+Examples:
+
+	usb {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges = <0x0 0x31020000 0x00001000>;
+
+		usbclk: clock-controller@F00 {
+			compatible = "nxp,lpc3220-usb-clk";
+			reg = <0xF00 0x100>;
+			#clock-cells = <1>;
+		};
+	};
-- 
2.1.4


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

* [PATCH 02/11] dt-bindings: clock: add description of LPC32xx USB clock controller
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

NXP LPC32xx USB controller has a subdevice, which controls USB AHB
slave, USB OTG, USB OHCI, USB device and I2C controller to USB phy
clocks, this change adds description of the clock controller, for more
details reference LPC32xx User's Manual, namely USB control, OTG clock
control and OTG clock status registers.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 .../bindings/clock/nxp,lpc3220-usb-clk.txt         | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
new file mode 100644
index 0000000..67fba7f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
@@ -0,0 +1,22 @@
+NXP LPC32xx USB Clock Controller
+
+Required properties:
+- compatible: should be "nxp,lpc3220-usb-clk"
+- reg:  should contain clock controller registers location and length
+- #clock-cells: must be 1, the cell holds id of a clock provided by the
+  USB clock controller
+
+Examples:
+
+	usb {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges = <0x0 0x31020000 0x00001000>;
+
+		usbclk: clock-controller at F00 {
+			compatible = "nxp,lpc3220-usb-clk";
+			reg = <0xF00 0x100>;
+			#clock-cells = <1>;
+		};
+	};
-- 
2.1.4

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

* [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
  2015-11-20  1:05 ` Vladimir Zapolskiy
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

The change adds a list of NXP LPC32xx clocks, which can be requested
by clock consumers.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 include/dt-bindings/clock/lpc32xx-clock.h | 56 +++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)
 create mode 100644 include/dt-bindings/clock/lpc32xx-clock.h

diff --git a/include/dt-bindings/clock/lpc32xx-clock.h b/include/dt-bindings/clock/lpc32xx-clock.h
new file mode 100644
index 0000000..6f4036a
--- /dev/null
+++ b/include/dt-bindings/clock/lpc32xx-clock.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015 Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ */
+
+#ifndef __DT_BINDINGS_LPC32XX_CLOCK_H
+#define __DT_BINDINGS_LPC32XX_CLOCK_H
+
+/* LPC32XX System Control Block clocks */
+#define LPC32XX_CLK_RTC		0
+#define LPC32XX_CLK_DMA		1
+#define LPC32XX_CLK_MLC		2
+#define LPC32XX_CLK_SLC		3
+#define LPC32XX_CLK_LCD		4
+#define LPC32XX_CLK_MAC		5
+#define LPC32XX_CLK_SD		6
+#define LPC32XX_CLK_DDRAM	7
+#define LPC32XX_CLK_SSP0	8
+#define LPC32XX_CLK_SSP1	9
+#define LPC32XX_CLK_UART3	10
+#define LPC32XX_CLK_UART4	11
+#define LPC32XX_CLK_UART5	12
+#define LPC32XX_CLK_UART6	13
+#define LPC32XX_CLK_IRDA	14
+#define LPC32XX_CLK_I2C1	15
+#define LPC32XX_CLK_I2C2	16
+#define LPC32XX_CLK_TIMER0	17
+#define LPC32XX_CLK_TIMER1	18
+#define LPC32XX_CLK_TIMER2	19
+#define LPC32XX_CLK_TIMER3	20
+#define LPC32XX_CLK_TIMER4	21
+#define LPC32XX_CLK_TIMER5	22
+#define LPC32XX_CLK_WDOG	23
+#define LPC32XX_CLK_I2S0	24
+#define LPC32XX_CLK_I2S1	25
+#define LPC32XX_CLK_SPI1	26
+#define LPC32XX_CLK_SPI2	27
+#define LPC32XX_CLK_MCPWM	28
+#define LPC32XX_CLK_HSTIMER	29
+#define LPC32XX_CLK_KEY		30
+#define LPC32XX_CLK_PWM1	31
+#define LPC32XX_CLK_PWM2	32
+#define LPC32XX_CLK_ADC		33
+
+/* LPC32XX USB clocks */
+#define LPC32XX_USB_CLK_I2C	0
+#define LPC32XX_USB_CLK_DEVICE	1
+#define LPC32XX_USB_CLK_HOST	2
+
+#endif /* __DT_BINDINGS_LPC32XX_CLOCK_H */
-- 
2.1.4


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

* [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

The change adds a list of NXP LPC32xx clocks, which can be requested
by clock consumers.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 include/dt-bindings/clock/lpc32xx-clock.h | 56 +++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)
 create mode 100644 include/dt-bindings/clock/lpc32xx-clock.h

diff --git a/include/dt-bindings/clock/lpc32xx-clock.h b/include/dt-bindings/clock/lpc32xx-clock.h
new file mode 100644
index 0000000..6f4036a
--- /dev/null
+++ b/include/dt-bindings/clock/lpc32xx-clock.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015 Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * This code is released using a dual license strategy: BSD/GPL
+ * You can choose the licence that better fits your requirements.
+ *
+ * Released under the terms of 3-clause BSD License
+ * Released under the terms of GNU General Public License Version 2.0
+ *
+ */
+
+#ifndef __DT_BINDINGS_LPC32XX_CLOCK_H
+#define __DT_BINDINGS_LPC32XX_CLOCK_H
+
+/* LPC32XX System Control Block clocks */
+#define LPC32XX_CLK_RTC		0
+#define LPC32XX_CLK_DMA		1
+#define LPC32XX_CLK_MLC		2
+#define LPC32XX_CLK_SLC		3
+#define LPC32XX_CLK_LCD		4
+#define LPC32XX_CLK_MAC		5
+#define LPC32XX_CLK_SD		6
+#define LPC32XX_CLK_DDRAM	7
+#define LPC32XX_CLK_SSP0	8
+#define LPC32XX_CLK_SSP1	9
+#define LPC32XX_CLK_UART3	10
+#define LPC32XX_CLK_UART4	11
+#define LPC32XX_CLK_UART5	12
+#define LPC32XX_CLK_UART6	13
+#define LPC32XX_CLK_IRDA	14
+#define LPC32XX_CLK_I2C1	15
+#define LPC32XX_CLK_I2C2	16
+#define LPC32XX_CLK_TIMER0	17
+#define LPC32XX_CLK_TIMER1	18
+#define LPC32XX_CLK_TIMER2	19
+#define LPC32XX_CLK_TIMER3	20
+#define LPC32XX_CLK_TIMER4	21
+#define LPC32XX_CLK_TIMER5	22
+#define LPC32XX_CLK_WDOG	23
+#define LPC32XX_CLK_I2S0	24
+#define LPC32XX_CLK_I2S1	25
+#define LPC32XX_CLK_SPI1	26
+#define LPC32XX_CLK_SPI2	27
+#define LPC32XX_CLK_MCPWM	28
+#define LPC32XX_CLK_HSTIMER	29
+#define LPC32XX_CLK_KEY		30
+#define LPC32XX_CLK_PWM1	31
+#define LPC32XX_CLK_PWM2	32
+#define LPC32XX_CLK_ADC		33
+
+/* LPC32XX USB clocks */
+#define LPC32XX_USB_CLK_I2C	0
+#define LPC32XX_USB_CLK_DEVICE	1
+#define LPC32XX_USB_CLK_HOST	2
+
+#endif /* __DT_BINDINGS_LPC32XX_CLOCK_H */
-- 
2.1.4

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

* [PATCH 04/11] arm: dts: lpc32xx: add device nodes for external oscillators
  2015-11-20  1:05 ` Vladimir Zapolskiy
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

NXP LPC32xx SoC has two external oscillators - one is mandatory and
always on 32768 Hz oscillator and one optional 10-20MHz oscillator,
which is practically always present on LPC32xx boards, because its
presence is needed to supply USB controller clock and by default it
supplies ARM and most of the peripheral clocks, LPC32xx User's Manual
references it as a main oscillator.

The change adds device nodes for both oscillators, frequency of
the main oscillator is selected to be 13MHz by default, this variant
is found on all LPC32xx reference boards.

The device nodes for external oscillators are needed to describe input
clocks of LPC32xx clock controller.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index c85cf97..a9f2d9a 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -28,6 +28,22 @@
 		};
 	};
 
+	clocks {
+		xtal_32k: xtal_32k {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "xtal_32k";
+		};
+
+		xtal: xtal {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <13000000>;
+			clock-output-names = "xtal";
+		};
+	};
+
 	ahb {
 		#address-cells = <1>;
 		#size-cells = <1>;
-- 
2.1.4


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

* [PATCH 04/11] arm: dts: lpc32xx: add device nodes for external oscillators
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

NXP LPC32xx SoC has two external oscillators - one is mandatory and
always on 32768 Hz oscillator and one optional 10-20MHz oscillator,
which is practically always present on LPC32xx boards, because its
presence is needed to supply USB controller clock and by default it
supplies ARM and most of the peripheral clocks, LPC32xx User's Manual
references it as a main oscillator.

The change adds device nodes for both oscillators, frequency of
the main oscillator is selected to be 13MHz by default, this variant
is found on all LPC32xx reference boards.

The device nodes for external oscillators are needed to describe input
clocks of LPC32xx clock controller.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index c85cf97..a9f2d9a 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -28,6 +28,22 @@
 		};
 	};
 
+	clocks {
+		xtal_32k: xtal_32k {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32768>;
+			clock-output-names = "xtal_32k";
+		};
+
+		xtal: xtal {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <13000000>;
+			clock-output-names = "xtal";
+		};
+	};
+
 	ahb {
 		#address-cells = <1>;
 		#size-cells = <1>;
-- 
2.1.4

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

* [PATCH 05/11] arm: dts: lpc32xx: add clock controller device node
  2015-11-20  1:05 ` Vladimir Zapolskiy
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
of system control block (SCB). CPC is supplied by two external
oscillators and it manages core and most of peripheral clocks, the
change adds SCB and CPC descriptions to shared LPC32xx dtsi file.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index a9f2d9a..65023c1 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -247,6 +247,23 @@
 			compatible = "simple-bus";
 			ranges = <0x20000000 0x20000000 0x30000000>;
 
+			/* System Control Block */
+			scb {
+				compatible = "simple-bus";
+				ranges = <0x0 0x040004000 0x00001000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				clk: clock-controller@0 {
+					compatible = "nxp,lpc3220-clk";
+					reg = <0x00 0x114>;
+					#clock-cells = <1>;
+
+					clocks = <&xtal_32k>, <&xtal>;
+					clock-names = "xtal_32k", "xtal";
+				};
+			};
+
 			/*
 			 * MIC Interrupt controller includes:
 			 *   MIC @40008000
-- 
2.1.4


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

* [PATCH 05/11] arm: dts: lpc32xx: add clock controller device node
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
of system control block (SCB). CPC is supplied by two external
oscillators and it manages core and most of peripheral clocks, the
change adds SCB and CPC descriptions to shared LPC32xx dtsi file.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index a9f2d9a..65023c1 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -247,6 +247,23 @@
 			compatible = "simple-bus";
 			ranges = <0x20000000 0x20000000 0x30000000>;
 
+			/* System Control Block */
+			scb {
+				compatible = "simple-bus";
+				ranges = <0x0 0x040004000 0x00001000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				clk: clock-controller at 0 {
+					compatible = "nxp,lpc3220-clk";
+					reg = <0x00 0x114>;
+					#clock-cells = <1>;
+
+					clocks = <&xtal_32k>, <&xtal>;
+					clock-names = "xtal_32k", "xtal";
+				};
+			};
+
 			/*
 			 * MIC Interrupt controller includes:
 			 *   MIC @40008000
-- 
2.1.4

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

* [PATCH 06/11] arm: dts: lpc32xx: add clock properties to device nodes
  2015-11-20  1:05 ` Vladimir Zapolskiy
  (?)
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

The change adds clock properties to all described peripheral devices,
clock ids are taken from dt-bindings/clock/lpc32xx-clock.h

Some existing drivers expect to get clock names, in those cases
clock-names are added as well.

Signed-off-by: Vladimir Zapolskiy <vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 65023c1..792468e 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -13,6 +13,8 @@
 
 #include "skeleton.dtsi"
 
+#include <dt-bindings/clock/lpc32xx-clock.h>
+
 / {
 	compatible = "nxp,lpc3220";
 	interrupt-parent = <&mic>;
@@ -57,6 +59,7 @@
 		slc: flash@20020000 {
 			compatible = "nxp,lpc3220-slc";
 			reg = <0x20020000 0x1000>;
+			clocks = <&clk LPC32XX_CLK_SLC>;
 			status = "disabled";
 		};
 
@@ -64,6 +67,7 @@
 			compatible = "nxp,lpc3220-mlc";
 			reg = <0x200a8000 0x11000>;
 			interrupts = <11 0>;
+			clocks = <&clk LPC32XX_CLK_MLC>;
 			status = "disabled";
 		};
 
@@ -71,6 +75,8 @@
 			compatible = "arm,pl080", "arm,primecell";
 			reg = <0x31000000 0x1000>;
 			interrupts = <0x1c 0>;
+			clocks = <&clk LPC32XX_CLK_DMA>;
+			clock-names = "apb_pclk";
 		};
 
 		usb {
@@ -110,6 +116,8 @@
 			compatible = "arm,pl110", "arm,primecell";
 			reg = <0x31040000 0x1000>;
 			interrupts = <0x0e 0>;
+			clocks = <&clk LPC32XX_CLK_LCD>;
+			clock-names = "apb_pclk";
 			status = "disabled";
 		};
 
@@ -117,11 +125,14 @@
 			compatible = "nxp,lpc-eth";
 			reg = <0x31060000 0x1000>;
 			interrupts = <0x1d 0>;
+			clocks = <&clk LPC32XX_CLK_MAC>;
 		};
 
 		emc: memory-controller@31080000 {
 			compatible = "arm,pl175", "arm,primecell";
 			reg = <0x31080000 0x1000>;
+			clocks = <&clk LPC32XX_CLK_DDRAM>, <&clk LPC32XX_CLK_DDRAM>;
+			clock-names = "mpmcclk", "apb_pclk";
 			#address-cells = <1>;
 			#size-cells = <1>;
 
@@ -142,6 +153,8 @@
 				compatible = "arm,pl022", "arm,primecell";
 				reg = <0x20084000 0x1000>;
 				interrupts = <0x14 0>;
+				clocks = <&clk LPC32XX_CLK_SSP0>;
+				clock-names = "apb_pclk";
 			};
 
 			spi1: spi@20088000 {
@@ -153,6 +166,8 @@
 				compatible = "arm,pl022", "arm,primecell";
 				reg = <0x2008c000 0x1000>;
 				interrupts = <0x15 0>;
+				clocks = <&clk LPC32XX_CLK_SSP1>;
+				clock-names = "apb_pclk";
 			};
 
 			spi2: spi@20090000 {
@@ -169,6 +184,8 @@
 				compatible = "arm,pl18x", "arm,primecell";
 				reg = <0x20098000 0x1000>;
 				interrupts = <0x0f 0>, <0x0d 0>;
+				clocks = <&clk LPC32XX_CLK_SD>;
+				clock-names = "apb_pclk";
 				status = "disabled";
 			};
 
@@ -185,6 +202,7 @@
 				interrupts = <9 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART5>;
 				status = "disabled";
 			};
 
@@ -194,6 +212,7 @@
 				interrupts = <7 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART3>;
 				status = "disabled";
 			};
 
@@ -203,6 +222,7 @@
 				interrupts = <8 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART4>;
 				status = "disabled";
 			};
 
@@ -212,6 +232,7 @@
 				interrupts = <10 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART6>;
 				status = "disabled";
 			};
 
@@ -222,6 +243,7 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pnx,timeout = <0x64>;
+				clocks = <&clk LPC32XX_CLK_I2C1>;
 			};
 
 			i2c2: i2c@400A8000 {
@@ -231,6 +253,7 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pnx,timeout = <0x64>;
+				clocks = <&clk LPC32XX_CLK_I2C2>;
 			};
 
 			mpwm: mpwm@400E8000 {
@@ -302,6 +325,7 @@
 				compatible = "nxp,lpc3220-rtc";
 				reg = <0x40024000 0x1000>;
 				interrupts = <0x34 0>;
+				clocks = <&clk LPC32XX_CLK_RTC>;
 			};
 
 			gpio: gpio@40028000 {
@@ -315,6 +339,8 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x4002C000 0x1000>;
 				interrupts = <0x3 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER4>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 
@@ -322,17 +348,22 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40030000 0x1000>;
 				interrupts = <0x4 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER5>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 
 			watchdog: watchdog@4003C000 {
 				compatible = "nxp,pnx4008-wdt";
 				reg = <0x4003C000 0x1000>;
+				clocks = <&clk LPC32XX_CLK_WDOG>;
 			};
 
 			timer0: timer@40044000 {
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40044000 0x1000>;
+				clocks = <&clk LPC32XX_CLK_TIMER0>;
+				clock-names = "timerclk";
 				interrupts = <0x10 0>;
 			};
 
@@ -347,6 +378,7 @@
 				compatible = "nxp,lpc3220-adc";
 				reg = <0x40048000 0x1000>;
 				interrupts = <0x27 0>;
+				clocks = <&clk LPC32XX_CLK_ADC>;
 				status = "disabled";
 			};
 
@@ -354,6 +386,7 @@
 				compatible = "nxp,lpc3220-tsc";
 				reg = <0x40048000 0x1000>;
 				interrupts = <0x27 0>;
+				clocks = <&clk LPC32XX_CLK_ADC>;
 				status = "disabled";
 			};
 
@@ -361,6 +394,8 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x4004C000 0x1000>;
 				interrupts = <0x11 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER1>;
+				clock-names = "timerclk";
 			};
 
 			key: key@40050000 {
@@ -374,18 +409,22 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40058000 0x1000>;
 				interrupts = <0x12 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER2>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 
 			pwm1: pwm@4005C000 {
 				compatible = "nxp,lpc3220-pwm";
 				reg = <0x4005C000 0x4>;
+				clocks = <&clk LPC32XX_CLK_PWM1>;
 				status = "disabled";
 			};
 
 			pwm2: pwm@4005C004 {
 				compatible = "nxp,lpc3220-pwm";
 				reg = <0x4005C004 0x4>;
+				clocks = <&clk LPC32XX_CLK_PWM2>;
 				status = "disabled";
 			};
 
@@ -393,6 +432,8 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40060000 0x1000>;
 				interrupts = <0x13 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER3>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 		};
-- 
2.1.4

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

* [PATCH 06/11] arm: dts: lpc32xx: add clock properties to device nodes
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

The change adds clock properties to all described peripheral devices,
clock ids are taken from dt-bindings/clock/lpc32xx-clock.h

Some existing drivers expect to get clock names, in those cases
clock-names are added as well.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 65023c1..792468e 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -13,6 +13,8 @@
 
 #include "skeleton.dtsi"
 
+#include <dt-bindings/clock/lpc32xx-clock.h>
+
 / {
 	compatible = "nxp,lpc3220";
 	interrupt-parent = <&mic>;
@@ -57,6 +59,7 @@
 		slc: flash@20020000 {
 			compatible = "nxp,lpc3220-slc";
 			reg = <0x20020000 0x1000>;
+			clocks = <&clk LPC32XX_CLK_SLC>;
 			status = "disabled";
 		};
 
@@ -64,6 +67,7 @@
 			compatible = "nxp,lpc3220-mlc";
 			reg = <0x200a8000 0x11000>;
 			interrupts = <11 0>;
+			clocks = <&clk LPC32XX_CLK_MLC>;
 			status = "disabled";
 		};
 
@@ -71,6 +75,8 @@
 			compatible = "arm,pl080", "arm,primecell";
 			reg = <0x31000000 0x1000>;
 			interrupts = <0x1c 0>;
+			clocks = <&clk LPC32XX_CLK_DMA>;
+			clock-names = "apb_pclk";
 		};
 
 		usb {
@@ -110,6 +116,8 @@
 			compatible = "arm,pl110", "arm,primecell";
 			reg = <0x31040000 0x1000>;
 			interrupts = <0x0e 0>;
+			clocks = <&clk LPC32XX_CLK_LCD>;
+			clock-names = "apb_pclk";
 			status = "disabled";
 		};
 
@@ -117,11 +125,14 @@
 			compatible = "nxp,lpc-eth";
 			reg = <0x31060000 0x1000>;
 			interrupts = <0x1d 0>;
+			clocks = <&clk LPC32XX_CLK_MAC>;
 		};
 
 		emc: memory-controller@31080000 {
 			compatible = "arm,pl175", "arm,primecell";
 			reg = <0x31080000 0x1000>;
+			clocks = <&clk LPC32XX_CLK_DDRAM>, <&clk LPC32XX_CLK_DDRAM>;
+			clock-names = "mpmcclk", "apb_pclk";
 			#address-cells = <1>;
 			#size-cells = <1>;
 
@@ -142,6 +153,8 @@
 				compatible = "arm,pl022", "arm,primecell";
 				reg = <0x20084000 0x1000>;
 				interrupts = <0x14 0>;
+				clocks = <&clk LPC32XX_CLK_SSP0>;
+				clock-names = "apb_pclk";
 			};
 
 			spi1: spi@20088000 {
@@ -153,6 +166,8 @@
 				compatible = "arm,pl022", "arm,primecell";
 				reg = <0x2008c000 0x1000>;
 				interrupts = <0x15 0>;
+				clocks = <&clk LPC32XX_CLK_SSP1>;
+				clock-names = "apb_pclk";
 			};
 
 			spi2: spi@20090000 {
@@ -169,6 +184,8 @@
 				compatible = "arm,pl18x", "arm,primecell";
 				reg = <0x20098000 0x1000>;
 				interrupts = <0x0f 0>, <0x0d 0>;
+				clocks = <&clk LPC32XX_CLK_SD>;
+				clock-names = "apb_pclk";
 				status = "disabled";
 			};
 
@@ -185,6 +202,7 @@
 				interrupts = <9 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART5>;
 				status = "disabled";
 			};
 
@@ -194,6 +212,7 @@
 				interrupts = <7 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART3>;
 				status = "disabled";
 			};
 
@@ -203,6 +222,7 @@
 				interrupts = <8 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART4>;
 				status = "disabled";
 			};
 
@@ -212,6 +232,7 @@
 				interrupts = <10 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART6>;
 				status = "disabled";
 			};
 
@@ -222,6 +243,7 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pnx,timeout = <0x64>;
+				clocks = <&clk LPC32XX_CLK_I2C1>;
 			};
 
 			i2c2: i2c@400A8000 {
@@ -231,6 +253,7 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pnx,timeout = <0x64>;
+				clocks = <&clk LPC32XX_CLK_I2C2>;
 			};
 
 			mpwm: mpwm@400E8000 {
@@ -302,6 +325,7 @@
 				compatible = "nxp,lpc3220-rtc";
 				reg = <0x40024000 0x1000>;
 				interrupts = <0x34 0>;
+				clocks = <&clk LPC32XX_CLK_RTC>;
 			};
 
 			gpio: gpio@40028000 {
@@ -315,6 +339,8 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x4002C000 0x1000>;
 				interrupts = <0x3 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER4>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 
@@ -322,17 +348,22 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40030000 0x1000>;
 				interrupts = <0x4 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER5>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 
 			watchdog: watchdog@4003C000 {
 				compatible = "nxp,pnx4008-wdt";
 				reg = <0x4003C000 0x1000>;
+				clocks = <&clk LPC32XX_CLK_WDOG>;
 			};
 
 			timer0: timer@40044000 {
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40044000 0x1000>;
+				clocks = <&clk LPC32XX_CLK_TIMER0>;
+				clock-names = "timerclk";
 				interrupts = <0x10 0>;
 			};
 
@@ -347,6 +378,7 @@
 				compatible = "nxp,lpc3220-adc";
 				reg = <0x40048000 0x1000>;
 				interrupts = <0x27 0>;
+				clocks = <&clk LPC32XX_CLK_ADC>;
 				status = "disabled";
 			};
 
@@ -354,6 +386,7 @@
 				compatible = "nxp,lpc3220-tsc";
 				reg = <0x40048000 0x1000>;
 				interrupts = <0x27 0>;
+				clocks = <&clk LPC32XX_CLK_ADC>;
 				status = "disabled";
 			};
 
@@ -361,6 +394,8 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x4004C000 0x1000>;
 				interrupts = <0x11 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER1>;
+				clock-names = "timerclk";
 			};
 
 			key: key@40050000 {
@@ -374,18 +409,22 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40058000 0x1000>;
 				interrupts = <0x12 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER2>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 
 			pwm1: pwm@4005C000 {
 				compatible = "nxp,lpc3220-pwm";
 				reg = <0x4005C000 0x4>;
+				clocks = <&clk LPC32XX_CLK_PWM1>;
 				status = "disabled";
 			};
 
 			pwm2: pwm@4005C004 {
 				compatible = "nxp,lpc3220-pwm";
 				reg = <0x4005C004 0x4>;
+				clocks = <&clk LPC32XX_CLK_PWM2>;
 				status = "disabled";
 			};
 
@@ -393,6 +432,8 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40060000 0x1000>;
 				interrupts = <0x13 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER3>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 		};
-- 
2.1.4

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

* [PATCH 06/11] arm: dts: lpc32xx: add clock properties to device nodes
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

The change adds clock properties to all described peripheral devices,
clock ids are taken from dt-bindings/clock/lpc32xx-clock.h

Some existing drivers expect to get clock names, in those cases
clock-names are added as well.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 65023c1..792468e 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -13,6 +13,8 @@
 
 #include "skeleton.dtsi"
 
+#include <dt-bindings/clock/lpc32xx-clock.h>
+
 / {
 	compatible = "nxp,lpc3220";
 	interrupt-parent = <&mic>;
@@ -57,6 +59,7 @@
 		slc: flash at 20020000 {
 			compatible = "nxp,lpc3220-slc";
 			reg = <0x20020000 0x1000>;
+			clocks = <&clk LPC32XX_CLK_SLC>;
 			status = "disabled";
 		};
 
@@ -64,6 +67,7 @@
 			compatible = "nxp,lpc3220-mlc";
 			reg = <0x200a8000 0x11000>;
 			interrupts = <11 0>;
+			clocks = <&clk LPC32XX_CLK_MLC>;
 			status = "disabled";
 		};
 
@@ -71,6 +75,8 @@
 			compatible = "arm,pl080", "arm,primecell";
 			reg = <0x31000000 0x1000>;
 			interrupts = <0x1c 0>;
+			clocks = <&clk LPC32XX_CLK_DMA>;
+			clock-names = "apb_pclk";
 		};
 
 		usb {
@@ -110,6 +116,8 @@
 			compatible = "arm,pl110", "arm,primecell";
 			reg = <0x31040000 0x1000>;
 			interrupts = <0x0e 0>;
+			clocks = <&clk LPC32XX_CLK_LCD>;
+			clock-names = "apb_pclk";
 			status = "disabled";
 		};
 
@@ -117,11 +125,14 @@
 			compatible = "nxp,lpc-eth";
 			reg = <0x31060000 0x1000>;
 			interrupts = <0x1d 0>;
+			clocks = <&clk LPC32XX_CLK_MAC>;
 		};
 
 		emc: memory-controller at 31080000 {
 			compatible = "arm,pl175", "arm,primecell";
 			reg = <0x31080000 0x1000>;
+			clocks = <&clk LPC32XX_CLK_DDRAM>, <&clk LPC32XX_CLK_DDRAM>;
+			clock-names = "mpmcclk", "apb_pclk";
 			#address-cells = <1>;
 			#size-cells = <1>;
 
@@ -142,6 +153,8 @@
 				compatible = "arm,pl022", "arm,primecell";
 				reg = <0x20084000 0x1000>;
 				interrupts = <0x14 0>;
+				clocks = <&clk LPC32XX_CLK_SSP0>;
+				clock-names = "apb_pclk";
 			};
 
 			spi1: spi at 20088000 {
@@ -153,6 +166,8 @@
 				compatible = "arm,pl022", "arm,primecell";
 				reg = <0x2008c000 0x1000>;
 				interrupts = <0x15 0>;
+				clocks = <&clk LPC32XX_CLK_SSP1>;
+				clock-names = "apb_pclk";
 			};
 
 			spi2: spi at 20090000 {
@@ -169,6 +184,8 @@
 				compatible = "arm,pl18x", "arm,primecell";
 				reg = <0x20098000 0x1000>;
 				interrupts = <0x0f 0>, <0x0d 0>;
+				clocks = <&clk LPC32XX_CLK_SD>;
+				clock-names = "apb_pclk";
 				status = "disabled";
 			};
 
@@ -185,6 +202,7 @@
 				interrupts = <9 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART5>;
 				status = "disabled";
 			};
 
@@ -194,6 +212,7 @@
 				interrupts = <7 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART3>;
 				status = "disabled";
 			};
 
@@ -203,6 +222,7 @@
 				interrupts = <8 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART4>;
 				status = "disabled";
 			};
 
@@ -212,6 +232,7 @@
 				interrupts = <10 0>;
 				clock-frequency = <13000000>;
 				reg-shift = <2>;
+				clocks = <&clk LPC32XX_CLK_UART6>;
 				status = "disabled";
 			};
 
@@ -222,6 +243,7 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pnx,timeout = <0x64>;
+				clocks = <&clk LPC32XX_CLK_I2C1>;
 			};
 
 			i2c2: i2c at 400A8000 {
@@ -231,6 +253,7 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pnx,timeout = <0x64>;
+				clocks = <&clk LPC32XX_CLK_I2C2>;
 			};
 
 			mpwm: mpwm at 400E8000 {
@@ -302,6 +325,7 @@
 				compatible = "nxp,lpc3220-rtc";
 				reg = <0x40024000 0x1000>;
 				interrupts = <0x34 0>;
+				clocks = <&clk LPC32XX_CLK_RTC>;
 			};
 
 			gpio: gpio at 40028000 {
@@ -315,6 +339,8 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x4002C000 0x1000>;
 				interrupts = <0x3 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER4>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 
@@ -322,17 +348,22 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40030000 0x1000>;
 				interrupts = <0x4 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER5>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 
 			watchdog: watchdog at 4003C000 {
 				compatible = "nxp,pnx4008-wdt";
 				reg = <0x4003C000 0x1000>;
+				clocks = <&clk LPC32XX_CLK_WDOG>;
 			};
 
 			timer0: timer at 40044000 {
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40044000 0x1000>;
+				clocks = <&clk LPC32XX_CLK_TIMER0>;
+				clock-names = "timerclk";
 				interrupts = <0x10 0>;
 			};
 
@@ -347,6 +378,7 @@
 				compatible = "nxp,lpc3220-adc";
 				reg = <0x40048000 0x1000>;
 				interrupts = <0x27 0>;
+				clocks = <&clk LPC32XX_CLK_ADC>;
 				status = "disabled";
 			};
 
@@ -354,6 +386,7 @@
 				compatible = "nxp,lpc3220-tsc";
 				reg = <0x40048000 0x1000>;
 				interrupts = <0x27 0>;
+				clocks = <&clk LPC32XX_CLK_ADC>;
 				status = "disabled";
 			};
 
@@ -361,6 +394,8 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x4004C000 0x1000>;
 				interrupts = <0x11 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER1>;
+				clock-names = "timerclk";
 			};
 
 			key: key at 40050000 {
@@ -374,18 +409,22 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40058000 0x1000>;
 				interrupts = <0x12 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER2>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 
 			pwm1: pwm at 4005C000 {
 				compatible = "nxp,lpc3220-pwm";
 				reg = <0x4005C000 0x4>;
+				clocks = <&clk LPC32XX_CLK_PWM1>;
 				status = "disabled";
 			};
 
 			pwm2: pwm at 4005C004 {
 				compatible = "nxp,lpc3220-pwm";
 				reg = <0x4005C004 0x4>;
+				clocks = <&clk LPC32XX_CLK_PWM2>;
 				status = "disabled";
 			};
 
@@ -393,6 +432,8 @@
 				compatible = "nxp,lpc3220-timer";
 				reg = <0x40060000 0x1000>;
 				interrupts = <0x13 0>;
+				clocks = <&clk LPC32XX_CLK_TIMER3>;
+				clock-names = "timerclk";
 				status = "disabled";
 			};
 		};
-- 
2.1.4

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

* [PATCH 07/11] arm: dts: lpc32xx: add USB clock controller
  2015-11-20  1:05 ` Vladimir Zapolskiy
  (?)
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

The change adds device node of LPC32xx USB clock controller and adds
clock properties to USB OHCI, USB device and I2C controller to USB phy
device nodes.

Signed-off-by: Vladimir Zapolskiy <vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 792468e..68bf011 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -92,6 +92,7 @@
 				compatible = "nxp,ohci-nxp", "usb-ohci";
 				reg = <0x0 0x300>;
 				interrupts = <0x3b 0>;
+				clocks = <&usbclk LPC32XX_USB_CLK_HOST>;
 				status = "disabled";
 			};
 
@@ -99,6 +100,7 @@
 				compatible = "nxp,lpc3220-udc";
 				reg = <0x0 0x300>;
 				interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
+				clocks = <&usbclk LPC32XX_USB_CLK_DEVICE>;
 				status = "disabled";
 			};
 
@@ -106,10 +108,17 @@
 				compatible = "nxp,pnx-i2c";
 				reg = <0x300 0x100>;
 				interrupts = <0x3f 0>;
+				clocks = <&usbclk LPC32XX_USB_CLK_I2C>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pnx,timeout = <0x64>;
 			};
+
+			usbclk: clock-controller@F00 {
+				compatible = "nxp,lpc3220-usb-clk";
+				reg = <0xF00 0x100>;
+				#clock-cells = <1>;
+			};
 		};
 
 		clcd: clcd@31040000 {
-- 
2.1.4

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

* [PATCH 07/11] arm: dts: lpc32xx: add USB clock controller
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

The change adds device node of LPC32xx USB clock controller and adds
clock properties to USB OHCI, USB device and I2C controller to USB phy
device nodes.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 792468e..68bf011 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -92,6 +92,7 @@
 				compatible = "nxp,ohci-nxp", "usb-ohci";
 				reg = <0x0 0x300>;
 				interrupts = <0x3b 0>;
+				clocks = <&usbclk LPC32XX_USB_CLK_HOST>;
 				status = "disabled";
 			};
 
@@ -99,6 +100,7 @@
 				compatible = "nxp,lpc3220-udc";
 				reg = <0x0 0x300>;
 				interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
+				clocks = <&usbclk LPC32XX_USB_CLK_DEVICE>;
 				status = "disabled";
 			};
 
@@ -106,10 +108,17 @@
 				compatible = "nxp,pnx-i2c";
 				reg = <0x300 0x100>;
 				interrupts = <0x3f 0>;
+				clocks = <&usbclk LPC32XX_USB_CLK_I2C>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pnx,timeout = <0x64>;
 			};
+
+			usbclk: clock-controller@F00 {
+				compatible = "nxp,lpc3220-usb-clk";
+				reg = <0xF00 0x100>;
+				#clock-cells = <1>;
+			};
 		};
 
 		clcd: clcd@31040000 {
-- 
2.1.4

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

* [PATCH 07/11] arm: dts: lpc32xx: add USB clock controller
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

The change adds device node of LPC32xx USB clock controller and adds
clock properties to USB OHCI, USB device and I2C controller to USB phy
device nodes.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 792468e..68bf011 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -92,6 +92,7 @@
 				compatible = "nxp,ohci-nxp", "usb-ohci";
 				reg = <0x0 0x300>;
 				interrupts = <0x3b 0>;
+				clocks = <&usbclk LPC32XX_USB_CLK_HOST>;
 				status = "disabled";
 			};
 
@@ -99,6 +100,7 @@
 				compatible = "nxp,lpc3220-udc";
 				reg = <0x0 0x300>;
 				interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>;
+				clocks = <&usbclk LPC32XX_USB_CLK_DEVICE>;
 				status = "disabled";
 			};
 
@@ -106,10 +108,17 @@
 				compatible = "nxp,pnx-i2c";
 				reg = <0x300 0x100>;
 				interrupts = <0x3f 0>;
+				clocks = <&usbclk LPC32XX_USB_CLK_I2C>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 				pnx,timeout = <0x64>;
 			};
+
+			usbclk: clock-controller at F00 {
+				compatible = "nxp,lpc3220-usb-clk";
+				reg = <0xF00 0x100>;
+				#clock-cells = <1>;
+			};
 		};
 
 		clcd: clcd at 31040000 {
-- 
2.1.4

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

* [PATCH 08/11] clk: lpc18xx: add NXP specific common clock framework selection
  2015-11-20  1:05 ` Vladimir Zapolskiy
  (?)
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	Joachim Eastwood

The change adds COMMON_CLK_NXP configuration symbol and enables it for
NXP LPC18XX architecture, this is needed to reuse drivers/clk/nxp
folder for NXP common clock framework drivers other than LPC18XX one.

Signed-off-by: Vladimir Zapolskiy <vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
Cc: Joachim Eastwood <manabian-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 arch/arm/Kconfig     | 1 +
 drivers/clk/Kconfig  | 5 +++++
 drivers/clk/Makefile | 2 +-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0365cbb..c318277 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -952,6 +952,7 @@ config ARCH_LPC18XX
 	select ARCH_HAS_RESET_CONTROLLER
 	select ARM_AMBA
 	select CLKSRC_LPC32XX
+	select COMMON_CLK
 	select PINCTRL
 	help
 	  Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c3e3a02..7fc1eb9 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -175,6 +175,11 @@ config COMMON_CLK_PWM
 	  Adapter driver so that any PWM output can be (mis)used as clock signal
 	  at 50% duty cycle.
 
+config COMMON_CLK_NXP
+	def_bool COMMON_CLK && ARCH_LPC18XX
+	---help---
+	  Support for clock providers on NXP platforms.
+
 config COMMON_CLK_PXA
 	def_bool COMMON_CLK && ARCH_PXA
 	---help---
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 820714c..15603c1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -62,8 +62,8 @@ endif
 obj-$(CONFIG_PLAT_ORION)		+= mvebu/
 obj-$(CONFIG_ARCH_MESON)		+= meson/
 obj-$(CONFIG_ARCH_MXS)			+= mxs/
-obj-$(CONFIG_ARCH_LPC18XX)		+= nxp/
 obj-$(CONFIG_MACH_PISTACHIO)		+= pistachio/
+obj-$(CONFIG_COMMON_CLK_NXP)		+= nxp/
 obj-$(CONFIG_COMMON_CLK_PXA)		+= pxa/
 obj-$(CONFIG_COMMON_CLK_QCOM)		+= qcom/
 obj-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip/
-- 
2.1.4

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

* [PATCH 08/11] clk: lpc18xx: add NXP specific common clock framework selection
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree,
	linux-arm-kernel, Joachim Eastwood

The change adds COMMON_CLK_NXP configuration symbol and enables it for
NXP LPC18XX architecture, this is needed to reuse drivers/clk/nxp
folder for NXP common clock framework drivers other than LPC18XX one.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Cc: Joachim Eastwood <manabian@gmail.com>
---
 arch/arm/Kconfig     | 1 +
 drivers/clk/Kconfig  | 5 +++++
 drivers/clk/Makefile | 2 +-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0365cbb..c318277 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -952,6 +952,7 @@ config ARCH_LPC18XX
 	select ARCH_HAS_RESET_CONTROLLER
 	select ARM_AMBA
 	select CLKSRC_LPC32XX
+	select COMMON_CLK
 	select PINCTRL
 	help
 	  Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c3e3a02..7fc1eb9 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -175,6 +175,11 @@ config COMMON_CLK_PWM
 	  Adapter driver so that any PWM output can be (mis)used as clock signal
 	  at 50% duty cycle.
 
+config COMMON_CLK_NXP
+	def_bool COMMON_CLK && ARCH_LPC18XX
+	---help---
+	  Support for clock providers on NXP platforms.
+
 config COMMON_CLK_PXA
 	def_bool COMMON_CLK && ARCH_PXA
 	---help---
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 820714c..15603c1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -62,8 +62,8 @@ endif
 obj-$(CONFIG_PLAT_ORION)		+= mvebu/
 obj-$(CONFIG_ARCH_MESON)		+= meson/
 obj-$(CONFIG_ARCH_MXS)			+= mxs/
-obj-$(CONFIG_ARCH_LPC18XX)		+= nxp/
 obj-$(CONFIG_MACH_PISTACHIO)		+= pistachio/
+obj-$(CONFIG_COMMON_CLK_NXP)		+= nxp/
 obj-$(CONFIG_COMMON_CLK_PXA)		+= pxa/
 obj-$(CONFIG_COMMON_CLK_QCOM)		+= qcom/
 obj-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip/
-- 
2.1.4

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

* [PATCH 08/11] clk: lpc18xx: add NXP specific common clock framework selection
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

The change adds COMMON_CLK_NXP configuration symbol and enables it for
NXP LPC18XX architecture, this is needed to reuse drivers/clk/nxp
folder for NXP common clock framework drivers other than LPC18XX one.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Cc: Joachim Eastwood <manabian@gmail.com>
---
 arch/arm/Kconfig     | 1 +
 drivers/clk/Kconfig  | 5 +++++
 drivers/clk/Makefile | 2 +-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0365cbb..c318277 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -952,6 +952,7 @@ config ARCH_LPC18XX
 	select ARCH_HAS_RESET_CONTROLLER
 	select ARM_AMBA
 	select CLKSRC_LPC32XX
+	select COMMON_CLK
 	select PINCTRL
 	help
 	  Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c3e3a02..7fc1eb9 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -175,6 +175,11 @@ config COMMON_CLK_PWM
 	  Adapter driver so that any PWM output can be (mis)used as clock signal
 	  at 50% duty cycle.
 
+config COMMON_CLK_NXP
+	def_bool COMMON_CLK && ARCH_LPC18XX
+	---help---
+	  Support for clock providers on NXP platforms.
+
 config COMMON_CLK_PXA
 	def_bool COMMON_CLK && ARCH_PXA
 	---help---
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 820714c..15603c1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -62,8 +62,8 @@ endif
 obj-$(CONFIG_PLAT_ORION)		+= mvebu/
 obj-$(CONFIG_ARCH_MESON)		+= meson/
 obj-$(CONFIG_ARCH_MXS)			+= mxs/
-obj-$(CONFIG_ARCH_LPC18XX)		+= nxp/
 obj-$(CONFIG_MACH_PISTACHIO)		+= pistachio/
+obj-$(CONFIG_COMMON_CLK_NXP)		+= nxp/
 obj-$(CONFIG_COMMON_CLK_PXA)		+= pxa/
 obj-$(CONFIG_COMMON_CLK_QCOM)		+= qcom/
 obj-$(CONFIG_ARCH_ROCKCHIP)		+= rockchip/
-- 
2.1.4

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

* [PATCH 09/11] clk: lpc32xx: add common clock framework driver
  2015-11-20  1:05 ` Vladimir Zapolskiy
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

Add support for all configurable clocks found on NXP LPC32xx SoC.

The list contains several heterogenous groups of clocks:
* system clocks including multiple dividers and muxes,
* x397 PLL, HCLK PLL and USB PLL,
* peripheral clocks inherited from rtc, hclk and pclk,
* USB controller clocks: AHB slave, I2C, OTG, OHCI and device.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 drivers/clk/Kconfig           |    3 +-
 drivers/clk/nxp/Makefile      |    1 +
 drivers/clk/nxp/clk-lpc32xx.c | 1562 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1565 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/nxp/clk-lpc32xx.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 7fc1eb9..9310cf4 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -176,7 +176,8 @@ config COMMON_CLK_PWM
 	  at 50% duty cycle.
 
 config COMMON_CLK_NXP
-	def_bool COMMON_CLK && ARCH_LPC18XX
+	def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
+	select REGMAP_MMIO if ARCH_LPC32XX
 	---help---
 	  Support for clock providers on NXP platforms.
 
diff --git a/drivers/clk/nxp/Makefile b/drivers/clk/nxp/Makefile
index 7f608b0..607bd48 100644
--- a/drivers/clk/nxp/Makefile
+++ b/drivers/clk/nxp/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ARCH_LPC18XX)	+= clk-lpc18xx-cgu.o
 obj-$(CONFIG_ARCH_LPC18XX)	+= clk-lpc18xx-ccu.o
+obj-$(CONFIG_ARCH_LPC32XX)	+= clk-lpc32xx.o
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
new file mode 100644
index 0000000..fcd7135
--- /dev/null
+++ b/drivers/clk/nxp/clk-lpc32xx.c
@@ -0,0 +1,1562 @@
+/*
+ * Copyright 2015 Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/lpc32xx-clock.h>
+
+#undef pr_fmt
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+/* Common bitfield definitions for x397 PLL (lock), USB PLL and HCLK PLL */
+#define PLL_CTRL_ENABLE			BIT(16)
+#define PLL_CTRL_BYPASS			BIT(15)
+#define PLL_CTRL_DIRECT			BIT(14)
+#define PLL_CTRL_FEEDBACK		BIT(13)
+#define PLL_CTRL_POSTDIV		(BIT(12)|BIT(11))
+#define PLL_CTRL_PREDIV			(BIT(10)|BIT(9))
+#define PLL_CTRL_FEEDDIV		(0xFF << 1)
+#define PLL_CTRL_LOCK			BIT(0)
+
+/* Clock registers on System Control Block */
+#define LPC32XX_CLKPWR_DEBUG_CTRL	0x00
+#define LPC32XX_CLKPWR_USB_DIV		0x1C
+#define LPC32XX_CLKPWR_HCLKDIV_CTRL	0x40
+#define LPC32XX_CLKPWR_PWR_CTRL		0x44
+#define LPC32XX_CLKPWR_PLL397_CTRL	0x48
+#define LPC32XX_CLKPWR_OSC_CTRL		0x4C
+#define LPC32XX_CLKPWR_SYSCLK_CTRL	0x50
+#define LPC32XX_CLKPWR_LCDCLK_CTRL	0x54
+#define LPC32XX_CLKPWR_HCLKPLL_CTRL	0x58
+#define LPC32XX_CLKPWR_ADCCLK_CTRL1	0x60
+#define LPC32XX_CLKPWR_USB_CTRL		0x64
+#define LPC32XX_CLKPWR_SSP_CTRL		0x78
+#define LPC32XX_CLKPWR_I2S_CTRL		0x7C
+#define LPC32XX_CLKPWR_MS_CTRL		0x80
+#define LPC32XX_CLKPWR_MACCLK_CTRL	0x90
+#define LPC32XX_CLKPWR_TEST_CLK_CTRL	0xA4
+#define LPC32XX_CLKPWR_I2CCLK_CTRL	0xAC
+#define LPC32XX_CLKPWR_KEYCLK_CTRL	0xB0
+#define LPC32XX_CLKPWR_ADCCLK_CTRL	0xB4
+#define LPC32XX_CLKPWR_PWMCLK_CTRL	0xB8
+#define LPC32XX_CLKPWR_TIMCLK_CTRL	0xBC
+#define LPC32XX_CLKPWR_TIMCLK_CTRL1	0xC0
+#define LPC32XX_CLKPWR_SPI_CTRL		0xC4
+#define LPC32XX_CLKPWR_FLASHCLK_CTRL	0xC8
+#define LPC32XX_CLKPWR_UART3_CLK_CTRL	0xD0
+#define LPC32XX_CLKPWR_UART4_CLK_CTRL	0xD4
+#define LPC32XX_CLKPWR_UART5_CLK_CTRL	0xD8
+#define LPC32XX_CLKPWR_UART6_CLK_CTRL	0xDC
+#define LPC32XX_CLKPWR_IRDA_CLK_CTRL	0xE0
+#define LPC32XX_CLKPWR_UART_CLK_CTRL	0xE4
+#define LPC32XX_CLKPWR_DMA_CLK_CTRL	0xE8
+
+/* Clock registers on USB controller */
+#define LPC32XX_USB_CLK_CTRL		0xF4
+#define LPC32XX_USB_CLK_STS		0xF8
+
+static struct regmap_config lpc32xx_scb_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.val_format_endian = REGMAP_ENDIAN_LITTLE,
+	.max_register = 0x114,
+	.fast_io = true,
+};
+
+static struct regmap *clk_regmap;
+static void __iomem *usb_clk_vbase;
+
+enum {
+	LPC32XX_USB_CLK_OTG = LPC32XX_USB_CLK_HOST + 1,
+	LPC32XX_USB_CLK_AHB,
+
+	LPC32XX_USB_CLK_MAX = LPC32XX_USB_CLK_AHB + 1,
+};
+
+enum {
+	/* Start from the last defined clock in dt bindings */
+	LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_ADC + 1,
+	LPC32XX_CLK_ADC_RTC,
+	LPC32XX_CLK_TEST1,
+	LPC32XX_CLK_TEST2,
+
+	/* System clocks, PLL 397x and HCLK PLL clocks */
+	LPC32XX_CLK_OSC,
+	LPC32XX_CLK_SYS,
+	LPC32XX_CLK_PLL397X,
+	LPC32XX_CLK_HCLK_PLL,
+	LPC32XX_CLK_HCLK_DIV_PERIPH,
+	LPC32XX_CLK_HCLK_DIV,
+	LPC32XX_CLK_HCLK,
+	LPC32XX_CLK_PERIPH,
+	LPC32XX_CLK_ARM,
+	LPC32XX_CLK_ARM_VFP,
+
+	/* USB clocks */
+	LPC32XX_CLK_USB_PLL,
+	LPC32XX_CLK_USB_DIV,
+	LPC32XX_CLK_USB,
+
+	/* Only one control PWR_CTRL[10] for both muxes */
+	LPC32XX_CLK_PERIPH_HCLK_MUX,
+	LPC32XX_CLK_PERIPH_ARM_MUX,
+
+	/* Only one control PWR_CTRL[2] for all three muxes */
+	LPC32XX_CLK_SYSCLK_PERIPH_MUX,
+	LPC32XX_CLK_SYSCLK_HCLK_MUX,
+	LPC32XX_CLK_SYSCLK_ARM_MUX,
+
+	/* Two clock sources external to the driver */
+	LPC32XX_CLK_XTAL_32K,
+	LPC32XX_CLK_XTAL,
+
+	/* Renumbered USB clocks, may have a parent from SCB table */
+	LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_I2C = LPC32XX_USB_CLK_I2C + LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_DEV = LPC32XX_USB_CLK_DEVICE + LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_HOST = LPC32XX_USB_CLK_HOST + LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_OTG = LPC32XX_USB_CLK_OTG + LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_AHB = LPC32XX_USB_CLK_AHB + LPC32XX_CLK_USB_OFFSET,
+
+	/* Stub for composite clocks */
+	LPC32XX_CLK__NULL,
+
+	/* Subclocks of composite clocks, clocks above are for CCF */
+	LPC32XX_CLK_PWM1_MUX,
+	LPC32XX_CLK_PWM1_DIV,
+	LPC32XX_CLK_PWM1_GATE,
+	LPC32XX_CLK_PWM2_MUX,
+	LPC32XX_CLK_PWM2_DIV,
+	LPC32XX_CLK_PWM2_GATE,
+	LPC32XX_CLK_UART3_MUX,
+	LPC32XX_CLK_UART3_DIV,
+	LPC32XX_CLK_UART3_GATE,
+	LPC32XX_CLK_UART4_MUX,
+	LPC32XX_CLK_UART4_DIV,
+	LPC32XX_CLK_UART4_GATE,
+	LPC32XX_CLK_UART5_MUX,
+	LPC32XX_CLK_UART5_DIV,
+	LPC32XX_CLK_UART5_GATE,
+	LPC32XX_CLK_UART6_MUX,
+	LPC32XX_CLK_UART6_DIV,
+	LPC32XX_CLK_UART6_GATE,
+	LPC32XX_CLK_TEST1_MUX,
+	LPC32XX_CLK_TEST1_GATE,
+	LPC32XX_CLK_TEST2_MUX,
+	LPC32XX_CLK_TEST2_GATE,
+	LPC32XX_CLK_USB_DIV_DIV,
+	LPC32XX_CLK_USB_DIV_GATE,
+	LPC32XX_CLK_SD_DIV,
+	LPC32XX_CLK_SD_GATE,
+	LPC32XX_CLK_LCD_DIV,
+	LPC32XX_CLK_LCD_GATE,
+
+	LPC32XX_CLK_HW_MAX,
+	LPC32XX_CLK_MAX = LPC32XX_CLK_SYSCLK_ARM_MUX + 1,
+	LPC32XX_CLK_CCF_MAX = LPC32XX_CLK_USB_AHB + 1,
+};
+
+static struct clk *clk[LPC32XX_CLK_MAX];
+static struct clk_onecell_data clk_data = {
+	.clks = clk,
+	.clk_num = LPC32XX_CLK_MAX,
+};
+
+static struct clk *usb_clk[LPC32XX_USB_CLK_MAX];
+static struct clk_onecell_data usb_clk_data = {
+	.clks = usb_clk,
+	.clk_num = LPC32XX_USB_CLK_MAX,
+};
+
+#define LPC32XX_CLK_PARENTS_MAX			5
+
+struct clk_proto_t {
+	const char *name;
+	const u8 parents[LPC32XX_CLK_PARENTS_MAX];
+	u8 num_parents;
+	unsigned long flags;
+};
+
+#define CLK_PREFIX(LITERAL)		LPC32XX_CLK_ ## LITERAL
+#define NUMARGS(...)	(sizeof((int[]){__VA_ARGS__})/sizeof(int))
+
+#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)		\
+	[CLK_PREFIX(_idx)] = {					\
+		.name = #_name,					\
+		.flags = _flags,				\
+		.parents = { __VA_ARGS__ },			\
+		.num_parents = NUMARGS(__VA_ARGS__),		\
+	 }
+
+static const struct clk_proto_t clk_proto[LPC32XX_CLK_CCF_MAX] __initconst = {
+	LPC32XX_CLK_DEFINE(XTAL, xtal, 0x0),
+	LPC32XX_CLK_DEFINE(XTAL_32K, xtal_32k, 0x0),
+
+	LPC32XX_CLK_DEFINE(RTC, rtc, 0x0, LPC32XX_CLK_XTAL_32K),
+	LPC32XX_CLK_DEFINE(OSC, osc, CLK_IGNORE_UNUSED, LPC32XX_CLK_XTAL),
+	LPC32XX_CLK_DEFINE(SYS, sys, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),
+	LPC32XX_CLK_DEFINE(PLL397X, pll_397x, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_RTC),
+	LPC32XX_CLK_DEFINE(HCLK_PLL, hclk_pll, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYS),
+	LPC32XX_CLK_DEFINE(HCLK_DIV_PERIPH, hclk_div_periph, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_HCLK_PLL),
+	LPC32XX_CLK_DEFINE(HCLK_DIV, hclk_div, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_HCLK_PLL),
+	LPC32XX_CLK_DEFINE(HCLK, hclk, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_PERIPH_HCLK_MUX),
+	LPC32XX_CLK_DEFINE(PERIPH, pclk, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYSCLK_PERIPH_MUX),
+	LPC32XX_CLK_DEFINE(ARM, arm, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_PERIPH_ARM_MUX),
+
+	LPC32XX_CLK_DEFINE(PERIPH_HCLK_MUX, periph_hclk_mux, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYSCLK_HCLK_MUX, LPC32XX_CLK_SYSCLK_PERIPH_MUX),
+	LPC32XX_CLK_DEFINE(PERIPH_ARM_MUX, periph_arm_mux, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYSCLK_ARM_MUX, LPC32XX_CLK_SYSCLK_PERIPH_MUX),
+	LPC32XX_CLK_DEFINE(SYSCLK_PERIPH_MUX, sysclk_periph_mux,
+		CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYS, LPC32XX_CLK_HCLK_DIV_PERIPH),
+	LPC32XX_CLK_DEFINE(SYSCLK_HCLK_MUX, sysclk_hclk_mux, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYS, LPC32XX_CLK_HCLK_DIV),
+	LPC32XX_CLK_DEFINE(SYSCLK_ARM_MUX, sysclk_arm_mux, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYS, LPC32XX_CLK_HCLK_PLL),
+
+	LPC32XX_CLK_DEFINE(ARM_VFP, vfp9, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_ARM),
+	LPC32XX_CLK_DEFINE(USB_PLL, usb_pll,
+		CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, LPC32XX_CLK_USB_DIV),
+	LPC32XX_CLK_DEFINE(USB_DIV, usb_div, 0x0, LPC32XX_CLK_OSC),
+	LPC32XX_CLK_DEFINE(USB, usb, 0x0, LPC32XX_CLK_USB_PLL),
+	LPC32XX_CLK_DEFINE(DMA, dma, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(MLC, mlc, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SLC, slc, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(LCD, lcd, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(MAC, mac, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SD, sd, 0x0, LPC32XX_CLK_ARM),
+	LPC32XX_CLK_DEFINE(DDRAM, ddram, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_SYSCLK_ARM_MUX),
+	LPC32XX_CLK_DEFINE(SSP0, ssp0, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SSP1, ssp1, 0x0, LPC32XX_CLK_HCLK),
+	/* CLK_GET_RATE_NOCACHE is needed, if disabled it is 0/0 in div */
+	LPC32XX_CLK_DEFINE(UART3, uart3, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(UART4, uart4, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(UART5, uart5, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(UART6, uart6, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(IRDA, irda, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(I2C1, i2c1, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(I2C2, i2c2, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(TIMER0, timer0, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER1, timer1, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER2, timer2, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER3, timer3, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER4, timer4, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER5, timer5, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(WDOG, watchdog, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(I2S0, i2s0, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(I2S1, i2s1, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SPI1, spi1, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SPI2, spi2, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(MCPWM, mcpwm, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(HSTIMER, hstimer, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(KEY, key, 0x0, LPC32XX_CLK_RTC),
+	LPC32XX_CLK_DEFINE(PWM1, pwm1, 0x0,
+		LPC32XX_CLK_RTC, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(PWM2, pwm2, 0x0,
+		LPC32XX_CLK_RTC, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(ADC, adc, 0x0,
+		LPC32XX_CLK_ADC_RTC, LPC32XX_CLK_ADC_DIV),
+	LPC32XX_CLK_DEFINE(ADC_DIV, adc_div, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(ADC_RTC, adc_rtc, 0x0, LPC32XX_CLK_RTC),
+	LPC32XX_CLK_DEFINE(TEST1, test1, 0x0,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_RTC, LPC32XX_CLK_OSC),
+	LPC32XX_CLK_DEFINE(TEST2, test2, 0x0,
+		LPC32XX_CLK_HCLK, LPC32XX_CLK_PERIPH, LPC32XX_CLK_USB,
+		LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),
+	/* USB controller clocks */
+	LPC32XX_CLK_DEFINE(USB_AHB, usb_ahb, 0x0, LPC32XX_CLK_USB),
+	LPC32XX_CLK_DEFINE(USB_OTG, usb_otg, 0x0, LPC32XX_CLK_USB_AHB),
+	LPC32XX_CLK_DEFINE(USB_I2C, usb_i2c, 0x0, LPC32XX_CLK_USB_AHB),
+	LPC32XX_CLK_DEFINE(USB_DEV, usb_dev, 0x0, LPC32XX_CLK_USB_OTG),
+	LPC32XX_CLK_DEFINE(USB_HOST, usb_host, 0x0, LPC32XX_CLK_USB_OTG),
+};
+
+struct lpc32xx_clk {
+	struct clk_hw hw;
+	u32 reg;
+	u32 enable;
+	u32 enable_mask;
+	u32 disable;
+	u32 disable_mask;
+	u32 busy;
+	u32 busy_mask;
+};
+
+enum clk_pll_mode {
+	PLL_UNKNOWN,
+	PLL_DIRECT,
+	PLL_BYPASS,
+	PLL_DIRECT_BYPASS,
+	PLL_INTEGER,
+	PLL_NON_INTEGER,
+};
+
+struct lpc32xx_pll_clk {
+	struct clk_hw hw;
+	u32 reg;
+	u32 enable;
+	unsigned long m_div;
+	unsigned long n_div;
+	unsigned long p_div;
+	enum clk_pll_mode mode;
+};
+
+struct lpc32xx_usb_clk {
+	struct clk_hw hw;
+	u32 ctrl_enable;
+	u32 ctrl_disable;
+	u32 ctrl_mask;
+	u32 enable;
+	u32 busy;
+};
+
+struct lpc32xx_clk_mux {
+	struct clk_hw	hw;
+	u32		reg;
+	u32		mask;
+	u8		shift;
+	u32		*table;
+	u8		flags;
+};
+
+struct lpc32xx_clk_div {
+	struct clk_hw	hw;
+	u32		reg;
+	u8		shift;
+	u8		width;
+	const struct clk_div_table	*table;
+	u8		flags;
+};
+
+struct lpc32xx_clk_gate {
+	struct clk_hw	hw;
+	u32		reg;
+	u8		bit_idx;
+	u8		flags;
+};
+
+#define to_lpc32xx_clk(_hw)	container_of(_hw, struct lpc32xx_clk, hw)
+#define to_lpc32xx_pll_clk(_hw)	container_of(_hw, struct lpc32xx_pll_clk, hw)
+#define to_lpc32xx_usb_clk(_hw)	container_of(_hw, struct lpc32xx_usb_clk, hw)
+#define to_lpc32xx_mux(_hw)	container_of(_hw, struct lpc32xx_clk_mux, hw)
+#define to_lpc32xx_div(_hw)	container_of(_hw, struct lpc32xx_clk_div, hw)
+#define to_lpc32xx_gate(_hw)	container_of(_hw, struct lpc32xx_clk_gate, hw)
+
+static inline bool pll_is_valid(u64 val0, u64 val1, u64 min, u64 max)
+{
+	return (val0 >= (val1 * min) && val0 <= (val1 * max));
+}
+
+static inline u32 lpc32xx_usb_clk_read(struct lpc32xx_usb_clk *clk)
+{
+	return readl(usb_clk_vbase + LPC32XX_USB_CLK_STS);
+}
+
+static inline void lpc32xx_usb_clk_write(struct lpc32xx_usb_clk *clk, u32 val)
+{
+	writel(val, usb_clk_vbase + LPC32XX_USB_CLK_CTRL);
+}
+
+static int clk_mask_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+
+	if (clk->busy_mask && (val & clk->busy_mask) == clk->busy)
+		return -EBUSY;
+
+	return regmap_update_bits(clk_regmap, clk->reg,
+				  clk->enable_mask, clk->enable);
+}
+
+static void clk_mask_disable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+
+	regmap_update_bits(clk_regmap, clk->reg,
+			   clk->disable_mask, clk->disable);
+}
+
+static int clk_mask_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+
+	return ((val & clk->enable_mask) == clk->enable);
+}
+
+static const struct clk_ops clk_mask_ops = {
+	.enable = clk_mask_enable,
+	.disable = clk_mask_disable,
+	.is_enabled = clk_mask_is_enabled,
+};
+
+static int clk_pll_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	u32 val, count;
+
+	regmap_update_bits(clk_regmap, clk->reg, clk->enable, clk->enable);
+
+	for (count = 0; count < 1000; count++) {
+		regmap_read(clk_regmap, clk->reg, &val);
+		if (val & PLL_CTRL_LOCK)
+			break;
+	}
+
+	if (val & PLL_CTRL_LOCK)
+		return 0;
+
+	return -ETIMEDOUT;
+}
+
+static void clk_pll_disable(struct clk_hw *hw)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+
+	regmap_update_bits(clk_regmap, clk->reg, clk->enable, 0x0);
+}
+
+static int clk_pll_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+
+	val &= clk->enable | PLL_CTRL_LOCK;
+	if (val == (clk->enable | PLL_CTRL_LOCK))
+		return 1;
+
+	return 0;
+}
+
+static unsigned long clk_pll_397x_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	return parent_rate * 397;
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	bool is_direct, is_bypass, is_feedback;
+	unsigned long rate, cco_rate, ref_rate;
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	is_direct = val & PLL_CTRL_DIRECT;
+	is_bypass = val & PLL_CTRL_BYPASS;
+	is_feedback = val & PLL_CTRL_FEEDBACK;
+
+	clk->m_div = ((val & PLL_CTRL_FEEDDIV) >> 1) + 1;
+	clk->n_div = ((val & PLL_CTRL_PREDIV) >> 9) + 1;
+	clk->p_div = ((val & PLL_CTRL_POSTDIV) >> 11) + 1;
+
+	if (is_direct && is_bypass) {
+		clk->p_div = 0;
+		clk->mode = PLL_DIRECT_BYPASS;
+		return parent_rate;
+	}
+	if (is_bypass) {
+		clk->mode = PLL_BYPASS;
+		return parent_rate / (1 << clk->p_div);
+	}
+	if (is_direct) {
+		clk->p_div = 0;
+		clk->mode = PLL_DIRECT;
+	}
+
+	ref_rate = parent_rate / clk->n_div;
+	rate = cco_rate = ref_rate * clk->m_div;
+
+	if (!is_direct) {
+		if (is_feedback) {
+			cco_rate *= (1 << clk->p_div);
+			clk->mode = PLL_INTEGER;
+		} else {
+			rate /= (1 << clk->p_div);
+			clk->mode = PLL_NON_INTEGER;
+		}
+	}
+
+	pr_debug("%s: %lu: 0x%x: %d/%d/%d, %lu/%lu/%d => %lu\n",
+		 clk_hw_get_name(hw),
+		 parent_rate, val, is_direct, is_bypass, is_feedback,
+		 clk->n_div, clk->m_div, (1 << clk->p_div), rate);
+
+	if (clk_pll_is_enabled(hw) &&
+	    !(pll_is_valid(parent_rate, 1, 1000000, 20000000)
+	      && pll_is_valid(cco_rate, 1, 156000000, 320000000)
+	      && pll_is_valid(ref_rate, 1, 1000000, 27000000)))
+		pr_err("%s: PLL clocks are not in valid ranges: %lu/%lu/%lu",
+		       clk_hw_get_name(hw),
+		       parent_rate, cco_rate, ref_rate);
+
+	return rate;
+}
+
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	u32 val;
+	unsigned long new_rate;
+
+	/* Validate PLL clock parameters computed on round rate stage */
+	switch (clk->mode) {
+	case PLL_DIRECT:
+		val = PLL_CTRL_DIRECT;
+		val |= (clk->m_div - 1) << 1;
+		val |= (clk->n_div - 1) << 9;
+		new_rate = (parent_rate * clk->m_div) / clk->n_div;
+		break;
+	case PLL_BYPASS:
+		val = PLL_CTRL_BYPASS;
+		val |= (clk->p_div - 1) << 11;
+		new_rate = parent_rate / (1 << (clk->p_div));
+		break;
+	case PLL_DIRECT_BYPASS:
+		val = PLL_CTRL_DIRECT | PLL_CTRL_BYPASS;
+		new_rate = parent_rate;
+		break;
+	case PLL_INTEGER:
+		val = PLL_CTRL_FEEDBACK;
+		val |= (clk->m_div - 1) << 1;
+		val |= (clk->n_div - 1) << 9;
+		val |= (clk->p_div - 1) << 11;
+		new_rate = (parent_rate * clk->m_div) / clk->n_div;
+		break;
+	case PLL_NON_INTEGER:
+		val = 0x0;
+		val |= (clk->m_div - 1) << 1;
+		val |= (clk->n_div - 1) << 9;
+		val |= (clk->p_div - 1) << 11;
+		new_rate = (parent_rate * clk->m_div) /
+				(clk->n_div * (1 << clk->p_div));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Sanity check that round rate is equal to the requested one */
+	if (!new_rate == rate)
+		return -EINVAL;
+
+	return regmap_update_bits(clk_regmap, clk->reg, 0x1FFFF, val);
+}
+
+static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *parent_rate)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	u64 m_i, m, n, p, o = rate, i = *parent_rate, d = (u64)rate << 6;
+	int p_i, n_i;
+
+	pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate);
+
+	if (rate > 266500000)
+		return -EINVAL;
+
+	/* Have to check all 20 possibilities to find the minimal M */
+	for (p_i = 4; p_i >= 0; p_i--) {
+		for (n_i = 4; n_i > 0; n_i--) {
+			m_i = div64_u64(o * n_i * (1 << p_i), i);
+
+			/* Check for valid PLL parameter constraints */
+			if (!(m_i && m_i <= 256
+			      && pll_is_valid(i, n_i, 1000000, 27000000)
+			      && pll_is_valid(i * m_i * (1 << p_i), n_i,
+					      156000000, 320000000)))
+				continue;
+
+			/* Store some intermediate valid parameters */
+			if (o * n_i * (1 << p_i) - i * m_i <= d) {
+				m = m_i;
+				n = n_i;
+				p = p_i;
+				d = o * n_i * (1 << p_i) - i * m_i;
+			}
+		}
+	}
+
+	if (d == (u64)rate << 6) {
+		pr_err("%s: %lu: no valid PLL parameters are found\n",
+		       clk_hw_get_name(hw), rate);
+		return -EINVAL;
+	}
+
+	clk->m_div = m;
+	clk->n_div = n;
+	clk->p_div = p;
+
+	/* Set only direct or non-integer mode of PLL */
+	if (!p)
+		clk->mode = PLL_DIRECT;
+	else
+		clk->mode = PLL_NON_INTEGER;
+
+	o = div64_u64(i * m, n * (1 << p));
+
+	if (!d)
+		pr_debug("%s: %lu: found exact match: %llu/%llu/%llu\n",
+			 clk_hw_get_name(hw), rate, m, n, p);
+	else
+		pr_debug("%s: %lu: found closest: %llu/%llu/%llu - %llu\n",
+			 clk_hw_get_name(hw), rate, m, n, p, o);
+
+	return o;
+}
+
+static long clk_usb_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long *parent_rate)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	struct clk_hw *usb_div_hw, *osc_hw;
+	u64 d_i, n_i, m, o;
+
+	pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate);
+
+	/*
+	 * The only supported USB clock is 48MHz, with PLL internal constraints
+	 * on Fclkin, Fcco and Fref this implies that Fcco must be 192MHz
+	 * and post-divider must be 4, this slightly simplifies calculation of
+	 * USB divider, USB PLL N and M parameters.
+	 */
+	if (rate != 48000000)
+		return -EINVAL;
+
+	/* USB divider clock */
+	usb_div_hw = clk_hw_get_parent_by_index(hw, 0);
+	if (!usb_div_hw)
+		return -EINVAL;
+
+	/* Main oscillator clock */
+	osc_hw = clk_hw_get_parent_by_index(usb_div_hw, 0);
+	if (!osc_hw)
+		return -EINVAL;
+	o = clk_hw_get_rate(osc_hw);	/* must be in range 1..20 MHz */
+
+	/* Check if valid USB divider and USB PLL parameters exists */
+	for (d_i = 16; d_i >= 1; d_i--) {
+		for (n_i = 1; n_i <= 4; n_i++) {
+			m = div64_u64(192000000 * d_i * n_i, o);
+			if (!(m && m <= 256
+			      && m * o == 192000000 * d_i * n_i
+			      && pll_is_valid(o, d_i, 1000000, 20000000)
+			      && pll_is_valid(o, d_i * n_i, 1000000, 27000000)))
+				continue;
+
+			clk->n_div = n_i;
+			clk->m_div = m;
+			clk->p_div = 2;
+			clk->mode = PLL_NON_INTEGER;
+			*parent_rate = div64_u64(o, d_i);
+
+			return rate;
+		}
+	}
+
+	return -EINVAL;
+}
+
+#define LPC32XX_DEFINE_PLL_OPS(_name, _rc, _sr, _rr)			\
+	static const struct clk_ops clk_ ##_name ## _ops = {		\
+		.enable = clk_pll_enable,				\
+		.disable = clk_pll_disable,				\
+		.is_enabled = clk_pll_is_enabled,			\
+		.recalc_rate = _rc,					\
+		.set_rate = _sr,					\
+		.round_rate = _rr,					\
+	}
+
+LPC32XX_DEFINE_PLL_OPS(pll_397x, clk_pll_397x_recalc_rate, NULL, NULL);
+LPC32XX_DEFINE_PLL_OPS(hclk_pll, clk_pll_recalc_rate,
+		       clk_pll_set_rate, clk_hclk_pll_round_rate);
+LPC32XX_DEFINE_PLL_OPS(usb_pll,  clk_pll_recalc_rate,
+		       clk_pll_set_rate, clk_usb_pll_round_rate);
+
+static int clk_ddram_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	val &= clk->enable_mask | clk->busy_mask;
+
+	return (val == (BIT(7) | BIT(0)) ||
+		val == (BIT(8) | BIT(1)));
+}
+
+static int clk_ddram_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val, hclk_div;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	hclk_div = val & clk->busy_mask;
+
+	/*
+	 * DDRAM clock must be 2 times higher than HCLK,
+	 * this implies DDRAM clock can not be enabled,
+	 * if HCLK clock rate is equal to ARM clock rate
+	 */
+	if (hclk_div == 0x0 || hclk_div == (BIT(1) | BIT(0)))
+		return -EINVAL;
+
+	return regmap_update_bits(clk_regmap, clk->reg,
+				  clk->enable_mask, hclk_div << 7);
+}
+
+static unsigned long clk_ddram_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val;
+
+	if (!clk_ddram_is_enabled(hw))
+		return 0;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	val &= clk->enable_mask;
+
+	return parent_rate / (val >> 7);
+}
+
+static const struct clk_ops clk_ddram_ops = {
+	.enable = clk_ddram_enable,
+	.disable = clk_mask_disable,
+	.is_enabled = clk_ddram_is_enabled,
+	.recalc_rate = clk_ddram_recalc_rate,
+};
+
+static unsigned long lpc32xx_clk_uart_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val, x, y;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	x = (val & 0xFF00) >> 8;
+	y = val & 0xFF;
+
+	if (x && y)
+		return (parent_rate * x) / y;
+	else
+		return 0;
+}
+
+static const struct clk_ops lpc32xx_uart_div_ops = {
+	.recalc_rate = lpc32xx_clk_uart_recalc_rate,
+};
+
+static const struct clk_div_table clk_hclk_div_table[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ },
+};
+
+static u32 test1_mux_table[] = { 0, 1, 2, };
+static u32 test2_mux_table[] = { 0, 1, 2, 5, 7, };
+
+static int clk_usb_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_usb_clk *clk = to_lpc32xx_usb_clk(hw);
+	u32 val, ctrl_val, count;
+
+	pr_debug("%s: 0x%x\n", clk_hw_get_name(hw), clk->enable);
+
+	if (clk->ctrl_mask) {
+		regmap_read(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, &ctrl_val);
+		regmap_update_bits(clk_regmap, LPC32XX_CLKPWR_USB_CTRL,
+				   clk->ctrl_mask, clk->ctrl_enable);
+	}
+
+	val = lpc32xx_usb_clk_read(clk);
+	if (clk->busy && (val & clk->busy) == clk->busy) {
+		if (clk->ctrl_mask)
+			regmap_write(clk_regmap, LPC32XX_CLKPWR_USB_CTRL,
+				     ctrl_val);
+		return -EBUSY;
+	}
+
+	val |= clk->enable;
+	lpc32xx_usb_clk_write(clk, val);
+
+	for (count = 0; count < 1000; count++) {
+		val = lpc32xx_usb_clk_read(clk);
+		if ((val & clk->enable) == clk->enable)
+			break;
+	}
+
+	if ((val & clk->enable) == clk->enable)
+		return 0;
+
+	if (clk->ctrl_mask)
+		regmap_write(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, ctrl_val);
+
+	return -ETIMEDOUT;
+}
+
+static void clk_usb_disable(struct clk_hw *hw)
+{
+	struct lpc32xx_usb_clk *clk = to_lpc32xx_usb_clk(hw);
+	u32 val = lpc32xx_usb_clk_read(clk);
+
+	val &= ~clk->enable;
+	lpc32xx_usb_clk_write(clk, val);
+
+	if (clk->ctrl_mask)
+		regmap_update_bits(clk_regmap, LPC32XX_CLKPWR_USB_CTRL,
+				   clk->ctrl_mask, clk->ctrl_disable);
+}
+
+static int clk_usb_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_usb_clk *clk = to_lpc32xx_usb_clk(hw);
+	u32 ctrl_val, val;
+
+	if (clk->ctrl_mask) {
+		regmap_read(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, &ctrl_val);
+		if ((ctrl_val & clk->ctrl_mask) != clk->ctrl_enable)
+			return 0;
+	}
+
+	val = lpc32xx_usb_clk_read(clk);
+
+	return ((val & clk->enable) == clk->enable);
+}
+
+static unsigned long clk_usb_i2c_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	return clk_get_rate(clk[LPC32XX_CLK_PERIPH]);
+}
+
+static const struct clk_ops clk_usb_ops = {
+	.enable = clk_usb_enable,
+	.disable = clk_usb_disable,
+	.is_enabled = clk_usb_is_enabled,
+};
+
+static const struct clk_ops clk_usb_i2c_ops = {
+	.enable = clk_usb_enable,
+	.disable = clk_usb_disable,
+	.is_enabled = clk_usb_is_enabled,
+	.recalc_rate = clk_usb_i2c_recalc_rate,
+};
+
+static int clk_gate_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
+	u32 mask = BIT(clk->bit_idx);
+	u32 val = (clk->flags & CLK_GATE_SET_TO_DISABLE ? 0x0 : mask);
+
+	return regmap_update_bits(clk_regmap, clk->reg, mask, val);
+}
+
+static void clk_gate_disable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
+	u32 mask = BIT(clk->bit_idx);
+	u32 val = (clk->flags & CLK_GATE_SET_TO_DISABLE ? mask : 0x0);
+
+	regmap_update_bits(clk_regmap, clk->reg, mask, val);
+}
+
+static int clk_gate_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
+	u32 val;
+	bool is_set;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	is_set = val & BIT(clk->bit_idx);
+
+	return (clk->flags & CLK_GATE_SET_TO_DISABLE ? !is_set : is_set);
+}
+
+static const struct clk_ops lpc32xx_clk_gate_ops = {
+	.enable = clk_gate_enable,
+	.disable = clk_gate_disable,
+	.is_enabled = clk_gate_is_enabled,
+};
+
+#define div_mask(width)	((1 << (width)) - 1)
+
+static unsigned int _get_table_div(const struct clk_div_table *table,
+							unsigned int val)
+{
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->val == val)
+			return clkt->div;
+	return 0;
+}
+
+static unsigned int _get_div(const struct clk_div_table *table,
+			     unsigned int val, unsigned long flags, u8 width)
+{
+	if (flags & CLK_DIVIDER_ONE_BASED)
+		return val;
+	if (table)
+		return _get_table_div(table, val);
+	return val + 1;
+}
+
+static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw);
+	unsigned int val;
+
+	regmap_read(clk_regmap, divider->reg, &val);
+
+	val >>= divider->shift;
+	val &= div_mask(divider->width);
+
+	return divider_recalc_rate(hw, parent_rate, val, divider->table,
+				   divider->flags);
+}
+
+static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw);
+	unsigned int bestdiv;
+
+	/* if read only, just return current value */
+	if (divider->flags & CLK_DIVIDER_READ_ONLY) {
+		regmap_read(clk_regmap, divider->reg, &bestdiv);
+		bestdiv >>= divider->shift;
+		bestdiv &= div_mask(divider->width);
+		bestdiv = _get_div(divider->table, bestdiv, divider->flags,
+			divider->width);
+		return DIV_ROUND_UP(*prate, bestdiv);
+	}
+
+	return divider_round_rate(hw, rate, prate, divider->table,
+				  divider->width, divider->flags);
+}
+
+static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw);
+	unsigned int value;
+
+	value = divider_get_val(rate, parent_rate, divider->table,
+				divider->width, divider->flags);
+
+	return regmap_update_bits(clk_regmap, divider->reg,
+				  div_mask(divider->width) << divider->shift,
+				  value << divider->shift);
+}
+
+static const struct clk_ops lpc32xx_clk_divider_ops = {
+	.recalc_rate = clk_divider_recalc_rate,
+	.round_rate = clk_divider_round_rate,
+	.set_rate = clk_divider_set_rate,
+};
+
+static u8 clk_mux_get_parent(struct clk_hw *hw)
+{
+	struct lpc32xx_clk_mux *mux = to_lpc32xx_mux(hw);
+	int num_parents = clk_hw_get_num_parents(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, mux->reg, &val);
+	val >>= mux->shift;
+	val &= mux->mask;
+
+	if (mux->table) {
+		int i;
+
+		for (i = 0; i < num_parents; i++)
+			if (mux->table[i] == val)
+				return i;
+		return -EINVAL;
+	}
+
+	if (val >= num_parents)
+		return -EINVAL;
+
+	return val;
+}
+
+static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct lpc32xx_clk_mux *mux = to_lpc32xx_mux(hw);
+
+	if (mux->table)
+		index = mux->table[index];
+
+	return regmap_update_bits(clk_regmap, mux->reg,
+			  mux->mask << mux->shift, index << mux->shift);
+}
+
+static const struct clk_ops lpc32xx_clk_mux_ro_ops = {
+	.get_parent = clk_mux_get_parent,
+};
+
+static const struct clk_ops lpc32xx_clk_mux_ops = {
+	.get_parent = clk_mux_get_parent,
+	.set_parent = clk_mux_set_parent,
+	.determine_rate = __clk_mux_determine_rate,
+};
+
+enum lpc32xx_clk_type {
+	CLK_FIXED,
+	CLK_MUX,
+	CLK_DIV,
+	CLK_GATE,
+	CLK_COMPOSITE,
+	CLK_LPC32XX,
+	CLK_LPC32XX_PLL,
+	CLK_LPC32XX_USB,
+};
+
+struct clk_hw_proto0 {
+	const struct clk_ops *ops;
+	union {
+		struct lpc32xx_pll_clk pll;
+		struct lpc32xx_clk clk;
+		struct lpc32xx_usb_clk usb_clk;
+		struct lpc32xx_clk_mux mux;
+		struct lpc32xx_clk_div div;
+		struct lpc32xx_clk_gate gate;
+	};
+};
+
+struct clk_hw_proto1 {
+	struct clk_hw_proto0 *mux;
+	struct clk_hw_proto0 *div;
+	struct clk_hw_proto0 *gate;
+};
+
+struct clk_hw_proto {
+	enum lpc32xx_clk_type type;
+
+	union {
+		struct clk_fixed_rate f;
+		struct clk_hw_proto0 hw0;
+		struct clk_hw_proto1 hw1;
+	};
+};
+
+#define LPC32XX_DEFINE_FIXED(_idx, _rate, _flags)			\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_FIXED,						\
+	{								\
+		.f = {							\
+			.fixed_rate = (_rate),				\
+			.flags = (_flags),				\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_PLL(_idx, _name, _reg, _enable)			\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_LPC32XX_PLL,					\
+	{								\
+		.hw0 = {						\
+			.ops = &clk_ ##_name ## _ops,			\
+			{						\
+				.pll = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.enable = (_enable),		\
+				},					\
+			},						\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_MUX(_idx, _reg, _shift, _mask, _table, _flags)	\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_MUX,						\
+	{								\
+		.hw0 = {						\
+			.ops = (_flags & CLK_MUX_READ_ONLY ?		\
+				&lpc32xx_clk_mux_ro_ops :		\
+				&lpc32xx_clk_mux_ops),			\
+			{						\
+				.mux = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.mask = (_mask),		\
+					.shift = (_shift),		\
+					.table = (_table),		\
+					.flags = (_flags),		\
+				},					\
+			},						\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_DIV(_idx, _reg, _shift, _width, _table, _flags)	\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_DIV,						\
+	{								\
+		.hw0 = {						\
+			.ops = &lpc32xx_clk_divider_ops,		\
+			{						\
+				.div = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.shift = (_shift),		\
+					.width = (_width),		\
+					.table = (_table),		\
+					.flags = (_flags),		\
+				 },					\
+			},						\
+		 },							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_GATE(_idx, _reg, _bit, _flags)			\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_GATE,						\
+	{								\
+		.hw0 = {						\
+			.ops = &lpc32xx_clk_gate_ops,			\
+			{						\
+				.gate = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.bit_idx = (_bit),		\
+					.flags = (_flags),		\
+				},					\
+			},						\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_CLK(_idx, _reg, _e, _em, _d, _dm, _b, _bm, _ops)	\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_LPC32XX,						\
+	{								\
+		.hw0 = {						\
+			.ops = &(_ops),					\
+			{						\
+				.clk = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.enable = (_e),			\
+					.enable_mask = (_em),		\
+					.disable = (_d),		\
+					.disable_mask = (_dm),		\
+					.busy = (_b),			\
+					.busy_mask = (_bm),		\
+				},					\
+			},						\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_USB(_idx, _ce, _cd, _cm, _e, _b, _ops)		\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_LPC32XX_USB,					\
+	{								\
+		.hw0 = {						\
+			.ops = &(_ops),					\
+			{						\
+				.usb_clk = {				\
+					.ctrl_enable = (_ce),		\
+					.ctrl_disable = (_cd),		\
+					.ctrl_mask = (_cm),		\
+					.enable = (_e),			\
+					.busy = (_b),			\
+				}					\
+			},						\
+		}							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_COMPOSITE(_idx, _mux, _div, _gate)		\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_COMPOSITE,						\
+	{								\
+		.hw1 = {						\
+		.mux = (CLK_PREFIX(_mux) == LPC32XX_CLK__NULL ? NULL :	\
+			&clk_hw_proto[CLK_PREFIX(_mux)].hw0),		\
+		.div = (CLK_PREFIX(_div) == LPC32XX_CLK__NULL ? NULL :	\
+			&clk_hw_proto[CLK_PREFIX(_div)].hw0),		\
+		.gate = (CLK_PREFIX(_gate) == LPC32XX_CLK__NULL ? NULL :\
+			 &clk_hw_proto[CLK_PREFIX(_gate)].hw0),		\
+		},							\
+	},								\
+}
+
+static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = {
+	LPC32XX_DEFINE_FIXED(RTC, 32768, 0),
+	LPC32XX_DEFINE_PLL(PLL397X, pll_397x, HCLKPLL_CTRL, BIT(1)),
+	LPC32XX_DEFINE_PLL(HCLK_PLL, hclk_pll, HCLKPLL_CTRL, PLL_CTRL_ENABLE),
+	LPC32XX_DEFINE_PLL(USB_PLL, usb_pll, USB_CTRL, PLL_CTRL_ENABLE),
+	LPC32XX_DEFINE_GATE(OSC, OSC_CTRL, 0, CLK_GATE_SET_TO_DISABLE),
+	LPC32XX_DEFINE_GATE(USB, USB_CTRL, 18, 0),
+
+	LPC32XX_DEFINE_DIV(HCLK_DIV_PERIPH, HCLKDIV_CTRL, 2, 5, NULL,
+			   CLK_DIVIDER_READ_ONLY),
+	LPC32XX_DEFINE_DIV(HCLK_DIV, HCLKDIV_CTRL, 0, 2, clk_hclk_div_table,
+			   CLK_DIVIDER_READ_ONLY),
+
+	/* Register 3 read-only muxes with a single control PWR_CTRL[2] */
+	LPC32XX_DEFINE_MUX(SYSCLK_PERIPH_MUX, PWR_CTRL, 2, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+	LPC32XX_DEFINE_MUX(SYSCLK_HCLK_MUX, PWR_CTRL, 2, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+	LPC32XX_DEFINE_MUX(SYSCLK_ARM_MUX, PWR_CTRL, 2, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+	/* Register 2 read-only muxes with a single control PWR_CTRL[10] */
+	LPC32XX_DEFINE_MUX(PERIPH_HCLK_MUX, PWR_CTRL, 10, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+	LPC32XX_DEFINE_MUX(PERIPH_ARM_MUX, PWR_CTRL, 10, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+
+	/* 3 always on gates with a single control PWR_CTRL[0] same as OSC */
+	LPC32XX_DEFINE_GATE(PERIPH, PWR_CTRL, 0, CLK_GATE_SET_TO_DISABLE),
+	LPC32XX_DEFINE_GATE(HCLK, PWR_CTRL, 0, CLK_GATE_SET_TO_DISABLE),
+	LPC32XX_DEFINE_GATE(ARM, PWR_CTRL, 0, CLK_GATE_SET_TO_DISABLE),
+
+	LPC32XX_DEFINE_GATE(ARM_VFP, DEBUG_CTRL, 4, 0),
+	LPC32XX_DEFINE_GATE(DMA, DMA_CLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_CLK(DDRAM, HCLKDIV_CTRL, 0x0, BIT(8) | BIT(7),
+		   0x0, BIT(8) | BIT(7), 0x0, BIT(1) | BIT(0), clk_ddram_ops),
+
+	LPC32XX_DEFINE_GATE(TIMER0, TIMCLK_CTRL1, 2, 0),
+	LPC32XX_DEFINE_GATE(TIMER1, TIMCLK_CTRL1, 3, 0),
+	LPC32XX_DEFINE_GATE(TIMER2, TIMCLK_CTRL1, 4, 0),
+	LPC32XX_DEFINE_GATE(TIMER3, TIMCLK_CTRL1, 5, 0),
+	LPC32XX_DEFINE_GATE(TIMER4, TIMCLK_CTRL1, 0, 0),
+	LPC32XX_DEFINE_GATE(TIMER5, TIMCLK_CTRL1, 1, 0),
+
+	LPC32XX_DEFINE_GATE(SSP0, SSP_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(SSP1, SSP_CTRL, 1, 0),
+	LPC32XX_DEFINE_GATE(SPI1, SPI_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(SPI2, SPI_CTRL, 4, 0),
+	LPC32XX_DEFINE_GATE(I2S0, I2S_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(I2S1, I2S_CTRL, 1, 0),
+	LPC32XX_DEFINE_GATE(I2C1, I2CCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(I2C2, I2CCLK_CTRL, 1, 0),
+	LPC32XX_DEFINE_GATE(WDOG, TIMCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(HSTIMER, TIMCLK_CTRL, 1, 0),
+
+	LPC32XX_DEFINE_GATE(KEY, KEYCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(MCPWM, TIMCLK_CTRL1, 6, 0),
+
+	LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0),
+	LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL,
+			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
+	LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE),
+
+	LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0),
+	LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL,
+			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
+	LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0),
+	LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE),
+
+	LPC32XX_DEFINE_MUX(UART3_MUX, UART3_CLK_CTRL, 16, 0x1, NULL, 0),
+	LPC32XX_DEFINE_CLK(UART3_DIV, UART3_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+	LPC32XX_DEFINE_GATE(UART3_GATE, UART_CLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_COMPOSITE(UART3, UART3_MUX, UART3_DIV, UART3_GATE),
+
+	LPC32XX_DEFINE_MUX(UART4_MUX, UART4_CLK_CTRL, 16, 0x1, NULL, 0),
+	LPC32XX_DEFINE_CLK(UART4_DIV, UART4_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+	LPC32XX_DEFINE_GATE(UART4_GATE, UART_CLK_CTRL, 1, 0),
+	LPC32XX_DEFINE_COMPOSITE(UART4, UART4_MUX, UART4_DIV, UART4_GATE),
+
+	LPC32XX_DEFINE_MUX(UART5_MUX, UART5_CLK_CTRL, 16, 0x1, NULL, 0),
+	LPC32XX_DEFINE_CLK(UART5_DIV, UART5_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+	LPC32XX_DEFINE_GATE(UART5_GATE, UART_CLK_CTRL, 2, 0),
+	LPC32XX_DEFINE_COMPOSITE(UART5, UART5_MUX, UART5_DIV, UART5_GATE),
+
+	LPC32XX_DEFINE_MUX(UART6_MUX, UART6_CLK_CTRL, 16, 0x1, NULL, 0),
+	LPC32XX_DEFINE_CLK(UART6_DIV, UART6_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+	LPC32XX_DEFINE_GATE(UART6_GATE, UART_CLK_CTRL, 3, 0),
+	LPC32XX_DEFINE_COMPOSITE(UART6, UART6_MUX, UART6_DIV, UART6_GATE),
+
+	LPC32XX_DEFINE_CLK(IRDA, IRDA_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+
+	LPC32XX_DEFINE_MUX(TEST1_MUX, TEST_CLK_CTRL, 5, 0x3,
+			   test1_mux_table, 0),
+	LPC32XX_DEFINE_GATE(TEST1_GATE, TEST_CLK_CTRL, 4, 0),
+	LPC32XX_DEFINE_COMPOSITE(TEST1, TEST1_MUX, _NULL, TEST1_GATE),
+
+	LPC32XX_DEFINE_MUX(TEST2_MUX, TEST_CLK_CTRL, 1, 0x7,
+			   test2_mux_table, 0),
+	LPC32XX_DEFINE_GATE(TEST2_GATE, TEST_CLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_COMPOSITE(TEST2, TEST2_MUX, _NULL, TEST2_GATE),
+
+	LPC32XX_DEFINE_MUX(SYS, SYSCLK_CTRL, 0, 0x1, NULL, CLK_MUX_READ_ONLY),
+
+	LPC32XX_DEFINE_DIV(USB_DIV_DIV, USB_DIV, 0, 4, NULL, 0),
+	LPC32XX_DEFINE_GATE(USB_DIV_GATE, USB_CTRL, 17, 0),
+	LPC32XX_DEFINE_COMPOSITE(USB_DIV, _NULL, USB_DIV_DIV, USB_DIV_GATE),
+
+	LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL,
+			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
+	LPC32XX_DEFINE_CLK(SD_GATE, MS_CTRL, BIT(5) | BIT(9), BIT(5) | BIT(9),
+			   0x0, BIT(5) | BIT(9), 0x0, 0x0, clk_mask_ops),
+	LPC32XX_DEFINE_COMPOSITE(SD, _NULL, SD_DIV, SD_GATE),
+
+	LPC32XX_DEFINE_DIV(LCD_DIV, LCDCLK_CTRL, 0, 5, NULL, 0),
+	LPC32XX_DEFINE_GATE(LCD_GATE, LCDCLK_CTRL, 5, 0),
+	LPC32XX_DEFINE_COMPOSITE(LCD, _NULL, LCD_DIV, LCD_GATE),
+
+	LPC32XX_DEFINE_CLK(MAC, MACCLK_CTRL,
+			   BIT(2) | BIT(1) | BIT(0), BIT(2) | BIT(1) | BIT(0),
+			   BIT(2) | BIT(1) | BIT(0), BIT(2) | BIT(1) | BIT(0),
+			   0x0, 0x0, clk_mask_ops),
+	LPC32XX_DEFINE_CLK(SLC, FLASHCLK_CTRL,
+			   BIT(2) | BIT(0), BIT(2) | BIT(0), 0x0,
+			   BIT(0), BIT(1), BIT(2) | BIT(1), clk_mask_ops),
+	LPC32XX_DEFINE_CLK(MLC, FLASHCLK_CTRL,
+			   BIT(1), BIT(2) | BIT(1), 0x0, BIT(1),
+			   BIT(2) | BIT(0), BIT(2) | BIT(0), clk_mask_ops),
+	/*
+	 * ADC/TS clock unfortunately cannot be registered as a composite one
+	 * due to a different connection of gate, div and mux, e.g. gating it
+	 * won't mean that the clock is off, if peripheral clock is its parent:
+	 *
+	 * rtc-->[gate]-->|     |
+	 *                | mux |--> adc/ts
+	 * pclk-->[div]-->|     |
+	 *
+	 * Constraints:
+	 * ADC --- resulting clock must be <= 4.5 MHz
+	 * TS  --- resulting clock must be <= 400 KHz
+	 */
+	LPC32XX_DEFINE_DIV(ADC_DIV, ADCCLK_CTRL1, 0, 8, NULL, 0),
+	LPC32XX_DEFINE_GATE(ADC_RTC, ADCCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_MUX(ADC, ADCCLK_CTRL1, 8, 0x1, NULL, 0),
+
+	/* USB controller clocks */
+	LPC32XX_DEFINE_USB(USB_AHB,
+			   BIT(24), 0x0, BIT(24), BIT(4), 0, clk_usb_ops),
+	LPC32XX_DEFINE_USB(USB_OTG,
+			   0x0, 0x0, 0x0, BIT(3), 0, clk_usb_ops),
+	LPC32XX_DEFINE_USB(USB_I2C,
+			   0x0, BIT(23), BIT(23), BIT(2), 0, clk_usb_i2c_ops),
+	LPC32XX_DEFINE_USB(USB_DEV,
+			   BIT(22), 0x0, BIT(22), BIT(1), BIT(0), clk_usb_ops),
+	LPC32XX_DEFINE_USB(USB_HOST,
+			   BIT(21), 0x0, BIT(21), BIT(0), BIT(1), clk_usb_ops),
+};
+
+static struct clk * __init lpc32xx_clk_register(u32 id)
+{
+	const struct clk_proto_t *lpc32xx_clk = &clk_proto[id];
+	struct clk_hw_proto *clk_hw = &clk_hw_proto[id];
+	const char *parents[LPC32XX_CLK_PARENTS_MAX];
+	struct clk *clk;
+	unsigned int i;
+
+	for (i = 0; i < lpc32xx_clk->num_parents; i++)
+		parents[i] = clk_proto[lpc32xx_clk->parents[i]].name;
+
+	pr_debug("%s: derived from '%s', clock type %d\n", lpc32xx_clk->name,
+		 parents[0], clk_hw->type);
+
+	switch (clk_hw->type) {
+	case CLK_LPC32XX:
+	case CLK_LPC32XX_PLL:
+	case CLK_LPC32XX_USB:
+	case CLK_MUX:
+	case CLK_DIV:
+	case CLK_GATE:
+	{
+		struct clk_init_data clk_init = {
+			.name = lpc32xx_clk->name,
+			.parent_names = parents,
+			.num_parents = lpc32xx_clk->num_parents,
+			.flags = lpc32xx_clk->flags,
+			.ops = clk_hw->hw0.ops,
+		};
+		struct clk_hw *hw;
+
+		if (clk_hw->type == CLK_LPC32XX)
+			hw = &clk_hw->hw0.clk.hw;
+		else if (clk_hw->type == CLK_LPC32XX_PLL)
+			hw = &clk_hw->hw0.pll.hw;
+		else if (clk_hw->type == CLK_LPC32XX_USB)
+			hw = &clk_hw->hw0.usb_clk.hw;
+		else if (clk_hw->type == CLK_MUX)
+			hw = &clk_hw->hw0.mux.hw;
+		else if (clk_hw->type == CLK_DIV)
+			hw = &clk_hw->hw0.div.hw;
+		else if (clk_hw->type == CLK_GATE)
+			hw = &clk_hw->hw0.gate.hw;
+
+		hw->init = &clk_init;
+		clk = clk_register(NULL, hw);
+		break;
+	}
+	case CLK_COMPOSITE:
+	{
+		struct clk_hw *mux_hw = NULL, *div_hw = NULL, *gate_hw = NULL;
+		const struct clk_ops *mops = NULL, *dops = NULL, *gops = NULL;
+		struct clk_hw_proto0 *mux0, *div0, *gate0;
+
+		mux0 = clk_hw->hw1.mux;
+		div0 = clk_hw->hw1.div;
+		gate0 = clk_hw->hw1.gate;
+		if (mux0) {
+			mops = mux0->ops;
+			mux_hw = &mux0->clk.hw;
+		}
+		if (div0) {
+			dops = div0->ops;
+			div_hw = &div0->clk.hw;
+		}
+		if (gate0) {
+			gops = gate0->ops;
+			gate_hw = &gate0->clk.hw;
+		}
+
+		clk = clk_register_composite(NULL, lpc32xx_clk->name,
+				parents, lpc32xx_clk->num_parents,
+				mux_hw, mops, div_hw, dops,
+				gate_hw, gops, lpc32xx_clk->flags);
+		break;
+	}
+	case CLK_FIXED:
+	{
+		struct clk_fixed_rate *fixed = &clk_hw->f;
+
+		clk = clk_register_fixed_rate(NULL, lpc32xx_clk->name,
+			parents[0], fixed->flags, fixed->fixed_rate);
+		break;
+	}
+	default:
+		clk = ERR_PTR(-EINVAL);
+	}
+
+	return clk;
+}
+
+static void __init lpc32xx_clk_init(struct device_node *np)
+{
+	unsigned int i;
+	struct clk *clk_osc, *clk_32k;
+	void __iomem *base = NULL;
+
+	/* Ensure that parent clocks are available and valid */
+	clk_32k = of_clk_get_by_name(np, clk_proto[LPC32XX_CLK_XTAL_32K].name);
+	if (IS_ERR(clk_32k)) {
+		pr_err("failed to find external 32KHz clock: %ld\n",
+		       PTR_ERR(clk_32k));
+		return;
+	}
+	if (clk_get_rate(clk_32k) != 32768) {
+		pr_err("invalid clock rate of external 32KHz oscillator");
+		return;
+	}
+
+	clk_osc = of_clk_get_by_name(np, clk_proto[LPC32XX_CLK_XTAL].name);
+	if (IS_ERR(clk_osc)) {
+		pr_err("failed to find external main oscillator clock: %ld\n",
+		       PTR_ERR(clk_osc));
+		return;
+	}
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("failed to map system control block registers\n");
+		return;
+	}
+
+	clk_regmap = regmap_init_mmio(NULL, base, &lpc32xx_scb_regmap_config);
+	if (IS_ERR(clk_regmap)) {
+		pr_err("failed to regmap system control block: %ld\n",
+			PTR_ERR(clk_regmap));
+		return;
+	}
+
+	for (i = 0; i < LPC32XX_CLK_MAX; i++) {
+		clk[i] = lpc32xx_clk_register(i);
+		if (IS_ERR(clk[i])) {
+			pr_err("failed to register %s clock: %ld\n",
+				clk_proto[i].name, PTR_ERR(clk[i]));
+			clk[i] = NULL;
+		}
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+	/* For 13MHz osc valid output range of PLL is from 156MHz to 266.5MHz */
+	clk_set_rate(clk[LPC32XX_CLK_HCLK_PLL], 208000000);
+
+	/* Set 48MHz rate of USB PLL clock */
+	clk_set_rate(clk[LPC32XX_CLK_USB_PLL], 48000000);
+
+	/* These two clocks must be always on independently on consumers */
+	clk_prepare_enable(clk[LPC32XX_CLK_ARM]);
+	clk_prepare_enable(clk[LPC32XX_CLK_HCLK]);
+
+	/* Enable ARM VFP by default */
+	clk_prepare_enable(clk[LPC32XX_CLK_ARM_VFP]);
+
+	/* Disable enabled by default clocks for NAND MLC and SLC */
+	clk_mask_disable(&clk_hw_proto[LPC32XX_CLK_SLC].hw0.clk.hw);
+	clk_mask_disable(&clk_hw_proto[LPC32XX_CLK_MLC].hw0.clk.hw);
+}
+CLK_OF_DECLARE(lpc32xx_clk, "nxp,lpc3220-clk", lpc32xx_clk_init);
+
+static void __init lpc32xx_usb_clk_init(struct device_node *np)
+{
+	unsigned int i;
+
+	usb_clk_vbase = of_iomap(np, 0);
+	if (!usb_clk_vbase) {
+		pr_err("failed to map address range\n");
+		return;
+	}
+
+	for (i = 0; i < LPC32XX_USB_CLK_MAX; i++) {
+		usb_clk[i] = lpc32xx_clk_register(i + LPC32XX_CLK_USB_OFFSET);
+		if (IS_ERR(usb_clk[i])) {
+			pr_err("failed to register %s clock: %ld\n",
+				clk_proto[i].name, PTR_ERR(usb_clk[i]));
+			usb_clk[i] = NULL;
+		}
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &usb_clk_data);
+}
+CLK_OF_DECLARE(lpc32xx_usb_clk, "nxp,lpc3220-usb-clk", lpc32xx_usb_clk_init);
-- 
2.1.4


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

* [PATCH 09/11] clk: lpc32xx: add common clock framework driver
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

Add support for all configurable clocks found on NXP LPC32xx SoC.

The list contains several heterogenous groups of clocks:
* system clocks including multiple dividers and muxes,
* x397 PLL, HCLK PLL and USB PLL,
* peripheral clocks inherited from rtc, hclk and pclk,
* USB controller clocks: AHB slave, I2C, OTG, OHCI and device.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 drivers/clk/Kconfig           |    3 +-
 drivers/clk/nxp/Makefile      |    1 +
 drivers/clk/nxp/clk-lpc32xx.c | 1562 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1565 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/nxp/clk-lpc32xx.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 7fc1eb9..9310cf4 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -176,7 +176,8 @@ config COMMON_CLK_PWM
 	  at 50% duty cycle.
 
 config COMMON_CLK_NXP
-	def_bool COMMON_CLK && ARCH_LPC18XX
+	def_bool COMMON_CLK && (ARCH_LPC18XX || ARCH_LPC32XX)
+	select REGMAP_MMIO if ARCH_LPC32XX
 	---help---
 	  Support for clock providers on NXP platforms.
 
diff --git a/drivers/clk/nxp/Makefile b/drivers/clk/nxp/Makefile
index 7f608b0..607bd48 100644
--- a/drivers/clk/nxp/Makefile
+++ b/drivers/clk/nxp/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ARCH_LPC18XX)	+= clk-lpc18xx-cgu.o
 obj-$(CONFIG_ARCH_LPC18XX)	+= clk-lpc18xx-ccu.o
+obj-$(CONFIG_ARCH_LPC32XX)	+= clk-lpc32xx.o
diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c
new file mode 100644
index 0000000..fcd7135
--- /dev/null
+++ b/drivers/clk/nxp/clk-lpc32xx.c
@@ -0,0 +1,1562 @@
+/*
+ * Copyright 2015 Vladimir Zapolskiy <vz@mleia.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/lpc32xx-clock.h>
+
+#undef pr_fmt
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+/* Common bitfield definitions for x397 PLL (lock), USB PLL and HCLK PLL */
+#define PLL_CTRL_ENABLE			BIT(16)
+#define PLL_CTRL_BYPASS			BIT(15)
+#define PLL_CTRL_DIRECT			BIT(14)
+#define PLL_CTRL_FEEDBACK		BIT(13)
+#define PLL_CTRL_POSTDIV		(BIT(12)|BIT(11))
+#define PLL_CTRL_PREDIV			(BIT(10)|BIT(9))
+#define PLL_CTRL_FEEDDIV		(0xFF << 1)
+#define PLL_CTRL_LOCK			BIT(0)
+
+/* Clock registers on System Control Block */
+#define LPC32XX_CLKPWR_DEBUG_CTRL	0x00
+#define LPC32XX_CLKPWR_USB_DIV		0x1C
+#define LPC32XX_CLKPWR_HCLKDIV_CTRL	0x40
+#define LPC32XX_CLKPWR_PWR_CTRL		0x44
+#define LPC32XX_CLKPWR_PLL397_CTRL	0x48
+#define LPC32XX_CLKPWR_OSC_CTRL		0x4C
+#define LPC32XX_CLKPWR_SYSCLK_CTRL	0x50
+#define LPC32XX_CLKPWR_LCDCLK_CTRL	0x54
+#define LPC32XX_CLKPWR_HCLKPLL_CTRL	0x58
+#define LPC32XX_CLKPWR_ADCCLK_CTRL1	0x60
+#define LPC32XX_CLKPWR_USB_CTRL		0x64
+#define LPC32XX_CLKPWR_SSP_CTRL		0x78
+#define LPC32XX_CLKPWR_I2S_CTRL		0x7C
+#define LPC32XX_CLKPWR_MS_CTRL		0x80
+#define LPC32XX_CLKPWR_MACCLK_CTRL	0x90
+#define LPC32XX_CLKPWR_TEST_CLK_CTRL	0xA4
+#define LPC32XX_CLKPWR_I2CCLK_CTRL	0xAC
+#define LPC32XX_CLKPWR_KEYCLK_CTRL	0xB0
+#define LPC32XX_CLKPWR_ADCCLK_CTRL	0xB4
+#define LPC32XX_CLKPWR_PWMCLK_CTRL	0xB8
+#define LPC32XX_CLKPWR_TIMCLK_CTRL	0xBC
+#define LPC32XX_CLKPWR_TIMCLK_CTRL1	0xC0
+#define LPC32XX_CLKPWR_SPI_CTRL		0xC4
+#define LPC32XX_CLKPWR_FLASHCLK_CTRL	0xC8
+#define LPC32XX_CLKPWR_UART3_CLK_CTRL	0xD0
+#define LPC32XX_CLKPWR_UART4_CLK_CTRL	0xD4
+#define LPC32XX_CLKPWR_UART5_CLK_CTRL	0xD8
+#define LPC32XX_CLKPWR_UART6_CLK_CTRL	0xDC
+#define LPC32XX_CLKPWR_IRDA_CLK_CTRL	0xE0
+#define LPC32XX_CLKPWR_UART_CLK_CTRL	0xE4
+#define LPC32XX_CLKPWR_DMA_CLK_CTRL	0xE8
+
+/* Clock registers on USB controller */
+#define LPC32XX_USB_CLK_CTRL		0xF4
+#define LPC32XX_USB_CLK_STS		0xF8
+
+static struct regmap_config lpc32xx_scb_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+	.val_format_endian = REGMAP_ENDIAN_LITTLE,
+	.max_register = 0x114,
+	.fast_io = true,
+};
+
+static struct regmap *clk_regmap;
+static void __iomem *usb_clk_vbase;
+
+enum {
+	LPC32XX_USB_CLK_OTG = LPC32XX_USB_CLK_HOST + 1,
+	LPC32XX_USB_CLK_AHB,
+
+	LPC32XX_USB_CLK_MAX = LPC32XX_USB_CLK_AHB + 1,
+};
+
+enum {
+	/* Start from the last defined clock in dt bindings */
+	LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_ADC + 1,
+	LPC32XX_CLK_ADC_RTC,
+	LPC32XX_CLK_TEST1,
+	LPC32XX_CLK_TEST2,
+
+	/* System clocks, PLL 397x and HCLK PLL clocks */
+	LPC32XX_CLK_OSC,
+	LPC32XX_CLK_SYS,
+	LPC32XX_CLK_PLL397X,
+	LPC32XX_CLK_HCLK_PLL,
+	LPC32XX_CLK_HCLK_DIV_PERIPH,
+	LPC32XX_CLK_HCLK_DIV,
+	LPC32XX_CLK_HCLK,
+	LPC32XX_CLK_PERIPH,
+	LPC32XX_CLK_ARM,
+	LPC32XX_CLK_ARM_VFP,
+
+	/* USB clocks */
+	LPC32XX_CLK_USB_PLL,
+	LPC32XX_CLK_USB_DIV,
+	LPC32XX_CLK_USB,
+
+	/* Only one control PWR_CTRL[10] for both muxes */
+	LPC32XX_CLK_PERIPH_HCLK_MUX,
+	LPC32XX_CLK_PERIPH_ARM_MUX,
+
+	/* Only one control PWR_CTRL[2] for all three muxes */
+	LPC32XX_CLK_SYSCLK_PERIPH_MUX,
+	LPC32XX_CLK_SYSCLK_HCLK_MUX,
+	LPC32XX_CLK_SYSCLK_ARM_MUX,
+
+	/* Two clock sources external to the driver */
+	LPC32XX_CLK_XTAL_32K,
+	LPC32XX_CLK_XTAL,
+
+	/* Renumbered USB clocks, may have a parent from SCB table */
+	LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_I2C = LPC32XX_USB_CLK_I2C + LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_DEV = LPC32XX_USB_CLK_DEVICE + LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_HOST = LPC32XX_USB_CLK_HOST + LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_OTG = LPC32XX_USB_CLK_OTG + LPC32XX_CLK_USB_OFFSET,
+	LPC32XX_CLK_USB_AHB = LPC32XX_USB_CLK_AHB + LPC32XX_CLK_USB_OFFSET,
+
+	/* Stub for composite clocks */
+	LPC32XX_CLK__NULL,
+
+	/* Subclocks of composite clocks, clocks above are for CCF */
+	LPC32XX_CLK_PWM1_MUX,
+	LPC32XX_CLK_PWM1_DIV,
+	LPC32XX_CLK_PWM1_GATE,
+	LPC32XX_CLK_PWM2_MUX,
+	LPC32XX_CLK_PWM2_DIV,
+	LPC32XX_CLK_PWM2_GATE,
+	LPC32XX_CLK_UART3_MUX,
+	LPC32XX_CLK_UART3_DIV,
+	LPC32XX_CLK_UART3_GATE,
+	LPC32XX_CLK_UART4_MUX,
+	LPC32XX_CLK_UART4_DIV,
+	LPC32XX_CLK_UART4_GATE,
+	LPC32XX_CLK_UART5_MUX,
+	LPC32XX_CLK_UART5_DIV,
+	LPC32XX_CLK_UART5_GATE,
+	LPC32XX_CLK_UART6_MUX,
+	LPC32XX_CLK_UART6_DIV,
+	LPC32XX_CLK_UART6_GATE,
+	LPC32XX_CLK_TEST1_MUX,
+	LPC32XX_CLK_TEST1_GATE,
+	LPC32XX_CLK_TEST2_MUX,
+	LPC32XX_CLK_TEST2_GATE,
+	LPC32XX_CLK_USB_DIV_DIV,
+	LPC32XX_CLK_USB_DIV_GATE,
+	LPC32XX_CLK_SD_DIV,
+	LPC32XX_CLK_SD_GATE,
+	LPC32XX_CLK_LCD_DIV,
+	LPC32XX_CLK_LCD_GATE,
+
+	LPC32XX_CLK_HW_MAX,
+	LPC32XX_CLK_MAX = LPC32XX_CLK_SYSCLK_ARM_MUX + 1,
+	LPC32XX_CLK_CCF_MAX = LPC32XX_CLK_USB_AHB + 1,
+};
+
+static struct clk *clk[LPC32XX_CLK_MAX];
+static struct clk_onecell_data clk_data = {
+	.clks = clk,
+	.clk_num = LPC32XX_CLK_MAX,
+};
+
+static struct clk *usb_clk[LPC32XX_USB_CLK_MAX];
+static struct clk_onecell_data usb_clk_data = {
+	.clks = usb_clk,
+	.clk_num = LPC32XX_USB_CLK_MAX,
+};
+
+#define LPC32XX_CLK_PARENTS_MAX			5
+
+struct clk_proto_t {
+	const char *name;
+	const u8 parents[LPC32XX_CLK_PARENTS_MAX];
+	u8 num_parents;
+	unsigned long flags;
+};
+
+#define CLK_PREFIX(LITERAL)		LPC32XX_CLK_ ## LITERAL
+#define NUMARGS(...)	(sizeof((int[]){__VA_ARGS__})/sizeof(int))
+
+#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)		\
+	[CLK_PREFIX(_idx)] = {					\
+		.name = #_name,					\
+		.flags = _flags,				\
+		.parents = { __VA_ARGS__ },			\
+		.num_parents = NUMARGS(__VA_ARGS__),		\
+	 }
+
+static const struct clk_proto_t clk_proto[LPC32XX_CLK_CCF_MAX] __initconst = {
+	LPC32XX_CLK_DEFINE(XTAL, xtal, 0x0),
+	LPC32XX_CLK_DEFINE(XTAL_32K, xtal_32k, 0x0),
+
+	LPC32XX_CLK_DEFINE(RTC, rtc, 0x0, LPC32XX_CLK_XTAL_32K),
+	LPC32XX_CLK_DEFINE(OSC, osc, CLK_IGNORE_UNUSED, LPC32XX_CLK_XTAL),
+	LPC32XX_CLK_DEFINE(SYS, sys, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),
+	LPC32XX_CLK_DEFINE(PLL397X, pll_397x, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_RTC),
+	LPC32XX_CLK_DEFINE(HCLK_PLL, hclk_pll, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYS),
+	LPC32XX_CLK_DEFINE(HCLK_DIV_PERIPH, hclk_div_periph, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_HCLK_PLL),
+	LPC32XX_CLK_DEFINE(HCLK_DIV, hclk_div, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_HCLK_PLL),
+	LPC32XX_CLK_DEFINE(HCLK, hclk, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_PERIPH_HCLK_MUX),
+	LPC32XX_CLK_DEFINE(PERIPH, pclk, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYSCLK_PERIPH_MUX),
+	LPC32XX_CLK_DEFINE(ARM, arm, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_PERIPH_ARM_MUX),
+
+	LPC32XX_CLK_DEFINE(PERIPH_HCLK_MUX, periph_hclk_mux, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYSCLK_HCLK_MUX, LPC32XX_CLK_SYSCLK_PERIPH_MUX),
+	LPC32XX_CLK_DEFINE(PERIPH_ARM_MUX, periph_arm_mux, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYSCLK_ARM_MUX, LPC32XX_CLK_SYSCLK_PERIPH_MUX),
+	LPC32XX_CLK_DEFINE(SYSCLK_PERIPH_MUX, sysclk_periph_mux,
+		CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYS, LPC32XX_CLK_HCLK_DIV_PERIPH),
+	LPC32XX_CLK_DEFINE(SYSCLK_HCLK_MUX, sysclk_hclk_mux, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYS, LPC32XX_CLK_HCLK_DIV),
+	LPC32XX_CLK_DEFINE(SYSCLK_ARM_MUX, sysclk_arm_mux, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_SYS, LPC32XX_CLK_HCLK_PLL),
+
+	LPC32XX_CLK_DEFINE(ARM_VFP, vfp9, CLK_IGNORE_UNUSED,
+		LPC32XX_CLK_ARM),
+	LPC32XX_CLK_DEFINE(USB_PLL, usb_pll,
+		CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, LPC32XX_CLK_USB_DIV),
+	LPC32XX_CLK_DEFINE(USB_DIV, usb_div, 0x0, LPC32XX_CLK_OSC),
+	LPC32XX_CLK_DEFINE(USB, usb, 0x0, LPC32XX_CLK_USB_PLL),
+	LPC32XX_CLK_DEFINE(DMA, dma, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(MLC, mlc, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SLC, slc, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(LCD, lcd, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(MAC, mac, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SD, sd, 0x0, LPC32XX_CLK_ARM),
+	LPC32XX_CLK_DEFINE(DDRAM, ddram, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_SYSCLK_ARM_MUX),
+	LPC32XX_CLK_DEFINE(SSP0, ssp0, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SSP1, ssp1, 0x0, LPC32XX_CLK_HCLK),
+	/* CLK_GET_RATE_NOCACHE is needed, if disabled it is 0/0 in div */
+	LPC32XX_CLK_DEFINE(UART3, uart3, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(UART4, uart4, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(UART5, uart5, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(UART6, uart6, CLK_GET_RATE_NOCACHE,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(IRDA, irda, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(I2C1, i2c1, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(I2C2, i2c2, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(TIMER0, timer0, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER1, timer1, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER2, timer2, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER3, timer3, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER4, timer4, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(TIMER5, timer5, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(WDOG, watchdog, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(I2S0, i2s0, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(I2S1, i2s1, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SPI1, spi1, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(SPI2, spi2, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(MCPWM, mcpwm, 0x0, LPC32XX_CLK_HCLK),
+	LPC32XX_CLK_DEFINE(HSTIMER, hstimer, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(KEY, key, 0x0, LPC32XX_CLK_RTC),
+	LPC32XX_CLK_DEFINE(PWM1, pwm1, 0x0,
+		LPC32XX_CLK_RTC, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(PWM2, pwm2, 0x0,
+		LPC32XX_CLK_RTC, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(ADC, adc, 0x0,
+		LPC32XX_CLK_ADC_RTC, LPC32XX_CLK_ADC_DIV),
+	LPC32XX_CLK_DEFINE(ADC_DIV, adc_div, 0x0, LPC32XX_CLK_PERIPH),
+	LPC32XX_CLK_DEFINE(ADC_RTC, adc_rtc, 0x0, LPC32XX_CLK_RTC),
+	LPC32XX_CLK_DEFINE(TEST1, test1, 0x0,
+		LPC32XX_CLK_PERIPH, LPC32XX_CLK_RTC, LPC32XX_CLK_OSC),
+	LPC32XX_CLK_DEFINE(TEST2, test2, 0x0,
+		LPC32XX_CLK_HCLK, LPC32XX_CLK_PERIPH, LPC32XX_CLK_USB,
+		LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),
+	/* USB controller clocks */
+	LPC32XX_CLK_DEFINE(USB_AHB, usb_ahb, 0x0, LPC32XX_CLK_USB),
+	LPC32XX_CLK_DEFINE(USB_OTG, usb_otg, 0x0, LPC32XX_CLK_USB_AHB),
+	LPC32XX_CLK_DEFINE(USB_I2C, usb_i2c, 0x0, LPC32XX_CLK_USB_AHB),
+	LPC32XX_CLK_DEFINE(USB_DEV, usb_dev, 0x0, LPC32XX_CLK_USB_OTG),
+	LPC32XX_CLK_DEFINE(USB_HOST, usb_host, 0x0, LPC32XX_CLK_USB_OTG),
+};
+
+struct lpc32xx_clk {
+	struct clk_hw hw;
+	u32 reg;
+	u32 enable;
+	u32 enable_mask;
+	u32 disable;
+	u32 disable_mask;
+	u32 busy;
+	u32 busy_mask;
+};
+
+enum clk_pll_mode {
+	PLL_UNKNOWN,
+	PLL_DIRECT,
+	PLL_BYPASS,
+	PLL_DIRECT_BYPASS,
+	PLL_INTEGER,
+	PLL_NON_INTEGER,
+};
+
+struct lpc32xx_pll_clk {
+	struct clk_hw hw;
+	u32 reg;
+	u32 enable;
+	unsigned long m_div;
+	unsigned long n_div;
+	unsigned long p_div;
+	enum clk_pll_mode mode;
+};
+
+struct lpc32xx_usb_clk {
+	struct clk_hw hw;
+	u32 ctrl_enable;
+	u32 ctrl_disable;
+	u32 ctrl_mask;
+	u32 enable;
+	u32 busy;
+};
+
+struct lpc32xx_clk_mux {
+	struct clk_hw	hw;
+	u32		reg;
+	u32		mask;
+	u8		shift;
+	u32		*table;
+	u8		flags;
+};
+
+struct lpc32xx_clk_div {
+	struct clk_hw	hw;
+	u32		reg;
+	u8		shift;
+	u8		width;
+	const struct clk_div_table	*table;
+	u8		flags;
+};
+
+struct lpc32xx_clk_gate {
+	struct clk_hw	hw;
+	u32		reg;
+	u8		bit_idx;
+	u8		flags;
+};
+
+#define to_lpc32xx_clk(_hw)	container_of(_hw, struct lpc32xx_clk, hw)
+#define to_lpc32xx_pll_clk(_hw)	container_of(_hw, struct lpc32xx_pll_clk, hw)
+#define to_lpc32xx_usb_clk(_hw)	container_of(_hw, struct lpc32xx_usb_clk, hw)
+#define to_lpc32xx_mux(_hw)	container_of(_hw, struct lpc32xx_clk_mux, hw)
+#define to_lpc32xx_div(_hw)	container_of(_hw, struct lpc32xx_clk_div, hw)
+#define to_lpc32xx_gate(_hw)	container_of(_hw, struct lpc32xx_clk_gate, hw)
+
+static inline bool pll_is_valid(u64 val0, u64 val1, u64 min, u64 max)
+{
+	return (val0 >= (val1 * min) && val0 <= (val1 * max));
+}
+
+static inline u32 lpc32xx_usb_clk_read(struct lpc32xx_usb_clk *clk)
+{
+	return readl(usb_clk_vbase + LPC32XX_USB_CLK_STS);
+}
+
+static inline void lpc32xx_usb_clk_write(struct lpc32xx_usb_clk *clk, u32 val)
+{
+	writel(val, usb_clk_vbase + LPC32XX_USB_CLK_CTRL);
+}
+
+static int clk_mask_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+
+	if (clk->busy_mask && (val & clk->busy_mask) == clk->busy)
+		return -EBUSY;
+
+	return regmap_update_bits(clk_regmap, clk->reg,
+				  clk->enable_mask, clk->enable);
+}
+
+static void clk_mask_disable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+
+	regmap_update_bits(clk_regmap, clk->reg,
+			   clk->disable_mask, clk->disable);
+}
+
+static int clk_mask_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+
+	return ((val & clk->enable_mask) == clk->enable);
+}
+
+static const struct clk_ops clk_mask_ops = {
+	.enable = clk_mask_enable,
+	.disable = clk_mask_disable,
+	.is_enabled = clk_mask_is_enabled,
+};
+
+static int clk_pll_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	u32 val, count;
+
+	regmap_update_bits(clk_regmap, clk->reg, clk->enable, clk->enable);
+
+	for (count = 0; count < 1000; count++) {
+		regmap_read(clk_regmap, clk->reg, &val);
+		if (val & PLL_CTRL_LOCK)
+			break;
+	}
+
+	if (val & PLL_CTRL_LOCK)
+		return 0;
+
+	return -ETIMEDOUT;
+}
+
+static void clk_pll_disable(struct clk_hw *hw)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+
+	regmap_update_bits(clk_regmap, clk->reg, clk->enable, 0x0);
+}
+
+static int clk_pll_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+
+	val &= clk->enable | PLL_CTRL_LOCK;
+	if (val == (clk->enable | PLL_CTRL_LOCK))
+		return 1;
+
+	return 0;
+}
+
+static unsigned long clk_pll_397x_recalc_rate(struct clk_hw *hw,
+					      unsigned long parent_rate)
+{
+	return parent_rate * 397;
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	bool is_direct, is_bypass, is_feedback;
+	unsigned long rate, cco_rate, ref_rate;
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	is_direct = val & PLL_CTRL_DIRECT;
+	is_bypass = val & PLL_CTRL_BYPASS;
+	is_feedback = val & PLL_CTRL_FEEDBACK;
+
+	clk->m_div = ((val & PLL_CTRL_FEEDDIV) >> 1) + 1;
+	clk->n_div = ((val & PLL_CTRL_PREDIV) >> 9) + 1;
+	clk->p_div = ((val & PLL_CTRL_POSTDIV) >> 11) + 1;
+
+	if (is_direct && is_bypass) {
+		clk->p_div = 0;
+		clk->mode = PLL_DIRECT_BYPASS;
+		return parent_rate;
+	}
+	if (is_bypass) {
+		clk->mode = PLL_BYPASS;
+		return parent_rate / (1 << clk->p_div);
+	}
+	if (is_direct) {
+		clk->p_div = 0;
+		clk->mode = PLL_DIRECT;
+	}
+
+	ref_rate = parent_rate / clk->n_div;
+	rate = cco_rate = ref_rate * clk->m_div;
+
+	if (!is_direct) {
+		if (is_feedback) {
+			cco_rate *= (1 << clk->p_div);
+			clk->mode = PLL_INTEGER;
+		} else {
+			rate /= (1 << clk->p_div);
+			clk->mode = PLL_NON_INTEGER;
+		}
+	}
+
+	pr_debug("%s: %lu: 0x%x: %d/%d/%d, %lu/%lu/%d => %lu\n",
+		 clk_hw_get_name(hw),
+		 parent_rate, val, is_direct, is_bypass, is_feedback,
+		 clk->n_div, clk->m_div, (1 << clk->p_div), rate);
+
+	if (clk_pll_is_enabled(hw) &&
+	    !(pll_is_valid(parent_rate, 1, 1000000, 20000000)
+	      && pll_is_valid(cco_rate, 1, 156000000, 320000000)
+	      && pll_is_valid(ref_rate, 1, 1000000, 27000000)))
+		pr_err("%s: PLL clocks are not in valid ranges: %lu/%lu/%lu",
+		       clk_hw_get_name(hw),
+		       parent_rate, cco_rate, ref_rate);
+
+	return rate;
+}
+
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	u32 val;
+	unsigned long new_rate;
+
+	/* Validate PLL clock parameters computed on round rate stage */
+	switch (clk->mode) {
+	case PLL_DIRECT:
+		val = PLL_CTRL_DIRECT;
+		val |= (clk->m_div - 1) << 1;
+		val |= (clk->n_div - 1) << 9;
+		new_rate = (parent_rate * clk->m_div) / clk->n_div;
+		break;
+	case PLL_BYPASS:
+		val = PLL_CTRL_BYPASS;
+		val |= (clk->p_div - 1) << 11;
+		new_rate = parent_rate / (1 << (clk->p_div));
+		break;
+	case PLL_DIRECT_BYPASS:
+		val = PLL_CTRL_DIRECT | PLL_CTRL_BYPASS;
+		new_rate = parent_rate;
+		break;
+	case PLL_INTEGER:
+		val = PLL_CTRL_FEEDBACK;
+		val |= (clk->m_div - 1) << 1;
+		val |= (clk->n_div - 1) << 9;
+		val |= (clk->p_div - 1) << 11;
+		new_rate = (parent_rate * clk->m_div) / clk->n_div;
+		break;
+	case PLL_NON_INTEGER:
+		val = 0x0;
+		val |= (clk->m_div - 1) << 1;
+		val |= (clk->n_div - 1) << 9;
+		val |= (clk->p_div - 1) << 11;
+		new_rate = (parent_rate * clk->m_div) /
+				(clk->n_div * (1 << clk->p_div));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Sanity check that round rate is equal to the requested one */
+	if (!new_rate == rate)
+		return -EINVAL;
+
+	return regmap_update_bits(clk_regmap, clk->reg, 0x1FFFF, val);
+}
+
+static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long *parent_rate)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	u64 m_i, m, n, p, o = rate, i = *parent_rate, d = (u64)rate << 6;
+	int p_i, n_i;
+
+	pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate);
+
+	if (rate > 266500000)
+		return -EINVAL;
+
+	/* Have to check all 20 possibilities to find the minimal M */
+	for (p_i = 4; p_i >= 0; p_i--) {
+		for (n_i = 4; n_i > 0; n_i--) {
+			m_i = div64_u64(o * n_i * (1 << p_i), i);
+
+			/* Check for valid PLL parameter constraints */
+			if (!(m_i && m_i <= 256
+			      && pll_is_valid(i, n_i, 1000000, 27000000)
+			      && pll_is_valid(i * m_i * (1 << p_i), n_i,
+					      156000000, 320000000)))
+				continue;
+
+			/* Store some intermediate valid parameters */
+			if (o * n_i * (1 << p_i) - i * m_i <= d) {
+				m = m_i;
+				n = n_i;
+				p = p_i;
+				d = o * n_i * (1 << p_i) - i * m_i;
+			}
+		}
+	}
+
+	if (d == (u64)rate << 6) {
+		pr_err("%s: %lu: no valid PLL parameters are found\n",
+		       clk_hw_get_name(hw), rate);
+		return -EINVAL;
+	}
+
+	clk->m_div = m;
+	clk->n_div = n;
+	clk->p_div = p;
+
+	/* Set only direct or non-integer mode of PLL */
+	if (!p)
+		clk->mode = PLL_DIRECT;
+	else
+		clk->mode = PLL_NON_INTEGER;
+
+	o = div64_u64(i * m, n * (1 << p));
+
+	if (!d)
+		pr_debug("%s: %lu: found exact match: %llu/%llu/%llu\n",
+			 clk_hw_get_name(hw), rate, m, n, p);
+	else
+		pr_debug("%s: %lu: found closest: %llu/%llu/%llu - %llu\n",
+			 clk_hw_get_name(hw), rate, m, n, p, o);
+
+	return o;
+}
+
+static long clk_usb_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long *parent_rate)
+{
+	struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw);
+	struct clk_hw *usb_div_hw, *osc_hw;
+	u64 d_i, n_i, m, o;
+
+	pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate);
+
+	/*
+	 * The only supported USB clock is 48MHz, with PLL internal constraints
+	 * on Fclkin, Fcco and Fref this implies that Fcco must be 192MHz
+	 * and post-divider must be 4, this slightly simplifies calculation of
+	 * USB divider, USB PLL N and M parameters.
+	 */
+	if (rate != 48000000)
+		return -EINVAL;
+
+	/* USB divider clock */
+	usb_div_hw = clk_hw_get_parent_by_index(hw, 0);
+	if (!usb_div_hw)
+		return -EINVAL;
+
+	/* Main oscillator clock */
+	osc_hw = clk_hw_get_parent_by_index(usb_div_hw, 0);
+	if (!osc_hw)
+		return -EINVAL;
+	o = clk_hw_get_rate(osc_hw);	/* must be in range 1..20 MHz */
+
+	/* Check if valid USB divider and USB PLL parameters exists */
+	for (d_i = 16; d_i >= 1; d_i--) {
+		for (n_i = 1; n_i <= 4; n_i++) {
+			m = div64_u64(192000000 * d_i * n_i, o);
+			if (!(m && m <= 256
+			      && m * o == 192000000 * d_i * n_i
+			      && pll_is_valid(o, d_i, 1000000, 20000000)
+			      && pll_is_valid(o, d_i * n_i, 1000000, 27000000)))
+				continue;
+
+			clk->n_div = n_i;
+			clk->m_div = m;
+			clk->p_div = 2;
+			clk->mode = PLL_NON_INTEGER;
+			*parent_rate = div64_u64(o, d_i);
+
+			return rate;
+		}
+	}
+
+	return -EINVAL;
+}
+
+#define LPC32XX_DEFINE_PLL_OPS(_name, _rc, _sr, _rr)			\
+	static const struct clk_ops clk_ ##_name ## _ops = {		\
+		.enable = clk_pll_enable,				\
+		.disable = clk_pll_disable,				\
+		.is_enabled = clk_pll_is_enabled,			\
+		.recalc_rate = _rc,					\
+		.set_rate = _sr,					\
+		.round_rate = _rr,					\
+	}
+
+LPC32XX_DEFINE_PLL_OPS(pll_397x, clk_pll_397x_recalc_rate, NULL, NULL);
+LPC32XX_DEFINE_PLL_OPS(hclk_pll, clk_pll_recalc_rate,
+		       clk_pll_set_rate, clk_hclk_pll_round_rate);
+LPC32XX_DEFINE_PLL_OPS(usb_pll,  clk_pll_recalc_rate,
+		       clk_pll_set_rate, clk_usb_pll_round_rate);
+
+static int clk_ddram_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	val &= clk->enable_mask | clk->busy_mask;
+
+	return (val == (BIT(7) | BIT(0)) ||
+		val == (BIT(8) | BIT(1)));
+}
+
+static int clk_ddram_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val, hclk_div;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	hclk_div = val & clk->busy_mask;
+
+	/*
+	 * DDRAM clock must be 2 times higher than HCLK,
+	 * this implies DDRAM clock can not be enabled,
+	 * if HCLK clock rate is equal to ARM clock rate
+	 */
+	if (hclk_div == 0x0 || hclk_div == (BIT(1) | BIT(0)))
+		return -EINVAL;
+
+	return regmap_update_bits(clk_regmap, clk->reg,
+				  clk->enable_mask, hclk_div << 7);
+}
+
+static unsigned long clk_ddram_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val;
+
+	if (!clk_ddram_is_enabled(hw))
+		return 0;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	val &= clk->enable_mask;
+
+	return parent_rate / (val >> 7);
+}
+
+static const struct clk_ops clk_ddram_ops = {
+	.enable = clk_ddram_enable,
+	.disable = clk_mask_disable,
+	.is_enabled = clk_ddram_is_enabled,
+	.recalc_rate = clk_ddram_recalc_rate,
+};
+
+static unsigned long lpc32xx_clk_uart_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct lpc32xx_clk *clk = to_lpc32xx_clk(hw);
+	u32 val, x, y;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	x = (val & 0xFF00) >> 8;
+	y = val & 0xFF;
+
+	if (x && y)
+		return (parent_rate * x) / y;
+	else
+		return 0;
+}
+
+static const struct clk_ops lpc32xx_uart_div_ops = {
+	.recalc_rate = lpc32xx_clk_uart_recalc_rate,
+};
+
+static const struct clk_div_table clk_hclk_div_table[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ },
+};
+
+static u32 test1_mux_table[] = { 0, 1, 2, };
+static u32 test2_mux_table[] = { 0, 1, 2, 5, 7, };
+
+static int clk_usb_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_usb_clk *clk = to_lpc32xx_usb_clk(hw);
+	u32 val, ctrl_val, count;
+
+	pr_debug("%s: 0x%x\n", clk_hw_get_name(hw), clk->enable);
+
+	if (clk->ctrl_mask) {
+		regmap_read(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, &ctrl_val);
+		regmap_update_bits(clk_regmap, LPC32XX_CLKPWR_USB_CTRL,
+				   clk->ctrl_mask, clk->ctrl_enable);
+	}
+
+	val = lpc32xx_usb_clk_read(clk);
+	if (clk->busy && (val & clk->busy) == clk->busy) {
+		if (clk->ctrl_mask)
+			regmap_write(clk_regmap, LPC32XX_CLKPWR_USB_CTRL,
+				     ctrl_val);
+		return -EBUSY;
+	}
+
+	val |= clk->enable;
+	lpc32xx_usb_clk_write(clk, val);
+
+	for (count = 0; count < 1000; count++) {
+		val = lpc32xx_usb_clk_read(clk);
+		if ((val & clk->enable) == clk->enable)
+			break;
+	}
+
+	if ((val & clk->enable) == clk->enable)
+		return 0;
+
+	if (clk->ctrl_mask)
+		regmap_write(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, ctrl_val);
+
+	return -ETIMEDOUT;
+}
+
+static void clk_usb_disable(struct clk_hw *hw)
+{
+	struct lpc32xx_usb_clk *clk = to_lpc32xx_usb_clk(hw);
+	u32 val = lpc32xx_usb_clk_read(clk);
+
+	val &= ~clk->enable;
+	lpc32xx_usb_clk_write(clk, val);
+
+	if (clk->ctrl_mask)
+		regmap_update_bits(clk_regmap, LPC32XX_CLKPWR_USB_CTRL,
+				   clk->ctrl_mask, clk->ctrl_disable);
+}
+
+static int clk_usb_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_usb_clk *clk = to_lpc32xx_usb_clk(hw);
+	u32 ctrl_val, val;
+
+	if (clk->ctrl_mask) {
+		regmap_read(clk_regmap, LPC32XX_CLKPWR_USB_CTRL, &ctrl_val);
+		if ((ctrl_val & clk->ctrl_mask) != clk->ctrl_enable)
+			return 0;
+	}
+
+	val = lpc32xx_usb_clk_read(clk);
+
+	return ((val & clk->enable) == clk->enable);
+}
+
+static unsigned long clk_usb_i2c_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	return clk_get_rate(clk[LPC32XX_CLK_PERIPH]);
+}
+
+static const struct clk_ops clk_usb_ops = {
+	.enable = clk_usb_enable,
+	.disable = clk_usb_disable,
+	.is_enabled = clk_usb_is_enabled,
+};
+
+static const struct clk_ops clk_usb_i2c_ops = {
+	.enable = clk_usb_enable,
+	.disable = clk_usb_disable,
+	.is_enabled = clk_usb_is_enabled,
+	.recalc_rate = clk_usb_i2c_recalc_rate,
+};
+
+static int clk_gate_enable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
+	u32 mask = BIT(clk->bit_idx);
+	u32 val = (clk->flags & CLK_GATE_SET_TO_DISABLE ? 0x0 : mask);
+
+	return regmap_update_bits(clk_regmap, clk->reg, mask, val);
+}
+
+static void clk_gate_disable(struct clk_hw *hw)
+{
+	struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
+	u32 mask = BIT(clk->bit_idx);
+	u32 val = (clk->flags & CLK_GATE_SET_TO_DISABLE ? mask : 0x0);
+
+	regmap_update_bits(clk_regmap, clk->reg, mask, val);
+}
+
+static int clk_gate_is_enabled(struct clk_hw *hw)
+{
+	struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw);
+	u32 val;
+	bool is_set;
+
+	regmap_read(clk_regmap, clk->reg, &val);
+	is_set = val & BIT(clk->bit_idx);
+
+	return (clk->flags & CLK_GATE_SET_TO_DISABLE ? !is_set : is_set);
+}
+
+static const struct clk_ops lpc32xx_clk_gate_ops = {
+	.enable = clk_gate_enable,
+	.disable = clk_gate_disable,
+	.is_enabled = clk_gate_is_enabled,
+};
+
+#define div_mask(width)	((1 << (width)) - 1)
+
+static unsigned int _get_table_div(const struct clk_div_table *table,
+							unsigned int val)
+{
+	const struct clk_div_table *clkt;
+
+	for (clkt = table; clkt->div; clkt++)
+		if (clkt->val == val)
+			return clkt->div;
+	return 0;
+}
+
+static unsigned int _get_div(const struct clk_div_table *table,
+			     unsigned int val, unsigned long flags, u8 width)
+{
+	if (flags & CLK_DIVIDER_ONE_BASED)
+		return val;
+	if (table)
+		return _get_table_div(table, val);
+	return val + 1;
+}
+
+static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw);
+	unsigned int val;
+
+	regmap_read(clk_regmap, divider->reg, &val);
+
+	val >>= divider->shift;
+	val &= div_mask(divider->width);
+
+	return divider_recalc_rate(hw, parent_rate, val, divider->table,
+				   divider->flags);
+}
+
+static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *prate)
+{
+	struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw);
+	unsigned int bestdiv;
+
+	/* if read only, just return current value */
+	if (divider->flags & CLK_DIVIDER_READ_ONLY) {
+		regmap_read(clk_regmap, divider->reg, &bestdiv);
+		bestdiv >>= divider->shift;
+		bestdiv &= div_mask(divider->width);
+		bestdiv = _get_div(divider->table, bestdiv, divider->flags,
+			divider->width);
+		return DIV_ROUND_UP(*prate, bestdiv);
+	}
+
+	return divider_round_rate(hw, rate, prate, divider->table,
+				  divider->width, divider->flags);
+}
+
+static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct lpc32xx_clk_div *divider = to_lpc32xx_div(hw);
+	unsigned int value;
+
+	value = divider_get_val(rate, parent_rate, divider->table,
+				divider->width, divider->flags);
+
+	return regmap_update_bits(clk_regmap, divider->reg,
+				  div_mask(divider->width) << divider->shift,
+				  value << divider->shift);
+}
+
+static const struct clk_ops lpc32xx_clk_divider_ops = {
+	.recalc_rate = clk_divider_recalc_rate,
+	.round_rate = clk_divider_round_rate,
+	.set_rate = clk_divider_set_rate,
+};
+
+static u8 clk_mux_get_parent(struct clk_hw *hw)
+{
+	struct lpc32xx_clk_mux *mux = to_lpc32xx_mux(hw);
+	int num_parents = clk_hw_get_num_parents(hw);
+	u32 val;
+
+	regmap_read(clk_regmap, mux->reg, &val);
+	val >>= mux->shift;
+	val &= mux->mask;
+
+	if (mux->table) {
+		int i;
+
+		for (i = 0; i < num_parents; i++)
+			if (mux->table[i] == val)
+				return i;
+		return -EINVAL;
+	}
+
+	if (val >= num_parents)
+		return -EINVAL;
+
+	return val;
+}
+
+static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct lpc32xx_clk_mux *mux = to_lpc32xx_mux(hw);
+
+	if (mux->table)
+		index = mux->table[index];
+
+	return regmap_update_bits(clk_regmap, mux->reg,
+			  mux->mask << mux->shift, index << mux->shift);
+}
+
+static const struct clk_ops lpc32xx_clk_mux_ro_ops = {
+	.get_parent = clk_mux_get_parent,
+};
+
+static const struct clk_ops lpc32xx_clk_mux_ops = {
+	.get_parent = clk_mux_get_parent,
+	.set_parent = clk_mux_set_parent,
+	.determine_rate = __clk_mux_determine_rate,
+};
+
+enum lpc32xx_clk_type {
+	CLK_FIXED,
+	CLK_MUX,
+	CLK_DIV,
+	CLK_GATE,
+	CLK_COMPOSITE,
+	CLK_LPC32XX,
+	CLK_LPC32XX_PLL,
+	CLK_LPC32XX_USB,
+};
+
+struct clk_hw_proto0 {
+	const struct clk_ops *ops;
+	union {
+		struct lpc32xx_pll_clk pll;
+		struct lpc32xx_clk clk;
+		struct lpc32xx_usb_clk usb_clk;
+		struct lpc32xx_clk_mux mux;
+		struct lpc32xx_clk_div div;
+		struct lpc32xx_clk_gate gate;
+	};
+};
+
+struct clk_hw_proto1 {
+	struct clk_hw_proto0 *mux;
+	struct clk_hw_proto0 *div;
+	struct clk_hw_proto0 *gate;
+};
+
+struct clk_hw_proto {
+	enum lpc32xx_clk_type type;
+
+	union {
+		struct clk_fixed_rate f;
+		struct clk_hw_proto0 hw0;
+		struct clk_hw_proto1 hw1;
+	};
+};
+
+#define LPC32XX_DEFINE_FIXED(_idx, _rate, _flags)			\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_FIXED,						\
+	{								\
+		.f = {							\
+			.fixed_rate = (_rate),				\
+			.flags = (_flags),				\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_PLL(_idx, _name, _reg, _enable)			\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_LPC32XX_PLL,					\
+	{								\
+		.hw0 = {						\
+			.ops = &clk_ ##_name ## _ops,			\
+			{						\
+				.pll = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.enable = (_enable),		\
+				},					\
+			},						\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_MUX(_idx, _reg, _shift, _mask, _table, _flags)	\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_MUX,						\
+	{								\
+		.hw0 = {						\
+			.ops = (_flags & CLK_MUX_READ_ONLY ?		\
+				&lpc32xx_clk_mux_ro_ops :		\
+				&lpc32xx_clk_mux_ops),			\
+			{						\
+				.mux = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.mask = (_mask),		\
+					.shift = (_shift),		\
+					.table = (_table),		\
+					.flags = (_flags),		\
+				},					\
+			},						\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_DIV(_idx, _reg, _shift, _width, _table, _flags)	\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_DIV,						\
+	{								\
+		.hw0 = {						\
+			.ops = &lpc32xx_clk_divider_ops,		\
+			{						\
+				.div = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.shift = (_shift),		\
+					.width = (_width),		\
+					.table = (_table),		\
+					.flags = (_flags),		\
+				 },					\
+			},						\
+		 },							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_GATE(_idx, _reg, _bit, _flags)			\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_GATE,						\
+	{								\
+		.hw0 = {						\
+			.ops = &lpc32xx_clk_gate_ops,			\
+			{						\
+				.gate = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.bit_idx = (_bit),		\
+					.flags = (_flags),		\
+				},					\
+			},						\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_CLK(_idx, _reg, _e, _em, _d, _dm, _b, _bm, _ops)	\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_LPC32XX,						\
+	{								\
+		.hw0 = {						\
+			.ops = &(_ops),					\
+			{						\
+				.clk = {				\
+					.reg = LPC32XX_CLKPWR_ ## _reg,	\
+					.enable = (_e),			\
+					.enable_mask = (_em),		\
+					.disable = (_d),		\
+					.disable_mask = (_dm),		\
+					.busy = (_b),			\
+					.busy_mask = (_bm),		\
+				},					\
+			},						\
+		},							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_USB(_idx, _ce, _cd, _cm, _e, _b, _ops)		\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_LPC32XX_USB,					\
+	{								\
+		.hw0 = {						\
+			.ops = &(_ops),					\
+			{						\
+				.usb_clk = {				\
+					.ctrl_enable = (_ce),		\
+					.ctrl_disable = (_cd),		\
+					.ctrl_mask = (_cm),		\
+					.enable = (_e),			\
+					.busy = (_b),			\
+				}					\
+			},						\
+		}							\
+	},								\
+}
+
+#define LPC32XX_DEFINE_COMPOSITE(_idx, _mux, _div, _gate)		\
+[CLK_PREFIX(_idx)] = {							\
+	.type = CLK_COMPOSITE,						\
+	{								\
+		.hw1 = {						\
+		.mux = (CLK_PREFIX(_mux) == LPC32XX_CLK__NULL ? NULL :	\
+			&clk_hw_proto[CLK_PREFIX(_mux)].hw0),		\
+		.div = (CLK_PREFIX(_div) == LPC32XX_CLK__NULL ? NULL :	\
+			&clk_hw_proto[CLK_PREFIX(_div)].hw0),		\
+		.gate = (CLK_PREFIX(_gate) == LPC32XX_CLK__NULL ? NULL :\
+			 &clk_hw_proto[CLK_PREFIX(_gate)].hw0),		\
+		},							\
+	},								\
+}
+
+static struct clk_hw_proto clk_hw_proto[LPC32XX_CLK_HW_MAX] = {
+	LPC32XX_DEFINE_FIXED(RTC, 32768, 0),
+	LPC32XX_DEFINE_PLL(PLL397X, pll_397x, HCLKPLL_CTRL, BIT(1)),
+	LPC32XX_DEFINE_PLL(HCLK_PLL, hclk_pll, HCLKPLL_CTRL, PLL_CTRL_ENABLE),
+	LPC32XX_DEFINE_PLL(USB_PLL, usb_pll, USB_CTRL, PLL_CTRL_ENABLE),
+	LPC32XX_DEFINE_GATE(OSC, OSC_CTRL, 0, CLK_GATE_SET_TO_DISABLE),
+	LPC32XX_DEFINE_GATE(USB, USB_CTRL, 18, 0),
+
+	LPC32XX_DEFINE_DIV(HCLK_DIV_PERIPH, HCLKDIV_CTRL, 2, 5, NULL,
+			   CLK_DIVIDER_READ_ONLY),
+	LPC32XX_DEFINE_DIV(HCLK_DIV, HCLKDIV_CTRL, 0, 2, clk_hclk_div_table,
+			   CLK_DIVIDER_READ_ONLY),
+
+	/* Register 3 read-only muxes with a single control PWR_CTRL[2] */
+	LPC32XX_DEFINE_MUX(SYSCLK_PERIPH_MUX, PWR_CTRL, 2, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+	LPC32XX_DEFINE_MUX(SYSCLK_HCLK_MUX, PWR_CTRL, 2, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+	LPC32XX_DEFINE_MUX(SYSCLK_ARM_MUX, PWR_CTRL, 2, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+	/* Register 2 read-only muxes with a single control PWR_CTRL[10] */
+	LPC32XX_DEFINE_MUX(PERIPH_HCLK_MUX, PWR_CTRL, 10, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+	LPC32XX_DEFINE_MUX(PERIPH_ARM_MUX, PWR_CTRL, 10, 0x1, NULL,
+			   CLK_MUX_READ_ONLY),
+
+	/* 3 always on gates with a single control PWR_CTRL[0] same as OSC */
+	LPC32XX_DEFINE_GATE(PERIPH, PWR_CTRL, 0, CLK_GATE_SET_TO_DISABLE),
+	LPC32XX_DEFINE_GATE(HCLK, PWR_CTRL, 0, CLK_GATE_SET_TO_DISABLE),
+	LPC32XX_DEFINE_GATE(ARM, PWR_CTRL, 0, CLK_GATE_SET_TO_DISABLE),
+
+	LPC32XX_DEFINE_GATE(ARM_VFP, DEBUG_CTRL, 4, 0),
+	LPC32XX_DEFINE_GATE(DMA, DMA_CLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_CLK(DDRAM, HCLKDIV_CTRL, 0x0, BIT(8) | BIT(7),
+		   0x0, BIT(8) | BIT(7), 0x0, BIT(1) | BIT(0), clk_ddram_ops),
+
+	LPC32XX_DEFINE_GATE(TIMER0, TIMCLK_CTRL1, 2, 0),
+	LPC32XX_DEFINE_GATE(TIMER1, TIMCLK_CTRL1, 3, 0),
+	LPC32XX_DEFINE_GATE(TIMER2, TIMCLK_CTRL1, 4, 0),
+	LPC32XX_DEFINE_GATE(TIMER3, TIMCLK_CTRL1, 5, 0),
+	LPC32XX_DEFINE_GATE(TIMER4, TIMCLK_CTRL1, 0, 0),
+	LPC32XX_DEFINE_GATE(TIMER5, TIMCLK_CTRL1, 1, 0),
+
+	LPC32XX_DEFINE_GATE(SSP0, SSP_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(SSP1, SSP_CTRL, 1, 0),
+	LPC32XX_DEFINE_GATE(SPI1, SPI_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(SPI2, SPI_CTRL, 4, 0),
+	LPC32XX_DEFINE_GATE(I2S0, I2S_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(I2S1, I2S_CTRL, 1, 0),
+	LPC32XX_DEFINE_GATE(I2C1, I2CCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(I2C2, I2CCLK_CTRL, 1, 0),
+	LPC32XX_DEFINE_GATE(WDOG, TIMCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(HSTIMER, TIMCLK_CTRL, 1, 0),
+
+	LPC32XX_DEFINE_GATE(KEY, KEYCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_GATE(MCPWM, TIMCLK_CTRL1, 6, 0),
+
+	LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0),
+	LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL,
+			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
+	LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE),
+
+	LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0),
+	LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL,
+			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
+	LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0),
+	LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE),
+
+	LPC32XX_DEFINE_MUX(UART3_MUX, UART3_CLK_CTRL, 16, 0x1, NULL, 0),
+	LPC32XX_DEFINE_CLK(UART3_DIV, UART3_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+	LPC32XX_DEFINE_GATE(UART3_GATE, UART_CLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_COMPOSITE(UART3, UART3_MUX, UART3_DIV, UART3_GATE),
+
+	LPC32XX_DEFINE_MUX(UART4_MUX, UART4_CLK_CTRL, 16, 0x1, NULL, 0),
+	LPC32XX_DEFINE_CLK(UART4_DIV, UART4_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+	LPC32XX_DEFINE_GATE(UART4_GATE, UART_CLK_CTRL, 1, 0),
+	LPC32XX_DEFINE_COMPOSITE(UART4, UART4_MUX, UART4_DIV, UART4_GATE),
+
+	LPC32XX_DEFINE_MUX(UART5_MUX, UART5_CLK_CTRL, 16, 0x1, NULL, 0),
+	LPC32XX_DEFINE_CLK(UART5_DIV, UART5_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+	LPC32XX_DEFINE_GATE(UART5_GATE, UART_CLK_CTRL, 2, 0),
+	LPC32XX_DEFINE_COMPOSITE(UART5, UART5_MUX, UART5_DIV, UART5_GATE),
+
+	LPC32XX_DEFINE_MUX(UART6_MUX, UART6_CLK_CTRL, 16, 0x1, NULL, 0),
+	LPC32XX_DEFINE_CLK(UART6_DIV, UART6_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+	LPC32XX_DEFINE_GATE(UART6_GATE, UART_CLK_CTRL, 3, 0),
+	LPC32XX_DEFINE_COMPOSITE(UART6, UART6_MUX, UART6_DIV, UART6_GATE),
+
+	LPC32XX_DEFINE_CLK(IRDA, IRDA_CLK_CTRL,
+			   0, 0, 0, 0, 0, 0, lpc32xx_uart_div_ops),
+
+	LPC32XX_DEFINE_MUX(TEST1_MUX, TEST_CLK_CTRL, 5, 0x3,
+			   test1_mux_table, 0),
+	LPC32XX_DEFINE_GATE(TEST1_GATE, TEST_CLK_CTRL, 4, 0),
+	LPC32XX_DEFINE_COMPOSITE(TEST1, TEST1_MUX, _NULL, TEST1_GATE),
+
+	LPC32XX_DEFINE_MUX(TEST2_MUX, TEST_CLK_CTRL, 1, 0x7,
+			   test2_mux_table, 0),
+	LPC32XX_DEFINE_GATE(TEST2_GATE, TEST_CLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_COMPOSITE(TEST2, TEST2_MUX, _NULL, TEST2_GATE),
+
+	LPC32XX_DEFINE_MUX(SYS, SYSCLK_CTRL, 0, 0x1, NULL, CLK_MUX_READ_ONLY),
+
+	LPC32XX_DEFINE_DIV(USB_DIV_DIV, USB_DIV, 0, 4, NULL, 0),
+	LPC32XX_DEFINE_GATE(USB_DIV_GATE, USB_CTRL, 17, 0),
+	LPC32XX_DEFINE_COMPOSITE(USB_DIV, _NULL, USB_DIV_DIV, USB_DIV_GATE),
+
+	LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL,
+			   CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
+	LPC32XX_DEFINE_CLK(SD_GATE, MS_CTRL, BIT(5) | BIT(9), BIT(5) | BIT(9),
+			   0x0, BIT(5) | BIT(9), 0x0, 0x0, clk_mask_ops),
+	LPC32XX_DEFINE_COMPOSITE(SD, _NULL, SD_DIV, SD_GATE),
+
+	LPC32XX_DEFINE_DIV(LCD_DIV, LCDCLK_CTRL, 0, 5, NULL, 0),
+	LPC32XX_DEFINE_GATE(LCD_GATE, LCDCLK_CTRL, 5, 0),
+	LPC32XX_DEFINE_COMPOSITE(LCD, _NULL, LCD_DIV, LCD_GATE),
+
+	LPC32XX_DEFINE_CLK(MAC, MACCLK_CTRL,
+			   BIT(2) | BIT(1) | BIT(0), BIT(2) | BIT(1) | BIT(0),
+			   BIT(2) | BIT(1) | BIT(0), BIT(2) | BIT(1) | BIT(0),
+			   0x0, 0x0, clk_mask_ops),
+	LPC32XX_DEFINE_CLK(SLC, FLASHCLK_CTRL,
+			   BIT(2) | BIT(0), BIT(2) | BIT(0), 0x0,
+			   BIT(0), BIT(1), BIT(2) | BIT(1), clk_mask_ops),
+	LPC32XX_DEFINE_CLK(MLC, FLASHCLK_CTRL,
+			   BIT(1), BIT(2) | BIT(1), 0x0, BIT(1),
+			   BIT(2) | BIT(0), BIT(2) | BIT(0), clk_mask_ops),
+	/*
+	 * ADC/TS clock unfortunately cannot be registered as a composite one
+	 * due to a different connection of gate, div and mux, e.g. gating it
+	 * won't mean that the clock is off, if peripheral clock is its parent:
+	 *
+	 * rtc-->[gate]-->|     |
+	 *                | mux |--> adc/ts
+	 * pclk-->[div]-->|     |
+	 *
+	 * Constraints:
+	 * ADC --- resulting clock must be <= 4.5 MHz
+	 * TS  --- resulting clock must be <= 400 KHz
+	 */
+	LPC32XX_DEFINE_DIV(ADC_DIV, ADCCLK_CTRL1, 0, 8, NULL, 0),
+	LPC32XX_DEFINE_GATE(ADC_RTC, ADCCLK_CTRL, 0, 0),
+	LPC32XX_DEFINE_MUX(ADC, ADCCLK_CTRL1, 8, 0x1, NULL, 0),
+
+	/* USB controller clocks */
+	LPC32XX_DEFINE_USB(USB_AHB,
+			   BIT(24), 0x0, BIT(24), BIT(4), 0, clk_usb_ops),
+	LPC32XX_DEFINE_USB(USB_OTG,
+			   0x0, 0x0, 0x0, BIT(3), 0, clk_usb_ops),
+	LPC32XX_DEFINE_USB(USB_I2C,
+			   0x0, BIT(23), BIT(23), BIT(2), 0, clk_usb_i2c_ops),
+	LPC32XX_DEFINE_USB(USB_DEV,
+			   BIT(22), 0x0, BIT(22), BIT(1), BIT(0), clk_usb_ops),
+	LPC32XX_DEFINE_USB(USB_HOST,
+			   BIT(21), 0x0, BIT(21), BIT(0), BIT(1), clk_usb_ops),
+};
+
+static struct clk * __init lpc32xx_clk_register(u32 id)
+{
+	const struct clk_proto_t *lpc32xx_clk = &clk_proto[id];
+	struct clk_hw_proto *clk_hw = &clk_hw_proto[id];
+	const char *parents[LPC32XX_CLK_PARENTS_MAX];
+	struct clk *clk;
+	unsigned int i;
+
+	for (i = 0; i < lpc32xx_clk->num_parents; i++)
+		parents[i] = clk_proto[lpc32xx_clk->parents[i]].name;
+
+	pr_debug("%s: derived from '%s', clock type %d\n", lpc32xx_clk->name,
+		 parents[0], clk_hw->type);
+
+	switch (clk_hw->type) {
+	case CLK_LPC32XX:
+	case CLK_LPC32XX_PLL:
+	case CLK_LPC32XX_USB:
+	case CLK_MUX:
+	case CLK_DIV:
+	case CLK_GATE:
+	{
+		struct clk_init_data clk_init = {
+			.name = lpc32xx_clk->name,
+			.parent_names = parents,
+			.num_parents = lpc32xx_clk->num_parents,
+			.flags = lpc32xx_clk->flags,
+			.ops = clk_hw->hw0.ops,
+		};
+		struct clk_hw *hw;
+
+		if (clk_hw->type == CLK_LPC32XX)
+			hw = &clk_hw->hw0.clk.hw;
+		else if (clk_hw->type == CLK_LPC32XX_PLL)
+			hw = &clk_hw->hw0.pll.hw;
+		else if (clk_hw->type == CLK_LPC32XX_USB)
+			hw = &clk_hw->hw0.usb_clk.hw;
+		else if (clk_hw->type == CLK_MUX)
+			hw = &clk_hw->hw0.mux.hw;
+		else if (clk_hw->type == CLK_DIV)
+			hw = &clk_hw->hw0.div.hw;
+		else if (clk_hw->type == CLK_GATE)
+			hw = &clk_hw->hw0.gate.hw;
+
+		hw->init = &clk_init;
+		clk = clk_register(NULL, hw);
+		break;
+	}
+	case CLK_COMPOSITE:
+	{
+		struct clk_hw *mux_hw = NULL, *div_hw = NULL, *gate_hw = NULL;
+		const struct clk_ops *mops = NULL, *dops = NULL, *gops = NULL;
+		struct clk_hw_proto0 *mux0, *div0, *gate0;
+
+		mux0 = clk_hw->hw1.mux;
+		div0 = clk_hw->hw1.div;
+		gate0 = clk_hw->hw1.gate;
+		if (mux0) {
+			mops = mux0->ops;
+			mux_hw = &mux0->clk.hw;
+		}
+		if (div0) {
+			dops = div0->ops;
+			div_hw = &div0->clk.hw;
+		}
+		if (gate0) {
+			gops = gate0->ops;
+			gate_hw = &gate0->clk.hw;
+		}
+
+		clk = clk_register_composite(NULL, lpc32xx_clk->name,
+				parents, lpc32xx_clk->num_parents,
+				mux_hw, mops, div_hw, dops,
+				gate_hw, gops, lpc32xx_clk->flags);
+		break;
+	}
+	case CLK_FIXED:
+	{
+		struct clk_fixed_rate *fixed = &clk_hw->f;
+
+		clk = clk_register_fixed_rate(NULL, lpc32xx_clk->name,
+			parents[0], fixed->flags, fixed->fixed_rate);
+		break;
+	}
+	default:
+		clk = ERR_PTR(-EINVAL);
+	}
+
+	return clk;
+}
+
+static void __init lpc32xx_clk_init(struct device_node *np)
+{
+	unsigned int i;
+	struct clk *clk_osc, *clk_32k;
+	void __iomem *base = NULL;
+
+	/* Ensure that parent clocks are available and valid */
+	clk_32k = of_clk_get_by_name(np, clk_proto[LPC32XX_CLK_XTAL_32K].name);
+	if (IS_ERR(clk_32k)) {
+		pr_err("failed to find external 32KHz clock: %ld\n",
+		       PTR_ERR(clk_32k));
+		return;
+	}
+	if (clk_get_rate(clk_32k) != 32768) {
+		pr_err("invalid clock rate of external 32KHz oscillator");
+		return;
+	}
+
+	clk_osc = of_clk_get_by_name(np, clk_proto[LPC32XX_CLK_XTAL].name);
+	if (IS_ERR(clk_osc)) {
+		pr_err("failed to find external main oscillator clock: %ld\n",
+		       PTR_ERR(clk_osc));
+		return;
+	}
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("failed to map system control block registers\n");
+		return;
+	}
+
+	clk_regmap = regmap_init_mmio(NULL, base, &lpc32xx_scb_regmap_config);
+	if (IS_ERR(clk_regmap)) {
+		pr_err("failed to regmap system control block: %ld\n",
+			PTR_ERR(clk_regmap));
+		return;
+	}
+
+	for (i = 0; i < LPC32XX_CLK_MAX; i++) {
+		clk[i] = lpc32xx_clk_register(i);
+		if (IS_ERR(clk[i])) {
+			pr_err("failed to register %s clock: %ld\n",
+				clk_proto[i].name, PTR_ERR(clk[i]));
+			clk[i] = NULL;
+		}
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+	/* For 13MHz osc valid output range of PLL is from 156MHz to 266.5MHz */
+	clk_set_rate(clk[LPC32XX_CLK_HCLK_PLL], 208000000);
+
+	/* Set 48MHz rate of USB PLL clock */
+	clk_set_rate(clk[LPC32XX_CLK_USB_PLL], 48000000);
+
+	/* These two clocks must be always on independently on consumers */
+	clk_prepare_enable(clk[LPC32XX_CLK_ARM]);
+	clk_prepare_enable(clk[LPC32XX_CLK_HCLK]);
+
+	/* Enable ARM VFP by default */
+	clk_prepare_enable(clk[LPC32XX_CLK_ARM_VFP]);
+
+	/* Disable enabled by default clocks for NAND MLC and SLC */
+	clk_mask_disable(&clk_hw_proto[LPC32XX_CLK_SLC].hw0.clk.hw);
+	clk_mask_disable(&clk_hw_proto[LPC32XX_CLK_MLC].hw0.clk.hw);
+}
+CLK_OF_DECLARE(lpc32xx_clk, "nxp,lpc3220-clk", lpc32xx_clk_init);
+
+static void __init lpc32xx_usb_clk_init(struct device_node *np)
+{
+	unsigned int i;
+
+	usb_clk_vbase = of_iomap(np, 0);
+	if (!usb_clk_vbase) {
+		pr_err("failed to map address range\n");
+		return;
+	}
+
+	for (i = 0; i < LPC32XX_USB_CLK_MAX; i++) {
+		usb_clk[i] = lpc32xx_clk_register(i + LPC32XX_CLK_USB_OFFSET);
+		if (IS_ERR(usb_clk[i])) {
+			pr_err("failed to register %s clock: %ld\n",
+				clk_proto[i].name, PTR_ERR(usb_clk[i]));
+			usb_clk[i] = NULL;
+		}
+	}
+
+	of_clk_add_provider(np, of_clk_src_onecell_get, &usb_clk_data);
+}
+CLK_OF_DECLARE(lpc32xx_usb_clk, "nxp,lpc3220-usb-clk", lpc32xx_usb_clk_init);
-- 
2.1.4

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

* [PATCH 10/11] arm: lpc32xx: switch to common clock framework
  2015-11-20  1:05 ` Vladimir Zapolskiy
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

The change switches NXP LPC32xx platforms to LPC32xx clock driver
powered by common clock framework, this obsoletes mach-lpc32xx/clock.o
legacy clock driver and thus it is removed.

Legacy timer driver mach-lpc32xx/timer.o strictly depends on legacy
clock support, but fortunately an existing LPC32xx clock source and
clock event driver completely replaces it, and thus it can be removed
as well.

Noticeably platform UART driver directly operates on LPC32xx source
control block registers, remove this dependency to avoid overlapping
with common clock framework driver, also this guarantees that UART is
working expectedly.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/Kconfig                |    3 +-
 arch/arm/mach-lpc32xx/Makefile  |    3 +-
 arch/arm/mach-lpc32xx/clock.c   | 1284 ---------------------------------------
 arch/arm/mach-lpc32xx/phy3250.c |    1 -
 arch/arm/mach-lpc32xx/serial.c  |    3 -
 arch/arm/mach-lpc32xx/timer.c   |  144 -----
 6 files changed, 3 insertions(+), 1435 deletions(-)
 delete mode 100644 arch/arm/mach-lpc32xx/clock.c
 delete mode 100644 arch/arm/mach-lpc32xx/timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c318277..5cc11f1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -592,7 +592,8 @@ config ARCH_LPC32XX
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_AMBA
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_LPC32XX
+	select COMMON_CLK
 	select CPU_ARM926T
 	select GENERIC_CLOCKEVENTS
 	select HAVE_IDE
diff --git a/arch/arm/mach-lpc32xx/Makefile b/arch/arm/mach-lpc32xx/Makefile
index f5db805..c70709a 100644
--- a/arch/arm/mach-lpc32xx/Makefile
+++ b/arch/arm/mach-lpc32xx/Makefile
@@ -2,7 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-obj-y	:= timer.o irq.o common.o serial.o clock.o
+obj-y	:= irq.o common.o serial.o
 obj-y	+= pm.o suspend.o
 obj-y	+= phy3250.o
-
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
deleted file mode 100644
index 661c8f4..0000000
--- a/arch/arm/mach-lpc32xx/clock.c
+++ /dev/null
@@ -1,1284 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/clock.c
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- *
- * 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.
- */
-
-/*
- * LPC32xx clock management driver overview
- *
- * The LPC32XX contains a number of high level system clocks that can be
- * generated from different sources. These system clocks are used to
- * generate the CPU and bus rates and the individual peripheral clocks in
- * the system. When Linux is started by the boot loader, the system
- * clocks are already running. Stopping a system clock during normal
- * Linux operation should never be attempted, as peripherals that require
- * those clocks will quit working (ie, DRAM).
- *
- * The LPC32xx high level clock tree looks as follows. Clocks marked with
- * an asterisk are always on and cannot be disabled. Clocks marked with
- * an ampersand can only be disabled in CPU suspend mode. Clocks marked
- * with a caret are always on if it is the selected clock for the SYSCLK
- * source. The clock that isn't used for SYSCLK can be enabled and
- * disabled normally.
- *                               32KHz oscillator*
- *                               /      |      \
- *                             RTC*   PLL397^ TOUCH
- *                                     /
- *               Main oscillator^     /
- *                   |        \      /
- *                   |         SYSCLK&
- *                   |            \
- *                   |             \
- *                USB_PLL       HCLK_PLL&
- *                   |           |    |
- *            USB host/device  PCLK&  |
- *                               |    |
- *                             Peripherals
- *
- * The CPU and chip bus rates are derived from the HCLK PLL, which can
- * generate various clock rates up to 266MHz and beyond. The internal bus
- * rates (PCLK and HCLK) are generated from dividers based on the HCLK
- * PLL rate. HCLK can be a ratio of 1:1, 1:2, or 1:4 or HCLK PLL rate,
- * while PCLK can be 1:1 to 1:32 of HCLK PLL rate. Most peripherals high
- * level clocks are based on either HCLK or PCLK, but have their own
- * dividers as part of the IP itself. Because of this, the system clock
- * rates should not be changed.
- *
- * The HCLK PLL is clocked from SYSCLK, which can be derived from the
- * main oscillator or PLL397. PLL397 generates a rate that is 397 times
- * the 32KHz oscillator rate. The main oscillator runs at the selected
- * oscillator/crystal rate on the mosc_in pin of the LPC32xx. This rate
- * is normally 13MHz, but depends on the selection of external crystals
- * or oscillators. If USB operation is required, the main oscillator must
- * be used in the system.
- *
- * Switching SYSCLK between sources during normal Linux operation is not
- * supported. SYSCLK is preset in the bootloader. Because of the
- * complexities of clock management during clock frequency changes,
- * there are some limitations to the clock driver explained below:
- * - The PLL397 and main oscillator can be enabled and disabled by the
- *   clk_enable() and clk_disable() functions unless SYSCLK is based
- *   on that clock. This allows the other oscillator that isn't driving
- *   the HCLK PLL to be used as another system clock that can be routed
- *   to an external pin.
- * - The muxed SYSCLK input and HCLK_PLL rate cannot be changed with
- *   this driver.
- * - HCLK and PCLK rates cannot be changed as part of this driver.
- * - Most peripherals have their own dividers are part of the peripheral
- *   block. Changing SYSCLK, HCLK PLL, HCLK, or PCLK sources or rates
- *   will also impact the individual peripheral rates.
- */
-
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/clcd.h>
-#include <linux/clkdev.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-#include "clock.h"
-#include "common.h"
-
-static DEFINE_SPINLOCK(global_clkregs_lock);
-
-static int usb_pll_enable, usb_pll_valid;
-
-static struct clk clk_armpll;
-static struct clk clk_usbpll;
-
-/*
- * Post divider values for PLLs based on selected register value
- */
-static const u32 pll_postdivs[4] = {1, 2, 4, 8};
-
-static unsigned long local_return_parent_rate(struct clk *clk)
-{
-	/*
-	 * If a clock has a rate of 0, then it inherits it's parent
-	 * clock rate
-	 */
-	while (clk->rate == 0)
-		clk = clk->parent;
-
-	return clk->rate;
-}
-
-/* 32KHz clock has a fixed rate and is not stoppable */
-static struct clk osc_32KHz = {
-	.rate		= LPC32XX_CLOCK_OSC_FREQ,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int local_pll397_enable(struct clk *clk, int enable)
-{
-	u32 reg;
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
-
-	reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL);
-
-	if (enable == 0) {
-		reg |= LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS;
-		__raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL);
-	} else {
-		/* Enable PLL397 */
-		reg &= ~LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS;
-		__raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL);
-
-		/* Wait for PLL397 lock */
-		while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
-			LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) &&
-			time_before(jiffies, timeout))
-			cpu_relax();
-
-		if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
-			LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0)
-			return -ENODEV;
-	}
-
-	return 0;
-}
-
-static int local_oscmain_enable(struct clk *clk, int enable)
-{
-	u32 reg;
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
-
-	reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL);
-
-	if (enable == 0) {
-		reg |= LPC32XX_CLKPWR_MOSC_DISABLE;
-		__raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL);
-	} else {
-		/* Enable main oscillator */
-		reg &= ~LPC32XX_CLKPWR_MOSC_DISABLE;
-		__raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL);
-
-		/* Wait for main oscillator to start */
-		while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
-			LPC32XX_CLKPWR_MOSC_DISABLE) != 0) &&
-			time_before(jiffies, timeout))
-			cpu_relax();
-
-		if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
-			LPC32XX_CLKPWR_MOSC_DISABLE) != 0)
-			return -ENODEV;
-	}
-
-	return 0;
-}
-
-static struct clk osc_pll397 = {
-	.parent		= &osc_32KHz,
-	.enable		= local_pll397_enable,
-	.rate		= LPC32XX_CLOCK_OSC_FREQ * 397,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk osc_main = {
-	.enable		= local_oscmain_enable,
-	.rate		= LPC32XX_MAIN_OSC_FREQ,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_sys;
-
-/*
- * Convert a PLL register value to a PLL output frequency
- */
-u32 clk_get_pllrate_from_reg(u32 inputclk, u32 regval)
-{
-	struct clk_pll_setup pllcfg;
-
-	pllcfg.cco_bypass_b15 = 0;
-	pllcfg.direct_output_b14 = 0;
-	pllcfg.fdbk_div_ctrl_b13 = 0;
-	if ((regval & LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS) != 0)
-		pllcfg.cco_bypass_b15 = 1;
-	if ((regval & LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS) != 0)
-		pllcfg.direct_output_b14 = 1;
-	if ((regval & LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK) != 0)
-		pllcfg.fdbk_div_ctrl_b13 = 1;
-	pllcfg.pll_m = 1 + ((regval >> 1) & 0xFF);
-	pllcfg.pll_n = 1 + ((regval >> 9) & 0x3);
-	pllcfg.pll_p = pll_postdivs[((regval >> 11) & 0x3)];
-
-	return clk_check_pll_setup(inputclk, &pllcfg);
-}
-
-/*
- * Setup the HCLK PLL with a PLL structure
- */
-static u32 local_clk_pll_setup(struct clk_pll_setup *PllSetup)
-{
-	u32 tv, tmp = 0;
-
-	if (PllSetup->analog_on != 0)
-		tmp |= LPC32XX_CLKPWR_HCLKPLL_POWER_UP;
-	if (PllSetup->cco_bypass_b15 != 0)
-		tmp |= LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS;
-	if (PllSetup->direct_output_b14 != 0)
-		tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS;
-	if (PllSetup->fdbk_div_ctrl_b13 != 0)
-		tmp |= LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK;
-
-	tv = ffs(PllSetup->pll_p) - 1;
-	if ((!is_power_of_2(PllSetup->pll_p)) || (tv > 3))
-		return 0;
-
-	tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(tv);
-	tmp |= LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(PllSetup->pll_n - 1);
-	tmp |= LPC32XX_CLKPWR_HCLKPLL_PLLM(PllSetup->pll_m - 1);
-
-	return tmp;
-}
-
-/*
- * Update the ARM core PLL frequency rate variable from the actual PLL setting
- */
-static void local_update_armpll_rate(void)
-{
-	u32 clkin, pllreg;
-
-	clkin = clk_armpll.parent->rate;
-	pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF;
-
-	clk_armpll.rate = clk_get_pllrate_from_reg(clkin, pllreg);
-}
-
-/*
- * Find a PLL configuration for the selected input frequency
- */
-static u32 local_clk_find_pll_cfg(u32 pllin_freq, u32 target_freq,
-	struct clk_pll_setup *pllsetup)
-{
-	u32 ifreq, freqtol, m, n, p, fclkout;
-
-	/* Determine frequency tolerance limits */
-	freqtol = target_freq / 250;
-	ifreq = pllin_freq;
-
-	/* Is direct bypass mode possible? */
-	if (abs(pllin_freq - target_freq) <= freqtol) {
-		pllsetup->analog_on = 0;
-		pllsetup->cco_bypass_b15 = 1;
-		pllsetup->direct_output_b14 = 1;
-		pllsetup->fdbk_div_ctrl_b13 = 1;
-		pllsetup->pll_p = pll_postdivs[0];
-		pllsetup->pll_n = 1;
-		pllsetup->pll_m = 1;
-		return clk_check_pll_setup(ifreq, pllsetup);
-	} else if (target_freq <= ifreq) {
-		pllsetup->analog_on = 0;
-		pllsetup->cco_bypass_b15 = 1;
-		pllsetup->direct_output_b14 = 0;
-		pllsetup->fdbk_div_ctrl_b13 = 1;
-		pllsetup->pll_n = 1;
-		pllsetup->pll_m = 1;
-		for (p = 0; p <= 3; p++) {
-			pllsetup->pll_p = pll_postdivs[p];
-			fclkout = clk_check_pll_setup(ifreq, pllsetup);
-			if (abs(target_freq - fclkout) <= freqtol)
-				return fclkout;
-		}
-	}
-
-	/* Is direct mode possible? */
-	pllsetup->analog_on = 1;
-	pllsetup->cco_bypass_b15 = 0;
-	pllsetup->direct_output_b14 = 1;
-	pllsetup->fdbk_div_ctrl_b13 = 0;
-	pllsetup->pll_p = pll_postdivs[0];
-	for (m = 1; m <= 256; m++) {
-		for (n = 1; n <= 4; n++) {
-			/* Compute output frequency for this value */
-			pllsetup->pll_n = n;
-			pllsetup->pll_m = m;
-			fclkout = clk_check_pll_setup(ifreq,
-				pllsetup);
-			if (abs(target_freq - fclkout) <=
-				freqtol)
-				return fclkout;
-		}
-	}
-
-	/* Is integer mode possible? */
-	pllsetup->analog_on = 1;
-	pllsetup->cco_bypass_b15 = 0;
-	pllsetup->direct_output_b14 = 0;
-	pllsetup->fdbk_div_ctrl_b13 = 1;
-	for (m = 1; m <= 256; m++) {
-		for (n = 1; n <= 4; n++) {
-			for (p = 0; p < 4; p++) {
-				/* Compute output frequency */
-				pllsetup->pll_p = pll_postdivs[p];
-				pllsetup->pll_n = n;
-				pllsetup->pll_m = m;
-				fclkout = clk_check_pll_setup(
-					ifreq, pllsetup);
-				if (abs(target_freq - fclkout) <= freqtol)
-					return fclkout;
-			}
-		}
-	}
-
-	/* Try non-integer mode */
-	pllsetup->analog_on = 1;
-	pllsetup->cco_bypass_b15 = 0;
-	pllsetup->direct_output_b14 = 0;
-	pllsetup->fdbk_div_ctrl_b13 = 0;
-	for (m = 1; m <= 256; m++) {
-		for (n = 1; n <= 4; n++) {
-			for (p = 0; p < 4; p++) {
-				/* Compute output frequency */
-				pllsetup->pll_p = pll_postdivs[p];
-				pllsetup->pll_n = n;
-				pllsetup->pll_m = m;
-				fclkout = clk_check_pll_setup(
-					ifreq, pllsetup);
-				if (abs(target_freq - fclkout) <= freqtol)
-					return fclkout;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static struct clk clk_armpll = {
-	.parent		= &clk_sys,
-	.get_rate	= local_return_parent_rate,
-};
-
-/*
- * Setup the USB PLL with a PLL structure
- */
-static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup)
-{
-	u32 reg, tmp = local_clk_pll_setup(pHCLKPllSetup);
-
-	reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL) & ~0x1FFFF;
-	reg |= tmp;
-	__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
-
-	return clk_check_pll_setup(clk_usbpll.parent->rate,
-		pHCLKPllSetup);
-}
-
-static int local_usbpll_enable(struct clk *clk, int enable)
-{
-	u32 reg;
-	int ret = 0;
-	unsigned long timeout = jiffies + msecs_to_jiffies(20);
-
-	reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
-
-	__raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 |
-		LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
-		LPC32XX_CLKPWR_USB_CTRL);
-	__raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1,
-		LPC32XX_CLKPWR_USB_CTRL);
-
-	if (enable && usb_pll_valid && usb_pll_enable) {
-		ret = -ENODEV;
-		/*
-		 * If the PLL rate has been previously set, then the rate
-		 * in the PLL register is valid and can be enabled here.
-		 * Otherwise, it needs to be enabled as part of setrate.
-		 */
-
-		/*
-		 * Gate clock into PLL
-		 */
-		reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
-		__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
-
-		/*
-		 * Enable PLL
-		 */
-		reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP;
-		__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
-
-		/*
-		 * Wait for PLL to lock
-		 */
-		while (time_before(jiffies, timeout) && (ret == -ENODEV)) {
-			reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
-			if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
-				ret = 0;
-			else
-				udelay(10);
-		}
-
-		/*
-		 * Gate clock from PLL if PLL is locked
-		 */
-		if (ret == 0) {
-			__raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2,
-				LPC32XX_CLKPWR_USB_CTRL);
-		} else {
-			__raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
-				LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
-				LPC32XX_CLKPWR_USB_CTRL);
-		}
-	} else if ((enable == 0) && usb_pll_valid  && usb_pll_enable) {
-		usb_pll_valid = 0;
-		usb_pll_enable = 0;
-	}
-
-	return ret;
-}
-
-static unsigned long local_usbpll_round_rate(struct clk *clk,
-	unsigned long rate)
-{
-	u32 clkin, usbdiv;
-	struct clk_pll_setup pllsetup;
-
-	/*
-	 * Unlike other clocks, this clock has a KHz input rate, so bump
-	 * it up to work with the PLL function
-	 */
-	rate = rate * 1000;
-
-	clkin = clk->get_rate(clk);
-	usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
-		LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
-	clkin = clkin / usbdiv;
-
-	/* Try to find a good rate setup */
-	if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
-		return 0;
-
-	return clk_check_pll_setup(clkin, &pllsetup);
-}
-
-static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -ENODEV;
-	u32 clkin, usbdiv;
-	struct clk_pll_setup pllsetup;
-
-	/*
-	 * Unlike other clocks, this clock has a KHz input rate, so bump
-	 * it up to work with the PLL function
-	 */
-	rate = rate * 1000;
-
-	clkin = clk->get_rate(clk->parent);
-	usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
-		LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
-	clkin = clkin / usbdiv;
-
-	/* Try to find a good rate setup */
-	if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
-		return -EINVAL;
-
-	/*
-	 * Disable PLL clocks during PLL change
-	 */
-	local_usbpll_enable(clk, 0);
-	pllsetup.analog_on = 0;
-	local_clk_usbpll_setup(&pllsetup);
-
-	/*
-	 * Start USB PLL and check PLL status
-	 */
-
-	usb_pll_valid = 1;
-	usb_pll_enable = 1;
-
-	ret = local_usbpll_enable(clk, 1);
-	if (ret >= 0)
-		clk->rate = clk_check_pll_setup(clkin, &pllsetup);
-
-	return ret;
-}
-
-static struct clk clk_usbpll = {
-	.parent		= &osc_main,
-	.set_rate	= local_usbpll_set_rate,
-	.enable		= local_usbpll_enable,
-	.rate		= 48000, /* In KHz */
-	.get_rate	= local_return_parent_rate,
-	.round_rate	= local_usbpll_round_rate,
-};
-
-static u32 clk_get_hclk_div(void)
-{
-	static const u32 hclkdivs[4] = {1, 2, 4, 4};
-	return hclkdivs[LPC32XX_CLKPWR_HCLKDIV_DIV_2POW(
-		__raw_readl(LPC32XX_CLKPWR_HCLK_DIV))];
-}
-
-static struct clk clk_hclk = {
-	.parent		= &clk_armpll,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_pclk = {
-	.parent		= &clk_armpll,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int local_onoff_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-
-	tmp = __raw_readl(clk->enable_reg);
-
-	if (enable == 0)
-		tmp &= ~clk->enable_mask;
-	else
-		tmp |= clk->enable_mask;
-
-	__raw_writel(tmp, clk->enable_reg);
-
-	return 0;
-}
-
-/* Peripheral clock sources */
-static struct clk clk_timer0 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_timer1 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_timer2 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_timer3 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_mpwm = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_MPWM_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_wdt = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMER_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_vfp9 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_DEBUG_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_dma = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_DMA_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_pwm = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_PWM_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_PWMCLK_PWM1CLK_EN |
-			  LPC32XX_CLKPWR_PWMCLK_PWM1SEL_PCLK |
-			  LPC32XX_CLKPWR_PWMCLK_PWM1_DIV(1) |
-			  LPC32XX_CLKPWR_PWMCLK_PWM2CLK_EN |
-			  LPC32XX_CLKPWR_PWMCLK_PWM2SEL_PCLK |
-			  LPC32XX_CLKPWR_PWMCLK_PWM2_DIV(1),
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_uart3 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_UART_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_uart4 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_UART_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_uart5 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_UART_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_uart6 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_UART_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_i2c0 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_I2C_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_i2c1 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_I2C_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_i2c2 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= io_p2v(LPC32XX_USB_BASE + 0xFF4),
-	.enable_mask	= 0x4,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_ssp0 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_SSP_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_ssp1 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_SSP_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_kscan = {
-	.parent		= &osc_32KHz,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_KEY_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_nand = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_NAND_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN |
-			  LPC32XX_CLKPWR_NANDCLK_SEL_SLC,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_nand_mlc = {
-	.parent         = &clk_hclk,
-	.enable         = local_onoff_enable,
-	.enable_reg     = LPC32XX_CLKPWR_NAND_CLK_CTRL,
-	.enable_mask    = LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN |
-			  LPC32XX_CLKPWR_NANDCLK_DMA_INT |
-			  LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC,
-	.get_rate       = local_return_parent_rate,
-};
-
-static struct clk clk_i2s0 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_I2S_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_i2s1 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_I2S_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN |
-			  LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_net = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_MACCLK_CTRL,
-	.enable_mask	= (LPC32XX_CLKPWR_MACCTRL_DMACLK_EN |
-		LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN |
-		LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN),
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_rtc = {
-	.parent		= &osc_32KHz,
-	.rate		= 1, /* 1 Hz */
-	.get_rate	= local_return_parent_rate,
-};
-
-static int local_usb_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-
-	if (enable) {
-		/* Set up I2C pull levels */
-		tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL);
-		tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE;
-		__raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL);
-	}
-
-	return local_onoff_enable(clk, enable);
-}
-
-static struct clk clk_usbd = {
-	.parent		= &clk_usbpll,
-	.enable		= local_usb_enable,
-	.enable_reg	= LPC32XX_CLKPWR_USB_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_USBCTRL_HCLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-#define OTG_ALWAYS_MASK		(LPC32XX_USB_OTG_OTG_CLOCK_ON | \
-				 LPC32XX_USB_OTG_I2C_CLOCK_ON)
-
-static int local_usb_otg_enable(struct clk *clk, int enable)
-{
-	int to = 1000;
-
-	if (enable) {
-		__raw_writel(clk->enable_mask, clk->enable_reg);
-
-		while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
-			clk->enable_mask) != clk->enable_mask) && (to > 0))
-			to--;
-	} else {
-		__raw_writel(OTG_ALWAYS_MASK, clk->enable_reg);
-
-		while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
-			OTG_ALWAYS_MASK) != OTG_ALWAYS_MASK) && (to > 0))
-			to--;
-	}
-
-	if (to)
-		return 0;
-	else
-		return -1;
-}
-
-static struct clk clk_usb_otg_dev = {
-	.parent		= &clk_usbpll,
-	.enable		= local_usb_otg_enable,
-	.enable_reg	= LPC32XX_USB_OTG_CLK_CTRL,
-	.enable_mask	= LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
-			  LPC32XX_USB_OTG_OTG_CLOCK_ON |
-			  LPC32XX_USB_OTG_DEV_CLOCK_ON |
-			  LPC32XX_USB_OTG_I2C_CLOCK_ON,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_usb_otg_host = {
-	.parent		= &clk_usbpll,
-	.enable		= local_usb_otg_enable,
-	.enable_reg	= LPC32XX_USB_OTG_CLK_CTRL,
-	.enable_mask	= LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
-			  LPC32XX_USB_OTG_OTG_CLOCK_ON |
-			  LPC32XX_USB_OTG_HOST_CLOCK_ON |
-			  LPC32XX_USB_OTG_I2C_CLOCK_ON,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int tsc_onoff_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-
-	/* Make sure 32KHz clock is the selected clock */
-	tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
-	tmp &= ~LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL;
-	__raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
-
-	if (enable == 0)
-		__raw_writel(0, clk->enable_reg);
-	else
-		__raw_writel(clk->enable_mask, clk->enable_reg);
-
-	return 0;
-}
-
-static struct clk clk_tsc = {
-	.parent		= &osc_32KHz,
-	.enable		= tsc_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_ADC_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int adc_onoff_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-	u32 divider;
-
-	/* Use PERIPH_CLOCK */
-	tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
-	tmp |= LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL;
-	/*
-	 * Set clock divider so that we have equal to or less than
-	 * 4.5MHz clock at ADC
-	 */
-	divider = clk->get_rate(clk) / 4500000 + 1;
-	tmp |= divider;
-	__raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
-
-	/* synchronize rate of this clock w/ actual HW setting */
-	clk->rate = clk->get_rate(clk->parent) / divider;
-
-	if (enable == 0)
-		__raw_writel(0, clk->enable_reg);
-	else
-		__raw_writel(clk->enable_mask, clk->enable_reg);
-
-	return 0;
-}
-
-static struct clk clk_adc = {
-	.parent		= &clk_pclk,
-	.enable		= adc_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_ADC_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int mmc_onoff_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-
-	tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) &
-		~(LPC32XX_CLKPWR_MSCARD_SDCARD_EN |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO_PIN_DIS |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO0_DIS |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO1_DIS |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO23_DIS);
-
-	/* If rate is 0, disable clock */
-	if (enable != 0)
-		tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN |
-			LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN;
-
-	__raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL);
-
-	return 0;
-}
-
-static unsigned long mmc_get_rate(struct clk *clk)
-{
-	u32 div, rate, oldclk;
-
-	/* The MMC clock must be on when accessing an MMC register */
-	oldclk = __raw_readl(LPC32XX_CLKPWR_MS_CTRL);
-	__raw_writel(oldclk | LPC32XX_CLKPWR_MSCARD_SDCARD_EN,
-		LPC32XX_CLKPWR_MS_CTRL);
-	div = __raw_readl(LPC32XX_CLKPWR_MS_CTRL);
-	__raw_writel(oldclk, LPC32XX_CLKPWR_MS_CTRL);
-
-	/* Get the parent clock rate */
-	rate = clk->parent->get_rate(clk->parent);
-
-	/* Get the MMC controller clock divider value */
-	div = div & LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf);
-
-	if (!div)
-		div = 1;
-
-	return rate / div;
-}
-
-static unsigned long mmc_round_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long div, prate;
-
-	/* Get the parent clock rate */
-	prate = clk->parent->get_rate(clk->parent);
-
-	if (rate >= prate)
-		return prate;
-
-	div = prate / rate;
-	if (div > 0xf)
-		div = 0xf;
-
-	return prate / div;
-}
-
-static int mmc_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 tmp;
-	unsigned long prate, div, crate = mmc_round_rate(clk, rate);
-
-	prate = clk->parent->get_rate(clk->parent);
-
-	div = prate / crate;
-
-	/* The MMC clock must be on when accessing an MMC register */
-	tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) &
-		~LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf);
-	tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(div) |
-		LPC32XX_CLKPWR_MSCARD_SDCARD_EN;
-	__raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL);
-
-	return 0;
-}
-
-static struct clk clk_mmc = {
-	.parent		= &clk_armpll,
-	.set_rate	= mmc_set_rate,
-	.get_rate	= mmc_get_rate,
-	.round_rate	= mmc_round_rate,
-	.enable		= mmc_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_MS_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_MSCARD_SDCARD_EN,
-};
-
-static unsigned long clcd_get_rate(struct clk *clk)
-{
-	u32 tmp, div, rate, oldclk;
-
-	/* The LCD clock must be on when accessing an LCD register */
-	oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL);
-	__raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
-		LPC32XX_CLKPWR_LCDCLK_CTRL);
-	tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2));
-	__raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL);
-
-	rate = clk->parent->get_rate(clk->parent);
-
-	/* Only supports internal clocking */
-	if (tmp & TIM2_BCD)
-		return rate;
-
-	div = (tmp & 0x1F) | ((tmp & 0xF8) >> 22);
-	tmp = rate / (2 + div);
-
-	return tmp;
-}
-
-static int clcd_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 tmp, prate, div, oldclk;
-
-	/* The LCD clock must be on when accessing an LCD register */
-	oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL);
-	__raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
-		LPC32XX_CLKPWR_LCDCLK_CTRL);
-
-	tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)) | TIM2_BCD;
-	prate = clk->parent->get_rate(clk->parent);
-
-	if (rate < prate) {
-		/* Find closest divider */
-		div = prate / rate;
-		if (div >= 2) {
-			div -= 2;
-			tmp &= ~TIM2_BCD;
-		}
-
-		tmp &= ~(0xF800001F);
-		tmp |= (div & 0x1F);
-		tmp |= (((div >> 5) & 0x1F) << 27);
-	}
-
-	__raw_writel(tmp, io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2));
-	__raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL);
-
-	return 0;
-}
-
-static unsigned long clcd_round_rate(struct clk *clk, unsigned long rate)
-{
-	u32 prate, div;
-
-	prate = clk->parent->get_rate(clk->parent);
-
-	if (rate >= prate)
-		rate = prate;
-	else {
-		div = prate / rate;
-		if (div > 0x3ff)
-			div = 0x3ff;
-
-		rate = prate / div;
-	}
-
-	return rate;
-}
-
-static struct clk clk_lcd = {
-	.parent		= &clk_hclk,
-	.set_rate	= clcd_set_rate,
-	.get_rate	= clcd_get_rate,
-	.round_rate	= clcd_round_rate,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_LCDCLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
-};
-
-static void local_clk_disable(struct clk *clk)
-{
-	/* Don't attempt to disable clock if it has no users */
-	if (clk->usecount > 0) {
-		clk->usecount--;
-
-		/* Only disable clock when it has no more users */
-		if ((clk->usecount == 0) && (clk->enable))
-			clk->enable(clk, 0);
-
-		/* Check parent clocks, they may need to be disabled too */
-		if (clk->parent)
-			local_clk_disable(clk->parent);
-	}
-}
-
-static int local_clk_enable(struct clk *clk)
-{
-	int ret = 0;
-
-	/* Enable parent clocks first and update use counts */
-	if (clk->parent)
-		ret = local_clk_enable(clk->parent);
-
-	if (!ret) {
-		/* Only enable clock if it's currently disabled */
-		if ((clk->usecount == 0) && (clk->enable))
-			ret = clk->enable(clk, 1);
-
-		if (!ret)
-			clk->usecount++;
-		else if (clk->parent)
-			local_clk_disable(clk->parent);
-	}
-
-	return ret;
-}
-
-/*
- * clk_enable - inform the system when the clock source should be running.
- */
-int clk_enable(struct clk *clk)
-{
-	int ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&global_clkregs_lock, flags);
-	ret = local_clk_enable(clk);
-	spin_unlock_irqrestore(&global_clkregs_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_enable);
-
-/*
- * clk_disable - inform the system when the clock source is no longer required
- */
-void clk_disable(struct clk *clk)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&global_clkregs_lock, flags);
-	local_clk_disable(clk);
-	spin_unlock_irqrestore(&global_clkregs_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-/*
- * clk_get_rate - obtain the current clock rate (in Hz) for a clock source
- */
-unsigned long clk_get_rate(struct clk *clk)
-{
-	return clk->get_rate(clk);
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-/*
- * clk_set_rate - set the clock rate for a clock source
- */
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -EINVAL;
-
-	/*
-	 * Most system clocks can only be enabled or disabled, with
-	 * the actual rate set as part of the peripheral dividers
-	 * instead of high level clock control
-	 */
-	if (clk->set_rate)
-		ret = clk->set_rate(clk, rate);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-/*
- * clk_round_rate - adjust a rate to the exact rate a clock can provide
- */
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (clk->round_rate)
-		rate = clk->round_rate(clk, rate);
-	else
-		rate = clk->get_rate(clk);
-
-	return rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-/*
- * clk_set_parent - set the parent clock source for this clock
- */
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	/* Clock re-parenting is not supported */
-	return -EINVAL;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-/*
- * clk_get_parent - get the parent clock source for this clock
- */
-struct clk *clk_get_parent(struct clk *clk)
-{
-	return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-static struct clk_lookup lookups[] = {
-	CLKDEV_INIT(NULL, "osc_32KHz", &osc_32KHz),
-	CLKDEV_INIT(NULL, "osc_pll397", &osc_pll397),
-	CLKDEV_INIT(NULL, "osc_main", &osc_main),
-	CLKDEV_INIT(NULL, "sys_ck", &clk_sys),
-	CLKDEV_INIT(NULL, "arm_pll_ck", &clk_armpll),
-	CLKDEV_INIT(NULL, "ck_pll5", &clk_usbpll),
-	CLKDEV_INIT(NULL, "hclk_ck", &clk_hclk),
-	CLKDEV_INIT(NULL, "pclk_ck", &clk_pclk),
-	CLKDEV_INIT(NULL, "timer0_ck", &clk_timer0),
-	CLKDEV_INIT(NULL, "timer1_ck", &clk_timer1),
-	CLKDEV_INIT(NULL, "timer2_ck", &clk_timer2),
-	CLKDEV_INIT(NULL, "timer3_ck", &clk_timer3),
-	CLKDEV_INIT(NULL, "vfp9_ck", &clk_vfp9),
-	CLKDEV_INIT("pl08xdmac", NULL, &clk_dma),
-	CLKDEV_INIT("4003c000.watchdog", NULL, &clk_wdt),
-	CLKDEV_INIT("4005c000.pwm", NULL, &clk_pwm),
-	CLKDEV_INIT("400e8000.mpwm", NULL, &clk_mpwm),
-	CLKDEV_INIT(NULL, "uart3_ck", &clk_uart3),
-	CLKDEV_INIT(NULL, "uart4_ck", &clk_uart4),
-	CLKDEV_INIT(NULL, "uart5_ck", &clk_uart5),
-	CLKDEV_INIT(NULL, "uart6_ck", &clk_uart6),
-	CLKDEV_INIT("400a0000.i2c", NULL, &clk_i2c0),
-	CLKDEV_INIT("400a8000.i2c", NULL, &clk_i2c1),
-	CLKDEV_INIT("31020300.i2c", NULL, &clk_i2c2),
-	CLKDEV_INIT("dev:ssp0", NULL, &clk_ssp0),
-	CLKDEV_INIT("dev:ssp1", NULL, &clk_ssp1),
-	CLKDEV_INIT("40050000.key", NULL, &clk_kscan),
-	CLKDEV_INIT("20020000.flash", NULL, &clk_nand),
-	CLKDEV_INIT("200a8000.flash", NULL, &clk_nand_mlc),
-	CLKDEV_INIT("40048000.adc", NULL, &clk_adc),
-	CLKDEV_INIT(NULL, "i2s0_ck", &clk_i2s0),
-	CLKDEV_INIT(NULL, "i2s1_ck", &clk_i2s1),
-	CLKDEV_INIT("40048000.tsc", NULL, &clk_tsc),
-	CLKDEV_INIT("20098000.sd", NULL, &clk_mmc),
-	CLKDEV_INIT("31060000.ethernet", NULL, &clk_net),
-	CLKDEV_INIT("dev:clcd", NULL, &clk_lcd),
-	CLKDEV_INIT("31020000.usbd", "ck_usbd", &clk_usbd),
-	CLKDEV_INIT("31020000.ohci", "ck_usbd", &clk_usbd),
-	CLKDEV_INIT("31020000.usbd", "ck_usb_otg", &clk_usb_otg_dev),
-	CLKDEV_INIT("31020000.ohci", "ck_usb_otg", &clk_usb_otg_host),
-	CLKDEV_INIT("lpc32xx_rtc", NULL, &clk_rtc),
-};
-
-static int __init clk_init(void)
-{
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
-	/*
-	 * Setup muxed SYSCLK for HCLK PLL base -this selects the
-	 * parent clock used for the ARM PLL and is used to derive
-	 * the many system clock rates in the device.
-	 */
-	if (clk_is_sysclk_mainosc() != 0)
-		clk_sys.parent = &osc_main;
-	else
-		clk_sys.parent = &osc_pll397;
-
-	clk_sys.rate = clk_sys.parent->rate;
-
-	/* Compute the current ARM PLL and USB PLL frequencies */
-	local_update_armpll_rate();
-
-	/* Compute HCLK and PCLK bus rates */
-	clk_hclk.rate = clk_hclk.parent->rate / clk_get_hclk_div();
-	clk_pclk.rate = clk_pclk.parent->rate / clk_get_pclk_div();
-
-	/*
-	 * Enable system clocks - this step is somewhat formal, as the
-	 * clocks are already running, but it does get the clock data
-	 * inline with the actual system state. Never disable these
-	 * clocks as they will only stop if the system is going to sleep.
-	 * In that case, the chip/system power management functions will
-	 * handle clock gating.
-	 */
-	if (clk_enable(&clk_hclk) || clk_enable(&clk_pclk))
-		printk(KERN_ERR "Error enabling system HCLK and PCLK\n");
-
-	/*
-	 * Timers 0 and 1 were enabled and are being used by the high
-	 * resolution tick function prior to this driver being initialized.
-	 * Tag them now as used.
-	 */
-	if (clk_enable(&clk_timer0) || clk_enable(&clk_timer1))
-		printk(KERN_ERR "Error enabling timer tick clocks\n");
-
-	return 0;
-}
-core_initcall(clk_init);
-
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index 77d6b1b..60f3392 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -260,7 +260,6 @@ DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)")
 	.atag_offset	= 0x100,
 	.map_io		= lpc32xx_map_io,
 	.init_irq	= lpc32xx_init_irq,
-	.init_time	= lpc32xx_timer_init,
 	.init_machine	= lpc3250_machine_init,
 	.dt_compat	= lpc32xx_dt_compat,
 	.restart	= lpc23xx_restart,
diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c
index 05621a2..1931229 100644
--- a/arch/arm/mach-lpc32xx/serial.c
+++ b/arch/arm/mach-lpc32xx/serial.c
@@ -76,9 +76,6 @@ void __init lpc32xx_serial_init(void)
 	unsigned int puart;
 	int i, j;
 
-	/* UART clocks are off, let clock driver manage them */
-	__raw_writel(0, LPC32XX_CLKPWR_UART_CLK_CTRL);
-
 	for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) {
 		clk = clk_get(NULL, uartinit_data[i].uart_ck_name);
 		if (!IS_ERR(clk)) {
diff --git a/arch/arm/mach-lpc32xx/timer.c b/arch/arm/mach-lpc32xx/timer.c
deleted file mode 100644
index ff3499d..0000000
--- a/arch/arm/mach-lpc32xx/timer.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/timer.c
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2009 - 2010 NXP Semiconductors
- * Copyright (C) 2009 Fontys University of Applied Sciences, Eindhoven
- *                    Ed Schouten <e.schouten@fontys.nl>
- *                    Laurens Timmermans <l.timmermans@fontys.nl>
- *
- * 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/interrupt.h>
-#include <linux/irq.h>
-#include <linux/time.h>
-#include <linux/err.h>
-#include <linux/clockchips.h>
-
-#include <asm/mach/time.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-#include "common.h"
-
-static int lpc32xx_clkevt_next_event(unsigned long delta,
-    struct clock_event_device *dev)
-{
-	__raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET,
-		LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-	__raw_writel(delta, LPC32XX_TIMER_PR(LPC32XX_TIMER0_BASE));
-	__raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
-		LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-
-	return 0;
-}
-
-static int lpc32xx_shutdown(struct clock_event_device *evt)
-{
-	/*
-	 * Disable the timer. When using oneshot, we must also
-	 * disable the timer to wait for the first call to
-	 * set_next_event().
-	 */
-	__raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-	return 0;
-}
-
-static struct clock_event_device lpc32xx_clkevt = {
-	.name			= "lpc32xx_clkevt",
-	.features		= CLOCK_EVT_FEAT_ONESHOT,
-	.rating			= 300,
-	.set_next_event		= lpc32xx_clkevt_next_event,
-	.set_state_shutdown	= lpc32xx_shutdown,
-	.set_state_oneshot	= lpc32xx_shutdown,
-};
-
-static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = &lpc32xx_clkevt;
-
-	/* Clear match */
-	__raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
-		LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction lpc32xx_timer_irq = {
-	.name		= "LPC32XX Timer Tick",
-	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= lpc32xx_timer_interrupt,
-};
-
-/*
- * The clock management driver isn't initialized at this point, so the
- * clocks need to be enabled here manually and then tagged as used in
- * the clock driver initialization
- */
-void __init lpc32xx_timer_init(void)
-{
-	u32 clkrate, pllreg;
-
-	/* Enable timer clock */
-	__raw_writel(LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN |
-		LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN,
-		LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1);
-
-	/*
-	 * The clock driver isn't initialized at this point. So determine if
-	 * the SYSCLK is driven from the PLL397 or main oscillator and then use
-	 * it to compute the PLL frequency and the PCLK divider to get the base
-	 * timer rates. This rate is needed to compute the tick rate.
-	 */
-	if (clk_is_sysclk_mainosc() != 0)
-		clkrate = LPC32XX_MAIN_OSC_FREQ;
-	else
-		clkrate = 397 * LPC32XX_CLOCK_OSC_FREQ;
-
-	/* Get ARM HCLKPLL register and convert it into a frequency */
-	pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF;
-	clkrate = clk_get_pllrate_from_reg(clkrate, pllreg);
-
-	/* Get PCLK divider and divide ARM PLL clock by it to get timer rate */
-	clkrate = clkrate / clk_get_pclk_div();
-
-	/* Initial timer setup */
-	__raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-	__raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
-		LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
-	__raw_writel(1, LPC32XX_TIMER_MR0(LPC32XX_TIMER0_BASE));
-	__raw_writel(LPC32XX_TIMER_CNTR_MCR_MTCH(0) |
-		LPC32XX_TIMER_CNTR_MCR_STOP(0) |
-		LPC32XX_TIMER_CNTR_MCR_RESET(0),
-		LPC32XX_TIMER_MCR(LPC32XX_TIMER0_BASE));
-
-	/* Setup tick interrupt */
-	setup_irq(IRQ_LPC32XX_TIMER0, &lpc32xx_timer_irq);
-
-	/* Setup the clockevent structure. */
-	lpc32xx_clkevt.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&lpc32xx_clkevt, clkrate, 1, -1);
-
-	/* Use timer1 as clock source. */
-	__raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET,
-		LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
-	__raw_writel(0, LPC32XX_TIMER_PR(LPC32XX_TIMER1_BASE));
-	__raw_writel(0, LPC32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
-	__raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
-		LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
-
-	clocksource_mmio_init(LPC32XX_TIMER_TC(LPC32XX_TIMER1_BASE),
-		"lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up);
-}
-- 
2.1.4


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

* [PATCH 10/11] arm: lpc32xx: switch to common clock framework
@ 2015-11-20  1:05   ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

The change switches NXP LPC32xx platforms to LPC32xx clock driver
powered by common clock framework, this obsoletes mach-lpc32xx/clock.o
legacy clock driver and thus it is removed.

Legacy timer driver mach-lpc32xx/timer.o strictly depends on legacy
clock support, but fortunately an existing LPC32xx clock source and
clock event driver completely replaces it, and thus it can be removed
as well.

Noticeably platform UART driver directly operates on LPC32xx source
control block registers, remove this dependency to avoid overlapping
with common clock framework driver, also this guarantees that UART is
working expectedly.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/Kconfig                |    3 +-
 arch/arm/mach-lpc32xx/Makefile  |    3 +-
 arch/arm/mach-lpc32xx/clock.c   | 1284 ---------------------------------------
 arch/arm/mach-lpc32xx/phy3250.c |    1 -
 arch/arm/mach-lpc32xx/serial.c  |    3 -
 arch/arm/mach-lpc32xx/timer.c   |  144 -----
 6 files changed, 3 insertions(+), 1435 deletions(-)
 delete mode 100644 arch/arm/mach-lpc32xx/clock.c
 delete mode 100644 arch/arm/mach-lpc32xx/timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c318277..5cc11f1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -592,7 +592,8 @@ config ARCH_LPC32XX
 	select ARCH_REQUIRE_GPIOLIB
 	select ARM_AMBA
 	select CLKDEV_LOOKUP
-	select CLKSRC_MMIO
+	select CLKSRC_LPC32XX
+	select COMMON_CLK
 	select CPU_ARM926T
 	select GENERIC_CLOCKEVENTS
 	select HAVE_IDE
diff --git a/arch/arm/mach-lpc32xx/Makefile b/arch/arm/mach-lpc32xx/Makefile
index f5db805..c70709a 100644
--- a/arch/arm/mach-lpc32xx/Makefile
+++ b/arch/arm/mach-lpc32xx/Makefile
@@ -2,7 +2,6 @@
 # Makefile for the linux kernel.
 #
 
-obj-y	:= timer.o irq.o common.o serial.o clock.o
+obj-y	:= irq.o common.o serial.o
 obj-y	+= pm.o suspend.o
 obj-y	+= phy3250.o
-
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
deleted file mode 100644
index 661c8f4..0000000
--- a/arch/arm/mach-lpc32xx/clock.c
+++ /dev/null
@@ -1,1284 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/clock.c
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- *
- * 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.
- */
-
-/*
- * LPC32xx clock management driver overview
- *
- * The LPC32XX contains a number of high level system clocks that can be
- * generated from different sources. These system clocks are used to
- * generate the CPU and bus rates and the individual peripheral clocks in
- * the system. When Linux is started by the boot loader, the system
- * clocks are already running. Stopping a system clock during normal
- * Linux operation should never be attempted, as peripherals that require
- * those clocks will quit working (ie, DRAM).
- *
- * The LPC32xx high level clock tree looks as follows. Clocks marked with
- * an asterisk are always on and cannot be disabled. Clocks marked with
- * an ampersand can only be disabled in CPU suspend mode. Clocks marked
- * with a caret are always on if it is the selected clock for the SYSCLK
- * source. The clock that isn't used for SYSCLK can be enabled and
- * disabled normally.
- *                               32KHz oscillator*
- *                               /      |      \
- *                             RTC*   PLL397^ TOUCH
- *                                     /
- *               Main oscillator^     /
- *                   |        \      /
- *                   |         SYSCLK&
- *                   |            \
- *                   |             \
- *                USB_PLL       HCLK_PLL&
- *                   |           |    |
- *            USB host/device  PCLK&  |
- *                               |    |
- *                             Peripherals
- *
- * The CPU and chip bus rates are derived from the HCLK PLL, which can
- * generate various clock rates up to 266MHz and beyond. The internal bus
- * rates (PCLK and HCLK) are generated from dividers based on the HCLK
- * PLL rate. HCLK can be a ratio of 1:1, 1:2, or 1:4 or HCLK PLL rate,
- * while PCLK can be 1:1 to 1:32 of HCLK PLL rate. Most peripherals high
- * level clocks are based on either HCLK or PCLK, but have their own
- * dividers as part of the IP itself. Because of this, the system clock
- * rates should not be changed.
- *
- * The HCLK PLL is clocked from SYSCLK, which can be derived from the
- * main oscillator or PLL397. PLL397 generates a rate that is 397 times
- * the 32KHz oscillator rate. The main oscillator runs at the selected
- * oscillator/crystal rate on the mosc_in pin of the LPC32xx. This rate
- * is normally 13MHz, but depends on the selection of external crystals
- * or oscillators. If USB operation is required, the main oscillator must
- * be used in the system.
- *
- * Switching SYSCLK between sources during normal Linux operation is not
- * supported. SYSCLK is preset in the bootloader. Because of the
- * complexities of clock management during clock frequency changes,
- * there are some limitations to the clock driver explained below:
- * - The PLL397 and main oscillator can be enabled and disabled by the
- *   clk_enable() and clk_disable() functions unless SYSCLK is based
- *   on that clock. This allows the other oscillator that isn't driving
- *   the HCLK PLL to be used as another system clock that can be routed
- *   to an external pin.
- * - The muxed SYSCLK input and HCLK_PLL rate cannot be changed with
- *   this driver.
- * - HCLK and PCLK rates cannot be changed as part of this driver.
- * - Most peripherals have their own dividers are part of the peripheral
- *   block. Changing SYSCLK, HCLK PLL, HCLK, or PCLK sources or rates
- *   will also impact the individual peripheral rates.
- */
-
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/clcd.h>
-#include <linux/clkdev.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-#include "clock.h"
-#include "common.h"
-
-static DEFINE_SPINLOCK(global_clkregs_lock);
-
-static int usb_pll_enable, usb_pll_valid;
-
-static struct clk clk_armpll;
-static struct clk clk_usbpll;
-
-/*
- * Post divider values for PLLs based on selected register value
- */
-static const u32 pll_postdivs[4] = {1, 2, 4, 8};
-
-static unsigned long local_return_parent_rate(struct clk *clk)
-{
-	/*
-	 * If a clock has a rate of 0, then it inherits it's parent
-	 * clock rate
-	 */
-	while (clk->rate == 0)
-		clk = clk->parent;
-
-	return clk->rate;
-}
-
-/* 32KHz clock has a fixed rate and is not stoppable */
-static struct clk osc_32KHz = {
-	.rate		= LPC32XX_CLOCK_OSC_FREQ,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int local_pll397_enable(struct clk *clk, int enable)
-{
-	u32 reg;
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
-
-	reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL);
-
-	if (enable == 0) {
-		reg |= LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS;
-		__raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL);
-	} else {
-		/* Enable PLL397 */
-		reg &= ~LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS;
-		__raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL);
-
-		/* Wait for PLL397 lock */
-		while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
-			LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) &&
-			time_before(jiffies, timeout))
-			cpu_relax();
-
-		if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) &
-			LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0)
-			return -ENODEV;
-	}
-
-	return 0;
-}
-
-static int local_oscmain_enable(struct clk *clk, int enable)
-{
-	u32 reg;
-	unsigned long timeout = jiffies + msecs_to_jiffies(10);
-
-	reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL);
-
-	if (enable == 0) {
-		reg |= LPC32XX_CLKPWR_MOSC_DISABLE;
-		__raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL);
-	} else {
-		/* Enable main oscillator */
-		reg &= ~LPC32XX_CLKPWR_MOSC_DISABLE;
-		__raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL);
-
-		/* Wait for main oscillator to start */
-		while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
-			LPC32XX_CLKPWR_MOSC_DISABLE) != 0) &&
-			time_before(jiffies, timeout))
-			cpu_relax();
-
-		if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) &
-			LPC32XX_CLKPWR_MOSC_DISABLE) != 0)
-			return -ENODEV;
-	}
-
-	return 0;
-}
-
-static struct clk osc_pll397 = {
-	.parent		= &osc_32KHz,
-	.enable		= local_pll397_enable,
-	.rate		= LPC32XX_CLOCK_OSC_FREQ * 397,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk osc_main = {
-	.enable		= local_oscmain_enable,
-	.rate		= LPC32XX_MAIN_OSC_FREQ,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_sys;
-
-/*
- * Convert a PLL register value to a PLL output frequency
- */
-u32 clk_get_pllrate_from_reg(u32 inputclk, u32 regval)
-{
-	struct clk_pll_setup pllcfg;
-
-	pllcfg.cco_bypass_b15 = 0;
-	pllcfg.direct_output_b14 = 0;
-	pllcfg.fdbk_div_ctrl_b13 = 0;
-	if ((regval & LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS) != 0)
-		pllcfg.cco_bypass_b15 = 1;
-	if ((regval & LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS) != 0)
-		pllcfg.direct_output_b14 = 1;
-	if ((regval & LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK) != 0)
-		pllcfg.fdbk_div_ctrl_b13 = 1;
-	pllcfg.pll_m = 1 + ((regval >> 1) & 0xFF);
-	pllcfg.pll_n = 1 + ((regval >> 9) & 0x3);
-	pllcfg.pll_p = pll_postdivs[((regval >> 11) & 0x3)];
-
-	return clk_check_pll_setup(inputclk, &pllcfg);
-}
-
-/*
- * Setup the HCLK PLL with a PLL structure
- */
-static u32 local_clk_pll_setup(struct clk_pll_setup *PllSetup)
-{
-	u32 tv, tmp = 0;
-
-	if (PllSetup->analog_on != 0)
-		tmp |= LPC32XX_CLKPWR_HCLKPLL_POWER_UP;
-	if (PllSetup->cco_bypass_b15 != 0)
-		tmp |= LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS;
-	if (PllSetup->direct_output_b14 != 0)
-		tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS;
-	if (PllSetup->fdbk_div_ctrl_b13 != 0)
-		tmp |= LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK;
-
-	tv = ffs(PllSetup->pll_p) - 1;
-	if ((!is_power_of_2(PllSetup->pll_p)) || (tv > 3))
-		return 0;
-
-	tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(tv);
-	tmp |= LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(PllSetup->pll_n - 1);
-	tmp |= LPC32XX_CLKPWR_HCLKPLL_PLLM(PllSetup->pll_m - 1);
-
-	return tmp;
-}
-
-/*
- * Update the ARM core PLL frequency rate variable from the actual PLL setting
- */
-static void local_update_armpll_rate(void)
-{
-	u32 clkin, pllreg;
-
-	clkin = clk_armpll.parent->rate;
-	pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF;
-
-	clk_armpll.rate = clk_get_pllrate_from_reg(clkin, pllreg);
-}
-
-/*
- * Find a PLL configuration for the selected input frequency
- */
-static u32 local_clk_find_pll_cfg(u32 pllin_freq, u32 target_freq,
-	struct clk_pll_setup *pllsetup)
-{
-	u32 ifreq, freqtol, m, n, p, fclkout;
-
-	/* Determine frequency tolerance limits */
-	freqtol = target_freq / 250;
-	ifreq = pllin_freq;
-
-	/* Is direct bypass mode possible? */
-	if (abs(pllin_freq - target_freq) <= freqtol) {
-		pllsetup->analog_on = 0;
-		pllsetup->cco_bypass_b15 = 1;
-		pllsetup->direct_output_b14 = 1;
-		pllsetup->fdbk_div_ctrl_b13 = 1;
-		pllsetup->pll_p = pll_postdivs[0];
-		pllsetup->pll_n = 1;
-		pllsetup->pll_m = 1;
-		return clk_check_pll_setup(ifreq, pllsetup);
-	} else if (target_freq <= ifreq) {
-		pllsetup->analog_on = 0;
-		pllsetup->cco_bypass_b15 = 1;
-		pllsetup->direct_output_b14 = 0;
-		pllsetup->fdbk_div_ctrl_b13 = 1;
-		pllsetup->pll_n = 1;
-		pllsetup->pll_m = 1;
-		for (p = 0; p <= 3; p++) {
-			pllsetup->pll_p = pll_postdivs[p];
-			fclkout = clk_check_pll_setup(ifreq, pllsetup);
-			if (abs(target_freq - fclkout) <= freqtol)
-				return fclkout;
-		}
-	}
-
-	/* Is direct mode possible? */
-	pllsetup->analog_on = 1;
-	pllsetup->cco_bypass_b15 = 0;
-	pllsetup->direct_output_b14 = 1;
-	pllsetup->fdbk_div_ctrl_b13 = 0;
-	pllsetup->pll_p = pll_postdivs[0];
-	for (m = 1; m <= 256; m++) {
-		for (n = 1; n <= 4; n++) {
-			/* Compute output frequency for this value */
-			pllsetup->pll_n = n;
-			pllsetup->pll_m = m;
-			fclkout = clk_check_pll_setup(ifreq,
-				pllsetup);
-			if (abs(target_freq - fclkout) <=
-				freqtol)
-				return fclkout;
-		}
-	}
-
-	/* Is integer mode possible? */
-	pllsetup->analog_on = 1;
-	pllsetup->cco_bypass_b15 = 0;
-	pllsetup->direct_output_b14 = 0;
-	pllsetup->fdbk_div_ctrl_b13 = 1;
-	for (m = 1; m <= 256; m++) {
-		for (n = 1; n <= 4; n++) {
-			for (p = 0; p < 4; p++) {
-				/* Compute output frequency */
-				pllsetup->pll_p = pll_postdivs[p];
-				pllsetup->pll_n = n;
-				pllsetup->pll_m = m;
-				fclkout = clk_check_pll_setup(
-					ifreq, pllsetup);
-				if (abs(target_freq - fclkout) <= freqtol)
-					return fclkout;
-			}
-		}
-	}
-
-	/* Try non-integer mode */
-	pllsetup->analog_on = 1;
-	pllsetup->cco_bypass_b15 = 0;
-	pllsetup->direct_output_b14 = 0;
-	pllsetup->fdbk_div_ctrl_b13 = 0;
-	for (m = 1; m <= 256; m++) {
-		for (n = 1; n <= 4; n++) {
-			for (p = 0; p < 4; p++) {
-				/* Compute output frequency */
-				pllsetup->pll_p = pll_postdivs[p];
-				pllsetup->pll_n = n;
-				pllsetup->pll_m = m;
-				fclkout = clk_check_pll_setup(
-					ifreq, pllsetup);
-				if (abs(target_freq - fclkout) <= freqtol)
-					return fclkout;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static struct clk clk_armpll = {
-	.parent		= &clk_sys,
-	.get_rate	= local_return_parent_rate,
-};
-
-/*
- * Setup the USB PLL with a PLL structure
- */
-static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup)
-{
-	u32 reg, tmp = local_clk_pll_setup(pHCLKPllSetup);
-
-	reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL) & ~0x1FFFF;
-	reg |= tmp;
-	__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
-
-	return clk_check_pll_setup(clk_usbpll.parent->rate,
-		pHCLKPllSetup);
-}
-
-static int local_usbpll_enable(struct clk *clk, int enable)
-{
-	u32 reg;
-	int ret = 0;
-	unsigned long timeout = jiffies + msecs_to_jiffies(20);
-
-	reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
-
-	__raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 |
-		LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
-		LPC32XX_CLKPWR_USB_CTRL);
-	__raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1,
-		LPC32XX_CLKPWR_USB_CTRL);
-
-	if (enable && usb_pll_valid && usb_pll_enable) {
-		ret = -ENODEV;
-		/*
-		 * If the PLL rate has been previously set, then the rate
-		 * in the PLL register is valid and can be enabled here.
-		 * Otherwise, it needs to be enabled as part of setrate.
-		 */
-
-		/*
-		 * Gate clock into PLL
-		 */
-		reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1;
-		__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
-
-		/*
-		 * Enable PLL
-		 */
-		reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP;
-		__raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL);
-
-		/*
-		 * Wait for PLL to lock
-		 */
-		while (time_before(jiffies, timeout) && (ret == -ENODEV)) {
-			reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL);
-			if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS)
-				ret = 0;
-			else
-				udelay(10);
-		}
-
-		/*
-		 * Gate clock from PLL if PLL is locked
-		 */
-		if (ret == 0) {
-			__raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2,
-				LPC32XX_CLKPWR_USB_CTRL);
-		} else {
-			__raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 |
-				LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP),
-				LPC32XX_CLKPWR_USB_CTRL);
-		}
-	} else if ((enable == 0) && usb_pll_valid  && usb_pll_enable) {
-		usb_pll_valid = 0;
-		usb_pll_enable = 0;
-	}
-
-	return ret;
-}
-
-static unsigned long local_usbpll_round_rate(struct clk *clk,
-	unsigned long rate)
-{
-	u32 clkin, usbdiv;
-	struct clk_pll_setup pllsetup;
-
-	/*
-	 * Unlike other clocks, this clock has a KHz input rate, so bump
-	 * it up to work with the PLL function
-	 */
-	rate = rate * 1000;
-
-	clkin = clk->get_rate(clk);
-	usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
-		LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
-	clkin = clkin / usbdiv;
-
-	/* Try to find a good rate setup */
-	if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
-		return 0;
-
-	return clk_check_pll_setup(clkin, &pllsetup);
-}
-
-static int local_usbpll_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -ENODEV;
-	u32 clkin, usbdiv;
-	struct clk_pll_setup pllsetup;
-
-	/*
-	 * Unlike other clocks, this clock has a KHz input rate, so bump
-	 * it up to work with the PLL function
-	 */
-	rate = rate * 1000;
-
-	clkin = clk->get_rate(clk->parent);
-	usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) &
-		LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1;
-	clkin = clkin / usbdiv;
-
-	/* Try to find a good rate setup */
-	if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0)
-		return -EINVAL;
-
-	/*
-	 * Disable PLL clocks during PLL change
-	 */
-	local_usbpll_enable(clk, 0);
-	pllsetup.analog_on = 0;
-	local_clk_usbpll_setup(&pllsetup);
-
-	/*
-	 * Start USB PLL and check PLL status
-	 */
-
-	usb_pll_valid = 1;
-	usb_pll_enable = 1;
-
-	ret = local_usbpll_enable(clk, 1);
-	if (ret >= 0)
-		clk->rate = clk_check_pll_setup(clkin, &pllsetup);
-
-	return ret;
-}
-
-static struct clk clk_usbpll = {
-	.parent		= &osc_main,
-	.set_rate	= local_usbpll_set_rate,
-	.enable		= local_usbpll_enable,
-	.rate		= 48000, /* In KHz */
-	.get_rate	= local_return_parent_rate,
-	.round_rate	= local_usbpll_round_rate,
-};
-
-static u32 clk_get_hclk_div(void)
-{
-	static const u32 hclkdivs[4] = {1, 2, 4, 4};
-	return hclkdivs[LPC32XX_CLKPWR_HCLKDIV_DIV_2POW(
-		__raw_readl(LPC32XX_CLKPWR_HCLK_DIV))];
-}
-
-static struct clk clk_hclk = {
-	.parent		= &clk_armpll,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_pclk = {
-	.parent		= &clk_armpll,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int local_onoff_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-
-	tmp = __raw_readl(clk->enable_reg);
-
-	if (enable == 0)
-		tmp &= ~clk->enable_mask;
-	else
-		tmp |= clk->enable_mask;
-
-	__raw_writel(tmp, clk->enable_reg);
-
-	return 0;
-}
-
-/* Peripheral clock sources */
-static struct clk clk_timer0 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_timer1 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_timer2 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_timer3 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_mpwm = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1,
-	.enable_mask	= LPC32XX_CLKPWR_TMRPWMCLK_MPWM_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_wdt = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_TIMER_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_PWMCLK_WDOG_EN,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_vfp9 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_DEBUG_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT,
-	.get_rate	= local_return_parent_rate,
-};
-static struct clk clk_dma = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_DMA_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_pwm = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_PWM_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_PWMCLK_PWM1CLK_EN |
-			  LPC32XX_CLKPWR_PWMCLK_PWM1SEL_PCLK |
-			  LPC32XX_CLKPWR_PWMCLK_PWM1_DIV(1) |
-			  LPC32XX_CLKPWR_PWMCLK_PWM2CLK_EN |
-			  LPC32XX_CLKPWR_PWMCLK_PWM2SEL_PCLK |
-			  LPC32XX_CLKPWR_PWMCLK_PWM2_DIV(1),
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_uart3 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_UART_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_uart4 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_UART_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_uart5 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_UART_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_uart6 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_UART_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_i2c0 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_I2C_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_i2c1 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_I2C_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_i2c2 = {
-	.parent		= &clk_pclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= io_p2v(LPC32XX_USB_BASE + 0xFF4),
-	.enable_mask	= 0x4,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_ssp0 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_SSP_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_ssp1 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_SSP_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_kscan = {
-	.parent		= &osc_32KHz,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_KEY_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_nand = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_NAND_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN |
-			  LPC32XX_CLKPWR_NANDCLK_SEL_SLC,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_nand_mlc = {
-	.parent         = &clk_hclk,
-	.enable         = local_onoff_enable,
-	.enable_reg     = LPC32XX_CLKPWR_NAND_CLK_CTRL,
-	.enable_mask    = LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN |
-			  LPC32XX_CLKPWR_NANDCLK_DMA_INT |
-			  LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC,
-	.get_rate       = local_return_parent_rate,
-};
-
-static struct clk clk_i2s0 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_I2S_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_i2s1 = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_I2S_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN |
-			  LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_net = {
-	.parent		= &clk_hclk,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_MACCLK_CTRL,
-	.enable_mask	= (LPC32XX_CLKPWR_MACCTRL_DMACLK_EN |
-		LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN |
-		LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN),
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_rtc = {
-	.parent		= &osc_32KHz,
-	.rate		= 1, /* 1 Hz */
-	.get_rate	= local_return_parent_rate,
-};
-
-static int local_usb_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-
-	if (enable) {
-		/* Set up I2C pull levels */
-		tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL);
-		tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE;
-		__raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL);
-	}
-
-	return local_onoff_enable(clk, enable);
-}
-
-static struct clk clk_usbd = {
-	.parent		= &clk_usbpll,
-	.enable		= local_usb_enable,
-	.enable_reg	= LPC32XX_CLKPWR_USB_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_USBCTRL_HCLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-#define OTG_ALWAYS_MASK		(LPC32XX_USB_OTG_OTG_CLOCK_ON | \
-				 LPC32XX_USB_OTG_I2C_CLOCK_ON)
-
-static int local_usb_otg_enable(struct clk *clk, int enable)
-{
-	int to = 1000;
-
-	if (enable) {
-		__raw_writel(clk->enable_mask, clk->enable_reg);
-
-		while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
-			clk->enable_mask) != clk->enable_mask) && (to > 0))
-			to--;
-	} else {
-		__raw_writel(OTG_ALWAYS_MASK, clk->enable_reg);
-
-		while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) &
-			OTG_ALWAYS_MASK) != OTG_ALWAYS_MASK) && (to > 0))
-			to--;
-	}
-
-	if (to)
-		return 0;
-	else
-		return -1;
-}
-
-static struct clk clk_usb_otg_dev = {
-	.parent		= &clk_usbpll,
-	.enable		= local_usb_otg_enable,
-	.enable_reg	= LPC32XX_USB_OTG_CLK_CTRL,
-	.enable_mask	= LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
-			  LPC32XX_USB_OTG_OTG_CLOCK_ON |
-			  LPC32XX_USB_OTG_DEV_CLOCK_ON |
-			  LPC32XX_USB_OTG_I2C_CLOCK_ON,
-	.get_rate	= local_return_parent_rate,
-};
-
-static struct clk clk_usb_otg_host = {
-	.parent		= &clk_usbpll,
-	.enable		= local_usb_otg_enable,
-	.enable_reg	= LPC32XX_USB_OTG_CLK_CTRL,
-	.enable_mask	= LPC32XX_USB_OTG_AHB_M_CLOCK_ON |
-			  LPC32XX_USB_OTG_OTG_CLOCK_ON |
-			  LPC32XX_USB_OTG_HOST_CLOCK_ON |
-			  LPC32XX_USB_OTG_I2C_CLOCK_ON,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int tsc_onoff_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-
-	/* Make sure 32KHz clock is the selected clock */
-	tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
-	tmp &= ~LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL;
-	__raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
-
-	if (enable == 0)
-		__raw_writel(0, clk->enable_reg);
-	else
-		__raw_writel(clk->enable_mask, clk->enable_reg);
-
-	return 0;
-}
-
-static struct clk clk_tsc = {
-	.parent		= &osc_32KHz,
-	.enable		= tsc_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_ADC_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int adc_onoff_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-	u32 divider;
-
-	/* Use PERIPH_CLOCK */
-	tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
-	tmp |= LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL;
-	/*
-	 * Set clock divider so that we have equal to or less than
-	 * 4.5MHz clock at ADC
-	 */
-	divider = clk->get_rate(clk) / 4500000 + 1;
-	tmp |= divider;
-	__raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
-
-	/* synchronize rate of this clock w/ actual HW setting */
-	clk->rate = clk->get_rate(clk->parent) / divider;
-
-	if (enable == 0)
-		__raw_writel(0, clk->enable_reg);
-	else
-		__raw_writel(clk->enable_mask, clk->enable_reg);
-
-	return 0;
-}
-
-static struct clk clk_adc = {
-	.parent		= &clk_pclk,
-	.enable		= adc_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_ADC_CLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN,
-	.get_rate	= local_return_parent_rate,
-};
-
-static int mmc_onoff_enable(struct clk *clk, int enable)
-{
-	u32 tmp;
-
-	tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) &
-		~(LPC32XX_CLKPWR_MSCARD_SDCARD_EN |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO_PIN_DIS |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO0_DIS |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO1_DIS |
-		  LPC32XX_CLKPWR_MSCARD_MSDIO23_DIS);
-
-	/* If rate is 0, disable clock */
-	if (enable != 0)
-		tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN |
-			LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN;
-
-	__raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL);
-
-	return 0;
-}
-
-static unsigned long mmc_get_rate(struct clk *clk)
-{
-	u32 div, rate, oldclk;
-
-	/* The MMC clock must be on when accessing an MMC register */
-	oldclk = __raw_readl(LPC32XX_CLKPWR_MS_CTRL);
-	__raw_writel(oldclk | LPC32XX_CLKPWR_MSCARD_SDCARD_EN,
-		LPC32XX_CLKPWR_MS_CTRL);
-	div = __raw_readl(LPC32XX_CLKPWR_MS_CTRL);
-	__raw_writel(oldclk, LPC32XX_CLKPWR_MS_CTRL);
-
-	/* Get the parent clock rate */
-	rate = clk->parent->get_rate(clk->parent);
-
-	/* Get the MMC controller clock divider value */
-	div = div & LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf);
-
-	if (!div)
-		div = 1;
-
-	return rate / div;
-}
-
-static unsigned long mmc_round_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long div, prate;
-
-	/* Get the parent clock rate */
-	prate = clk->parent->get_rate(clk->parent);
-
-	if (rate >= prate)
-		return prate;
-
-	div = prate / rate;
-	if (div > 0xf)
-		div = 0xf;
-
-	return prate / div;
-}
-
-static int mmc_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 tmp;
-	unsigned long prate, div, crate = mmc_round_rate(clk, rate);
-
-	prate = clk->parent->get_rate(clk->parent);
-
-	div = prate / crate;
-
-	/* The MMC clock must be on when accessing an MMC register */
-	tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) &
-		~LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf);
-	tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(div) |
-		LPC32XX_CLKPWR_MSCARD_SDCARD_EN;
-	__raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL);
-
-	return 0;
-}
-
-static struct clk clk_mmc = {
-	.parent		= &clk_armpll,
-	.set_rate	= mmc_set_rate,
-	.get_rate	= mmc_get_rate,
-	.round_rate	= mmc_round_rate,
-	.enable		= mmc_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_MS_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_MSCARD_SDCARD_EN,
-};
-
-static unsigned long clcd_get_rate(struct clk *clk)
-{
-	u32 tmp, div, rate, oldclk;
-
-	/* The LCD clock must be on when accessing an LCD register */
-	oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL);
-	__raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
-		LPC32XX_CLKPWR_LCDCLK_CTRL);
-	tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2));
-	__raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL);
-
-	rate = clk->parent->get_rate(clk->parent);
-
-	/* Only supports internal clocking */
-	if (tmp & TIM2_BCD)
-		return rate;
-
-	div = (tmp & 0x1F) | ((tmp & 0xF8) >> 22);
-	tmp = rate / (2 + div);
-
-	return tmp;
-}
-
-static int clcd_set_rate(struct clk *clk, unsigned long rate)
-{
-	u32 tmp, prate, div, oldclk;
-
-	/* The LCD clock must be on when accessing an LCD register */
-	oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL);
-	__raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
-		LPC32XX_CLKPWR_LCDCLK_CTRL);
-
-	tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)) | TIM2_BCD;
-	prate = clk->parent->get_rate(clk->parent);
-
-	if (rate < prate) {
-		/* Find closest divider */
-		div = prate / rate;
-		if (div >= 2) {
-			div -= 2;
-			tmp &= ~TIM2_BCD;
-		}
-
-		tmp &= ~(0xF800001F);
-		tmp |= (div & 0x1F);
-		tmp |= (((div >> 5) & 0x1F) << 27);
-	}
-
-	__raw_writel(tmp, io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2));
-	__raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL);
-
-	return 0;
-}
-
-static unsigned long clcd_round_rate(struct clk *clk, unsigned long rate)
-{
-	u32 prate, div;
-
-	prate = clk->parent->get_rate(clk->parent);
-
-	if (rate >= prate)
-		rate = prate;
-	else {
-		div = prate / rate;
-		if (div > 0x3ff)
-			div = 0x3ff;
-
-		rate = prate / div;
-	}
-
-	return rate;
-}
-
-static struct clk clk_lcd = {
-	.parent		= &clk_hclk,
-	.set_rate	= clcd_set_rate,
-	.get_rate	= clcd_get_rate,
-	.round_rate	= clcd_round_rate,
-	.enable		= local_onoff_enable,
-	.enable_reg	= LPC32XX_CLKPWR_LCDCLK_CTRL,
-	.enable_mask	= LPC32XX_CLKPWR_LCDCTRL_CLK_EN,
-};
-
-static void local_clk_disable(struct clk *clk)
-{
-	/* Don't attempt to disable clock if it has no users */
-	if (clk->usecount > 0) {
-		clk->usecount--;
-
-		/* Only disable clock when it has no more users */
-		if ((clk->usecount == 0) && (clk->enable))
-			clk->enable(clk, 0);
-
-		/* Check parent clocks, they may need to be disabled too */
-		if (clk->parent)
-			local_clk_disable(clk->parent);
-	}
-}
-
-static int local_clk_enable(struct clk *clk)
-{
-	int ret = 0;
-
-	/* Enable parent clocks first and update use counts */
-	if (clk->parent)
-		ret = local_clk_enable(clk->parent);
-
-	if (!ret) {
-		/* Only enable clock if it's currently disabled */
-		if ((clk->usecount == 0) && (clk->enable))
-			ret = clk->enable(clk, 1);
-
-		if (!ret)
-			clk->usecount++;
-		else if (clk->parent)
-			local_clk_disable(clk->parent);
-	}
-
-	return ret;
-}
-
-/*
- * clk_enable - inform the system when the clock source should be running.
- */
-int clk_enable(struct clk *clk)
-{
-	int ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&global_clkregs_lock, flags);
-	ret = local_clk_enable(clk);
-	spin_unlock_irqrestore(&global_clkregs_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_enable);
-
-/*
- * clk_disable - inform the system when the clock source is no longer required
- */
-void clk_disable(struct clk *clk)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&global_clkregs_lock, flags);
-	local_clk_disable(clk);
-	spin_unlock_irqrestore(&global_clkregs_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-/*
- * clk_get_rate - obtain the current clock rate (in Hz) for a clock source
- */
-unsigned long clk_get_rate(struct clk *clk)
-{
-	return clk->get_rate(clk);
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-/*
- * clk_set_rate - set the clock rate for a clock source
- */
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -EINVAL;
-
-	/*
-	 * Most system clocks can only be enabled or disabled, with
-	 * the actual rate set as part of the peripheral dividers
-	 * instead of high level clock control
-	 */
-	if (clk->set_rate)
-		ret = clk->set_rate(clk, rate);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-/*
- * clk_round_rate - adjust a rate to the exact rate a clock can provide
- */
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (clk->round_rate)
-		rate = clk->round_rate(clk, rate);
-	else
-		rate = clk->get_rate(clk);
-
-	return rate;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-/*
- * clk_set_parent - set the parent clock source for this clock
- */
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	/* Clock re-parenting is not supported */
-	return -EINVAL;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-/*
- * clk_get_parent - get the parent clock source for this clock
- */
-struct clk *clk_get_parent(struct clk *clk)
-{
-	return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-static struct clk_lookup lookups[] = {
-	CLKDEV_INIT(NULL, "osc_32KHz", &osc_32KHz),
-	CLKDEV_INIT(NULL, "osc_pll397", &osc_pll397),
-	CLKDEV_INIT(NULL, "osc_main", &osc_main),
-	CLKDEV_INIT(NULL, "sys_ck", &clk_sys),
-	CLKDEV_INIT(NULL, "arm_pll_ck", &clk_armpll),
-	CLKDEV_INIT(NULL, "ck_pll5", &clk_usbpll),
-	CLKDEV_INIT(NULL, "hclk_ck", &clk_hclk),
-	CLKDEV_INIT(NULL, "pclk_ck", &clk_pclk),
-	CLKDEV_INIT(NULL, "timer0_ck", &clk_timer0),
-	CLKDEV_INIT(NULL, "timer1_ck", &clk_timer1),
-	CLKDEV_INIT(NULL, "timer2_ck", &clk_timer2),
-	CLKDEV_INIT(NULL, "timer3_ck", &clk_timer3),
-	CLKDEV_INIT(NULL, "vfp9_ck", &clk_vfp9),
-	CLKDEV_INIT("pl08xdmac", NULL, &clk_dma),
-	CLKDEV_INIT("4003c000.watchdog", NULL, &clk_wdt),
-	CLKDEV_INIT("4005c000.pwm", NULL, &clk_pwm),
-	CLKDEV_INIT("400e8000.mpwm", NULL, &clk_mpwm),
-	CLKDEV_INIT(NULL, "uart3_ck", &clk_uart3),
-	CLKDEV_INIT(NULL, "uart4_ck", &clk_uart4),
-	CLKDEV_INIT(NULL, "uart5_ck", &clk_uart5),
-	CLKDEV_INIT(NULL, "uart6_ck", &clk_uart6),
-	CLKDEV_INIT("400a0000.i2c", NULL, &clk_i2c0),
-	CLKDEV_INIT("400a8000.i2c", NULL, &clk_i2c1),
-	CLKDEV_INIT("31020300.i2c", NULL, &clk_i2c2),
-	CLKDEV_INIT("dev:ssp0", NULL, &clk_ssp0),
-	CLKDEV_INIT("dev:ssp1", NULL, &clk_ssp1),
-	CLKDEV_INIT("40050000.key", NULL, &clk_kscan),
-	CLKDEV_INIT("20020000.flash", NULL, &clk_nand),
-	CLKDEV_INIT("200a8000.flash", NULL, &clk_nand_mlc),
-	CLKDEV_INIT("40048000.adc", NULL, &clk_adc),
-	CLKDEV_INIT(NULL, "i2s0_ck", &clk_i2s0),
-	CLKDEV_INIT(NULL, "i2s1_ck", &clk_i2s1),
-	CLKDEV_INIT("40048000.tsc", NULL, &clk_tsc),
-	CLKDEV_INIT("20098000.sd", NULL, &clk_mmc),
-	CLKDEV_INIT("31060000.ethernet", NULL, &clk_net),
-	CLKDEV_INIT("dev:clcd", NULL, &clk_lcd),
-	CLKDEV_INIT("31020000.usbd", "ck_usbd", &clk_usbd),
-	CLKDEV_INIT("31020000.ohci", "ck_usbd", &clk_usbd),
-	CLKDEV_INIT("31020000.usbd", "ck_usb_otg", &clk_usb_otg_dev),
-	CLKDEV_INIT("31020000.ohci", "ck_usb_otg", &clk_usb_otg_host),
-	CLKDEV_INIT("lpc32xx_rtc", NULL, &clk_rtc),
-};
-
-static int __init clk_init(void)
-{
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
-	/*
-	 * Setup muxed SYSCLK for HCLK PLL base -this selects the
-	 * parent clock used for the ARM PLL and is used to derive
-	 * the many system clock rates in the device.
-	 */
-	if (clk_is_sysclk_mainosc() != 0)
-		clk_sys.parent = &osc_main;
-	else
-		clk_sys.parent = &osc_pll397;
-
-	clk_sys.rate = clk_sys.parent->rate;
-
-	/* Compute the current ARM PLL and USB PLL frequencies */
-	local_update_armpll_rate();
-
-	/* Compute HCLK and PCLK bus rates */
-	clk_hclk.rate = clk_hclk.parent->rate / clk_get_hclk_div();
-	clk_pclk.rate = clk_pclk.parent->rate / clk_get_pclk_div();
-
-	/*
-	 * Enable system clocks - this step is somewhat formal, as the
-	 * clocks are already running, but it does get the clock data
-	 * inline with the actual system state. Never disable these
-	 * clocks as they will only stop if the system is going to sleep.
-	 * In that case, the chip/system power management functions will
-	 * handle clock gating.
-	 */
-	if (clk_enable(&clk_hclk) || clk_enable(&clk_pclk))
-		printk(KERN_ERR "Error enabling system HCLK and PCLK\n");
-
-	/*
-	 * Timers 0 and 1 were enabled and are being used by the high
-	 * resolution tick function prior to this driver being initialized.
-	 * Tag them now as used.
-	 */
-	if (clk_enable(&clk_timer0) || clk_enable(&clk_timer1))
-		printk(KERN_ERR "Error enabling timer tick clocks\n");
-
-	return 0;
-}
-core_initcall(clk_init);
-
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index 77d6b1b..60f3392 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -260,7 +260,6 @@ DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)")
 	.atag_offset	= 0x100,
 	.map_io		= lpc32xx_map_io,
 	.init_irq	= lpc32xx_init_irq,
-	.init_time	= lpc32xx_timer_init,
 	.init_machine	= lpc3250_machine_init,
 	.dt_compat	= lpc32xx_dt_compat,
 	.restart	= lpc23xx_restart,
diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c
index 05621a2..1931229 100644
--- a/arch/arm/mach-lpc32xx/serial.c
+++ b/arch/arm/mach-lpc32xx/serial.c
@@ -76,9 +76,6 @@ void __init lpc32xx_serial_init(void)
 	unsigned int puart;
 	int i, j;
 
-	/* UART clocks are off, let clock driver manage them */
-	__raw_writel(0, LPC32XX_CLKPWR_UART_CLK_CTRL);
-
 	for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) {
 		clk = clk_get(NULL, uartinit_data[i].uart_ck_name);
 		if (!IS_ERR(clk)) {
diff --git a/arch/arm/mach-lpc32xx/timer.c b/arch/arm/mach-lpc32xx/timer.c
deleted file mode 100644
index ff3499d..0000000
--- a/arch/arm/mach-lpc32xx/timer.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/timer.c
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2009 - 2010 NXP Semiconductors
- * Copyright (C) 2009 Fontys University of Applied Sciences, Eindhoven
- *                    Ed Schouten <e.schouten@fontys.nl>
- *                    Laurens Timmermans <l.timmermans@fontys.nl>
- *
- * 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/interrupt.h>
-#include <linux/irq.h>
-#include <linux/time.h>
-#include <linux/err.h>
-#include <linux/clockchips.h>
-
-#include <asm/mach/time.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-#include "common.h"
-
-static int lpc32xx_clkevt_next_event(unsigned long delta,
-    struct clock_event_device *dev)
-{
-	__raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET,
-		LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-	__raw_writel(delta, LPC32XX_TIMER_PR(LPC32XX_TIMER0_BASE));
-	__raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
-		LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-
-	return 0;
-}
-
-static int lpc32xx_shutdown(struct clock_event_device *evt)
-{
-	/*
-	 * Disable the timer. When using oneshot, we must also
-	 * disable the timer to wait for the first call to
-	 * set_next_event().
-	 */
-	__raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-	return 0;
-}
-
-static struct clock_event_device lpc32xx_clkevt = {
-	.name			= "lpc32xx_clkevt",
-	.features		= CLOCK_EVT_FEAT_ONESHOT,
-	.rating			= 300,
-	.set_next_event		= lpc32xx_clkevt_next_event,
-	.set_state_shutdown	= lpc32xx_shutdown,
-	.set_state_oneshot	= lpc32xx_shutdown,
-};
-
-static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = &lpc32xx_clkevt;
-
-	/* Clear match */
-	__raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
-		LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction lpc32xx_timer_irq = {
-	.name		= "LPC32XX Timer Tick",
-	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= lpc32xx_timer_interrupt,
-};
-
-/*
- * The clock management driver isn't initialized at this point, so the
- * clocks need to be enabled here manually and then tagged as used in
- * the clock driver initialization
- */
-void __init lpc32xx_timer_init(void)
-{
-	u32 clkrate, pllreg;
-
-	/* Enable timer clock */
-	__raw_writel(LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN |
-		LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN,
-		LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1);
-
-	/*
-	 * The clock driver isn't initialized at this point. So determine if
-	 * the SYSCLK is driven from the PLL397 or main oscillator and then use
-	 * it to compute the PLL frequency and the PCLK divider to get the base
-	 * timer rates. This rate is needed to compute the tick rate.
-	 */
-	if (clk_is_sysclk_mainosc() != 0)
-		clkrate = LPC32XX_MAIN_OSC_FREQ;
-	else
-		clkrate = 397 * LPC32XX_CLOCK_OSC_FREQ;
-
-	/* Get ARM HCLKPLL register and convert it into a frequency */
-	pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF;
-	clkrate = clk_get_pllrate_from_reg(clkrate, pllreg);
-
-	/* Get PCLK divider and divide ARM PLL clock by it to get timer rate */
-	clkrate = clkrate / clk_get_pclk_div();
-
-	/* Initial timer setup */
-	__raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE));
-	__raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0),
-		LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE));
-	__raw_writel(1, LPC32XX_TIMER_MR0(LPC32XX_TIMER0_BASE));
-	__raw_writel(LPC32XX_TIMER_CNTR_MCR_MTCH(0) |
-		LPC32XX_TIMER_CNTR_MCR_STOP(0) |
-		LPC32XX_TIMER_CNTR_MCR_RESET(0),
-		LPC32XX_TIMER_MCR(LPC32XX_TIMER0_BASE));
-
-	/* Setup tick interrupt */
-	setup_irq(IRQ_LPC32XX_TIMER0, &lpc32xx_timer_irq);
-
-	/* Setup the clockevent structure. */
-	lpc32xx_clkevt.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&lpc32xx_clkevt, clkrate, 1, -1);
-
-	/* Use timer1 as clock source. */
-	__raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET,
-		LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
-	__raw_writel(0, LPC32XX_TIMER_PR(LPC32XX_TIMER1_BASE));
-	__raw_writel(0, LPC32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
-	__raw_writel(LPC32XX_TIMER_CNTR_TCR_EN,
-		LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
-
-	clocksource_mmio_init(LPC32XX_TIMER_TC(LPC32XX_TIMER1_BASE),
-		"lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up);
-}
-- 
2.1.4

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

* [PATCH 11/11] arm: dts: lpc32xx: remove clock frequency property from UART device nodes
  2015-11-20  1:05 ` Vladimir Zapolskiy
  (?)
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

If clock-frequency property is given, then it substitutes calculation
of supplying clock frequency from parent clock, this may break UART,
if parent clock is given and managed by common clock framework.

Signed-off-by: Vladimir Zapolskiy <vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 68bf011..f396343 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -209,7 +209,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40090000 0x1000>;
 				interrupts = <9 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART5>;
 				status = "disabled";
@@ -219,7 +218,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40080000 0x1000>;
 				interrupts = <7 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART3>;
 				status = "disabled";
@@ -229,7 +227,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40088000 0x1000>;
 				interrupts = <8 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART4>;
 				status = "disabled";
@@ -239,7 +236,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40098000 0x1000>;
 				interrupts = <10 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART6>;
 				status = "disabled";
-- 
2.1.4

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

* [PATCH 11/11] arm: dts: lpc32xx: remove clock frequency property from UART device nodes
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann
  Cc: Russell King, Roland Stigge, linux-clk, devicetree, linux-arm-kernel

If clock-frequency property is given, then it substitutes calculation
of supplying clock frequency from parent clock, this may break UART,
if parent clock is given and managed by common clock framework.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 68bf011..f396343 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -209,7 +209,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40090000 0x1000>;
 				interrupts = <9 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART5>;
 				status = "disabled";
@@ -219,7 +218,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40080000 0x1000>;
 				interrupts = <7 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART3>;
 				status = "disabled";
@@ -229,7 +227,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40088000 0x1000>;
 				interrupts = <8 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART4>;
 				status = "disabled";
@@ -239,7 +236,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40098000 0x1000>;
 				interrupts = <10 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART6>;
 				status = "disabled";
-- 
2.1.4

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

* [PATCH 11/11] arm: dts: lpc32xx: remove clock frequency property from UART device nodes
@ 2015-11-20  1:05     ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20  1:05 UTC (permalink / raw)
  To: linux-arm-kernel

If clock-frequency property is given, then it substitutes calculation
of supplying clock frequency from parent clock, this may break UART,
if parent clock is given and managed by common clock framework.

Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
 arch/arm/boot/dts/lpc32xx.dtsi | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi
index 68bf011..f396343 100644
--- a/arch/arm/boot/dts/lpc32xx.dtsi
+++ b/arch/arm/boot/dts/lpc32xx.dtsi
@@ -209,7 +209,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40090000 0x1000>;
 				interrupts = <9 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART5>;
 				status = "disabled";
@@ -219,7 +218,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40080000 0x1000>;
 				interrupts = <7 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART3>;
 				status = "disabled";
@@ -229,7 +227,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40088000 0x1000>;
 				interrupts = <8 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART4>;
 				status = "disabled";
@@ -239,7 +236,6 @@
 				compatible = "nxp,lpc3220-uart";
 				reg = <0x40098000 0x1000>;
 				interrupts = <10 0>;
-				clock-frequency = <13000000>;
 				reg-shift = <2>;
 				clocks = <&clk LPC32XX_CLK_UART6>;
 				status = "disabled";
-- 
2.1.4

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

* Re: [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
  2015-11-20  1:05   ` Vladimir Zapolskiy
  (?)
@ 2015-11-20 13:56     ` Arnd Bergmann
  -1 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 13:56 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Roland Stigge, devicetree, Russell King, Michael Turquette,
	Stephen Boyd, Rob Herring, linux-clk, linux-arm-kernel

On Friday 20 November 2015 03:05:03 Vladimir Zapolskiy wrote:
> +
> +/* LPC32XX System Control Block clocks */
> +#define LPC32XX_CLK_RTC                0
> +#define LPC32XX_CLK_DMA                1
> +#define LPC32XX_CLK_MLC                2
> +#define LPC32XX_CLK_SLC                3
> +#define LPC32XX_CLK_LCD                4
> +#define LPC32XX_CLK_MAC                5
> +#define LPC32XX_CLK_SD         6
> +#define LPC32XX_CLK_DDRAM      7
> +#define LPC32XX_CLK_SSP0       8
> +#define LPC32XX_CLK_SSP1       9
> +#define LPC32XX_CLK_UART3      10
> +#define LPC32XX_CLK_UART4      11
> +#define LPC32XX_CLK_UART5      12
> +#define LPC32XX_CLK_UART6      13
> +#define LPC32XX_CLK_IRDA       14
> +#define LPC32XX_CLK_I2C1       15
> 

Any chance we can avoid the include file? This is going to make it really
hard to merge everything in one merge window with the dependencies between
the driver, the bindings and the platform code.

If there is a way to describe the clocks based on numbers from the
data sheet instead of making up your own, that makes life much
easier for us.

	Arnd

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

* Re: [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
@ 2015-11-20 13:56     ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 13:56 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Rob Herring, Stephen Boyd, Michael Turquette, Russell King,
	Roland Stigge, linux-clk, devicetree, linux-arm-kernel

On Friday 20 November 2015 03:05:03 Vladimir Zapolskiy wrote:
> +
> +/* LPC32XX System Control Block clocks */
> +#define LPC32XX_CLK_RTC                0
> +#define LPC32XX_CLK_DMA                1
> +#define LPC32XX_CLK_MLC                2
> +#define LPC32XX_CLK_SLC                3
> +#define LPC32XX_CLK_LCD                4
> +#define LPC32XX_CLK_MAC                5
> +#define LPC32XX_CLK_SD         6
> +#define LPC32XX_CLK_DDRAM      7
> +#define LPC32XX_CLK_SSP0       8
> +#define LPC32XX_CLK_SSP1       9
> +#define LPC32XX_CLK_UART3      10
> +#define LPC32XX_CLK_UART4      11
> +#define LPC32XX_CLK_UART5      12
> +#define LPC32XX_CLK_UART6      13
> +#define LPC32XX_CLK_IRDA       14
> +#define LPC32XX_CLK_I2C1       15
> 

Any chance we can avoid the include file? This is going to make it really
hard to merge everything in one merge window with the dependencies between
the driver, the bindings and the platform code.

If there is a way to describe the clocks based on numbers from the
data sheet instead of making up your own, that makes life much
easier for us.

	Arnd

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

* [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
@ 2015-11-20 13:56     ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 November 2015 03:05:03 Vladimir Zapolskiy wrote:
> +
> +/* LPC32XX System Control Block clocks */
> +#define LPC32XX_CLK_RTC                0
> +#define LPC32XX_CLK_DMA                1
> +#define LPC32XX_CLK_MLC                2
> +#define LPC32XX_CLK_SLC                3
> +#define LPC32XX_CLK_LCD                4
> +#define LPC32XX_CLK_MAC                5
> +#define LPC32XX_CLK_SD         6
> +#define LPC32XX_CLK_DDRAM      7
> +#define LPC32XX_CLK_SSP0       8
> +#define LPC32XX_CLK_SSP1       9
> +#define LPC32XX_CLK_UART3      10
> +#define LPC32XX_CLK_UART4      11
> +#define LPC32XX_CLK_UART5      12
> +#define LPC32XX_CLK_UART6      13
> +#define LPC32XX_CLK_IRDA       14
> +#define LPC32XX_CLK_I2C1       15
> 

Any chance we can avoid the include file? This is going to make it really
hard to merge everything in one merge window with the dependencies between
the driver, the bindings and the platform code.

If there is a way to describe the clocks based on numbers from the
data sheet instead of making up your own, that makes life much
easier for us.

	Arnd

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

* Re: [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
  2015-11-20  1:05     ` Vladimir Zapolskiy
@ 2015-11-20 13:58       ` Arnd Bergmann
  -1 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 13:58 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Vladimir Zapolskiy, Rob Herring, Stephen Boyd, Michael Turquette,
	Roland Stigge, devicetree, Russell King, linux-clk

On Friday 20 November 2015 03:05:01 Vladimir Zapolskiy wrote:
> NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
> of system control block (SCB). CPC is supplied by two external
> oscillators and it manages core and most of peripheral
> clocks, the change adds description of DT bindings for clock
> controller found on LPC32xx SoC series.
> 
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> ---
>  .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  | 30 ++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
> new file mode 100644
> index 0000000..20cbca3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
> @@ -0,0 +1,30 @@
> +NXP LPC32xx Clock Controller
> +
> +Required properties:
> +- compatible: should be "nxp,lpc3220-clk"

Please use a specific model number without 'xx' wildcards. If you have
multiple chips that are mutually compatible, pick one as the base number
and then list the others as more specific instances, like

	compatible = "nxp,lpc3250-clk", "nxp,lpc3220-clk";

	Arnd

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

* [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
@ 2015-11-20 13:58       ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 13:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 November 2015 03:05:01 Vladimir Zapolskiy wrote:
> NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
> of system control block (SCB). CPC is supplied by two external
> oscillators and it manages core and most of peripheral
> clocks, the change adds description of DT bindings for clock
> controller found on LPC32xx SoC series.
> 
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> ---
>  .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  | 30 ++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
> new file mode 100644
> index 0000000..20cbca3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
> @@ -0,0 +1,30 @@
> +NXP LPC32xx Clock Controller
> +
> +Required properties:
> +- compatible: should be "nxp,lpc3220-clk"

Please use a specific model number without 'xx' wildcards. If you have
multiple chips that are mutually compatible, pick one as the base number
and then list the others as more specific instances, like

	compatible = "nxp,lpc3250-clk", "nxp,lpc3220-clk";

	Arnd

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

* Re: [PATCH 09/11] clk: lpc32xx: add common clock framework driver
  2015-11-20  1:05   ` Vladimir Zapolskiy
@ 2015-11-20 14:04     ` Arnd Bergmann
  -1 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 14:04 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Vladimir Zapolskiy, Rob Herring, Stephen Boyd, Michael Turquette,
	Roland Stigge, devicetree, Russell King, linux-clk

On Friday 20 November 2015 03:05:09 Vladimir Zapolskiy wrote:
> +
> +struct clk_proto_t {
> +       const char *name;
> +       const u8 parents[LPC32XX_CLK_PARENTS_MAX];
> +       u8 num_parents;
> +       unsigned long flags;
> +};
> +
> +#define CLK_PREFIX(LITERAL)            LPC32XX_CLK_ ## LITERAL
> +#define NUMARGS(...)   (sizeof((int[]){__VA_ARGS__})/sizeof(int))
> +
> +#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)           \
> +       [CLK_PREFIX(_idx)] = {                                  \
> +               .name = #_name,                                 \
> +               .flags = _flags,                                \
> +               .parents = { __VA_ARGS__ },                     \
> +               .num_parents = NUMARGS(__VA_ARGS__),            \
> +        }
> +

Try to not outsmart yourself with the macros. It's better to avoid
string concatenation so it's possible to grep for uses of some
constant.

I would probably not use a macro at all here and just open-code the
entire table. If you ensure that '0' is not a valid parent, then
you can leave out the .num_parents field and just look for the
zero-termination.

	Arnd

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

* [PATCH 09/11] clk: lpc32xx: add common clock framework driver
@ 2015-11-20 14:04     ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 November 2015 03:05:09 Vladimir Zapolskiy wrote:
> +
> +struct clk_proto_t {
> +       const char *name;
> +       const u8 parents[LPC32XX_CLK_PARENTS_MAX];
> +       u8 num_parents;
> +       unsigned long flags;
> +};
> +
> +#define CLK_PREFIX(LITERAL)            LPC32XX_CLK_ ## LITERAL
> +#define NUMARGS(...)   (sizeof((int[]){__VA_ARGS__})/sizeof(int))
> +
> +#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)           \
> +       [CLK_PREFIX(_idx)] = {                                  \
> +               .name = #_name,                                 \
> +               .flags = _flags,                                \
> +               .parents = { __VA_ARGS__ },                     \
> +               .num_parents = NUMARGS(__VA_ARGS__),            \
> +        }
> +

Try to not outsmart yourself with the macros. It's better to avoid
string concatenation so it's possible to grep for uses of some
constant.

I would probably not use a macro at all here and just open-code the
entire table. If you ensure that '0' is not a valid parent, then
you can leave out the .num_parents field and just look for the
zero-termination.

	Arnd

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

* Re: [PATCH 02/11] dt-bindings: clock: add description of LPC32xx USB clock controller
  2015-11-20  1:05   ` Vladimir Zapolskiy
@ 2015-11-20 16:41     ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2015-11-20 16:41 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Stephen Boyd, Michael Turquette, Arnd Bergmann, Russell King,
	Roland Stigge, linux-clk, devicetree, linux-arm-kernel

On Fri, Nov 20, 2015 at 03:05:02AM +0200, Vladimir Zapolskiy wrote:
> NXP LPC32xx USB controller has a subdevice, which controls USB AHB
> slave, USB OTG, USB OHCI, USB device and I2C controller to USB phy
> clocks, this change adds description of the clock controller, for more
> details reference LPC32xx User's Manual, namely USB control, OTG clock
> control and OTG clock status registers.
> 
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> ---
>  .../bindings/clock/nxp,lpc3220-usb-clk.txt         | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
> new file mode 100644
> index 0000000..67fba7f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
> @@ -0,0 +1,22 @@
> +NXP LPC32xx USB Clock Controller
> +
> +Required properties:
> +- compatible: should be "nxp,lpc3220-usb-clk"
> +- reg:  should contain clock controller registers location and length
> +- #clock-cells: must be 1, the cell holds id of a clock provided by the
> +  USB clock controller
> +
> +Examples:
> +
> +	usb {

I don't understand the full structure of USB blocks. Can you make the 
example complete. All the blocks are a child of this node?

> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "simple-bus";
> +		ranges = <0x0 0x31020000 0x00001000>;
> +
> +		usbclk: clock-controller@F00 {
lower case                               ^

> +			compatible = "nxp,lpc3220-usb-clk";
> +			reg = <0xF00 0x100>;

lower case

> +			#clock-cells = <1>;
> +		};
> +	};
> -- 
> 2.1.4
> 

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

* [PATCH 02/11] dt-bindings: clock: add description of LPC32xx USB clock controller
@ 2015-11-20 16:41     ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2015-11-20 16:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 20, 2015 at 03:05:02AM +0200, Vladimir Zapolskiy wrote:
> NXP LPC32xx USB controller has a subdevice, which controls USB AHB
> slave, USB OTG, USB OHCI, USB device and I2C controller to USB phy
> clocks, this change adds description of the clock controller, for more
> details reference LPC32xx User's Manual, namely USB control, OTG clock
> control and OTG clock status registers.
> 
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> ---
>  .../bindings/clock/nxp,lpc3220-usb-clk.txt         | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
> new file mode 100644
> index 0000000..67fba7f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
> @@ -0,0 +1,22 @@
> +NXP LPC32xx USB Clock Controller
> +
> +Required properties:
> +- compatible: should be "nxp,lpc3220-usb-clk"
> +- reg:  should contain clock controller registers location and length
> +- #clock-cells: must be 1, the cell holds id of a clock provided by the
> +  USB clock controller
> +
> +Examples:
> +
> +	usb {

I don't understand the full structure of USB blocks. Can you make the 
example complete. All the blocks are a child of this node?

> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "simple-bus";
> +		ranges = <0x0 0x31020000 0x00001000>;
> +
> +		usbclk: clock-controller at F00 {
lower case                               ^

> +			compatible = "nxp,lpc3220-usb-clk";
> +			reg = <0xF00 0x100>;

lower case

> +			#clock-cells = <1>;
> +		};
> +	};
> -- 
> 2.1.4
> 

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

* Re: [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
  2015-11-20 13:56     ` Arnd Bergmann
@ 2015-11-20 17:58       ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 17:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Rob Herring, Stephen Boyd, Michael Turquette, Russell King,
	Roland Stigge, linux-clk, devicetree, linux-arm-kernel

On 20.11.2015 15:56, Arnd Bergmann wrote:
> On Friday 20 November 2015 03:05:03 Vladimir Zapolskiy wrote:
>> +
>> +/* LPC32XX System Control Block clocks */
>> +#define LPC32XX_CLK_RTC                0
>> +#define LPC32XX_CLK_DMA                1
>> +#define LPC32XX_CLK_MLC                2
>> +#define LPC32XX_CLK_SLC                3
>> +#define LPC32XX_CLK_LCD                4
>> +#define LPC32XX_CLK_MAC                5
>> +#define LPC32XX_CLK_SD         6
>> +#define LPC32XX_CLK_DDRAM      7
>> +#define LPC32XX_CLK_SSP0       8
>> +#define LPC32XX_CLK_SSP1       9
>> +#define LPC32XX_CLK_UART3      10
>> +#define LPC32XX_CLK_UART4      11
>> +#define LPC32XX_CLK_UART5      12
>> +#define LPC32XX_CLK_UART6      13
>> +#define LPC32XX_CLK_IRDA       14
>> +#define LPC32XX_CLK_I2C1       15
>>
> 
> Any chance we can avoid the include file? This is going to make it really
> hard to merge everything in one merge window with the dependencies between
> the driver, the bindings and the platform code.

I see only one option to avoid this commit, namely squash it with the
CCF driver and merge it before making changes in DTS.

However I suppose ARM trees won't be synced on clk tree, so probably it
won't simplify maintainer's work.

> If there is a way to describe the clocks based on numbers from the
> data sheet instead of making up your own, that makes life much
> easier for us.

There are no any clock numbers in the datasheet, unfortunately.

--
Vladimir

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

* [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
@ 2015-11-20 17:58       ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 17:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 20.11.2015 15:56, Arnd Bergmann wrote:
> On Friday 20 November 2015 03:05:03 Vladimir Zapolskiy wrote:
>> +
>> +/* LPC32XX System Control Block clocks */
>> +#define LPC32XX_CLK_RTC                0
>> +#define LPC32XX_CLK_DMA                1
>> +#define LPC32XX_CLK_MLC                2
>> +#define LPC32XX_CLK_SLC                3
>> +#define LPC32XX_CLK_LCD                4
>> +#define LPC32XX_CLK_MAC                5
>> +#define LPC32XX_CLK_SD         6
>> +#define LPC32XX_CLK_DDRAM      7
>> +#define LPC32XX_CLK_SSP0       8
>> +#define LPC32XX_CLK_SSP1       9
>> +#define LPC32XX_CLK_UART3      10
>> +#define LPC32XX_CLK_UART4      11
>> +#define LPC32XX_CLK_UART5      12
>> +#define LPC32XX_CLK_UART6      13
>> +#define LPC32XX_CLK_IRDA       14
>> +#define LPC32XX_CLK_I2C1       15
>>
> 
> Any chance we can avoid the include file? This is going to make it really
> hard to merge everything in one merge window with the dependencies between
> the driver, the bindings and the platform code.

I see only one option to avoid this commit, namely squash it with the
CCF driver and merge it before making changes in DTS.

However I suppose ARM trees won't be synced on clk tree, so probably it
won't simplify maintainer's work.

> If there is a way to describe the clocks based on numbers from the
> data sheet instead of making up your own, that makes life much
> easier for us.

There are no any clock numbers in the datasheet, unfortunately.

--
Vladimir

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

* Re: [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
  2015-11-20 13:58       ` Arnd Bergmann
  (?)
@ 2015-11-20 18:01         ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 18:01 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Rob Herring, Stephen Boyd, Michael Turquette, Roland Stigge,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Russell King,
	linux-clk-u79uwXL29TY76Z2rM5mHXA

Arnd,

On 20.11.2015 15:58, Arnd Bergmann wrote:
> On Friday 20 November 2015 03:05:01 Vladimir Zapolskiy wrote:
>> NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
>> of system control block (SCB). CPC is supplied by two external
>> oscillators and it manages core and most of peripheral
>> clocks, the change adds description of DT bindings for clock
>> controller found on LPC32xx SoC series.
>>
>> Signed-off-by: Vladimir Zapolskiy <vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
>> ---
>>  .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  | 30 ++++++++++++++++++++++
>>  1 file changed, 30 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
>> new file mode 100644
>> index 0000000..20cbca3
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
>> @@ -0,0 +1,30 @@
>> +NXP LPC32xx Clock Controller
>> +
>> +Required properties:
>> +- compatible: should be "nxp,lpc3220-clk"
> 
> Please use a specific model number without 'xx' wildcards. If you have
> multiple chips that are mutually compatible, pick one as the base number
> and then list the others as more specific instances, like
> 
> 	compatible = "nxp,lpc3250-clk", "nxp,lpc3220-clk";

Do you ask me to change a title? You may see that compatible property
does not contain any wildcards?

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

* Re: [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
@ 2015-11-20 18:01         ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 18:01 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Rob Herring, Stephen Boyd, Michael Turquette, Roland Stigge,
	devicetree, Russell King, linux-clk

Arnd,

On 20.11.2015 15:58, Arnd Bergmann wrote:
> On Friday 20 November 2015 03:05:01 Vladimir Zapolskiy wrote:
>> NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
>> of system control block (SCB). CPC is supplied by two external
>> oscillators and it manages core and most of peripheral
>> clocks, the change adds description of DT bindings for clock
>> controller found on LPC32xx SoC series.
>>
>> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
>> ---
>>  .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  | 30 ++++++++++++++++++++++
>>  1 file changed, 30 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
>> new file mode 100644
>> index 0000000..20cbca3
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
>> @@ -0,0 +1,30 @@
>> +NXP LPC32xx Clock Controller
>> +
>> +Required properties:
>> +- compatible: should be "nxp,lpc3220-clk"
> 
> Please use a specific model number without 'xx' wildcards. If you have
> multiple chips that are mutually compatible, pick one as the base number
> and then list the others as more specific instances, like
> 
> 	compatible = "nxp,lpc3250-clk", "nxp,lpc3220-clk";

Do you ask me to change a title? You may see that compatible property
does not contain any wildcards?

--
Vladimir

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

* [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
@ 2015-11-20 18:01         ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

Arnd,

On 20.11.2015 15:58, Arnd Bergmann wrote:
> On Friday 20 November 2015 03:05:01 Vladimir Zapolskiy wrote:
>> NXP LPC32xx SoC has a clocking and power control unit (CPC) as a part
>> of system control block (SCB). CPC is supplied by two external
>> oscillators and it manages core and most of peripheral
>> clocks, the change adds description of DT bindings for clock
>> controller found on LPC32xx SoC series.
>>
>> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
>> ---
>>  .../devicetree/bindings/clock/nxp,lpc3220-clk.txt  | 30 ++++++++++++++++++++++
>>  1 file changed, 30 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
>> new file mode 100644
>> index 0000000..20cbca3
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-clk.txt
>> @@ -0,0 +1,30 @@
>> +NXP LPC32xx Clock Controller
>> +
>> +Required properties:
>> +- compatible: should be "nxp,lpc3220-clk"
> 
> Please use a specific model number without 'xx' wildcards. If you have
> multiple chips that are mutually compatible, pick one as the base number
> and then list the others as more specific instances, like
> 
> 	compatible = "nxp,lpc3250-clk", "nxp,lpc3220-clk";

Do you ask me to change a title? You may see that compatible property
does not contain any wildcards?

--
Vladimir

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

* Re: [PATCH 09/11] clk: lpc32xx: add common clock framework driver
  2015-11-20 14:04     ` Arnd Bergmann
  (?)
@ 2015-11-20 18:07       ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 18:07 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: Rob Herring, Stephen Boyd, Michael Turquette, Roland Stigge,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Russell King,
	linux-clk-u79uwXL29TY76Z2rM5mHXA

On 20.11.2015 16:04, Arnd Bergmann wrote:
> On Friday 20 November 2015 03:05:09 Vladimir Zapolskiy wrote:
>> +
>> +struct clk_proto_t {
>> +       const char *name;
>> +       const u8 parents[LPC32XX_CLK_PARENTS_MAX];
>> +       u8 num_parents;
>> +       unsigned long flags;
>> +};
>> +
>> +#define CLK_PREFIX(LITERAL)            LPC32XX_CLK_ ## LITERAL
>> +#define NUMARGS(...)   (sizeof((int[]){__VA_ARGS__})/sizeof(int))
>> +
>> +#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)           \
>> +       [CLK_PREFIX(_idx)] = {                                  \
>> +               .name = #_name,                                 \
>> +               .flags = _flags,                                \
>> +               .parents = { __VA_ARGS__ },                     \
>> +               .num_parents = NUMARGS(__VA_ARGS__),            \
>> +        }
>> +
> 
> Try to not outsmart yourself with the macros. It's better to avoid
> string concatenation so it's possible to grep for uses of some
> constant.
> 
> I would probably not use a macro at all here and just open-code the
> entire table. If you ensure that '0' is not a valid parent, then
> you can leave out the .num_parents field and just look for the
> zero-termination.

Macros are here for simplicity, code size reduction and to avoid some
stupid mistakes like different number of .parents and .num_parents.

I believe macro unwrapping in this code will add another 1000 LoC and
will result in quite unreadable and less maintainable code.

--
Best wishes,
Vladimir
--
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] 67+ messages in thread

* Re: [PATCH 09/11] clk: lpc32xx: add common clock framework driver
@ 2015-11-20 18:07       ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 18:07 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Rob Herring, Stephen Boyd, Michael Turquette, Roland Stigge,
	devicetree, Russell King, linux-clk

On 20.11.2015 16:04, Arnd Bergmann wrote:
> On Friday 20 November 2015 03:05:09 Vladimir Zapolskiy wrote:
>> +
>> +struct clk_proto_t {
>> +       const char *name;
>> +       const u8 parents[LPC32XX_CLK_PARENTS_MAX];
>> +       u8 num_parents;
>> +       unsigned long flags;
>> +};
>> +
>> +#define CLK_PREFIX(LITERAL)            LPC32XX_CLK_ ## LITERAL
>> +#define NUMARGS(...)   (sizeof((int[]){__VA_ARGS__})/sizeof(int))
>> +
>> +#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)           \
>> +       [CLK_PREFIX(_idx)] = {                                  \
>> +               .name = #_name,                                 \
>> +               .flags = _flags,                                \
>> +               .parents = { __VA_ARGS__ },                     \
>> +               .num_parents = NUMARGS(__VA_ARGS__),            \
>> +        }
>> +
> 
> Try to not outsmart yourself with the macros. It's better to avoid
> string concatenation so it's possible to grep for uses of some
> constant.
> 
> I would probably not use a macro at all here and just open-code the
> entire table. If you ensure that '0' is not a valid parent, then
> you can leave out the .num_parents field and just look for the
> zero-termination.

Macros are here for simplicity, code size reduction and to avoid some
stupid mistakes like different number of .parents and .num_parents.

I believe macro unwrapping in this code will add another 1000 LoC and
will result in quite unreadable and less maintainable code.

--
Best wishes,
Vladimir

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

* [PATCH 09/11] clk: lpc32xx: add common clock framework driver
@ 2015-11-20 18:07       ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 18:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 20.11.2015 16:04, Arnd Bergmann wrote:
> On Friday 20 November 2015 03:05:09 Vladimir Zapolskiy wrote:
>> +
>> +struct clk_proto_t {
>> +       const char *name;
>> +       const u8 parents[LPC32XX_CLK_PARENTS_MAX];
>> +       u8 num_parents;
>> +       unsigned long flags;
>> +};
>> +
>> +#define CLK_PREFIX(LITERAL)            LPC32XX_CLK_ ## LITERAL
>> +#define NUMARGS(...)   (sizeof((int[]){__VA_ARGS__})/sizeof(int))
>> +
>> +#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)           \
>> +       [CLK_PREFIX(_idx)] = {                                  \
>> +               .name = #_name,                                 \
>> +               .flags = _flags,                                \
>> +               .parents = { __VA_ARGS__ },                     \
>> +               .num_parents = NUMARGS(__VA_ARGS__),            \
>> +        }
>> +
> 
> Try to not outsmart yourself with the macros. It's better to avoid
> string concatenation so it's possible to grep for uses of some
> constant.
> 
> I would probably not use a macro at all here and just open-code the
> entire table. If you ensure that '0' is not a valid parent, then
> you can leave out the .num_parents field and just look for the
> zero-termination.

Macros are here for simplicity, code size reduction and to avoid some
stupid mistakes like different number of .parents and .num_parents.

I believe macro unwrapping in this code will add another 1000 LoC and
will result in quite unreadable and less maintainable code.

--
Best wishes,
Vladimir

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

* Re: [PATCH 02/11] dt-bindings: clock: add description of LPC32xx USB clock controller
  2015-11-20 16:41     ` Rob Herring
@ 2015-11-20 18:14       ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 18:14 UTC (permalink / raw)
  To: Rob Herring
  Cc: Stephen Boyd, Michael Turquette, Arnd Bergmann, Russell King,
	Roland Stigge, linux-clk, devicetree, linux-arm-kernel

On 20.11.2015 18:41, Rob Herring wrote:
> On Fri, Nov 20, 2015 at 03:05:02AM +0200, Vladimir Zapolskiy wrote:
>> NXP LPC32xx USB controller has a subdevice, which controls USB AHB
>> slave, USB OTG, USB OHCI, USB device and I2C controller to USB phy
>> clocks, this change adds description of the clock controller, for more
>> details reference LPC32xx User's Manual, namely USB control, OTG clock
>> control and OTG clock status registers.
>>
>> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
>> ---
>>  .../bindings/clock/nxp,lpc3220-usb-clk.txt         | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
>> new file mode 100644
>> index 0000000..67fba7f
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
>> @@ -0,0 +1,22 @@
>> +NXP LPC32xx USB Clock Controller
>> +
>> +Required properties:
>> +- compatible: should be "nxp,lpc3220-usb-clk"
>> +- reg:  should contain clock controller registers location and length
>> +- #clock-cells: must be 1, the cell holds id of a clock provided by the
>> +  USB clock controller
>> +
>> +Examples:
>> +
>> +	usb {
> 
> I don't understand the full structure of USB blocks. Can you make the 
> example complete. All the blocks are a child of this node?

Yes, all the blocks are children of this node.

USB controller contains 5 subdevices, interestingly one of these
subdevices, I2C controller, is the same as a general purpose I2C
controller device.

Please find some description here:
http://www.spinics.net/lists/devicetree/msg98538.html

>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
>> +		compatible = "simple-bus";
>> +		ranges = <0x0 0x31020000 0x00001000>;
>> +
>> +		usbclk: clock-controller@F00 {
> lower case                               ^
> 
>> +			compatible = "nxp,lpc3220-usb-clk";
>> +			reg = <0xF00 0x100>;
> 
> lower case

Ok, thanks for pointing it out.

>> +			#clock-cells = <1>;
>> +		};
>> +	};
>> -- 
>> 2.1.4
>>

--
Vladimir

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

* [PATCH 02/11] dt-bindings: clock: add description of LPC32xx USB clock controller
@ 2015-11-20 18:14       ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-20 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 20.11.2015 18:41, Rob Herring wrote:
> On Fri, Nov 20, 2015 at 03:05:02AM +0200, Vladimir Zapolskiy wrote:
>> NXP LPC32xx USB controller has a subdevice, which controls USB AHB
>> slave, USB OTG, USB OHCI, USB device and I2C controller to USB phy
>> clocks, this change adds description of the clock controller, for more
>> details reference LPC32xx User's Manual, namely USB control, OTG clock
>> control and OTG clock status registers.
>>
>> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
>> ---
>>  .../bindings/clock/nxp,lpc3220-usb-clk.txt         | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
>> new file mode 100644
>> index 0000000..67fba7f
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/nxp,lpc3220-usb-clk.txt
>> @@ -0,0 +1,22 @@
>> +NXP LPC32xx USB Clock Controller
>> +
>> +Required properties:
>> +- compatible: should be "nxp,lpc3220-usb-clk"
>> +- reg:  should contain clock controller registers location and length
>> +- #clock-cells: must be 1, the cell holds id of a clock provided by the
>> +  USB clock controller
>> +
>> +Examples:
>> +
>> +	usb {
> 
> I don't understand the full structure of USB blocks. Can you make the 
> example complete. All the blocks are a child of this node?

Yes, all the blocks are children of this node.

USB controller contains 5 subdevices, interestingly one of these
subdevices, I2C controller, is the same as a general purpose I2C
controller device.

Please find some description here:
http://www.spinics.net/lists/devicetree/msg98538.html

>> +		#address-cells = <1>;
>> +		#size-cells = <1>;
>> +		compatible = "simple-bus";
>> +		ranges = <0x0 0x31020000 0x00001000>;
>> +
>> +		usbclk: clock-controller at F00 {
> lower case                               ^
> 
>> +			compatible = "nxp,lpc3220-usb-clk";
>> +			reg = <0xF00 0x100>;
> 
> lower case

Ok, thanks for pointing it out.

>> +			#clock-cells = <1>;
>> +		};
>> +	};
>> -- 
>> 2.1.4
>>

--
Vladimir

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

* Re: [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
  2015-11-20 18:01         ` Vladimir Zapolskiy
@ 2015-11-20 20:03           ` Arnd Bergmann
  -1 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 20:03 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: linux-arm-kernel, Rob Herring, Stephen Boyd, Michael Turquette,
	Roland Stigge, devicetree, Russell King, linux-clk

On Friday 20 November 2015 20:01:00 Vladimir Zapolskiy wrote:
> > 
> > Please use a specific model number without 'xx' wildcards. If you have
> > multiple chips that are mutually compatible, pick one as the base number
> > and then list the others as more specific instances, like
> > 
> >       compatible = "nxp,lpc3250-clk", "nxp,lpc3220-clk";
> 
> Do you ask me to change a title? You may see that compatible property
> does not contain any wildcards?
> 

Nevermind, I saw so many 'xx's that I didn't notice you got the
important one right.

	Arnd

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

* [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller
@ 2015-11-20 20:03           ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 20:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 November 2015 20:01:00 Vladimir Zapolskiy wrote:
> > 
> > Please use a specific model number without 'xx' wildcards. If you have
> > multiple chips that are mutually compatible, pick one as the base number
> > and then list the others as more specific instances, like
> > 
> >       compatible = "nxp,lpc3250-clk", "nxp,lpc3220-clk";
> 
> Do you ask me to change a title? You may see that compatible property
> does not contain any wildcards?
> 

Nevermind, I saw so many 'xx's that I didn't notice you got the
important one right.

	Arnd

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

* Re: [PATCH 09/11] clk: lpc32xx: add common clock framework driver
  2015-11-20 18:07       ` Vladimir Zapolskiy
@ 2015-11-20 20:20         ` Arnd Bergmann
  -1 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 20:20 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: linux-arm-kernel, Rob Herring, Stephen Boyd, Michael Turquette,
	Roland Stigge, devicetree, Russell King, linux-clk

On Friday 20 November 2015 20:07:46 Vladimir Zapolskiy wrote:
> On 20.11.2015 16:04, Arnd Bergmann wrote:
> > On Friday 20 November 2015 03:05:09 Vladimir Zapolskiy wrote:
> >> +
> >> +struct clk_proto_t {
> >> +       const char *name;
> >> +       const u8 parents[LPC32XX_CLK_PARENTS_MAX];
> >> +       u8 num_parents;
> >> +       unsigned long flags;
> >> +};
> >> +
> >> +#define CLK_PREFIX(LITERAL)            LPC32XX_CLK_ ## LITERAL
> >> +#define NUMARGS(...)   (sizeof((int[]){__VA_ARGS__})/sizeof(int))
> >> +
> >> +#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)           \
> >> +       [CLK_PREFIX(_idx)] = {                                  \
> >> +               .name = #_name,                                 \
> >> +               .flags = _flags,                                \
> >> +               .parents = { __VA_ARGS__ },                     \
> >> +               .num_parents = NUMARGS(__VA_ARGS__),            \
> >> +        }
> >> +
> > 
> > Try to not outsmart yourself with the macros. It's better to avoid
> > string concatenation so it's possible to grep for uses of some
> > constant.
> > 
> > I would probably not use a macro at all here and just open-code the
> > entire table. If you ensure that '0' is not a valid parent, then
> > you can leave out the .num_parents field and just look for the
> > zero-termination.
> 
> Macros are here for simplicity, code size reduction and to avoid some
> stupid mistakes like different number of .parents and .num_parents.
> 
> I believe macro unwrapping in this code will add another 1000 LoC and
> will result in quite unreadable and less maintainable code.

I mean specifically the macro above:

static const struct clk_proto_t clk_proto[LPC32XX_CLK_CCF_MAX] __initconst = {
+       LPC32XX_CLK_DEFINE(XTAL, xtal, 0x0),
+       LPC32XX_CLK_DEFINE(XTAL_32K, xtal_32k, 0x0),
+
+       LPC32XX_CLK_DEFINE(RTC, rtc, 0x0, LPC32XX_CLK_XTAL_32K),
+       LPC32XX_CLK_DEFINE(OSC, osc, CLK_IGNORE_UNUSED, LPC32XX_CLK_XTAL),
+       LPC32XX_CLK_DEFINE(SYS, sys, CLK_IGNORE_UNUSED,
+               LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),
+       LPC32XX_CLK_DEFINE(PLL397X, pll_397x, CLK_IGNORE_UNUSED,
+               LPC32XX_CLK_RTC),

can become

static const struct clk_proto_t clk_proto[] __initconst = {
	[LPC32XX_CLK_XTAL]	= { "xtal" },
	[LPC32XX_CLK_XTAL_32K]	= { "xtal_32k" },
	[LPC32XX_CLK_RTC]	= { "rtc",
			.parents = { LPC32XX_CLK_XTAL_32K, 0 } },
	[LPC32XX_CLK_OSC]	= { "osc", CLK_IGNORE_UNUSED,
			.parents = { LPC32XX_CLK_XTAL, 0 } },
	[LPC32XX_CLK_SYS]	= { "sys", CLK_IGNORE_UNUSED,
			.parents = { LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X, 0) },
	[LPC32XX_CLK_PLL397X]	= { "pll_397x", CLK_IGNORE_UNUSED,
			.parents = { LPC32XX_CLK_RTC, 0 },

Not harder to read at all, not really longer, but easier to grep for.

	Arnd

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

* [PATCH 09/11] clk: lpc32xx: add common clock framework driver
@ 2015-11-20 20:20         ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 20:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 November 2015 20:07:46 Vladimir Zapolskiy wrote:
> On 20.11.2015 16:04, Arnd Bergmann wrote:
> > On Friday 20 November 2015 03:05:09 Vladimir Zapolskiy wrote:
> >> +
> >> +struct clk_proto_t {
> >> +       const char *name;
> >> +       const u8 parents[LPC32XX_CLK_PARENTS_MAX];
> >> +       u8 num_parents;
> >> +       unsigned long flags;
> >> +};
> >> +
> >> +#define CLK_PREFIX(LITERAL)            LPC32XX_CLK_ ## LITERAL
> >> +#define NUMARGS(...)   (sizeof((int[]){__VA_ARGS__})/sizeof(int))
> >> +
> >> +#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)           \
> >> +       [CLK_PREFIX(_idx)] = {                                  \
> >> +               .name = #_name,                                 \
> >> +               .flags = _flags,                                \
> >> +               .parents = { __VA_ARGS__ },                     \
> >> +               .num_parents = NUMARGS(__VA_ARGS__),            \
> >> +        }
> >> +
> > 
> > Try to not outsmart yourself with the macros. It's better to avoid
> > string concatenation so it's possible to grep for uses of some
> > constant.
> > 
> > I would probably not use a macro at all here and just open-code the
> > entire table. If you ensure that '0' is not a valid parent, then
> > you can leave out the .num_parents field and just look for the
> > zero-termination.
> 
> Macros are here for simplicity, code size reduction and to avoid some
> stupid mistakes like different number of .parents and .num_parents.
> 
> I believe macro unwrapping in this code will add another 1000 LoC and
> will result in quite unreadable and less maintainable code.

I mean specifically the macro above:

static const struct clk_proto_t clk_proto[LPC32XX_CLK_CCF_MAX] __initconst = {
+       LPC32XX_CLK_DEFINE(XTAL, xtal, 0x0),
+       LPC32XX_CLK_DEFINE(XTAL_32K, xtal_32k, 0x0),
+
+       LPC32XX_CLK_DEFINE(RTC, rtc, 0x0, LPC32XX_CLK_XTAL_32K),
+       LPC32XX_CLK_DEFINE(OSC, osc, CLK_IGNORE_UNUSED, LPC32XX_CLK_XTAL),
+       LPC32XX_CLK_DEFINE(SYS, sys, CLK_IGNORE_UNUSED,
+               LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),
+       LPC32XX_CLK_DEFINE(PLL397X, pll_397x, CLK_IGNORE_UNUSED,
+               LPC32XX_CLK_RTC),

can become

static const struct clk_proto_t clk_proto[] __initconst = {
	[LPC32XX_CLK_XTAL]	= { "xtal" },
	[LPC32XX_CLK_XTAL_32K]	= { "xtal_32k" },
	[LPC32XX_CLK_RTC]	= { "rtc",
			.parents = { LPC32XX_CLK_XTAL_32K, 0 } },
	[LPC32XX_CLK_OSC]	= { "osc", CLK_IGNORE_UNUSED,
			.parents = { LPC32XX_CLK_XTAL, 0 } },
	[LPC32XX_CLK_SYS]	= { "sys", CLK_IGNORE_UNUSED,
			.parents = { LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X, 0) },
	[LPC32XX_CLK_PLL397X]	= { "pll_397x", CLK_IGNORE_UNUSED,
			.parents = { LPC32XX_CLK_RTC, 0 },

Not harder to read at all, not really longer, but easier to grep for.

	Arnd

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

* Re: [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
  2015-11-20 17:58       ` Vladimir Zapolskiy
@ 2015-11-20 21:07         ` Arnd Bergmann
  -1 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 21:07 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Vladimir Zapolskiy, Roland Stigge, devicetree, Russell King,
	Michael Turquette, Stephen Boyd, Rob Herring, linux-clk

On Friday 20 November 2015 19:58:06 Vladimir Zapolskiy wrote:
> On 20.11.2015 15:56, Arnd Bergmann wrote:
> > On Friday 20 November 2015 03:05:03 Vladimir Zapolskiy wrote:
> >> +
> >> +/* LPC32XX System Control Block clocks */
> >> +#define LPC32XX_CLK_RTC                0
> >> +#define LPC32XX_CLK_DMA                1
> >> +#define LPC32XX_CLK_MLC                2
> >> +#define LPC32XX_CLK_SLC                3
> >> +#define LPC32XX_CLK_LCD                4
> >> +#define LPC32XX_CLK_MAC                5
> >> +#define LPC32XX_CLK_SD         6
> >> +#define LPC32XX_CLK_DDRAM      7
> >> +#define LPC32XX_CLK_SSP0       8
> >> +#define LPC32XX_CLK_SSP1       9
> >> +#define LPC32XX_CLK_UART3      10
> >> +#define LPC32XX_CLK_UART4      11
> >> +#define LPC32XX_CLK_UART5      12
> >> +#define LPC32XX_CLK_UART6      13
> >> +#define LPC32XX_CLK_IRDA       14
> >> +#define LPC32XX_CLK_I2C1       15
> >>
> > 
> > Any chance we can avoid the include file? This is going to make it really
> > hard to merge everything in one merge window with the dependencies between
> > the driver, the bindings and the platform code.
> 
> I see only one option to avoid this commit, namely squash it with the
> CCF driver and merge it before making changes in DTS.
> 
> However I suppose ARM trees won't be synced on clk tree, so probably it
> won't simplify maintainer's work.

I think the best way for this would then be to have one git branch that
contains the binding header, and base the other patches on top of that
branch, for both the changes going into the clk git and arm-soc.

That way, both have the commit we need, but we don't get duplicate
commits when they are both merged into mainline.

> > If there is a way to describe the clocks based on numbers from the
> > data sheet instead of making up your own, that makes life much
> > easier for us.
> 
> There are no any clock numbers in the datasheet, unfortunately.

I was thinking that maybe there would be a logical numbering based
on the register layout, e.g. a tuple of register index and bit position,
but it seems that the mmio area is too irregular to make that easy.

	Arnd

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

* [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
@ 2015-11-20 21:07         ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2015-11-20 21:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 20 November 2015 19:58:06 Vladimir Zapolskiy wrote:
> On 20.11.2015 15:56, Arnd Bergmann wrote:
> > On Friday 20 November 2015 03:05:03 Vladimir Zapolskiy wrote:
> >> +
> >> +/* LPC32XX System Control Block clocks */
> >> +#define LPC32XX_CLK_RTC                0
> >> +#define LPC32XX_CLK_DMA                1
> >> +#define LPC32XX_CLK_MLC                2
> >> +#define LPC32XX_CLK_SLC                3
> >> +#define LPC32XX_CLK_LCD                4
> >> +#define LPC32XX_CLK_MAC                5
> >> +#define LPC32XX_CLK_SD         6
> >> +#define LPC32XX_CLK_DDRAM      7
> >> +#define LPC32XX_CLK_SSP0       8
> >> +#define LPC32XX_CLK_SSP1       9
> >> +#define LPC32XX_CLK_UART3      10
> >> +#define LPC32XX_CLK_UART4      11
> >> +#define LPC32XX_CLK_UART5      12
> >> +#define LPC32XX_CLK_UART6      13
> >> +#define LPC32XX_CLK_IRDA       14
> >> +#define LPC32XX_CLK_I2C1       15
> >>
> > 
> > Any chance we can avoid the include file? This is going to make it really
> > hard to merge everything in one merge window with the dependencies between
> > the driver, the bindings and the platform code.
> 
> I see only one option to avoid this commit, namely squash it with the
> CCF driver and merge it before making changes in DTS.
> 
> However I suppose ARM trees won't be synced on clk tree, so probably it
> won't simplify maintainer's work.

I think the best way for this would then be to have one git branch that
contains the binding header, and base the other patches on top of that
branch, for both the changes going into the clk git and arm-soc.

That way, both have the commit we need, but we don't get duplicate
commits when they are both merged into mainline.

> > If there is a way to describe the clocks based on numbers from the
> > data sheet instead of making up your own, that makes life much
> > easier for us.
> 
> There are no any clock numbers in the datasheet, unfortunately.

I was thinking that maybe there would be a logical numbering based
on the register layout, e.g. a tuple of register index and bit position,
but it seems that the mmio area is too irregular to make that easy.

	Arnd

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

* Re: [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
  2015-11-20 21:07         ` Arnd Bergmann
@ 2015-11-21 18:53           ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-21 18:53 UTC (permalink / raw)
  To: Arnd Bergmann, linux-arm-kernel
  Cc: Roland Stigge, devicetree, Russell King, Michael Turquette,
	Stephen Boyd, Rob Herring, linux-clk

Hi Arnd,

On 20.11.2015 23:07, Arnd Bergmann wrote:
> On Friday 20 November 2015 19:58:06 Vladimir Zapolskiy wrote:
>> On 20.11.2015 15:56, Arnd Bergmann wrote:
>>> On Friday 20 November 2015 03:05:03 Vladimir Zapolskiy wrote:
>>>> +
>>>> +/* LPC32XX System Control Block clocks */
>>>> +#define LPC32XX_CLK_RTC                0
>>>> +#define LPC32XX_CLK_DMA                1
>>>> +#define LPC32XX_CLK_MLC                2
>>>> +#define LPC32XX_CLK_SLC                3
>>>> +#define LPC32XX_CLK_LCD                4
>>>> +#define LPC32XX_CLK_MAC                5
>>>> +#define LPC32XX_CLK_SD         6
>>>> +#define LPC32XX_CLK_DDRAM      7
>>>> +#define LPC32XX_CLK_SSP0       8
>>>> +#define LPC32XX_CLK_SSP1       9
>>>> +#define LPC32XX_CLK_UART3      10
>>>> +#define LPC32XX_CLK_UART4      11
>>>> +#define LPC32XX_CLK_UART5      12
>>>> +#define LPC32XX_CLK_UART6      13
>>>> +#define LPC32XX_CLK_IRDA       14
>>>> +#define LPC32XX_CLK_I2C1       15
>>>>
>>>
>>> Any chance we can avoid the include file? This is going to make it really
>>> hard to merge everything in one merge window with the dependencies between
>>> the driver, the bindings and the platform code.
>>
>> I see only one option to avoid this commit, namely squash it with the
>> CCF driver and merge it before making changes in DTS.
>>
>> However I suppose ARM trees won't be synced on clk tree, so probably it
>> won't simplify maintainer's work.
> 
> I think the best way for this would then be to have one git branch that
> contains the binding header, and base the other patches on top of that
> branch, for both the changes going into the clk git and arm-soc.
> 
> That way, both have the commit we need, but we don't get duplicate
> commits when they are both merged into mainline.

I isolated the binding header, because in my opinion it may be reviewed
(and hopefully accepted unchanged) separately from the CCF driver. If I
am not mistaken, merging of two branches with an identical commit is
seamless.

It is hard to predict, when the CCF driver gets into mainline, but the
presence of the binding header in arm-soc tree will allow to avoid lots
of conflicts and/or code rebases concerning lpc32xx.dtsi file.

>>> If there is a way to describe the clocks based on numbers from the
>>> data sheet instead of making up your own, that makes life much
>>> easier for us.
>>
>> There are no any clock numbers in the datasheet, unfortunately.
> 
> I was thinking that maybe there would be a logical numbering based
> on the register layout, e.g. a tuple of register index and bit position,
> but it seems that the mmio area is too irregular to make that easy.

Absolutely correct. Only if we consider registers, the clock controller
registers are scattered in System Control Block, which also contains 3
wakeup controllers, partially pinmux and DMA settings, "software
interrupt" controller, fine tuned configurations of ARM core debugging
mechanisms and so on.

--
With best wishes,
Vladimir

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

* [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers
@ 2015-11-21 18:53           ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-21 18:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On 20.11.2015 23:07, Arnd Bergmann wrote:
> On Friday 20 November 2015 19:58:06 Vladimir Zapolskiy wrote:
>> On 20.11.2015 15:56, Arnd Bergmann wrote:
>>> On Friday 20 November 2015 03:05:03 Vladimir Zapolskiy wrote:
>>>> +
>>>> +/* LPC32XX System Control Block clocks */
>>>> +#define LPC32XX_CLK_RTC                0
>>>> +#define LPC32XX_CLK_DMA                1
>>>> +#define LPC32XX_CLK_MLC                2
>>>> +#define LPC32XX_CLK_SLC                3
>>>> +#define LPC32XX_CLK_LCD                4
>>>> +#define LPC32XX_CLK_MAC                5
>>>> +#define LPC32XX_CLK_SD         6
>>>> +#define LPC32XX_CLK_DDRAM      7
>>>> +#define LPC32XX_CLK_SSP0       8
>>>> +#define LPC32XX_CLK_SSP1       9
>>>> +#define LPC32XX_CLK_UART3      10
>>>> +#define LPC32XX_CLK_UART4      11
>>>> +#define LPC32XX_CLK_UART5      12
>>>> +#define LPC32XX_CLK_UART6      13
>>>> +#define LPC32XX_CLK_IRDA       14
>>>> +#define LPC32XX_CLK_I2C1       15
>>>>
>>>
>>> Any chance we can avoid the include file? This is going to make it really
>>> hard to merge everything in one merge window with the dependencies between
>>> the driver, the bindings and the platform code.
>>
>> I see only one option to avoid this commit, namely squash it with the
>> CCF driver and merge it before making changes in DTS.
>>
>> However I suppose ARM trees won't be synced on clk tree, so probably it
>> won't simplify maintainer's work.
> 
> I think the best way for this would then be to have one git branch that
> contains the binding header, and base the other patches on top of that
> branch, for both the changes going into the clk git and arm-soc.
> 
> That way, both have the commit we need, but we don't get duplicate
> commits when they are both merged into mainline.

I isolated the binding header, because in my opinion it may be reviewed
(and hopefully accepted unchanged) separately from the CCF driver. If I
am not mistaken, merging of two branches with an identical commit is
seamless.

It is hard to predict, when the CCF driver gets into mainline, but the
presence of the binding header in arm-soc tree will allow to avoid lots
of conflicts and/or code rebases concerning lpc32xx.dtsi file.

>>> If there is a way to describe the clocks based on numbers from the
>>> data sheet instead of making up your own, that makes life much
>>> easier for us.
>>
>> There are no any clock numbers in the datasheet, unfortunately.
> 
> I was thinking that maybe there would be a logical numbering based
> on the register layout, e.g. a tuple of register index and bit position,
> but it seems that the mmio area is too irregular to make that easy.

Absolutely correct. Only if we consider registers, the clock controller
registers are scattered in System Control Block, which also contains 3
wakeup controllers, partially pinmux and DMA settings, "software
interrupt" controller, fine tuned configurations of ARM core debugging
mechanisms and so on.

--
With best wishes,
Vladimir

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

* Re: [PATCH 08/11] clk: lpc18xx: add NXP specific common clock framework selection
  2015-11-20  1:05     ` Vladimir Zapolskiy
  (?)
@ 2015-11-22 20:38       ` Joachim Eastwood
  -1 siblings, 0 replies; 67+ messages in thread
From: Joachim Eastwood @ 2015-11-22 20:38 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann,
	Russell King, Roland Stigge, linux-clk, devicetree,
	linux-arm-kernel

Hi Vladimir,

On 20 November 2015 at 02:05, Vladimir Zapolskiy <vz@mleia.com> wrote:
> The change adds COMMON_CLK_NXP configuration symbol and enables it for
> NXP LPC18XX architecture, this is needed to reuse drivers/clk/nxp
> folder for NXP common clock framework drivers other than LPC18XX one.
>
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> Cc: Joachim Eastwood <manabian@gmail.com>
> ---
>  arch/arm/Kconfig     | 1 +
>  drivers/clk/Kconfig  | 5 +++++
>  drivers/clk/Makefile | 2 +-
>  3 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 0365cbb..c318277 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -952,6 +952,7 @@ config ARCH_LPC18XX
>         select ARCH_HAS_RESET_CONTROLLER
>         select ARM_AMBA
>         select CLKSRC_LPC32XX
> +       select COMMON_CLK

COMMON_CLK is already selected by ARM_SINGLE_ARMV7M which ARCH_LPC18XX
depends on so this hunk should not be necessary.

>         select PINCTRL
>         help
>           Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index c3e3a02..7fc1eb9 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -175,6 +175,11 @@ config COMMON_CLK_PWM
>           Adapter driver so that any PWM output can be (mis)used as clock signal
>           at 50% duty cycle.
>
> +config COMMON_CLK_NXP
> +       def_bool COMMON_CLK && ARCH_LPC18XX
> +       ---help---
> +         Support for clock providers on NXP platforms.
> +
>  config COMMON_CLK_PXA
>         def_bool COMMON_CLK && ARCH_PXA
>         ---help---
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 820714c..15603c1 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -62,8 +62,8 @@ endif
>  obj-$(CONFIG_PLAT_ORION)               += mvebu/
>  obj-$(CONFIG_ARCH_MESON)               += meson/
>  obj-$(CONFIG_ARCH_MXS)                 += mxs/
> -obj-$(CONFIG_ARCH_LPC18XX)             += nxp/
>  obj-$(CONFIG_MACH_PISTACHIO)           += pistachio/
> +obj-$(CONFIG_COMMON_CLK_NXP)           += nxp/
>  obj-$(CONFIG_COMMON_CLK_PXA)           += pxa/
>  obj-$(CONFIG_COMMON_CLK_QCOM)          += qcom/
>  obj-$(CONFIG_ARCH_ROCKCHIP)            += rockchip/
> --

Other than the one comment above it looks good to me:
Acked-by: Joachim Eastwood <manabian@gmail.com>

I'll try to find the time look through the other patches you have for
lpc32xx. I also have a EA LPC3250 dev kit v2
(http://embeddedartists.com/products/kits/lpc3250_kit_v2.php) in my
collection.

regards,
Joachim Eastwood

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

* Re: [PATCH 08/11] clk: lpc18xx: add NXP specific common clock framework selection
@ 2015-11-22 20:38       ` Joachim Eastwood
  0 siblings, 0 replies; 67+ messages in thread
From: Joachim Eastwood @ 2015-11-22 20:38 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: Rob Herring, Stephen Boyd, Michael Turquette, Arnd Bergmann,
	Russell King, Roland Stigge, linux-clk, devicetree,
	linux-arm-kernel

Hi Vladimir,

On 20 November 2015 at 02:05, Vladimir Zapolskiy <vz@mleia.com> wrote:
> The change adds COMMON_CLK_NXP configuration symbol and enables it for
> NXP LPC18XX architecture, this is needed to reuse drivers/clk/nxp
> folder for NXP common clock framework drivers other than LPC18XX one.
>
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> Cc: Joachim Eastwood <manabian@gmail.com>
> ---
>  arch/arm/Kconfig     | 1 +
>  drivers/clk/Kconfig  | 5 +++++
>  drivers/clk/Makefile | 2 +-
>  3 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 0365cbb..c318277 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -952,6 +952,7 @@ config ARCH_LPC18XX
>         select ARCH_HAS_RESET_CONTROLLER
>         select ARM_AMBA
>         select CLKSRC_LPC32XX
> +       select COMMON_CLK

COMMON_CLK is already selected by ARM_SINGLE_ARMV7M which ARCH_LPC18XX
depends on so this hunk should not be necessary.

>         select PINCTRL
>         help
>           Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index c3e3a02..7fc1eb9 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -175,6 +175,11 @@ config COMMON_CLK_PWM
>           Adapter driver so that any PWM output can be (mis)used as clock signal
>           at 50% duty cycle.
>
> +config COMMON_CLK_NXP
> +       def_bool COMMON_CLK && ARCH_LPC18XX
> +       ---help---
> +         Support for clock providers on NXP platforms.
> +
>  config COMMON_CLK_PXA
>         def_bool COMMON_CLK && ARCH_PXA
>         ---help---
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 820714c..15603c1 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -62,8 +62,8 @@ endif
>  obj-$(CONFIG_PLAT_ORION)               += mvebu/
>  obj-$(CONFIG_ARCH_MESON)               += meson/
>  obj-$(CONFIG_ARCH_MXS)                 += mxs/
> -obj-$(CONFIG_ARCH_LPC18XX)             += nxp/
>  obj-$(CONFIG_MACH_PISTACHIO)           += pistachio/
> +obj-$(CONFIG_COMMON_CLK_NXP)           += nxp/
>  obj-$(CONFIG_COMMON_CLK_PXA)           += pxa/
>  obj-$(CONFIG_COMMON_CLK_QCOM)          += qcom/
>  obj-$(CONFIG_ARCH_ROCKCHIP)            += rockchip/
> --

Other than the one comment above it looks good to me:
Acked-by: Joachim Eastwood <manabian@gmail.com>

I'll try to find the time look through the other patches you have for
lpc32xx. I also have a EA LPC3250 dev kit v2
(http://embeddedartists.com/products/kits/lpc3250_kit_v2.php) in my
collection.

regards,
Joachim Eastwood

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

* [PATCH 08/11] clk: lpc18xx: add NXP specific common clock framework selection
@ 2015-11-22 20:38       ` Joachim Eastwood
  0 siblings, 0 replies; 67+ messages in thread
From: Joachim Eastwood @ 2015-11-22 20:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vladimir,

On 20 November 2015 at 02:05, Vladimir Zapolskiy <vz@mleia.com> wrote:
> The change adds COMMON_CLK_NXP configuration symbol and enables it for
> NXP LPC18XX architecture, this is needed to reuse drivers/clk/nxp
> folder for NXP common clock framework drivers other than LPC18XX one.
>
> Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
> Cc: Joachim Eastwood <manabian@gmail.com>
> ---
>  arch/arm/Kconfig     | 1 +
>  drivers/clk/Kconfig  | 5 +++++
>  drivers/clk/Makefile | 2 +-
>  3 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 0365cbb..c318277 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -952,6 +952,7 @@ config ARCH_LPC18XX
>         select ARCH_HAS_RESET_CONTROLLER
>         select ARM_AMBA
>         select CLKSRC_LPC32XX
> +       select COMMON_CLK

COMMON_CLK is already selected by ARM_SINGLE_ARMV7M which ARCH_LPC18XX
depends on so this hunk should not be necessary.

>         select PINCTRL
>         help
>           Support for NXP's LPC18xx Cortex-M3 and LPC43xx Cortex-M4
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index c3e3a02..7fc1eb9 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -175,6 +175,11 @@ config COMMON_CLK_PWM
>           Adapter driver so that any PWM output can be (mis)used as clock signal
>           at 50% duty cycle.
>
> +config COMMON_CLK_NXP
> +       def_bool COMMON_CLK && ARCH_LPC18XX
> +       ---help---
> +         Support for clock providers on NXP platforms.
> +
>  config COMMON_CLK_PXA
>         def_bool COMMON_CLK && ARCH_PXA
>         ---help---
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> index 820714c..15603c1 100644
> --- a/drivers/clk/Makefile
> +++ b/drivers/clk/Makefile
> @@ -62,8 +62,8 @@ endif
>  obj-$(CONFIG_PLAT_ORION)               += mvebu/
>  obj-$(CONFIG_ARCH_MESON)               += meson/
>  obj-$(CONFIG_ARCH_MXS)                 += mxs/
> -obj-$(CONFIG_ARCH_LPC18XX)             += nxp/
>  obj-$(CONFIG_MACH_PISTACHIO)           += pistachio/
> +obj-$(CONFIG_COMMON_CLK_NXP)           += nxp/
>  obj-$(CONFIG_COMMON_CLK_PXA)           += pxa/
>  obj-$(CONFIG_COMMON_CLK_QCOM)          += qcom/
>  obj-$(CONFIG_ARCH_ROCKCHIP)            += rockchip/
> --

Other than the one comment above it looks good to me:
Acked-by: Joachim Eastwood <manabian@gmail.com>

I'll try to find the time look through the other patches you have for
lpc32xx. I also have a EA LPC3250 dev kit v2
(http://embeddedartists.com/products/kits/lpc3250_kit_v2.php) in my
collection.

regards,
Joachim Eastwood

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

* Re: [PATCH 09/11] clk: lpc32xx: add common clock framework driver
  2015-11-20 20:20         ` Arnd Bergmann
@ 2015-11-29 13:00           ` Vladimir Zapolskiy
  -1 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-29 13:00 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, Rob Herring, Stephen Boyd, Michael Turquette,
	Roland Stigge, devicetree, Russell King, linux-clk

Hi Arnd,

On 20.11.2015 22:20, Arnd Bergmann wrote:
> On Friday 20 November 2015 20:07:46 Vladimir Zapolskiy wrote:
>> On 20.11.2015 16:04, Arnd Bergmann wrote:
>>> On Friday 20 November 2015 03:05:09 Vladimir Zapolskiy wrote:
>>>> +
>>>> +struct clk_proto_t {
>>>> +       const char *name;
>>>> +       const u8 parents[LPC32XX_CLK_PARENTS_MAX];
>>>> +       u8 num_parents;
>>>> +       unsigned long flags;
>>>> +};
>>>> +
>>>> +#define CLK_PREFIX(LITERAL)            LPC32XX_CLK_ ## LITERAL
>>>> +#define NUMARGS(...)   (sizeof((int[]){__VA_ARGS__})/sizeof(int))
>>>> +
>>>> +#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)           \
>>>> +       [CLK_PREFIX(_idx)] = {                                  \
>>>> +               .name = #_name,                                 \
>>>> +               .flags = _flags,                                \
>>>> +               .parents = { __VA_ARGS__ },                     \
>>>> +               .num_parents = NUMARGS(__VA_ARGS__),            \
>>>> +        }
>>>> +
>>>
>>> Try to not outsmart yourself with the macros. It's better to avoid
>>> string concatenation so it's possible to grep for uses of some
>>> constant.
>>>
>>> I would probably not use a macro at all here and just open-code the
>>> entire table. If you ensure that '0' is not a valid parent, then
>>> you can leave out the .num_parents field and just look for the
>>> zero-termination.
>>
>> Macros are here for simplicity, code size reduction and to avoid some
>> stupid mistakes like different number of .parents and .num_parents.
>>
>> I believe macro unwrapping in this code will add another 1000 LoC and
>> will result in quite unreadable and less maintainable code.
> 
> I mean specifically the macro above:
> 
> static const struct clk_proto_t clk_proto[LPC32XX_CLK_CCF_MAX] __initconst = {
> +       LPC32XX_CLK_DEFINE(XTAL, xtal, 0x0),
> +       LPC32XX_CLK_DEFINE(XTAL_32K, xtal_32k, 0x0),
> +
> +       LPC32XX_CLK_DEFINE(RTC, rtc, 0x0, LPC32XX_CLK_XTAL_32K),
> +       LPC32XX_CLK_DEFINE(OSC, osc, CLK_IGNORE_UNUSED, LPC32XX_CLK_XTAL),
> +       LPC32XX_CLK_DEFINE(SYS, sys, CLK_IGNORE_UNUSED,
> +               LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),
> +       LPC32XX_CLK_DEFINE(PLL397X, pll_397x, CLK_IGNORE_UNUSED,
> +               LPC32XX_CLK_RTC),
> 
> can become
> 
> static const struct clk_proto_t clk_proto[] __initconst = {
> 	[LPC32XX_CLK_XTAL]	= { "xtal" },
> 	[LPC32XX_CLK_XTAL_32K]	= { "xtal_32k" },
> 	[LPC32XX_CLK_RTC]	= { "rtc",
> 			.parents = { LPC32XX_CLK_XTAL_32K, 0 } },

this one and all below are two lines instead of one.

Also .num_parents is not set at compilation stage, this will require
running over parents arrays for every registered clock on boot, it might
noticeably slow down the booting process on a 200MHz core.

The clocks in the beginning have not so many parents, at the opposite
extreme the situation is worse:

	LPC32XX_CLK_DEFINE(TEST1, test1, 0x0,
		LPC32XX_CLK_PERIPH, LPC32XX_CLK_RTC, LPC32XX_CLK_OSC),
	LPC32XX_CLK_DEFINE(TEST2, test2, 0x0,
		LPC32XX_CLK_HCLK, LPC32XX_CLK_PERIPH, LPC32XX_CLK_USB,
		LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),

vs.

	[LPC32XX_CLK_TEST1]	= { "test1",
		.parents = { LPC32XX_CLK_PERIPH, LPC32XX_CLK_RTC,
			     LPC32XX_CLK_OSC, 0 } },
	[LPC32XX_CLK_TEST1]	= { "test2",
		.parents = { LPC32XX_CLK_HCLK, LPC32XX_CLK_PERIPH,
			     LPC32XX_CLK_USB, LPC32XX_CLK_OSC,
			     LPC32XX_CLK_PLL397X, 0 } },


> 	[LPC32XX_CLK_OSC]	= { "osc", CLK_IGNORE_UNUSED,
> 			.parents = { LPC32XX_CLK_XTAL, 0 } },
> 	[LPC32XX_CLK_SYS]	= { "sys", CLK_IGNORE_UNUSED,
> 			.parents = { LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X, 0) },
> 	[LPC32XX_CLK_PLL397X]	= { "pll_397x", CLK_IGNORE_UNUSED,
> 			.parents = { LPC32XX_CLK_RTC, 0 },
> 
> Not harder to read at all, not really longer, but easier to grep for.
> 

If it is not principal, I would prefer to keep the original notation,
but convert stringified values to plane strings, all in all the table is
fixed and it is not supposed to be updated anymore.

But in general I got your idea, I can implement it in v2, if you ask.

--
With best wishes,
Vladimir

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

* [PATCH 09/11] clk: lpc32xx: add common clock framework driver
@ 2015-11-29 13:00           ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2015-11-29 13:00 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Arnd,

On 20.11.2015 22:20, Arnd Bergmann wrote:
> On Friday 20 November 2015 20:07:46 Vladimir Zapolskiy wrote:
>> On 20.11.2015 16:04, Arnd Bergmann wrote:
>>> On Friday 20 November 2015 03:05:09 Vladimir Zapolskiy wrote:
>>>> +
>>>> +struct clk_proto_t {
>>>> +       const char *name;
>>>> +       const u8 parents[LPC32XX_CLK_PARENTS_MAX];
>>>> +       u8 num_parents;
>>>> +       unsigned long flags;
>>>> +};
>>>> +
>>>> +#define CLK_PREFIX(LITERAL)            LPC32XX_CLK_ ## LITERAL
>>>> +#define NUMARGS(...)   (sizeof((int[]){__VA_ARGS__})/sizeof(int))
>>>> +
>>>> +#define LPC32XX_CLK_DEFINE(_idx, _name, _flags, ...)           \
>>>> +       [CLK_PREFIX(_idx)] = {                                  \
>>>> +               .name = #_name,                                 \
>>>> +               .flags = _flags,                                \
>>>> +               .parents = { __VA_ARGS__ },                     \
>>>> +               .num_parents = NUMARGS(__VA_ARGS__),            \
>>>> +        }
>>>> +
>>>
>>> Try to not outsmart yourself with the macros. It's better to avoid
>>> string concatenation so it's possible to grep for uses of some
>>> constant.
>>>
>>> I would probably not use a macro at all here and just open-code the
>>> entire table. If you ensure that '0' is not a valid parent, then
>>> you can leave out the .num_parents field and just look for the
>>> zero-termination.
>>
>> Macros are here for simplicity, code size reduction and to avoid some
>> stupid mistakes like different number of .parents and .num_parents.
>>
>> I believe macro unwrapping in this code will add another 1000 LoC and
>> will result in quite unreadable and less maintainable code.
> 
> I mean specifically the macro above:
> 
> static const struct clk_proto_t clk_proto[LPC32XX_CLK_CCF_MAX] __initconst = {
> +       LPC32XX_CLK_DEFINE(XTAL, xtal, 0x0),
> +       LPC32XX_CLK_DEFINE(XTAL_32K, xtal_32k, 0x0),
> +
> +       LPC32XX_CLK_DEFINE(RTC, rtc, 0x0, LPC32XX_CLK_XTAL_32K),
> +       LPC32XX_CLK_DEFINE(OSC, osc, CLK_IGNORE_UNUSED, LPC32XX_CLK_XTAL),
> +       LPC32XX_CLK_DEFINE(SYS, sys, CLK_IGNORE_UNUSED,
> +               LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),
> +       LPC32XX_CLK_DEFINE(PLL397X, pll_397x, CLK_IGNORE_UNUSED,
> +               LPC32XX_CLK_RTC),
> 
> can become
> 
> static const struct clk_proto_t clk_proto[] __initconst = {
> 	[LPC32XX_CLK_XTAL]	= { "xtal" },
> 	[LPC32XX_CLK_XTAL_32K]	= { "xtal_32k" },
> 	[LPC32XX_CLK_RTC]	= { "rtc",
> 			.parents = { LPC32XX_CLK_XTAL_32K, 0 } },

this one and all below are two lines instead of one.

Also .num_parents is not set at compilation stage, this will require
running over parents arrays for every registered clock on boot, it might
noticeably slow down the booting process on a 200MHz core.

The clocks in the beginning have not so many parents, at the opposite
extreme the situation is worse:

	LPC32XX_CLK_DEFINE(TEST1, test1, 0x0,
		LPC32XX_CLK_PERIPH, LPC32XX_CLK_RTC, LPC32XX_CLK_OSC),
	LPC32XX_CLK_DEFINE(TEST2, test2, 0x0,
		LPC32XX_CLK_HCLK, LPC32XX_CLK_PERIPH, LPC32XX_CLK_USB,
		LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X),

vs.

	[LPC32XX_CLK_TEST1]	= { "test1",
		.parents = { LPC32XX_CLK_PERIPH, LPC32XX_CLK_RTC,
			     LPC32XX_CLK_OSC, 0 } },
	[LPC32XX_CLK_TEST1]	= { "test2",
		.parents = { LPC32XX_CLK_HCLK, LPC32XX_CLK_PERIPH,
			     LPC32XX_CLK_USB, LPC32XX_CLK_OSC,
			     LPC32XX_CLK_PLL397X, 0 } },


> 	[LPC32XX_CLK_OSC]	= { "osc", CLK_IGNORE_UNUSED,
> 			.parents = { LPC32XX_CLK_XTAL, 0 } },
> 	[LPC32XX_CLK_SYS]	= { "sys", CLK_IGNORE_UNUSED,
> 			.parents = { LPC32XX_CLK_OSC, LPC32XX_CLK_PLL397X, 0) },
> 	[LPC32XX_CLK_PLL397X]	= { "pll_397x", CLK_IGNORE_UNUSED,
> 			.parents = { LPC32XX_CLK_RTC, 0 },
> 
> Not harder to read at all, not really longer, but easier to grep for.
> 

If it is not principal, I would prefer to keep the original notation,
but convert stringified values to plane strings, all in all the table is
fixed and it is not supposed to be updated anymore.

But in general I got your idea, I can implement it in v2, if you ask.

--
With best wishes,
Vladimir

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

* Re: [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx
  2015-11-20  1:05 ` Vladimir Zapolskiy
                   ` (8 preceding siblings ...)
  (?)
@ 2016-02-09 21:01 ` Sylvain Lemieux
       [not found]   ` <loom.20160209T215103-78-eS7Uydv5nfjZ+VzJOa5vwg@public.gmane.org>
  -1 siblings, 1 reply; 67+ messages in thread
From: Sylvain Lemieux @ 2016-02-09 21:01 UTC (permalink / raw)
  To: devicetree-u79uwXL29TY76Z2rM5mHXA

Vladimir Zapolskiy <vz@...> writes:
> 
> This changeset adds common clock framework driver for NXP LPC32xx
> boards.

Hi Vladimir,

Just to let you know that we did some testing using this changeset;
I installed patches 4 to 7, 10 & 11 on top of 4.5-rc1.

I was able to run our software (SIC1 interrupt sources disable)
without any problem a custom LPC32xx board.

We did not get any problem with the clock signals we are using.

Sylvain Lemieux
 
> Vladimir Zapolskiy (11):
>   dt-bindings: clock: add description of LPC32xx clock controller
>   dt-bindings: clock: add description of LPC32xx USB clock controller
>   dt-bindings: clock: add NXP LPC32xx clock list for consumers
>   arm: dts: lpc32xx: add device nodes for external oscillators
>   arm: dts: lpc32xx: add clock controller device node
>   arm: dts: lpc32xx: add clock properties to device nodes
>   arm: dts: lpc32xx: add USB clock controller
>   clk: lpc18xx: add NXP specific common clock framework selection
>   clk: lpc32xx: add common clock framework driver
>   arm: lpc32xx: switch to common clock framework
>   arm: dts: lpc32xx: remove clock frequency property from UART device
>     nodes




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

* Re: [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx
  2016-02-09 21:01 ` [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx Sylvain Lemieux
@ 2016-02-10  0:19       ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2016-02-10  0:19 UTC (permalink / raw)
  To: Sylvain Lemieux
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

Hi Sylvain,

On 09.02.2016 23:01, Sylvain Lemieux wrote:
> Vladimir Zapolskiy <vz@...> writes:
>>
>> This changeset adds common clock framework driver for NXP LPC32xx
>> boards.
> 
> Hi Vladimir,
> 
> Just to let you know that we did some testing using this changeset;
> I installed patches 4 to 7, 10 & 11 on top of 4.5-rc1.
> 
> I was able to run our software (SIC1 interrupt sources disable)
> without any problem a custom LPC32xx board.

this is a known issue, and I hope it will be fixed in upstream in v4.6,
the required changes in irqchip and gpiochip drivers were sent for
review some time ago, a bit more work is needed to 

Also 2-3 more clean-up changes in USB host and gadget drivers are done
locally (no more need to configure clocks out of the common clock
framework), but not yet submitted, will do it tomorrow.

> We did not get any problem with the clock signals we are using.
> 

Thank you for testing, I'm going to add your Tested-by tag (if you
don't mind) and submit a PR to ARM maintainers shortly.

>> Vladimir Zapolskiy (11):
>>   dt-bindings: clock: add description of LPC32xx clock controller
>>   dt-bindings: clock: add description of LPC32xx USB clock controller
>>   dt-bindings: clock: add NXP LPC32xx clock list for consumers
>>   arm: dts: lpc32xx: add device nodes for external oscillators
>>   arm: dts: lpc32xx: add clock controller device node
>>   arm: dts: lpc32xx: add clock properties to device nodes
>>   arm: dts: lpc32xx: add USB clock controller
>>   clk: lpc18xx: add NXP specific common clock framework selection
>>   clk: lpc32xx: add common clock framework driver
>>   arm: lpc32xx: switch to common clock framework
>>   arm: dts: lpc32xx: remove clock frequency property from UART device
>>     nodes
> 
> 

With best wishes,
Vladimir
--
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] 67+ messages in thread

* [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx
@ 2016-02-10  0:19       ` Vladimir Zapolskiy
  0 siblings, 0 replies; 67+ messages in thread
From: Vladimir Zapolskiy @ 2016-02-10  0:19 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sylvain,

On 09.02.2016 23:01, Sylvain Lemieux wrote:
> Vladimir Zapolskiy <vz@...> writes:
>>
>> This changeset adds common clock framework driver for NXP LPC32xx
>> boards.
> 
> Hi Vladimir,
> 
> Just to let you know that we did some testing using this changeset;
> I installed patches 4 to 7, 10 & 11 on top of 4.5-rc1.
> 
> I was able to run our software (SIC1 interrupt sources disable)
> without any problem a custom LPC32xx board.

this is a known issue, and I hope it will be fixed in upstream in v4.6,
the required changes in irqchip and gpiochip drivers were sent for
review some time ago, a bit more work is needed to 

Also 2-3 more clean-up changes in USB host and gadget drivers are done
locally (no more need to configure clocks out of the common clock
framework), but not yet submitted, will do it tomorrow.

> We did not get any problem with the clock signals we are using.
> 

Thank you for testing, I'm going to add your Tested-by tag (if you
don't mind) and submit a PR to ARM maintainers shortly.

>> Vladimir Zapolskiy (11):
>>   dt-bindings: clock: add description of LPC32xx clock controller
>>   dt-bindings: clock: add description of LPC32xx USB clock controller
>>   dt-bindings: clock: add NXP LPC32xx clock list for consumers
>>   arm: dts: lpc32xx: add device nodes for external oscillators
>>   arm: dts: lpc32xx: add clock controller device node
>>   arm: dts: lpc32xx: add clock properties to device nodes
>>   arm: dts: lpc32xx: add USB clock controller
>>   clk: lpc18xx: add NXP specific common clock framework selection
>>   clk: lpc32xx: add common clock framework driver
>>   arm: lpc32xx: switch to common clock framework
>>   arm: dts: lpc32xx: remove clock frequency property from UART device
>>     nodes
> 
> 

With best wishes,
Vladimir

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

* Re: [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx
  2016-02-10  0:19       ` Vladimir Zapolskiy
@ 2016-02-10 14:25           ` Sylvain Lemieux
  -1 siblings, 0 replies; 67+ messages in thread
From: Sylvain Lemieux @ 2016-02-10 14:25 UTC (permalink / raw)
  To: Vladimir Zapolskiy
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Vladimir,

On Wed, 2016-02-10 at 02:19 +0200, Vladimir Zapolskiy wrote:
> Hi Sylvain,
> 
> On 09.02.2016 23:01, Sylvain Lemieux wrote:
> > Vladimir Zapolskiy <vz@...> writes:
> >>
> >> This changeset adds common clock framework driver for NXP LPC32xx
> >> boards.
> > 
> > Just to let you know that we did some testing using this changeset;
> > I installed patches 4 to 7, 10 & 11 on top of 4.5-rc1.
> > 
> > I was able to run our software (SIC1 interrupt sources disable)
> > without any problem a custom LPC32xx board.
> 
> this is a known issue, and I hope it will be fixed in upstream in v4.6,
> the required changes in irqchip and gpiochip drivers were sent for
> review some time ago, a bit more work is needed to 
> 
I also tested the irqchip patches you sent previously;
I will send a separate e-mail with the information.

> Also 2-3 more clean-up changes in USB host and gadget drivers are done
> locally (no more need to configure clocks out of the common clock
> framework), but not yet submitted, will do it tomorrow.
> 
> > We did not get any problem with the clock signals we are using.
> > 
> 
> Thank you for testing, I'm going to add your Tested-by tag (if you
> don't mind) and submit a PR to ARM maintainers shortly.
> 
You can go ahead for the tag; please use slemieux-1xCVI8+nB4ZBDgjK7y7TUQ@public.gmane.org

> >> Vladimir Zapolskiy (11):
> >>   dt-bindings: clock: add description of LPC32xx clock controller
> >>   dt-bindings: clock: add description of LPC32xx USB clock controller
> >>   dt-bindings: clock: add NXP LPC32xx clock list for consumers
> >>   arm: dts: lpc32xx: add device nodes for external oscillators
> >>   arm: dts: lpc32xx: add clock controller device node
> >>   arm: dts: lpc32xx: add clock properties to device nodes
> >>   arm: dts: lpc32xx: add USB clock controller
> >>   clk: lpc18xx: add NXP specific common clock framework selection
> >>   clk: lpc32xx: add common clock framework driver
> >>   arm: lpc32xx: switch to common clock framework
> >>   arm: dts: lpc32xx: remove clock frequency property from UART device
> >>     nodes
> > 
> > 
> 
> With best wishes,
> Vladimir


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

* [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx
@ 2016-02-10 14:25           ` Sylvain Lemieux
  0 siblings, 0 replies; 67+ messages in thread
From: Sylvain Lemieux @ 2016-02-10 14:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vladimir,

On Wed, 2016-02-10 at 02:19 +0200, Vladimir Zapolskiy wrote:
> Hi Sylvain,
> 
> On 09.02.2016 23:01, Sylvain Lemieux wrote:
> > Vladimir Zapolskiy <vz@...> writes:
> >>
> >> This changeset adds common clock framework driver for NXP LPC32xx
> >> boards.
> > 
> > Just to let you know that we did some testing using this changeset;
> > I installed patches 4 to 7, 10 & 11 on top of 4.5-rc1.
> > 
> > I was able to run our software (SIC1 interrupt sources disable)
> > without any problem a custom LPC32xx board.
> 
> this is a known issue, and I hope it will be fixed in upstream in v4.6,
> the required changes in irqchip and gpiochip drivers were sent for
> review some time ago, a bit more work is needed to 
> 
I also tested the irqchip patches you sent previously;
I will send a separate e-mail with the information.

> Also 2-3 more clean-up changes in USB host and gadget drivers are done
> locally (no more need to configure clocks out of the common clock
> framework), but not yet submitted, will do it tomorrow.
> 
> > We did not get any problem with the clock signals we are using.
> > 
> 
> Thank you for testing, I'm going to add your Tested-by tag (if you
> don't mind) and submit a PR to ARM maintainers shortly.
> 
You can go ahead for the tag; please use slemieux at tycoint.com

> >> Vladimir Zapolskiy (11):
> >>   dt-bindings: clock: add description of LPC32xx clock controller
> >>   dt-bindings: clock: add description of LPC32xx USB clock controller
> >>   dt-bindings: clock: add NXP LPC32xx clock list for consumers
> >>   arm: dts: lpc32xx: add device nodes for external oscillators
> >>   arm: dts: lpc32xx: add clock controller device node
> >>   arm: dts: lpc32xx: add clock properties to device nodes
> >>   arm: dts: lpc32xx: add USB clock controller
> >>   clk: lpc18xx: add NXP specific common clock framework selection
> >>   clk: lpc32xx: add common clock framework driver
> >>   arm: lpc32xx: switch to common clock framework
> >>   arm: dts: lpc32xx: remove clock frequency property from UART device
> >>     nodes
> > 
> > 
> 
> With best wishes,
> Vladimir

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

end of thread, other threads:[~2016-02-10 14:25 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-20  1:05 [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx Vladimir Zapolskiy
2015-11-20  1:05 ` Vladimir Zapolskiy
2015-11-20  1:05 ` Vladimir Zapolskiy
2015-11-20  1:05 ` [PATCH 02/11] dt-bindings: clock: add description of LPC32xx USB clock controller Vladimir Zapolskiy
2015-11-20  1:05   ` Vladimir Zapolskiy
2015-11-20 16:41   ` Rob Herring
2015-11-20 16:41     ` Rob Herring
2015-11-20 18:14     ` Vladimir Zapolskiy
2015-11-20 18:14       ` Vladimir Zapolskiy
2015-11-20  1:05 ` [PATCH 03/11] dt-bindings: clock: add NXP LPC32xx clock list for consumers Vladimir Zapolskiy
2015-11-20  1:05   ` Vladimir Zapolskiy
2015-11-20 13:56   ` Arnd Bergmann
2015-11-20 13:56     ` Arnd Bergmann
2015-11-20 13:56     ` Arnd Bergmann
2015-11-20 17:58     ` Vladimir Zapolskiy
2015-11-20 17:58       ` Vladimir Zapolskiy
2015-11-20 21:07       ` Arnd Bergmann
2015-11-20 21:07         ` Arnd Bergmann
2015-11-21 18:53         ` Vladimir Zapolskiy
2015-11-21 18:53           ` Vladimir Zapolskiy
2015-11-20  1:05 ` [PATCH 04/11] arm: dts: lpc32xx: add device nodes for external oscillators Vladimir Zapolskiy
2015-11-20  1:05   ` Vladimir Zapolskiy
2015-11-20  1:05 ` [PATCH 05/11] arm: dts: lpc32xx: add clock controller device node Vladimir Zapolskiy
2015-11-20  1:05   ` Vladimir Zapolskiy
     [not found] ` <1447981511-29653-1-git-send-email-vz-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
2015-11-20  1:05   ` [PATCH 01/11] dt-bindings: clock: add description of LPC32xx clock controller Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-20 13:58     ` Arnd Bergmann
2015-11-20 13:58       ` Arnd Bergmann
2015-11-20 18:01       ` Vladimir Zapolskiy
2015-11-20 18:01         ` Vladimir Zapolskiy
2015-11-20 18:01         ` Vladimir Zapolskiy
2015-11-20 20:03         ` Arnd Bergmann
2015-11-20 20:03           ` Arnd Bergmann
2015-11-20  1:05   ` [PATCH 06/11] arm: dts: lpc32xx: add clock properties to device nodes Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-20  1:05   ` [PATCH 07/11] arm: dts: lpc32xx: add USB clock controller Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-20  1:05   ` [PATCH 08/11] clk: lpc18xx: add NXP specific common clock framework selection Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-22 20:38     ` Joachim Eastwood
2015-11-22 20:38       ` Joachim Eastwood
2015-11-22 20:38       ` Joachim Eastwood
2015-11-20  1:05   ` [PATCH 11/11] arm: dts: lpc32xx: remove clock frequency property from UART device nodes Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-20  1:05     ` Vladimir Zapolskiy
2015-11-20  1:05 ` [PATCH 09/11] clk: lpc32xx: add common clock framework driver Vladimir Zapolskiy
2015-11-20  1:05   ` Vladimir Zapolskiy
2015-11-20 14:04   ` Arnd Bergmann
2015-11-20 14:04     ` Arnd Bergmann
2015-11-20 18:07     ` Vladimir Zapolskiy
2015-11-20 18:07       ` Vladimir Zapolskiy
2015-11-20 18:07       ` Vladimir Zapolskiy
2015-11-20 20:20       ` Arnd Bergmann
2015-11-20 20:20         ` Arnd Bergmann
2015-11-29 13:00         ` Vladimir Zapolskiy
2015-11-29 13:00           ` Vladimir Zapolskiy
2015-11-20  1:05 ` [PATCH 10/11] arm: lpc32xx: switch to common clock framework Vladimir Zapolskiy
2015-11-20  1:05   ` Vladimir Zapolskiy
2016-02-09 21:01 ` [PATCH 00/11] clk: lpc32xx: add clock support for NXP LPC32xx Sylvain Lemieux
     [not found]   ` <loom.20160209T215103-78-eS7Uydv5nfjZ+VzJOa5vwg@public.gmane.org>
2016-02-10  0:19     ` Vladimir Zapolskiy
2016-02-10  0:19       ` Vladimir Zapolskiy
     [not found]       ` <56BA81F7.4080006-ChpfBGZJDbMAvxtiuMwx3w@public.gmane.org>
2016-02-10 14:25         ` Sylvain Lemieux
2016-02-10 14:25           ` Sylvain Lemieux

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.