linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] arm: ep93xx: CCF conversion
@ 2021-07-26 11:50 Nikita Shubin
  2021-07-26 11:50 ` [PATCH 1/8] iio: ep93xx: Prepare clock before using it Nikita Shubin
                   ` (9 more replies)
  0 siblings, 10 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 11:50 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	Andrew Morton, Andrzej Pietrasiewicz, Anshuman Khandual,
	Ard Biesheuvel, Arnd Bergmann,
	open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, Dmitry Torokhov,
	open list:FRAMEBUFFER LAYER, Geert Uytterhoeven,
	Jonathan Cameron, Krzysztof Kozlowski, Krzysztof Kozlowski,
	Kuninori Morimoto, Lars-Peter Clausen, Linus Walleij,
	moderated list:ARM PORT, open list:FRAMEBUFFER LAYER,
	open list:IIO SUBSYSTEM AND DRIVERS, open list:INPUT (KEYBOARD,
	MOUSE, JOYSTICK , TOUCHSCREEN)...,
	open list, open list:PWM SUBSYSTEM, open list:SPI SUBSYSTEM,
	Mark Brown, Mike Rapoport, Russell King, Uwe Kleine-König,
	YiFei Zhu

This series series of patches converts ep93xx to Common Clock Framework.

It consists of preparation patches to use clk_prepare_enable where it is 
needed, instead of clk_enable used in ep93xx drivers prior to CCF and
a patch converting mach-ep93xx/clock.c to CCF.

Link: https://lore.kernel.org/patchwork/cover/1445563/
Link: https://lore.kernel.org/patchwork/patch/1435884/

Alexander Sverdlin (7):
  iio: ep93xx: Prepare clock before using it
  spi: spi-ep93xx: Prepare clock before using it
  Input: ep93xx_keypad: Prepare clock before using it
  video: ep93xx: Prepare clock before using it
  dmaengine: ep93xx: Prepare clock before using it
  ASoC: cirrus: i2s: Prepare clock before using it
  pwm: ep93xx: Prepare clock before using it

Nikita Shubin (1):
  ep93xx: clock: convert in-place to COMMON_CLK

 arch/arm/Kconfig                       |   2 +-
 arch/arm/mach-ep93xx/clock.c           | 975 ++++++++++++++-----------
 arch/arm/mach-ep93xx/core.c            |   2 +-
 arch/arm/mach-ep93xx/soc.h             |  42 +-
 drivers/dma/ep93xx_dma.c               |   6 +-
 drivers/iio/adc/ep93xx_adc.c           |   6 +-
 drivers/input/keyboard/ep93xx_keypad.c |   4 +-
 drivers/pwm/pwm-ep93xx.c               |  12 +-
 drivers/spi/spi-ep93xx.c               |   4 +-
 drivers/video/fbdev/ep93xx-fb.c        |   4 +-
 sound/soc/cirrus/ep93xx-i2s.c          |  12 +-
 11 files changed, 605 insertions(+), 464 deletions(-)


base-commit: 64376a981a0e2e57c46efa63197c2ebb7dab35df
-- 
2.26.2


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

* [PATCH 1/8] iio: ep93xx: Prepare clock before using it
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
@ 2021-07-26 11:50 ` Nikita Shubin
  2021-07-26 11:50 ` [PATCH 2/8] spi: spi-ep93xx: " Nikita Shubin
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 11:50 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Jonathan Cameron, Jonathan Cameron, Lars-Peter Clausen,
	open list:IIO SUBSYSTEM AND DRIVERS, open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework, otherwise the following is visible:

WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
Enabling unprepared ep93xx-adc
...
Hardware name: Cirrus Logic EDB9302 Evaluation Board
unwind_backtrace) from [<c000c590>] (show_stack+0x10/0x18)
...
clk_core_enable
clk_core_enable_lock
ep93xx_adc_probe
...
ep93xx-adc ep93xx-adc: Cannot enable clock
ep93xx-adc: probe of ep93xx-adc failed with error -108

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
 drivers/iio/adc/ep93xx_adc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/adc/ep93xx_adc.c b/drivers/iio/adc/ep93xx_adc.c
index c08ab3c6dfaf..5c85257b814c 100644
--- a/drivers/iio/adc/ep93xx_adc.c
+++ b/drivers/iio/adc/ep93xx_adc.c
@@ -207,7 +207,7 @@ static int ep93xx_adc_probe(struct platform_device *pdev)
 		 */
 	}
 
-	ret = clk_enable(priv->clk);
+	ret = clk_prepare_enable(priv->clk);
 	if (ret) {
 		dev_err(&pdev->dev, "Cannot enable clock\n");
 		return ret;
@@ -215,7 +215,7 @@ static int ep93xx_adc_probe(struct platform_device *pdev)
 
 	ret = iio_device_register(iiodev);
 	if (ret)
-		clk_disable(priv->clk);
+		clk_disable_unprepare(priv->clk);
 
 	return ret;
 }
@@ -226,7 +226,7 @@ static int ep93xx_adc_remove(struct platform_device *pdev)
 	struct ep93xx_adc_priv *priv = iio_priv(iiodev);
 
 	iio_device_unregister(iiodev);
-	clk_disable(priv->clk);
+	clk_disable_unprepare(priv->clk);
 
 	return 0;
 }
-- 
2.26.2


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

* [PATCH 2/8] spi: spi-ep93xx: Prepare clock before using it
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
  2021-07-26 11:50 ` [PATCH 1/8] iio: ep93xx: Prepare clock before using it Nikita Shubin
@ 2021-07-26 11:50 ` Nikita Shubin
  2021-07-26 12:01   ` Mark Brown
  2021-07-26 11:50 ` [PATCH 3/8] Input: ep93xx_keypad: " Nikita Shubin
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 11:50 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Mark Brown, open list:SPI SUBSYSTEM, open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework, otherwise the following is visible:

WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
Enabling unprepared ep93xx-spi.0
...
Hardware name: Cirrus Logic EDB9302 Evaluation Board
...
clk_core_enable
clk_core_enable_lock
ep93xx_spi_prepare_hardware
__spi_pump_messages
__spi_sync
spi_sync
spi_sync_transfer.constprop.0
regmap_spi_write
_regmap_raw_write_impl
_regmap_bus_raw_write
_regmap_update_bits
regmap_update_bits_base
cs4271_component_probe
snd_soc_component_probe
soc_probe_component
snd_soc_bind_card
edb93xx_probe
...
spi_master spi0: failed to prepare transfer hardware: -108

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 drivers/spi/spi-ep93xx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c
index aa676559d273..5896a7b2fade 100644
--- a/drivers/spi/spi-ep93xx.c
+++ b/drivers/spi/spi-ep93xx.c
@@ -550,7 +550,7 @@ static int ep93xx_spi_prepare_hardware(struct spi_master *master)
 	u32 val;
 	int ret;
 
-	ret = clk_enable(espi->clk);
+	ret = clk_prepare_enable(espi->clk);
 	if (ret)
 		return ret;
 
@@ -570,7 +570,7 @@ static int ep93xx_spi_unprepare_hardware(struct spi_master *master)
 	val &= ~SSPCR1_SSE;
 	writel(val, espi->mmio + SSPCR1);
 
-	clk_disable(espi->clk);
+	clk_disable_unprepare(espi->clk);
 
 	return 0;
 }
-- 
2.26.2


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

* [PATCH 3/8] Input: ep93xx_keypad: Prepare clock before using it
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
  2021-07-26 11:50 ` [PATCH 1/8] iio: ep93xx: Prepare clock before using it Nikita Shubin
  2021-07-26 11:50 ` [PATCH 2/8] spi: spi-ep93xx: " Nikita Shubin
@ 2021-07-26 11:50 ` Nikita Shubin
  2021-07-26 11:50 ` [PATCH 4/8] video: ep93xx: " Nikita Shubin
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 11:50 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Dmitry Torokhov, Krzysztof Kozlowski, Andrzej Pietrasiewicz,
	open list:INPUT (KEYBOARD, MOUSE, JOYSTICK , TOUCHSCREEN)...,
	open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/ep93xx_keypad.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
index c8194333d612..e0e931e796fa 100644
--- a/drivers/input/keyboard/ep93xx_keypad.c
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -157,7 +157,7 @@ static int ep93xx_keypad_open(struct input_dev *pdev)
 
 	if (!keypad->enabled) {
 		ep93xx_keypad_config(keypad);
-		clk_enable(keypad->clk);
+		clk_prepare_enable(keypad->clk);
 		keypad->enabled = true;
 	}
 
@@ -169,7 +169,7 @@ static void ep93xx_keypad_close(struct input_dev *pdev)
 	struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
 
 	if (keypad->enabled) {
-		clk_disable(keypad->clk);
+		clk_disable_unprepare(keypad->clk);
 		keypad->enabled = false;
 	}
 }
-- 
2.26.2


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

* [PATCH 4/8] video: ep93xx: Prepare clock before using it
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                   ` (2 preceding siblings ...)
  2021-07-26 11:50 ` [PATCH 3/8] Input: ep93xx_keypad: " Nikita Shubin
@ 2021-07-26 11:50 ` Nikita Shubin
  2021-07-26 11:50 ` [PATCH 5/8] dmaengine: " Nikita Shubin
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 11:50 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: open list:FRAMEBUFFER LAYER, open list:FRAMEBUFFER LAYER, open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 drivers/video/fbdev/ep93xx-fb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c
index ba33b4dce0df..2398b3d48fed 100644
--- a/drivers/video/fbdev/ep93xx-fb.c
+++ b/drivers/video/fbdev/ep93xx-fb.c
@@ -548,7 +548,7 @@ static int ep93xxfb_probe(struct platform_device *pdev)
 	}
 
 	ep93xxfb_set_par(info);
-	clk_enable(fbi->clk);
+	clk_prepare_enable(fbi->clk);
 
 	err = register_framebuffer(info);
 	if (err)
@@ -577,7 +577,7 @@ static int ep93xxfb_remove(struct platform_device *pdev)
 	struct ep93xx_fbi *fbi = info->par;
 
 	unregister_framebuffer(info);
-	clk_disable(fbi->clk);
+	clk_disable_unprepare(fbi->clk);
 	ep93xxfb_dealloc_videomem(info);
 	fb_dealloc_cmap(&info->cmap);
 
-- 
2.26.2


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

* [PATCH 5/8] dmaengine: ep93xx: Prepare clock before using it
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                   ` (3 preceding siblings ...)
  2021-07-26 11:50 ` [PATCH 4/8] video: ep93xx: " Nikita Shubin
@ 2021-07-26 11:50 ` Nikita Shubin
  2021-07-26 11:50 ` [PATCH 6/8] ASoC: cirrus: i2s: " Nikita Shubin
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 11:50 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Vinod Koul, open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework, otherwise the following is visible:

WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
Enabling unprepared m2p0
...
Hardware name: Cirrus Logic EDB9302 Evaluation Board
...
clk_core_enable
clk_core_enable_lock
ep93xx_dma_alloc_chan_resources
dma_chan_get
find_candidate
__dma_request_channel
snd_dmaengine_pcm_request_channel
dmaengine_pcm_new
snd_soc_pcm_component_new
soc_new_pcm
snd_soc_bind_card
edb93xx_probe
...
ep93xx-i2s ep93xx-i2s: Missing dma channel for stream: 0
ep93xx-i2s ep93xx-i2s: ASoC: error at snd_soc_pcm_component_new on ep93xx-i2s: -22
edb93xx-audio edb93xx-audio: ASoC: can't create pcm CS4271 HiFi :-22
edb93xx-audio edb93xx-audio: snd_soc_register_card() failed: -22
edb93xx-audio: probe of edb93xx-audio failed with error -22

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 drivers/dma/ep93xx_dma.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 01027779beb8..98f9ee70362e 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -897,7 +897,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)
 	if (data && data->name)
 		name = data->name;
 
-	ret = clk_enable(edmac->clk);
+	ret = clk_prepare_enable(edmac->clk);
 	if (ret)
 		return ret;
 
@@ -936,7 +936,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)
 fail_free_irq:
 	free_irq(edmac->irq, edmac);
 fail_clk_disable:
-	clk_disable(edmac->clk);
+	clk_disable_unprepare(edmac->clk);
 
 	return ret;
 }
@@ -969,7 +969,7 @@ static void ep93xx_dma_free_chan_resources(struct dma_chan *chan)
 	list_for_each_entry_safe(desc, d, &list, node)
 		kfree(desc);
 
-	clk_disable(edmac->clk);
+	clk_disable_unprepare(edmac->clk);
 	free_irq(edmac->irq, edmac);
 }
 
-- 
2.26.2


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

* [PATCH 6/8] ASoC: cirrus: i2s: Prepare clock before using it
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                   ` (4 preceding siblings ...)
  2021-07-26 11:50 ` [PATCH 5/8] dmaengine: " Nikita Shubin
@ 2021-07-26 11:50 ` Nikita Shubin
  2021-07-26 11:50 ` [PATCH 7/8] pwm: ep93xx: " Nikita Shubin
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 11:50 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Kuninori Morimoto,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework, otherwise the following is visible:

WARNING: CPU: 0 PID: 97 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
Enabling unprepared mclk
...
Hardware name: Cirrus Logic EDB9302 Evaluation Board
...
clk_core_enable
clk_core_enable_lock
ep93xx_i2s_hw_params
snd_soc_dai_hw_params
soc_pcm_hw_params
snd_pcm_hw_params
snd_pcm_ioctl
...

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 sound/soc/cirrus/ep93xx-i2s.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 0d26550d0df8..4d3179f03202 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -111,9 +111,9 @@ static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream)
 	if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
 	    (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
 		/* Enable clocks */
-		clk_enable(info->mclk);
-		clk_enable(info->sclk);
-		clk_enable(info->lrclk);
+		clk_prepare_enable(info->mclk);
+		clk_prepare_enable(info->sclk);
+		clk_prepare_enable(info->lrclk);
 
 		/* Enable i2s */
 		ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1);
@@ -156,9 +156,9 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
 		ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 0);
 
 		/* Disable clocks */
-		clk_disable(info->lrclk);
-		clk_disable(info->sclk);
-		clk_disable(info->mclk);
+		clk_disable_unprepare(info->lrclk);
+		clk_disable_unprepare(info->sclk);
+		clk_disable_unprepare(info->mclk);
 	}
 }
 
-- 
2.26.2


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

* [PATCH 7/8] pwm: ep93xx: Prepare clock before using it
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                   ` (5 preceding siblings ...)
  2021-07-26 11:50 ` [PATCH 6/8] ASoC: cirrus: i2s: " Nikita Shubin
@ 2021-07-26 11:50 ` Nikita Shubin
  2021-07-26 11:50 ` [PATCH 8/8] ep93xx: clock: convert in-place to COMMON_CLK Nikita Shubin
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 11:50 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Uwe Kleine-König, Thierry Reding, Lee Jones,
	open list:PWM SUBSYSTEM, open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 drivers/pwm/pwm-ep93xx.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/pwm-ep93xx.c b/drivers/pwm/pwm-ep93xx.c
index 4ca70794ad96..8c0d4d69d9e6 100644
--- a/drivers/pwm/pwm-ep93xx.c
+++ b/drivers/pwm/pwm-ep93xx.c
@@ -74,7 +74,7 @@ static int ep93xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * Configuration can be changed at any time.
 	 */
 	if (!pwm_is_enabled(pwm)) {
-		ret = clk_enable(ep93xx_pwm->clk);
+		ret = clk_prepare_enable(ep93xx_pwm->clk);
 		if (ret)
 			return ret;
 	}
@@ -105,7 +105,7 @@ static int ep93xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	if (!pwm_is_enabled(pwm))
-		clk_disable(ep93xx_pwm->clk);
+		clk_disable_unprepare(ep93xx_pwm->clk);
 
 	return ret;
 }
@@ -120,7 +120,7 @@ static int ep93xx_pwm_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * The clock needs to be enabled to access the PWM registers.
 	 * Polarity can only be changed when the PWM is disabled.
 	 */
-	ret = clk_enable(ep93xx_pwm->clk);
+	ret = clk_prepare_enable(ep93xx_pwm->clk);
 	if (ret)
 		return ret;
 
@@ -129,7 +129,7 @@ static int ep93xx_pwm_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 	else
 		writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_INVERT);
 
-	clk_disable(ep93xx_pwm->clk);
+	clk_disable_unprepare(ep93xx_pwm->clk);
 
 	return 0;
 }
@@ -139,7 +139,7 @@ static int ep93xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 	struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
 	int ret;
 
-	ret = clk_enable(ep93xx_pwm->clk);
+	ret = clk_prepare_enable(ep93xx_pwm->clk);
 	if (ret)
 		return ret;
 
@@ -153,7 +153,7 @@ static void ep93xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 	struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
 
 	writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_ENABLE);
-	clk_disable(ep93xx_pwm->clk);
+	clk_disable_unprepare(ep93xx_pwm->clk);
 }
 
 static const struct pwm_ops ep93xx_pwm_ops = {
-- 
2.26.2


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

* [PATCH 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                   ` (6 preceding siblings ...)
  2021-07-26 11:50 ` [PATCH 7/8] pwm: ep93xx: " Nikita Shubin
@ 2021-07-26 11:50 ` Nikita Shubin
  2021-07-26 11:57   ` Alexander Sverdlin
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
  2021-07-31 22:04 ` [PATCH " Linus Walleij
  9 siblings, 1 reply; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 11:50 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin, Russell King, Hartley Sweeten, Arnd Bergmann,
	Linus Walleij, Andrew Morton, Ard Biesheuvel,
	Krzysztof Kozlowski, Anshuman Khandual, Geert Uytterhoeven,
	YiFei Zhu, Uwe Kleine-König, Mike Rapoport,
	moderated list:ARM PORT, open list

Converted in-place without moving file to drivers/clk.

tested on ts7250 (EP9302).

Only setting rate and change parent tested for, as they
are missing on ts7250:
- video
- I2S
- ADC/KEYPAD
- PWM

Only video and I2S clock are interesting, as they are
GATE + double DIV + MUX, all other are pretty much
common but require ep93xx_syscon_swlocked_write to set
registers.

Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 arch/arm/Kconfig             |   2 +-
 arch/arm/mach-ep93xx/clock.c | 975 ++++++++++++++++++++---------------
 arch/arm/mach-ep93xx/core.c  |   2 +-
 arch/arm/mach-ep93xx/soc.h   |  42 +-
 4 files changed, 581 insertions(+), 440 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 24804f11302d..8f4a74a37406 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -357,7 +357,7 @@ config ARCH_EP93XX
 	select CLKSRC_MMIO
 	select CPU_ARM920T
 	select GPIOLIB
-	select HAVE_LEGACY_CLK
+	select COMMON_CLK
 	help
 	  This enables support for the Cirrus EP93xx series of CPUs.
 
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 2810eb5b2aca..cc75087134d3 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/soc/cirrus/ep93xx.h>
 
 #include "hardware.h"
@@ -24,348 +25,194 @@
 
 #include "soc.h"
 
-struct clk {
-	struct clk	*parent;
-	unsigned long	rate;
-	int		users;
-	int		sw_locked;
-	void __iomem	*enable_reg;
-	u32		enable_mask;
-
-	unsigned long	(*get_rate)(struct clk *clk);
-	int		(*set_rate)(struct clk *clk, unsigned long rate);
-};
-
-
-static unsigned long get_uart_rate(struct clk *clk);
-
-static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
-static int set_div_rate(struct clk *clk, unsigned long rate);
-static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
-static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
+static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk clk_xtali = {
-	.rate		= EP93XX_EXT_CLK_RATE,
-};
-static struct clk clk_uart1 = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_DEVCFG,
-	.enable_mask	= EP93XX_SYSCON_DEVCFG_U1EN,
-	.get_rate	= get_uart_rate,
-};
-static struct clk clk_uart2 = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_DEVCFG,
-	.enable_mask	= EP93XX_SYSCON_DEVCFG_U2EN,
-	.get_rate	= get_uart_rate,
-};
-static struct clk clk_uart3 = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_DEVCFG,
-	.enable_mask	= EP93XX_SYSCON_DEVCFG_U3EN,
-	.get_rate	= get_uart_rate,
-};
-static struct clk clk_pll1 = {
-	.parent		= &clk_xtali,
-};
-static struct clk clk_f = {
-	.parent		= &clk_pll1,
-};
-static struct clk clk_h = {
-	.parent		= &clk_pll1,
-};
-static struct clk clk_p = {
-	.parent		= &clk_pll1,
-};
-static struct clk clk_pll2 = {
-	.parent		= &clk_xtali,
-};
-static struct clk clk_usb_host = {
-	.parent		= &clk_pll2,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_USH_EN,
-};
-static struct clk clk_keypad = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_KEYTCHCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
-	.set_rate	= set_keytchclk_rate,
-};
-static struct clk clk_adc = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_KEYTCHCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
-	.set_rate	= set_keytchclk_rate,
-};
-static struct clk clk_spi = {
-	.parent		= &clk_xtali,
-	.rate		= EP93XX_EXT_CLK_RATE,
-};
-static struct clk clk_pwm = {
-	.parent		= &clk_xtali,
-	.rate		= EP93XX_EXT_CLK_RATE,
-};
+static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
+static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
+static char pclk_divisors[] = { 1, 2, 4, 8 };
 
-static struct clk clk_video = {
-	.sw_locked	= 1,
-	.enable_reg     = EP93XX_SYSCON_VIDCLKDIV,
-	.enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
-	.set_rate	= set_div_rate,
-};
+static char adc_divisors[] = { 16, 4 };
+static char sclk_divisors[] = { 2, 4 };
+static char lrclk_divisors[] = { 32, 64, 128 };
 
-static struct clk clk_i2s_mclk = {
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_I2SCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_CLKDIV_ENABLE,
-	.set_rate	= set_div_rate,
+static const char * const mux_parents[] = {
+	"xtali",
+	"pll1",
+	"pll2"
 };
 
-static struct clk clk_i2s_sclk = {
-	.sw_locked	= 1,
-	.parent		= &clk_i2s_mclk,
-	.enable_reg	= EP93XX_SYSCON_I2SCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_I2SCLKDIV_SENA,
-	.set_rate	= set_i2s_sclk_rate,
-};
+/*
+ * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
+ */
+static unsigned long calc_pll_rate(unsigned long long rate, u32 config_word)
+{
+	int i;
 
-static struct clk clk_i2s_lrclk = {
-	.sw_locked	= 1,
-	.parent		= &clk_i2s_sclk,
-	.enable_reg	= EP93XX_SYSCON_I2SCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_I2SCLKDIV_SENA,
-	.set_rate	= set_i2s_lrclk_rate,
-};
+	rate *= ((config_word >> 11) & 0x1f) + 1;		/* X1FBD */
+	rate *= ((config_word >> 5) & 0x3f) + 1;		/* X2FBD */
+	do_div(rate, (config_word & 0x1f) + 1);			/* X2IPD */
+	for (i = 0; i < ((config_word >> 16) & 3); i++)		/* PS */
+		rate >>= 1;
 
-/* DMA Clocks */
-static struct clk clk_m2p0 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P0,
-};
-static struct clk clk_m2p1 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P1,
-};
-static struct clk clk_m2p2 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P2,
-};
-static struct clk clk_m2p3 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P3,
-};
-static struct clk clk_m2p4 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P4,
-};
-static struct clk clk_m2p5 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P5,
-};
-static struct clk clk_m2p6 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P6,
-};
-static struct clk clk_m2p7 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P7,
-};
-static struct clk clk_m2p8 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P8,
-};
-static struct clk clk_m2p9 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P9,
-};
-static struct clk clk_m2m0 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2M0,
-};
-static struct clk clk_m2m1 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2M1,
-};
+	return (unsigned long)rate;
+}
 
-#define INIT_CK(dev,con,ck)					\
-	{ .dev_id = dev, .con_id = con, .clk = ck }
-
-static struct clk_lookup clocks[] = {
-	INIT_CK(NULL,			"xtali",	&clk_xtali),
-	INIT_CK("apb:uart1",		NULL,		&clk_uart1),
-	INIT_CK("apb:uart2",		NULL,		&clk_uart2),
-	INIT_CK("apb:uart3",		NULL,		&clk_uart3),
-	INIT_CK(NULL,			"pll1",		&clk_pll1),
-	INIT_CK(NULL,			"fclk",		&clk_f),
-	INIT_CK(NULL,			"hclk",		&clk_h),
-	INIT_CK(NULL,			"apb_pclk",	&clk_p),
-	INIT_CK(NULL,			"pll2",		&clk_pll2),
-	INIT_CK("ohci-platform",	NULL,		&clk_usb_host),
-	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
-	INIT_CK("ep93xx-adc",		NULL,		&clk_adc),
-	INIT_CK("ep93xx-fb",		NULL,		&clk_video),
-	INIT_CK("ep93xx-spi.0",		NULL,		&clk_spi),
-	INIT_CK("ep93xx-i2s",		"mclk",		&clk_i2s_mclk),
-	INIT_CK("ep93xx-i2s",		"sclk",		&clk_i2s_sclk),
-	INIT_CK("ep93xx-i2s",		"lrclk",	&clk_i2s_lrclk),
-	INIT_CK(NULL,			"pwm_clk",	&clk_pwm),
-	INIT_CK(NULL,			"m2p0",		&clk_m2p0),
-	INIT_CK(NULL,			"m2p1",		&clk_m2p1),
-	INIT_CK(NULL,			"m2p2",		&clk_m2p2),
-	INIT_CK(NULL,			"m2p3",		&clk_m2p3),
-	INIT_CK(NULL,			"m2p4",		&clk_m2p4),
-	INIT_CK(NULL,			"m2p5",		&clk_m2p5),
-	INIT_CK(NULL,			"m2p6",		&clk_m2p6),
-	INIT_CK(NULL,			"m2p7",		&clk_m2p7),
-	INIT_CK(NULL,			"m2p8",		&clk_m2p8),
-	INIT_CK(NULL,			"m2p9",		&clk_m2p9),
-	INIT_CK(NULL,			"m2m0",		&clk_m2m0),
-	INIT_CK(NULL,			"m2m1",		&clk_m2m1),
+struct clk_psc {
+	struct clk_hw hw;
+	void __iomem *reg;
+	u8 bit_idx;
+	u32 mask;
+	u8 shift;
+	u8 width;
+	char *div;
+	u8 num_div;
+	spinlock_t *lock;
 };
 
-static DEFINE_SPINLOCK(clk_lock);
+#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw)
 
-static void __clk_enable(struct clk *clk)
+static int ep93xx_clk_is_enabled(struct clk_hw *hw)
 {
-	if (!clk->users++) {
-		if (clk->parent)
-			__clk_enable(clk->parent);
-
-		if (clk->enable_reg) {
-			u32 v;
-
-			v = __raw_readl(clk->enable_reg);
-			v |= clk->enable_mask;
-			if (clk->sw_locked)
-				ep93xx_syscon_swlocked_write(v, clk->enable_reg);
-			else
-				__raw_writel(v, clk->enable_reg);
-		}
-	}
+	struct clk_psc *psc = to_clk_psc(hw);
+	u32 val = readl(psc->reg);
+
+	return (val & BIT(psc->bit_idx)) ? 1 : 0;
 }
 
-int clk_enable(struct clk *clk)
+static int ep93xx_clk_enable(struct clk_hw *hw)
 {
-	unsigned long flags;
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long flags = 0;
+	u32 val;
 
-	if (!clk)
-		return -EINVAL;
+	if (psc->lock)
+		spin_lock_irqsave(psc->lock, flags);
+
+	val = __raw_readl(psc->reg);
+	val |= BIT(psc->bit_idx);
+
+	ep93xx_syscon_swlocked_write(val, psc->reg);
 
-	spin_lock_irqsave(&clk_lock, flags);
-	__clk_enable(clk);
-	spin_unlock_irqrestore(&clk_lock, flags);
+	if (psc->lock)
+		spin_unlock_irqrestore(psc->lock, flags);
 
 	return 0;
 }
-EXPORT_SYMBOL(clk_enable);
 
-static void __clk_disable(struct clk *clk)
+static void ep93xx_clk_disable(struct clk_hw *hw)
 {
-	if (!--clk->users) {
-		if (clk->enable_reg) {
-			u32 v;
-
-			v = __raw_readl(clk->enable_reg);
-			v &= ~clk->enable_mask;
-			if (clk->sw_locked)
-				ep93xx_syscon_swlocked_write(v, clk->enable_reg);
-			else
-				__raw_writel(v, clk->enable_reg);
-		}
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long flags = 0;
+	u32 val;
 
-		if (clk->parent)
-			__clk_disable(clk->parent);
-	}
-}
+	if (psc->lock)
+		spin_lock_irqsave(psc->lock, flags);
 
-void clk_disable(struct clk *clk)
-{
-	unsigned long flags;
+	val = __raw_readl(psc->reg);
+	val &= ~BIT(psc->bit_idx);
 
-	if (!clk)
-		return;
+	ep93xx_syscon_swlocked_write(val, psc->reg);
 
-	spin_lock_irqsave(&clk_lock, flags);
-	__clk_disable(clk);
-	spin_unlock_irqrestore(&clk_lock, flags);
+	if (psc->lock)
+		spin_unlock_irqrestore(psc->lock, flags);
 }
-EXPORT_SYMBOL(clk_disable);
 
-static unsigned long get_uart_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	u32 value;
+static const struct clk_ops clk_ep93xx_gate_ops = {
+	.enable = ep93xx_clk_enable,
+	.disable = ep93xx_clk_disable,
+	.is_enabled = ep93xx_clk_is_enabled,
+};
 
-	value = __raw_readl(EP93XX_SYSCON_PWRCNT);
-	if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
-		return rate;
-	else
-		return rate / 2;
+static struct clk_hw *ep93xx_clk_register_gate(const char *name,
+				    const char *parent_name,
+				    void __iomem *reg,
+				    u8 bit_idx)
+{
+	struct clk_init_data init;
+	struct clk_psc *psc;
+	struct clk *clk;
+
+	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+	if (!psc)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_ep93xx_gate_ops;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	psc->reg = reg;
+	psc->bit_idx = bit_idx;
+	psc->hw.init = &init;
+	psc->lock = &clk_lock;
+
+	clk = clk_register(NULL, &psc->hw);
+	if (IS_ERR(clk))
+		kfree(psc);
+
+	return &psc->hw;
 }
 
-unsigned long clk_get_rate(struct clk *clk)
+static u8 ep93xx_mux_get_parent(struct clk_hw *hw)
 {
-	if (clk->get_rate)
-		return clk->get_rate(clk);
+	struct clk_psc *psc = to_clk_psc(hw);
+	u32 val = __raw_readl(psc->reg);
 
-	return clk->rate;
+	if (!(val & EP93XX_SYSCON_CLKDIV_ESEL))
+		return 0;
+
+	if (!(val & EP93XX_SYSCON_CLKDIV_PSEL))
+		return 1;
+
+	return 2;
 }
-EXPORT_SYMBOL(clk_get_rate);
 
-static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
+static int ep93xx_mux_set_parent_lock(struct clk_hw *hw, u8 index)
 {
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long flags = 0;
 	u32 val;
-	u32 div_bit;
 
-	val = __raw_readl(clk->enable_reg);
+	if (index >= ARRAY_SIZE(mux_parents))
+		return -EINVAL;
 
-	/*
-	 * The Key Matrix and ADC clocks are configured using the same
-	 * System Controller register.  The clock used will be either
-	 * 1/4 or 1/16 the external clock rate depending on the
-	 * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
-	 * bit being set or cleared.
-	 */
-	div_bit = clk->enable_mask >> 15;
+	if (psc->lock)
+		spin_lock_irqsave(psc->lock, flags);
 
-	if (rate == EP93XX_KEYTCHCLK_DIV4)
-		val |= div_bit;
-	else if (rate == EP93XX_KEYTCHCLK_DIV16)
-		val &= ~div_bit;
-	else
-		return -EINVAL;
+	val = __raw_readl(psc->reg);
+	val &= ~(EP93XX_SYSCON_CLKDIV_ESEL | EP93XX_SYSCON_CLKDIV_PSEL);
+
+
+	if (index != 0) {
+		val |= EP93XX_SYSCON_CLKDIV_ESEL;
+		val |= (index - 1) ? EP93XX_SYSCON_CLKDIV_PSEL : 0;
+	}
+
+	ep93xx_syscon_swlocked_write(val, psc->reg);
+
+	if (psc->lock)
+		spin_unlock_irqrestore(psc->lock, flags);
 
-	ep93xx_syscon_swlocked_write(val, clk->enable_reg);
-	clk->rate = rate;
 	return 0;
 }
 
-static int calc_clk_div(struct clk *clk, unsigned long rate,
-			int *psel, int *esel, int *pdiv, int *div)
+static bool is_best(unsigned long rate, unsigned long now,
+		     unsigned long best)
 {
-	struct clk *mclk;
-	unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
-	int i, found = 0, __div = 0, __pdiv = 0;
+	return abs(rate - now) < abs(rate - best);
+}
 
-	/* Don't exceed the maximum rate */
-	max_rate = max3(clk_pll1.rate / 4, clk_pll2.rate / 4, clk_xtali.rate / 4);
-	rate = min(rate, max_rate);
+static int ep93xx_mux_determine_rate(struct clk_hw *hw,
+				struct clk_rate_request *req)
+{
+	unsigned long rate = req->rate;
+	struct clk *best_parent = 0;
+	unsigned long __parent_rate;
+	unsigned long best_rate = 0, actual_rate, mclk_rate;
+	unsigned long best_parent_rate;
+	int __div = 0, __pdiv = 0;
+	int i;
 
 	/*
 	 * Try the two pll's and the external clock
@@ -376,14 +223,11 @@ static int calc_clk_div(struct clk *clk, unsigned long rate,
 	 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
 	 *
 	 */
-	for (i = 0; i < 3; i++) {
-		if (i == 0)
-			mclk = &clk_xtali;
-		else if (i == 1)
-			mclk = &clk_pll1;
-		else
-			mclk = &clk_pll2;
-		mclk_rate = mclk->rate * 2;
+	for (i = 0; i < ARRAY_SIZE(mux_parents); i++) {
+		struct clk *parent = clk_get_sys(mux_parents[i], NULL);
+
+		__parent_rate = clk_get_rate(parent);
+		mclk_rate = __parent_rate * 2;
 
 		/* Try each predivider value */
 		for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
@@ -392,197 +236,494 @@ static int calc_clk_div(struct clk *clk, unsigned long rate,
 				continue;
 
 			actual_rate = mclk_rate / (__pdiv * __div);
-
-			if (!found || abs(actual_rate - rate) < rate_err) {
-				*pdiv = __pdiv - 3;
-				*div = __div;
-				*psel = (i == 2);
-				*esel = (i != 0);
-				clk->parent = mclk;
-				clk->rate = actual_rate;
-				rate_err = abs(actual_rate - rate);
-				found = 1;
+			if (is_best(rate, actual_rate, best_rate)) {
+				best_rate = actual_rate;
+				best_parent_rate = __parent_rate;
+				best_parent = parent;
 			}
 		}
 	}
 
-	if (!found)
+	if (!best_parent)
 		return -EINVAL;
 
+	req->best_parent_rate = best_parent_rate;
+	req->best_parent_hw = __clk_get_hw(best_parent);
+	req->rate = best_rate;
+
 	return 0;
 }
 
-static int set_div_rate(struct clk *clk, unsigned long rate)
+static unsigned long ep93xx_ddiv_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
 {
-	int err, psel = 0, esel = 0, pdiv = 0, div = 0;
-	u32 val;
-
-	err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
-	if (err)
-		return err;
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long rate = 0;
+	u32 val = __raw_readl(psc->reg);
+	int __pdiv = ((val >> EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) & 0x03);
+	int __div = val & 0x7f;
 
-	/* Clear the esel, psel, pdiv and div bits */
-	val = __raw_readl(clk->enable_reg);
-	val &= ~0x7fff;
+	if (__div > 0)
+		rate = (parent_rate * 2) / ((__pdiv + 3) * __div);
 
-	/* Set the new esel, psel, pdiv and div bits for the new clock rate */
-	val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
-		(psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
-		(pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
-	ep93xx_syscon_swlocked_write(val, clk->enable_reg);
-	return 0;
+	return rate;
 }
 
-static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
+static int ep93xx_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
 {
-	unsigned val = __raw_readl(clk->enable_reg);
-
-	if (rate == clk_i2s_mclk.rate / 2)
-		ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV, 
-					     clk->enable_reg);
-	else if (rate == clk_i2s_mclk.rate / 4)
-		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV, 
-					     clk->enable_reg);
-	else
+	struct clk_psc *psc = to_clk_psc(hw);
+	int pdiv = 0, div = 0;
+	unsigned long best_rate = 0, actual_rate, mclk_rate;
+	int __div = 0, __pdiv = 0;
+	u32 val;
+
+	mclk_rate = parent_rate * 2;
+
+	for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
+		__div = mclk_rate / (rate * __pdiv);
+		if (__div < 2 || __div > 127)
+			continue;
+
+		actual_rate = mclk_rate / (__pdiv * __div);
+		if (is_best(rate, actual_rate, best_rate)) {
+			pdiv = __pdiv - 3;
+			div = __div;
+			best_rate = actual_rate;
+		}
+	}
+
+	if (!best_rate)
 		return -EINVAL;
 
-	clk_i2s_sclk.rate = rate;
+	val = __raw_readl(psc->reg);
+
+	/* Clear old dividers */
+	val &= ~0x37f;
+
+	/* Set the new pdiv and div bits for the new clock rate */
+	val |= (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
+	ep93xx_syscon_swlocked_write(val, psc->reg);
+
 	return 0;
 }
 
-static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned val = __raw_readl(clk->enable_reg) & 
-		~EP93XX_I2SCLKDIV_LRDIV_MASK;
-	
-	if (rate == clk_i2s_sclk.rate / 32)
-		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
-					     clk->enable_reg);
-	else if (rate == clk_i2s_sclk.rate / 64)
-		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
-					     clk->enable_reg);
-	else if (rate == clk_i2s_sclk.rate / 128)
-		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
-					     clk->enable_reg);
-	else
-		return -EINVAL;
+static const struct clk_ops clk_ddiv_ops = {
+	.enable = ep93xx_clk_enable,
+	.disable = ep93xx_clk_disable,
+	.is_enabled = ep93xx_clk_is_enabled,
+	.get_parent = ep93xx_mux_get_parent,
+	.set_parent = ep93xx_mux_set_parent_lock,
+	.determine_rate = ep93xx_mux_determine_rate,
+	.recalc_rate = ep93xx_ddiv_recalc_rate,
+	.set_rate = ep93xx_ddiv_set_rate,
+};
 
-	clk_i2s_lrclk.rate = rate;
-	return 0;
+static struct clk_hw *clk_hw_register_ddiv(const char *name,
+					  void __iomem *reg,
+					  u8 bit_idx)
+{
+	struct clk_init_data init;
+	struct clk_psc *psc;
+	struct clk *clk;
+
+	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+	if (!psc)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_ddiv_ops;
+	init.flags = 0;
+	init.parent_names = mux_parents;
+	init.num_parents = ARRAY_SIZE(mux_parents);
+
+	psc->reg = reg;
+	psc->bit_idx = bit_idx;
+	psc->lock = &clk_lock;
+	psc->hw.init = &init;
+
+	clk = clk_register(NULL, &psc->hw);
+	if (IS_ERR(clk))
+		kfree(psc);
+
+	return &psc->hw;
 }
 
-int clk_set_rate(struct clk *clk, unsigned long rate)
+static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
 {
-	if (clk->set_rate)
-		return clk->set_rate(clk, rate);
+	struct clk_psc *psc = to_clk_psc(hw);
+	u32 val = __raw_readl(psc->reg);
+	u8 index = (val & psc->mask) >> psc->shift;
 
-	return -EINVAL;
+	if (index > psc->num_div)
+		return 0;
+
+	return DIV_ROUND_UP_ULL(parent_rate, psc->div[index]);
 }
-EXPORT_SYMBOL(clk_set_rate);
 
-long clk_round_rate(struct clk *clk, unsigned long rate)
+static long ep93xx_div_round_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long *parent_rate)
 {
-	WARN_ON(clk);
-	return 0;
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long best = 0, now, maxdiv;
+	int i;
+
+	maxdiv = psc->div[psc->num_div - 1];
+
+	for (i = 0; i < psc->num_div; i++) {
+		if ((rate * psc->div[i]) == *parent_rate)
+			return DIV_ROUND_UP_ULL((u64)*parent_rate, psc->div[i]);
+
+		now = DIV_ROUND_UP_ULL((u64)*parent_rate, psc->div[i]);
+
+		if (is_best(rate, now, best))
+			best = now;
+	}
+
+	if (!best)
+		best = DIV_ROUND_UP_ULL(*parent_rate, maxdiv);
+
+	return best;
 }
-EXPORT_SYMBOL(clk_round_rate);
 
-int clk_set_parent(struct clk *clk, struct clk *parent)
+static int ep93xx_div_set_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long parent_rate)
 {
-	WARN_ON(clk);
+	struct clk_psc *psc = to_clk_psc(hw);
+	u32 val = __raw_readl(psc->reg) & ~psc->mask;
+	int i;
+
+	for (i = 0; i < psc->num_div; i++)
+		if (rate == parent_rate / psc->div[i]) {
+			val |= i << psc->shift;
+			break;
+		}
+
+	if (i == psc->num_div)
+		return -EINVAL;
+
+	ep93xx_syscon_swlocked_write(val, psc->reg);
+
 	return 0;
 }
-EXPORT_SYMBOL(clk_set_parent);
 
-struct clk *clk_get_parent(struct clk *clk)
+static const struct clk_ops ep93xx_div_ops = {
+	.enable = ep93xx_clk_enable,
+	.disable = ep93xx_clk_disable,
+	.is_enabled = ep93xx_clk_is_enabled,
+	.recalc_rate = ep93xx_div_recalc_rate,
+	.round_rate = ep93xx_div_round_rate,
+	.set_rate = ep93xx_div_set_rate,
+};
+
+static struct clk_hw *clk_hw_register_div(const char *name,
+					  const char *parent_name,
+					  void __iomem *reg,
+					  u8 enable_bit,
+					  u8 shift,
+					  u8 width,
+					  char *clk_divisors,
+					  u8 num_div)
 {
-	return clk->parent;
+	struct clk_init_data init;
+	struct clk_psc *psc;
+	struct clk *clk;
+
+	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+	if (!psc)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &ep93xx_div_ops;
+	init.flags = 0;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = 1;
+
+	psc->reg = reg;
+	psc->bit_idx = enable_bit;
+	psc->mask = GENMASK(shift + width - 1, shift);
+	psc->shift = shift;
+	psc->div = clk_divisors;
+	psc->num_div = num_div;
+	psc->lock = &clk_lock;
+	psc->hw.init = &init;
+
+	clk = clk_register(NULL, &psc->hw);
+	if (IS_ERR(clk))
+		kfree(psc);
+
+	return &psc->hw;
 }
-EXPORT_SYMBOL(clk_get_parent);
 
+struct ep93xx_gate {
+	unsigned int bit;
+	const char *dev_id;
+	const char *con_id;
+};
 
-static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
-static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
-static char pclk_divisors[] = { 1, 2, 4, 8 };
+static struct ep93xx_gate ep93xx_uarts[] = {
+	{EP93XX_SYSCON_DEVCFG_U1EN, "apb:uart1", NULL},
+	{EP93XX_SYSCON_DEVCFG_U2EN, "apb:uart2", NULL},
+	{EP93XX_SYSCON_DEVCFG_U3EN, "apb:uart3", NULL},
+};
 
-/*
- * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
- */
-static unsigned long calc_pll_rate(u32 config_word)
+static void __init ep93xx_uart_clock_init(void)
 {
-	unsigned long long rate;
-	int i;
+	unsigned int i;
+	struct clk_hw *hw;
+	u32 value;
+	unsigned int clk_uart_div;
 
-	rate = clk_xtali.rate;
-	rate *= ((config_word >> 11) & 0x1f) + 1;		/* X1FBD */
-	rate *= ((config_word >> 5) & 0x3f) + 1;		/* X2FBD */
-	do_div(rate, (config_word & 0x1f) + 1);			/* X2IPD */
-	for (i = 0; i < ((config_word >> 16) & 3); i++)		/* PS */
-		rate >>= 1;
+	value = __raw_readl(EP93XX_SYSCON_PWRCNT);
+	if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
+		clk_uart_div = 1;
+	else
+		clk_uart_div = 2;
 
-	return (unsigned long)rate;
+	hw = clk_hw_register_fixed_factor(NULL, "uart", "xtali", 0, 1, clk_uart_div);
+
+	/* parenting uart gate clocks to uart clock */
+	for (i = 0; i < ARRAY_SIZE(ep93xx_uarts); i++) {
+		hw = ep93xx_clk_register_gate(ep93xx_uarts[i].dev_id,
+					"uart",
+					EP93XX_SYSCON_DEVCFG,
+					ep93xx_uarts[i].bit);
+
+		clk_hw_register_clkdev(hw, NULL, ep93xx_uarts[i].dev_id);
+	}
 }
 
+static struct ep93xx_gate ep93xx_dmas[] = {
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P0, NULL, "m2p0"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P1, NULL, "m2p1"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P2, NULL, "m2p2"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P3, NULL, "m2p3"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P4, NULL, "m2p4"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P5, NULL, "m2p5"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P6, NULL, "m2p6"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P7, NULL, "m2p7"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P8, NULL, "m2p8"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P9, NULL, "m2p9"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2M0, NULL, "m2m0"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2M1, NULL, "m2m1"},
+};
+
 static void __init ep93xx_dma_clock_init(void)
 {
-	clk_m2p0.rate = clk_h.rate;
-	clk_m2p1.rate = clk_h.rate;
-	clk_m2p2.rate = clk_h.rate;
-	clk_m2p3.rate = clk_h.rate;
-	clk_m2p4.rate = clk_h.rate;
-	clk_m2p5.rate = clk_h.rate;
-	clk_m2p6.rate = clk_h.rate;
-	clk_m2p7.rate = clk_h.rate;
-	clk_m2p8.rate = clk_h.rate;
-	clk_m2p9.rate = clk_h.rate;
-	clk_m2m0.rate = clk_h.rate;
-	clk_m2m1.rate = clk_h.rate;
+	unsigned int i;
+	struct clk_hw *hw;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(ep93xx_dmas); i++) {
+		hw = clk_hw_register_gate(NULL, ep93xx_dmas[i].con_id,
+					"hclk", 0,
+					EP93XX_SYSCON_PWRCNT,
+					ep93xx_dmas[i].bit,
+					0,
+					&clk_lock);
+
+		ret = clk_hw_register_clkdev(hw, ep93xx_dmas[i].con_id, NULL);
+		if (ret)
+			pr_err("%s: failed to register lookup %s\n",
+			       __func__, ep93xx_dmas[i].con_id);
+	}
 }
 
 static int __init ep93xx_clock_init(void)
 {
 	u32 value;
+	struct clk_hw *hw;
+	unsigned long clk_pll1_rate;
+	unsigned long clk_f_rate;
+	unsigned long clk_h_rate;
+	unsigned long clk_p_rate;
+	unsigned long clk_pll2_rate;
+	unsigned int clk_f_div;
+	unsigned int clk_h_div;
+	unsigned int clk_p_div;
+	unsigned int clk_usb_div;
+	unsigned long clk_spi_div;
+
+	hw = clk_hw_register_fixed_rate(NULL, "xtali", NULL, 0, EP93XX_EXT_CLK_RATE);
+	clk_hw_register_clkdev(hw, NULL, "xtali");
 
 	/* Determine the bootloader configured pll1 rate */
 	value = __raw_readl(EP93XX_SYSCON_CLKSET1);
 	if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
-		clk_pll1.rate = clk_xtali.rate;
+		clk_pll1_rate = EP93XX_EXT_CLK_RATE;
 	else
-		clk_pll1.rate = calc_pll_rate(value);
+		clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
+
+	hw = clk_hw_register_fixed_rate(NULL, "pll1", "xtali", 0, clk_pll1_rate);
+	clk_hw_register_clkdev(hw, NULL, "pll1");
 
 	/* Initialize the pll1 derived clocks */
-	clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
-	clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
-	clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
+	clk_f_div = fclk_divisors[(value >> 25) & 0x7];
+	clk_h_div = hclk_divisors[(value >> 20) & 0x7];
+	clk_p_div = pclk_divisors[(value >> 18) & 0x3];
+
+	hw = clk_hw_register_fixed_factor(NULL, "fclk", "pll1", 0, 1, clk_f_div);
+	clk_f_rate = clk_get_rate(hw->clk);
+	hw = clk_hw_register_fixed_factor(NULL, "hclk", "pll1", 0, 1, clk_h_div);
+	clk_h_rate = clk_get_rate(hw->clk);
+	hw = clk_hw_register_fixed_factor(NULL, "pclk", "hclk", 0, 1, clk_p_div);
+	clk_p_rate = clk_get_rate(hw->clk);
+
+	clk_hw_register_clkdev(hw, "apb_pclk", NULL);
+
 	ep93xx_dma_clock_init();
 
 	/* Determine the bootloader configured pll2 rate */
 	value = __raw_readl(EP93XX_SYSCON_CLKSET2);
 	if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
-		clk_pll2.rate = clk_xtali.rate;
+		clk_pll2_rate = EP93XX_EXT_CLK_RATE;
 	else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
-		clk_pll2.rate = calc_pll_rate(value);
+		clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
 	else
-		clk_pll2.rate = 0;
+		clk_pll2_rate = 0;
+
+	hw = clk_hw_register_fixed_rate(NULL, "pll2", "xtali", 0, clk_pll2_rate);
+	clk_hw_register_clkdev(hw, NULL, "pll2");
 
 	/* Initialize the pll2 derived clocks */
-	clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
+	/*
+	 * These four bits set the divide ratio between the PLL2
+	 * output and the USB clock.
+	 * 0000 - Divide by 1
+	 * 0001 - Divide by 2
+	 * 0010 - Divide by 3
+	 * 0011 - Divide by 4
+	 * 0100 - Divide by 5
+	 * 0101 - Divide by 6
+	 * 0110 - Divide by 7
+	 * 0111 - Divide by 8
+	 * 1000 - Divide by 9
+	 * 1001 - Divide by 10
+	 * 1010 - Divide by 11
+	 * 1011 - Divide by 12
+	 * 1100 - Divide by 13
+	 * 1101 - Divide by 14
+	 * 1110 - Divide by 15
+	 * 1111 - Divide by 1
+	 * On power-on-reset these bits are reset to 0000b.
+	 */
+	clk_usb_div = (((value >> 28) & 0xf) + 1);
+	hw = clk_hw_register_fixed_factor(NULL, "usb_clk", "pll2", 0, 1, clk_usb_div);
+	hw = clk_hw_register_gate(NULL, "ohci-platform",
+				"usb_clk", 0,
+				EP93XX_SYSCON_PWRCNT,
+				EP93XX_SYSCON_PWRCNT_USH_EN,
+				0,
+				&clk_lock);
+	clk_hw_register_clkdev(hw, NULL, "ohci-platform");
 
 	/*
 	 * EP93xx SSP clock rate was doubled in version E2. For more information
 	 * see:
 	 *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
 	 */
+	clk_spi_div = 1;
 	if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
-		clk_spi.rate /= 2;
+		clk_spi_div = 2;
+	hw = clk_hw_register_fixed_factor(NULL, "ep93xx-spi.0", "xtali", 0, 1, clk_spi_div);
+	clk_hw_register_clkdev(hw, NULL, "ep93xx-spi.0");
+
+	/* pwm clock */
+	hw = clk_hw_register_fixed_factor(NULL, "pwm_clk", "xtali", 0, 1, 1);
+	clk_hw_register_clkdev(hw, "pwm_clk", NULL);
 
 	pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
-		clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
+		clk_pll1_rate / 1000000, clk_pll2_rate / 1000000);
 	pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
-		clk_f.rate / 1000000, clk_h.rate / 1000000,
-		clk_p.rate / 1000000);
+		clk_f_rate / 1000000, clk_h_rate / 1000000,
+		clk_p_rate / 1000000);
+
+	ep93xx_uart_clock_init();
+
+	/* touchscreen/adc clock */
+	hw = clk_hw_register_div("ep93xx-adc",
+				"xtali",
+				EP93XX_SYSCON_KEYTCHCLKDIV,
+				EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
+				EP93XX_SYSCON_KEYTCHCLKDIV_ADIV,
+				1,
+				adc_divisors,
+				ARRAY_SIZE(adc_divisors));
+
+	clk_hw_register_clkdev(hw, NULL, "ep93xx-adc");
+
+	/* keypad clock */
+	hw = clk_hw_register_div("ep93xx-keypad",
+				"xtali",
+				EP93XX_SYSCON_KEYTCHCLKDIV,
+				EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
+				EP93XX_SYSCON_KEYTCHCLKDIV_KDIV,
+				1,
+				adc_divisors,
+				ARRAY_SIZE(adc_divisors));
+
+	clk_hw_register_clkdev(hw, NULL, "ep93xx-keypad");
+
+	/* On reset PDIV and VDIV is set to zero, while PDIV zero
+	 * means clock disable, VDIV shouldn't be zero.
+	 * So i set both dividers to minimum.
+	 */
+	/* ENA - Enable CLK divider. */
+	/* PDIV - 00 - Disable clock */
+	/* VDIV - at least 2 */
+	/* Check and enable video clk registers */
+	value = __raw_readl(EP93XX_SYSCON_VIDCLKDIV);
+	value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
+	ep93xx_syscon_swlocked_write(value, EP93XX_SYSCON_VIDCLKDIV);
+
+	/* check and enable i2s clk registers */
+	value = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
+	value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
+	ep93xx_syscon_swlocked_write(value, EP93XX_SYSCON_I2SCLKDIV);
+
+	/* video clk */
+	hw = clk_hw_register_ddiv("ep93xx-fb",
+				EP93XX_SYSCON_VIDCLKDIV,
+				EP93XX_SYSCON_CLKDIV_ENABLE);
+
+	clk_hw_register_clkdev(hw, NULL, "ep93xx-fb");
+
+	/* i2s clk */
+	hw = clk_hw_register_ddiv("mclk",
+				EP93XX_SYSCON_I2SCLKDIV,
+				EP93XX_SYSCON_CLKDIV_ENABLE);
+
+	clk_hw_register_clkdev(hw, "mclk", "ep93xx-i2s");
+
+	/* i2s sclk */
+#define EP93XX_I2SCLKDIV_SDIV_SHIFT	16
+#define EP93XX_I2SCLKDIV_SDIV_WIDTH	1
+	hw = clk_hw_register_div("sclk",
+				"mclk",
+				EP93XX_SYSCON_I2SCLKDIV,
+				EP93XX_SYSCON_I2SCLKDIV_SENA,
+				EP93XX_I2SCLKDIV_SDIV_SHIFT,
+				EP93XX_I2SCLKDIV_SDIV_WIDTH,
+				sclk_divisors,
+				ARRAY_SIZE(sclk_divisors));
+
+	clk_hw_register_clkdev(hw, "sclk", "ep93xx-i2s");
+
+	/* i2s lrclk */
+#define EP93XX_I2SCLKDIV_LRDIV32_SHIFT	17
+#define EP93XX_I2SCLKDIV_LRDIV32_WIDTH	3
+	hw = clk_hw_register_div("lrclk",
+				"sclk",
+				EP93XX_SYSCON_I2SCLKDIV,
+				EP93XX_SYSCON_I2SCLKDIV_SENA,
+				EP93XX_I2SCLKDIV_LRDIV32_SHIFT,
+				EP93XX_I2SCLKDIV_LRDIV32_WIDTH,
+				lrclk_divisors,
+				ARRAY_SIZE(lrclk_divisors));
+
+	clk_hw_register_clkdev(hw, "lrclk", "ep93xx-i2s");
 
-	clkdev_add_table(clocks, ARRAY_SIZE(clocks));
 	return 0;
 }
 postcore_initcall(ep93xx_clock_init);
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 6fb19a393fd2..bbb79f263331 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -214,7 +214,7 @@ static int ep93xx_ohci_power_on(struct platform_device *pdev)
 			return PTR_ERR(ep93xx_ohci_host_clock);
 	}
 
-	return clk_enable(ep93xx_ohci_host_clock);
+	return clk_prepare_enable(ep93xx_ohci_host_clock);
 }
 
 static void ep93xx_ohci_power_off(struct platform_device *pdev)
diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h
index f2dace1c9154..94ef7f275f94 100644
--- a/arch/arm/mach-ep93xx/soc.h
+++ b/arch/arm/mach-ep93xx/soc.h
@@ -111,19 +111,19 @@
 #define EP93XX_SYSCON_PWRCNT		EP93XX_SYSCON_REG(0x04)
 #define EP93XX_SYSCON_PWRCNT_FIR_EN	(1<<31)
 #define EP93XX_SYSCON_PWRCNT_UARTBAUD	(1<<29)
-#define EP93XX_SYSCON_PWRCNT_USH_EN	(1<<28)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2M1	(1<<27)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2M0	(1<<26)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P8	(1<<25)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P9	(1<<24)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P6	(1<<23)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P7	(1<<22)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P4	(1<<21)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P5	(1<<20)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P2	(1<<19)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P3	(1<<18)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P0	(1<<17)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P1	(1<<16)
+#define EP93XX_SYSCON_PWRCNT_USH_EN	28
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M1	27
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M0	26
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P8	25
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P9	24
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P6	23
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P7	22
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P4	21
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P5	20
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P2	19
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P3	18
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P0	17
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P1	16
 #define EP93XX_SYSCON_HALT		EP93XX_SYSCON_REG(0x08)
 #define EP93XX_SYSCON_STANDBY		EP93XX_SYSCON_REG(0x0c)
 #define EP93XX_SYSCON_CLKSET1		EP93XX_SYSCON_REG(0x20)
@@ -139,13 +139,13 @@
 #define EP93XX_SYSCON_DEVCFG_GONK	(1<<27)
 #define EP93XX_SYSCON_DEVCFG_TONG	(1<<26)
 #define EP93XX_SYSCON_DEVCFG_MONG	(1<<25)
-#define EP93XX_SYSCON_DEVCFG_U3EN	(1<<24)
+#define EP93XX_SYSCON_DEVCFG_U3EN	24
 #define EP93XX_SYSCON_DEVCFG_CPENA	(1<<23)
 #define EP93XX_SYSCON_DEVCFG_A2ONG	(1<<22)
 #define EP93XX_SYSCON_DEVCFG_A1ONG	(1<<21)
-#define EP93XX_SYSCON_DEVCFG_U2EN	(1<<20)
+#define EP93XX_SYSCON_DEVCFG_U2EN	20
 #define EP93XX_SYSCON_DEVCFG_EXVC	(1<<19)
-#define EP93XX_SYSCON_DEVCFG_U1EN	(1<<18)
+#define EP93XX_SYSCON_DEVCFG_U1EN	18
 #define EP93XX_SYSCON_DEVCFG_TIN	(1<<17)
 #define EP93XX_SYSCON_DEVCFG_HC3IN	(1<<15)
 #define EP93XX_SYSCON_DEVCFG_HC3EN	(1<<14)
@@ -163,12 +163,12 @@
 #define EP93XX_SYSCON_DEVCFG_KEYS	(1<<1)
 #define EP93XX_SYSCON_DEVCFG_SHENA	(1<<0)
 #define EP93XX_SYSCON_VIDCLKDIV		EP93XX_SYSCON_REG(0x84)
-#define EP93XX_SYSCON_CLKDIV_ENABLE	(1<<15)
+#define EP93XX_SYSCON_CLKDIV_ENABLE	15
 #define EP93XX_SYSCON_CLKDIV_ESEL	(1<<14)
 #define EP93XX_SYSCON_CLKDIV_PSEL	(1<<13)
 #define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT	8
 #define EP93XX_SYSCON_I2SCLKDIV		EP93XX_SYSCON_REG(0x8c)
-#define EP93XX_SYSCON_I2SCLKDIV_SENA	(1<<31)
+#define EP93XX_SYSCON_I2SCLKDIV_SENA	31
 #define EP93XX_SYSCON_I2SCLKDIV_ORIDE   (1<<29)
 #define EP93XX_SYSCON_I2SCLKDIV_SPOL	(1<<19)
 #define EP93XX_I2SCLKDIV_SDIV		(1 << 16)
@@ -177,9 +177,9 @@
 #define EP93XX_I2SCLKDIV_LRDIV128	(2 << 17)
 #define EP93XX_I2SCLKDIV_LRDIV_MASK	(3 << 17)
 #define EP93XX_SYSCON_KEYTCHCLKDIV	EP93XX_SYSCON_REG(0x90)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN	(1<<31)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV	(1<<16)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN	(1<<15)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN	31
+#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV	16
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN	15
 #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV	(1<<0)
 #define EP93XX_SYSCON_SYSCFG		EP93XX_SYSCON_REG(0x9c)
 #define EP93XX_SYSCON_SYSCFG_REV_MASK	(0xf0000000)
-- 
2.26.2


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

* Re: [PATCH 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-07-26 11:50 ` [PATCH 8/8] ep93xx: clock: convert in-place to COMMON_CLK Nikita Shubin
@ 2021-07-26 11:57   ` Alexander Sverdlin
  0 siblings, 0 replies; 46+ messages in thread
From: Alexander Sverdlin @ 2021-07-26 11:57 UTC (permalink / raw)
  To: Nikita Shubin, Geert Uytterhoeven
  Cc: Russell King, Hartley Sweeten, Arnd Bergmann, Linus Walleij,
	Andrew Morton, Ard Biesheuvel, Krzysztof Kozlowski,
	Anshuman Khandual, Geert Uytterhoeven, YiFei Zhu,
	Uwe Kleine-König, Mike Rapoport, moderated list:ARM PORT,
	open list

Hello Nikita!

Thanks for posting the combined series!

On Mon, 2021-07-26 at 14:50 +0300, Nikita Shubin wrote:
> Converted in-place without moving file to drivers/clk.
> 
> tested on ts7250 (EP9302).
> 
> Only setting rate and change parent tested for, as they
> are missing on ts7250:
> - video
> - I2S
> - ADC/KEYPAD

I've been testing I2S and ADC with your original patch
(and so had to prepare the fixes in the drivers), therefore...

> - PWM
> 
> Only video and I2S clock are interesting, as they are
> GATE + double DIV + MUX, all other are pretty much
> common but require ep93xx_syscon_swlocked_write to set
> registers.
> 
> Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>

Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>

> ---
>  arch/arm/Kconfig             |   2 +-
>  arch/arm/mach-ep93xx/clock.c | 975 ++++++++++++++++++++---------------
>  arch/arm/mach-ep93xx/core.c  |   2 +-
>  arch/arm/mach-ep93xx/soc.h   |  42 +-
>  4 files changed, 581 insertions(+), 440 deletions(-)

-- 
Alexander Sverdlin.



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

* Re: [PATCH 2/8] spi: spi-ep93xx: Prepare clock before using it
  2021-07-26 11:50 ` [PATCH 2/8] spi: spi-ep93xx: " Nikita Shubin
@ 2021-07-26 12:01   ` Mark Brown
  0 siblings, 0 replies; 46+ messages in thread
From: Mark Brown @ 2021-07-26 12:01 UTC (permalink / raw)
  To: Nikita Shubin
  Cc: Alexander Sverdlin, Geert Uytterhoeven, open list:SPI SUBSYSTEM,
	open list

[-- Attachment #1: Type: text/plain, Size: 433 bytes --]

On Mon, Jul 26, 2021 at 02:50:46PM +0300, Nikita Shubin wrote:
> spi_master spi0: failed to prepare transfer hardware: -108
> 
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> ---
>  drivers/spi/spi-ep93xx.c | 4 ++--

You've not provided a Signed-off-by for this so I can't do anything with
it, please see Documentation/process/submitting-patches.rst for details
on what this is and why it's important.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* [PATCH v2 0/8] arm: ep93xx: CCF conversion
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                   ` (7 preceding siblings ...)
  2021-07-26 11:50 ` [PATCH 8/8] ep93xx: clock: convert in-place to COMMON_CLK Nikita Shubin
@ 2021-07-26 13:59 ` Nikita Shubin
  2021-07-26 13:59   ` [PATCH v2 1/8] iio: ep93xx: Prepare clock before using it Nikita Shubin
                     ` (8 more replies)
  2021-07-31 22:04 ` [PATCH " Linus Walleij
  9 siblings, 9 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 13:59 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	Andrew Morton, Andrzej Pietrasiewicz, Anshuman Khandual,
	Ard Biesheuvel, Arnd Bergmann,
	open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, Dmitry Torokhov,
	open list:FRAMEBUFFER LAYER, Geert Uytterhoeven,
	Jonathan Cameron, Krzysztof Kozlowski, Krzysztof Kozlowski,
	Kuninori Morimoto, Lars-Peter Clausen, Linus Walleij,
	moderated list:ARM PORT, open list:FRAMEBUFFER LAYER,
	open list:IIO SUBSYSTEM AND DRIVERS, open list:INPUT (KEYBOARD,
	MOUSE, JOYSTICK , TOUCHSCREEN)...,
	open list, open list:PWM SUBSYSTEM, open list:SPI SUBSYSTEM,
	Mark Brown, Mike Rapoport, Russell King, Uwe Kleine-König,
	YiFei Zhu

This series series of patches converts ep93xx to Common Clock Framework.

It consists of preparation patches to use clk_prepare_enable where it is 
needed, instead of clk_enable used in ep93xx drivers prior to CCF and
a patch converting mach-ep93xx/clock.c to CCF.

Link: https://lore.kernel.org/patchwork/cover/1445563/
Link: https://lore.kernel.org/patchwork/patch/1435884/

v1->v2:
- added SoB

Alexander Sverdlin (7):
  iio: ep93xx: Prepare clock before using it
  spi: spi-ep93xx: Prepare clock before using it
  Input: ep93xx_keypad: Prepare clock before using it
  video: ep93xx: Prepare clock before using it
  dmaengine: ep93xx: Prepare clock before using it
  ASoC: cirrus: i2s: Prepare clock before using it
  pwm: ep93xx: Prepare clock before using it

Nikita Shubin (1):
  ep93xx: clock: convert in-place to COMMON_CLK

 arch/arm/Kconfig                       |   2 +-
 arch/arm/mach-ep93xx/clock.c           | 975 ++++++++++++++-----------
 arch/arm/mach-ep93xx/core.c            |   2 +-
 arch/arm/mach-ep93xx/soc.h             |  42 +-
 drivers/dma/ep93xx_dma.c               |   6 +-
 drivers/iio/adc/ep93xx_adc.c           |   6 +-
 drivers/input/keyboard/ep93xx_keypad.c |   4 +-
 drivers/pwm/pwm-ep93xx.c               |  12 +-
 drivers/spi/spi-ep93xx.c               |   4 +-
 drivers/video/fbdev/ep93xx-fb.c        |   4 +-
 sound/soc/cirrus/ep93xx-i2s.c          |  12 +-
 11 files changed, 605 insertions(+), 464 deletions(-)


base-commit: 64376a981a0e2e57c46efa63197c2ebb7dab35df
-- 
2.26.2


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

* [PATCH v2 1/8] iio: ep93xx: Prepare clock before using it
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
@ 2021-07-26 13:59   ` Nikita Shubin
  2021-07-26 13:59   ` [PATCH v2 2/8] spi: spi-ep93xx: " Nikita Shubin
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 13:59 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin, Jonathan Cameron, Jonathan Cameron,
	Lars-Peter Clausen, open list:IIO SUBSYSTEM AND DRIVERS,
	open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework, otherwise the following is visible:

WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
Enabling unprepared ep93xx-adc
...
Hardware name: Cirrus Logic EDB9302 Evaluation Board
unwind_backtrace) from [<c000c590>] (show_stack+0x10/0x18)
...
clk_core_enable
clk_core_enable_lock
ep93xx_adc_probe
...
ep93xx-adc ep93xx-adc: Cannot enable clock
ep93xx-adc: probe of ep93xx-adc failed with error -108

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 drivers/iio/adc/ep93xx_adc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/adc/ep93xx_adc.c b/drivers/iio/adc/ep93xx_adc.c
index c08ab3c6dfaf..5c85257b814c 100644
--- a/drivers/iio/adc/ep93xx_adc.c
+++ b/drivers/iio/adc/ep93xx_adc.c
@@ -207,7 +207,7 @@ static int ep93xx_adc_probe(struct platform_device *pdev)
 		 */
 	}
 
-	ret = clk_enable(priv->clk);
+	ret = clk_prepare_enable(priv->clk);
 	if (ret) {
 		dev_err(&pdev->dev, "Cannot enable clock\n");
 		return ret;
@@ -215,7 +215,7 @@ static int ep93xx_adc_probe(struct platform_device *pdev)
 
 	ret = iio_device_register(iiodev);
 	if (ret)
-		clk_disable(priv->clk);
+		clk_disable_unprepare(priv->clk);
 
 	return ret;
 }
@@ -226,7 +226,7 @@ static int ep93xx_adc_remove(struct platform_device *pdev)
 	struct ep93xx_adc_priv *priv = iio_priv(iiodev);
 
 	iio_device_unregister(iiodev);
-	clk_disable(priv->clk);
+	clk_disable_unprepare(priv->clk);
 
 	return 0;
 }

base-commit: 64376a981a0e2e57c46efa63197c2ebb7dab35df
-- 
2.26.2


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

* [PATCH v2 2/8] spi: spi-ep93xx: Prepare clock before using it
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
  2021-07-26 13:59   ` [PATCH v2 1/8] iio: ep93xx: Prepare clock before using it Nikita Shubin
@ 2021-07-26 13:59   ` Nikita Shubin
  2021-07-26 16:51     ` Mark Brown
  2021-07-26 13:59   ` [PATCH v2 3/8] Input: ep93xx_keypad: " Nikita Shubin
                     ` (6 subsequent siblings)
  8 siblings, 1 reply; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 13:59 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin, Mark Brown, open list:SPI SUBSYSTEM, open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework, otherwise the following is visible:

WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
Enabling unprepared ep93xx-spi.0
...
Hardware name: Cirrus Logic EDB9302 Evaluation Board
...
clk_core_enable
clk_core_enable_lock
ep93xx_spi_prepare_hardware
__spi_pump_messages
__spi_sync
spi_sync
spi_sync_transfer.constprop.0
regmap_spi_write
_regmap_raw_write_impl
_regmap_bus_raw_write
_regmap_update_bits
regmap_update_bits_base
cs4271_component_probe
snd_soc_component_probe
soc_probe_component
snd_soc_bind_card
edb93xx_probe
...
spi_master spi0: failed to prepare transfer hardware: -108

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 drivers/spi/spi-ep93xx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c
index aa676559d273..5896a7b2fade 100644
--- a/drivers/spi/spi-ep93xx.c
+++ b/drivers/spi/spi-ep93xx.c
@@ -550,7 +550,7 @@ static int ep93xx_spi_prepare_hardware(struct spi_master *master)
 	u32 val;
 	int ret;
 
-	ret = clk_enable(espi->clk);
+	ret = clk_prepare_enable(espi->clk);
 	if (ret)
 		return ret;
 
@@ -570,7 +570,7 @@ static int ep93xx_spi_unprepare_hardware(struct spi_master *master)
 	val &= ~SSPCR1_SSE;
 	writel(val, espi->mmio + SSPCR1);
 
-	clk_disable(espi->clk);
+	clk_disable_unprepare(espi->clk);
 
 	return 0;
 }
-- 
2.26.2


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

* [PATCH v2 3/8] Input: ep93xx_keypad: Prepare clock before using it
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
  2021-07-26 13:59   ` [PATCH v2 1/8] iio: ep93xx: Prepare clock before using it Nikita Shubin
  2021-07-26 13:59   ` [PATCH v2 2/8] spi: spi-ep93xx: " Nikita Shubin
@ 2021-07-26 13:59   ` Nikita Shubin
  2021-07-26 13:59   ` [PATCH v2 4/8] video: ep93xx: " Nikita Shubin
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 13:59 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin, Dmitry Torokhov, Krzysztof Kozlowski,
	Andrzej Pietrasiewicz, open list:INPUT (KEYBOARD, MOUSE,
	JOYSTICK , TOUCHSCREEN)...,
	open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 drivers/input/keyboard/ep93xx_keypad.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c
index c8194333d612..e0e931e796fa 100644
--- a/drivers/input/keyboard/ep93xx_keypad.c
+++ b/drivers/input/keyboard/ep93xx_keypad.c
@@ -157,7 +157,7 @@ static int ep93xx_keypad_open(struct input_dev *pdev)
 
 	if (!keypad->enabled) {
 		ep93xx_keypad_config(keypad);
-		clk_enable(keypad->clk);
+		clk_prepare_enable(keypad->clk);
 		keypad->enabled = true;
 	}
 
@@ -169,7 +169,7 @@ static void ep93xx_keypad_close(struct input_dev *pdev)
 	struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
 
 	if (keypad->enabled) {
-		clk_disable(keypad->clk);
+		clk_disable_unprepare(keypad->clk);
 		keypad->enabled = false;
 	}
 }
-- 
2.26.2


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

* [PATCH v2 4/8] video: ep93xx: Prepare clock before using it
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                     ` (2 preceding siblings ...)
  2021-07-26 13:59   ` [PATCH v2 3/8] Input: ep93xx_keypad: " Nikita Shubin
@ 2021-07-26 13:59   ` Nikita Shubin
  2021-07-26 13:59   ` [PATCH v2 5/8] dmaengine: " Nikita Shubin
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 13:59 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin, open list:FRAMEBUFFER LAYER,
	open list:FRAMEBUFFER LAYER, open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 drivers/video/fbdev/ep93xx-fb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c
index ba33b4dce0df..2398b3d48fed 100644
--- a/drivers/video/fbdev/ep93xx-fb.c
+++ b/drivers/video/fbdev/ep93xx-fb.c
@@ -548,7 +548,7 @@ static int ep93xxfb_probe(struct platform_device *pdev)
 	}
 
 	ep93xxfb_set_par(info);
-	clk_enable(fbi->clk);
+	clk_prepare_enable(fbi->clk);
 
 	err = register_framebuffer(info);
 	if (err)
@@ -577,7 +577,7 @@ static int ep93xxfb_remove(struct platform_device *pdev)
 	struct ep93xx_fbi *fbi = info->par;
 
 	unregister_framebuffer(info);
-	clk_disable(fbi->clk);
+	clk_disable_unprepare(fbi->clk);
 	ep93xxfb_dealloc_videomem(info);
 	fb_dealloc_cmap(&info->cmap);
 
-- 
2.26.2


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

* [PATCH v2 5/8] dmaengine: ep93xx: Prepare clock before using it
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                     ` (3 preceding siblings ...)
  2021-07-26 13:59   ` [PATCH v2 4/8] video: ep93xx: " Nikita Shubin
@ 2021-07-26 13:59   ` Nikita Shubin
  2021-08-02  6:57     ` Vinod Koul
  2021-07-26 13:59   ` [PATCH v2 6/8] ASoC: cirrus: i2s: " Nikita Shubin
                     ` (3 subsequent siblings)
  8 siblings, 1 reply; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 13:59 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin, Vinod Koul,
	open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework, otherwise the following is visible:

WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
Enabling unprepared m2p0
...
Hardware name: Cirrus Logic EDB9302 Evaluation Board
...
clk_core_enable
clk_core_enable_lock
ep93xx_dma_alloc_chan_resources
dma_chan_get
find_candidate
__dma_request_channel
snd_dmaengine_pcm_request_channel
dmaengine_pcm_new
snd_soc_pcm_component_new
soc_new_pcm
snd_soc_bind_card
edb93xx_probe
...
ep93xx-i2s ep93xx-i2s: Missing dma channel for stream: 0
ep93xx-i2s ep93xx-i2s: ASoC: error at snd_soc_pcm_component_new on ep93xx-i2s: -22
edb93xx-audio edb93xx-audio: ASoC: can't create pcm CS4271 HiFi :-22
edb93xx-audio edb93xx-audio: snd_soc_register_card() failed: -22
edb93xx-audio: probe of edb93xx-audio failed with error -22

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 drivers/dma/ep93xx_dma.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 01027779beb8..98f9ee70362e 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -897,7 +897,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)
 	if (data && data->name)
 		name = data->name;
 
-	ret = clk_enable(edmac->clk);
+	ret = clk_prepare_enable(edmac->clk);
 	if (ret)
 		return ret;
 
@@ -936,7 +936,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan)
 fail_free_irq:
 	free_irq(edmac->irq, edmac);
 fail_clk_disable:
-	clk_disable(edmac->clk);
+	clk_disable_unprepare(edmac->clk);
 
 	return ret;
 }
@@ -969,7 +969,7 @@ static void ep93xx_dma_free_chan_resources(struct dma_chan *chan)
 	list_for_each_entry_safe(desc, d, &list, node)
 		kfree(desc);
 
-	clk_disable(edmac->clk);
+	clk_disable_unprepare(edmac->clk);
 	free_irq(edmac->irq, edmac);
 }
 
-- 
2.26.2


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

* [PATCH v2 6/8] ASoC: cirrus: i2s: Prepare clock before using it
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                     ` (4 preceding siblings ...)
  2021-07-26 13:59   ` [PATCH v2 5/8] dmaengine: " Nikita Shubin
@ 2021-07-26 13:59   ` Nikita Shubin
  2021-07-26 16:51     ` Mark Brown
  2021-07-26 13:59   ` [PATCH v2 7/8] pwm: ep93xx: " Nikita Shubin
                     ` (2 subsequent siblings)
  8 siblings, 1 reply; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 13:59 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Kuninori Morimoto,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework, otherwise the following is visible:

WARNING: CPU: 0 PID: 97 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
Enabling unprepared mclk
...
Hardware name: Cirrus Logic EDB9302 Evaluation Board
...
clk_core_enable
clk_core_enable_lock
ep93xx_i2s_hw_params
snd_soc_dai_hw_params
soc_pcm_hw_params
snd_pcm_hw_params
snd_pcm_ioctl
...

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 sound/soc/cirrus/ep93xx-i2s.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index 0d26550d0df8..4d3179f03202 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -111,9 +111,9 @@ static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream)
 	if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&
 	    (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {
 		/* Enable clocks */
-		clk_enable(info->mclk);
-		clk_enable(info->sclk);
-		clk_enable(info->lrclk);
+		clk_prepare_enable(info->mclk);
+		clk_prepare_enable(info->sclk);
+		clk_prepare_enable(info->lrclk);
 
 		/* Enable i2s */
 		ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1);
@@ -156,9 +156,9 @@ static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)
 		ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 0);
 
 		/* Disable clocks */
-		clk_disable(info->lrclk);
-		clk_disable(info->sclk);
-		clk_disable(info->mclk);
+		clk_disable_unprepare(info->lrclk);
+		clk_disable_unprepare(info->sclk);
+		clk_disable_unprepare(info->mclk);
 	}
 }
 
-- 
2.26.2


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

* [PATCH v2 7/8] pwm: ep93xx: Prepare clock before using it
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                     ` (5 preceding siblings ...)
  2021-07-26 13:59   ` [PATCH v2 6/8] ASoC: cirrus: i2s: " Nikita Shubin
@ 2021-07-26 13:59   ` Nikita Shubin
  2021-07-26 13:59   ` [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK Nikita Shubin
  2021-08-03 22:35   ` (subset) [PATCH v2 0/8] arm: ep93xx: CCF conversion Mark Brown
  8 siblings, 0 replies; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 13:59 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin, Uwe Kleine-König, Thierry Reding, Lee Jones,
	open list:PWM SUBSYSTEM, open list

From: Alexander Sverdlin <alexander.sverdlin@gmail.com>

Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
to Common Clock Framework.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 drivers/pwm/pwm-ep93xx.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pwm/pwm-ep93xx.c b/drivers/pwm/pwm-ep93xx.c
index 4ca70794ad96..8c0d4d69d9e6 100644
--- a/drivers/pwm/pwm-ep93xx.c
+++ b/drivers/pwm/pwm-ep93xx.c
@@ -74,7 +74,7 @@ static int ep93xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * Configuration can be changed at any time.
 	 */
 	if (!pwm_is_enabled(pwm)) {
-		ret = clk_enable(ep93xx_pwm->clk);
+		ret = clk_prepare_enable(ep93xx_pwm->clk);
 		if (ret)
 			return ret;
 	}
@@ -105,7 +105,7 @@ static int ep93xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	}
 
 	if (!pwm_is_enabled(pwm))
-		clk_disable(ep93xx_pwm->clk);
+		clk_disable_unprepare(ep93xx_pwm->clk);
 
 	return ret;
 }
@@ -120,7 +120,7 @@ static int ep93xx_pwm_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * The clock needs to be enabled to access the PWM registers.
 	 * Polarity can only be changed when the PWM is disabled.
 	 */
-	ret = clk_enable(ep93xx_pwm->clk);
+	ret = clk_prepare_enable(ep93xx_pwm->clk);
 	if (ret)
 		return ret;
 
@@ -129,7 +129,7 @@ static int ep93xx_pwm_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
 	else
 		writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_INVERT);
 
-	clk_disable(ep93xx_pwm->clk);
+	clk_disable_unprepare(ep93xx_pwm->clk);
 
 	return 0;
 }
@@ -139,7 +139,7 @@ static int ep93xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 	struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
 	int ret;
 
-	ret = clk_enable(ep93xx_pwm->clk);
+	ret = clk_prepare_enable(ep93xx_pwm->clk);
 	if (ret)
 		return ret;
 
@@ -153,7 +153,7 @@ static void ep93xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 	struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip);
 
 	writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_ENABLE);
-	clk_disable(ep93xx_pwm->clk);
+	clk_disable_unprepare(ep93xx_pwm->clk);
 }
 
 static const struct pwm_ops ep93xx_pwm_ops = {
-- 
2.26.2


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

* [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                     ` (6 preceding siblings ...)
  2021-07-26 13:59   ` [PATCH v2 7/8] pwm: ep93xx: " Nikita Shubin
@ 2021-07-26 13:59   ` Nikita Shubin
  2021-10-12  8:03     ` Alexander Sverdlin
  2021-08-03 22:35   ` (subset) [PATCH v2 0/8] arm: ep93xx: CCF conversion Mark Brown
  8 siblings, 1 reply; 46+ messages in thread
From: Nikita Shubin @ 2021-07-26 13:59 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven
  Cc: Nikita Shubin, Russell King, Hartley Sweeten, Arnd Bergmann,
	Linus Walleij, Ard Biesheuvel, Andrew Morton,
	Krzysztof Kozlowski, Anshuman Khandual, Geert Uytterhoeven,
	YiFei Zhu, Mike Rapoport, Uwe Kleine-König,
	moderated list:ARM PORT, open list

Converted in-place without moving file to drivers/clk.

tested on ts7250 (EP9302).

Only setting rate and change parent tested for, as they
are missing on ts7250:
- video
- I2S
- ADC/KEYPAD
- PWM

Only video and I2S clock are interesting, as they are
GATE + double DIV + MUX, all other are pretty much
common but require ep93xx_syscon_swlocked_write to set
registers.

Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 arch/arm/Kconfig             |   2 +-
 arch/arm/mach-ep93xx/clock.c | 975 ++++++++++++++++++++---------------
 arch/arm/mach-ep93xx/core.c  |   2 +-
 arch/arm/mach-ep93xx/soc.h   |  42 +-
 4 files changed, 581 insertions(+), 440 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 24804f11302d..8f4a74a37406 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -357,7 +357,7 @@ config ARCH_EP93XX
 	select CLKSRC_MMIO
 	select CPU_ARM920T
 	select GPIOLIB
-	select HAVE_LEGACY_CLK
+	select COMMON_CLK
 	help
 	  This enables support for the Cirrus EP93xx series of CPUs.
 
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 2810eb5b2aca..cc75087134d3 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/soc/cirrus/ep93xx.h>
 
 #include "hardware.h"
@@ -24,348 +25,194 @@
 
 #include "soc.h"
 
-struct clk {
-	struct clk	*parent;
-	unsigned long	rate;
-	int		users;
-	int		sw_locked;
-	void __iomem	*enable_reg;
-	u32		enable_mask;
-
-	unsigned long	(*get_rate)(struct clk *clk);
-	int		(*set_rate)(struct clk *clk, unsigned long rate);
-};
-
-
-static unsigned long get_uart_rate(struct clk *clk);
-
-static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
-static int set_div_rate(struct clk *clk, unsigned long rate);
-static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
-static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
+static DEFINE_SPINLOCK(clk_lock);
 
-static struct clk clk_xtali = {
-	.rate		= EP93XX_EXT_CLK_RATE,
-};
-static struct clk clk_uart1 = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_DEVCFG,
-	.enable_mask	= EP93XX_SYSCON_DEVCFG_U1EN,
-	.get_rate	= get_uart_rate,
-};
-static struct clk clk_uart2 = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_DEVCFG,
-	.enable_mask	= EP93XX_SYSCON_DEVCFG_U2EN,
-	.get_rate	= get_uart_rate,
-};
-static struct clk clk_uart3 = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_DEVCFG,
-	.enable_mask	= EP93XX_SYSCON_DEVCFG_U3EN,
-	.get_rate	= get_uart_rate,
-};
-static struct clk clk_pll1 = {
-	.parent		= &clk_xtali,
-};
-static struct clk clk_f = {
-	.parent		= &clk_pll1,
-};
-static struct clk clk_h = {
-	.parent		= &clk_pll1,
-};
-static struct clk clk_p = {
-	.parent		= &clk_pll1,
-};
-static struct clk clk_pll2 = {
-	.parent		= &clk_xtali,
-};
-static struct clk clk_usb_host = {
-	.parent		= &clk_pll2,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_USH_EN,
-};
-static struct clk clk_keypad = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_KEYTCHCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
-	.set_rate	= set_keytchclk_rate,
-};
-static struct clk clk_adc = {
-	.parent		= &clk_xtali,
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_KEYTCHCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
-	.set_rate	= set_keytchclk_rate,
-};
-static struct clk clk_spi = {
-	.parent		= &clk_xtali,
-	.rate		= EP93XX_EXT_CLK_RATE,
-};
-static struct clk clk_pwm = {
-	.parent		= &clk_xtali,
-	.rate		= EP93XX_EXT_CLK_RATE,
-};
+static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
+static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
+static char pclk_divisors[] = { 1, 2, 4, 8 };
 
-static struct clk clk_video = {
-	.sw_locked	= 1,
-	.enable_reg     = EP93XX_SYSCON_VIDCLKDIV,
-	.enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
-	.set_rate	= set_div_rate,
-};
+static char adc_divisors[] = { 16, 4 };
+static char sclk_divisors[] = { 2, 4 };
+static char lrclk_divisors[] = { 32, 64, 128 };
 
-static struct clk clk_i2s_mclk = {
-	.sw_locked	= 1,
-	.enable_reg	= EP93XX_SYSCON_I2SCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_CLKDIV_ENABLE,
-	.set_rate	= set_div_rate,
+static const char * const mux_parents[] = {
+	"xtali",
+	"pll1",
+	"pll2"
 };
 
-static struct clk clk_i2s_sclk = {
-	.sw_locked	= 1,
-	.parent		= &clk_i2s_mclk,
-	.enable_reg	= EP93XX_SYSCON_I2SCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_I2SCLKDIV_SENA,
-	.set_rate	= set_i2s_sclk_rate,
-};
+/*
+ * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
+ */
+static unsigned long calc_pll_rate(unsigned long long rate, u32 config_word)
+{
+	int i;
 
-static struct clk clk_i2s_lrclk = {
-	.sw_locked	= 1,
-	.parent		= &clk_i2s_sclk,
-	.enable_reg	= EP93XX_SYSCON_I2SCLKDIV,
-	.enable_mask	= EP93XX_SYSCON_I2SCLKDIV_SENA,
-	.set_rate	= set_i2s_lrclk_rate,
-};
+	rate *= ((config_word >> 11) & 0x1f) + 1;		/* X1FBD */
+	rate *= ((config_word >> 5) & 0x3f) + 1;		/* X2FBD */
+	do_div(rate, (config_word & 0x1f) + 1);			/* X2IPD */
+	for (i = 0; i < ((config_word >> 16) & 3); i++)		/* PS */
+		rate >>= 1;
 
-/* DMA Clocks */
-static struct clk clk_m2p0 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P0,
-};
-static struct clk clk_m2p1 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P1,
-};
-static struct clk clk_m2p2 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P2,
-};
-static struct clk clk_m2p3 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P3,
-};
-static struct clk clk_m2p4 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P4,
-};
-static struct clk clk_m2p5 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P5,
-};
-static struct clk clk_m2p6 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P6,
-};
-static struct clk clk_m2p7 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P7,
-};
-static struct clk clk_m2p8 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P8,
-};
-static struct clk clk_m2p9 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2P9,
-};
-static struct clk clk_m2m0 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2M0,
-};
-static struct clk clk_m2m1 = {
-	.parent		= &clk_h,
-	.enable_reg	= EP93XX_SYSCON_PWRCNT,
-	.enable_mask	= EP93XX_SYSCON_PWRCNT_DMA_M2M1,
-};
+	return (unsigned long)rate;
+}
 
-#define INIT_CK(dev,con,ck)					\
-	{ .dev_id = dev, .con_id = con, .clk = ck }
-
-static struct clk_lookup clocks[] = {
-	INIT_CK(NULL,			"xtali",	&clk_xtali),
-	INIT_CK("apb:uart1",		NULL,		&clk_uart1),
-	INIT_CK("apb:uart2",		NULL,		&clk_uart2),
-	INIT_CK("apb:uart3",		NULL,		&clk_uart3),
-	INIT_CK(NULL,			"pll1",		&clk_pll1),
-	INIT_CK(NULL,			"fclk",		&clk_f),
-	INIT_CK(NULL,			"hclk",		&clk_h),
-	INIT_CK(NULL,			"apb_pclk",	&clk_p),
-	INIT_CK(NULL,			"pll2",		&clk_pll2),
-	INIT_CK("ohci-platform",	NULL,		&clk_usb_host),
-	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
-	INIT_CK("ep93xx-adc",		NULL,		&clk_adc),
-	INIT_CK("ep93xx-fb",		NULL,		&clk_video),
-	INIT_CK("ep93xx-spi.0",		NULL,		&clk_spi),
-	INIT_CK("ep93xx-i2s",		"mclk",		&clk_i2s_mclk),
-	INIT_CK("ep93xx-i2s",		"sclk",		&clk_i2s_sclk),
-	INIT_CK("ep93xx-i2s",		"lrclk",	&clk_i2s_lrclk),
-	INIT_CK(NULL,			"pwm_clk",	&clk_pwm),
-	INIT_CK(NULL,			"m2p0",		&clk_m2p0),
-	INIT_CK(NULL,			"m2p1",		&clk_m2p1),
-	INIT_CK(NULL,			"m2p2",		&clk_m2p2),
-	INIT_CK(NULL,			"m2p3",		&clk_m2p3),
-	INIT_CK(NULL,			"m2p4",		&clk_m2p4),
-	INIT_CK(NULL,			"m2p5",		&clk_m2p5),
-	INIT_CK(NULL,			"m2p6",		&clk_m2p6),
-	INIT_CK(NULL,			"m2p7",		&clk_m2p7),
-	INIT_CK(NULL,			"m2p8",		&clk_m2p8),
-	INIT_CK(NULL,			"m2p9",		&clk_m2p9),
-	INIT_CK(NULL,			"m2m0",		&clk_m2m0),
-	INIT_CK(NULL,			"m2m1",		&clk_m2m1),
+struct clk_psc {
+	struct clk_hw hw;
+	void __iomem *reg;
+	u8 bit_idx;
+	u32 mask;
+	u8 shift;
+	u8 width;
+	char *div;
+	u8 num_div;
+	spinlock_t *lock;
 };
 
-static DEFINE_SPINLOCK(clk_lock);
+#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw)
 
-static void __clk_enable(struct clk *clk)
+static int ep93xx_clk_is_enabled(struct clk_hw *hw)
 {
-	if (!clk->users++) {
-		if (clk->parent)
-			__clk_enable(clk->parent);
-
-		if (clk->enable_reg) {
-			u32 v;
-
-			v = __raw_readl(clk->enable_reg);
-			v |= clk->enable_mask;
-			if (clk->sw_locked)
-				ep93xx_syscon_swlocked_write(v, clk->enable_reg);
-			else
-				__raw_writel(v, clk->enable_reg);
-		}
-	}
+	struct clk_psc *psc = to_clk_psc(hw);
+	u32 val = readl(psc->reg);
+
+	return (val & BIT(psc->bit_idx)) ? 1 : 0;
 }
 
-int clk_enable(struct clk *clk)
+static int ep93xx_clk_enable(struct clk_hw *hw)
 {
-	unsigned long flags;
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long flags = 0;
+	u32 val;
 
-	if (!clk)
-		return -EINVAL;
+	if (psc->lock)
+		spin_lock_irqsave(psc->lock, flags);
+
+	val = __raw_readl(psc->reg);
+	val |= BIT(psc->bit_idx);
+
+	ep93xx_syscon_swlocked_write(val, psc->reg);
 
-	spin_lock_irqsave(&clk_lock, flags);
-	__clk_enable(clk);
-	spin_unlock_irqrestore(&clk_lock, flags);
+	if (psc->lock)
+		spin_unlock_irqrestore(psc->lock, flags);
 
 	return 0;
 }
-EXPORT_SYMBOL(clk_enable);
 
-static void __clk_disable(struct clk *clk)
+static void ep93xx_clk_disable(struct clk_hw *hw)
 {
-	if (!--clk->users) {
-		if (clk->enable_reg) {
-			u32 v;
-
-			v = __raw_readl(clk->enable_reg);
-			v &= ~clk->enable_mask;
-			if (clk->sw_locked)
-				ep93xx_syscon_swlocked_write(v, clk->enable_reg);
-			else
-				__raw_writel(v, clk->enable_reg);
-		}
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long flags = 0;
+	u32 val;
 
-		if (clk->parent)
-			__clk_disable(clk->parent);
-	}
-}
+	if (psc->lock)
+		spin_lock_irqsave(psc->lock, flags);
 
-void clk_disable(struct clk *clk)
-{
-	unsigned long flags;
+	val = __raw_readl(psc->reg);
+	val &= ~BIT(psc->bit_idx);
 
-	if (!clk)
-		return;
+	ep93xx_syscon_swlocked_write(val, psc->reg);
 
-	spin_lock_irqsave(&clk_lock, flags);
-	__clk_disable(clk);
-	spin_unlock_irqrestore(&clk_lock, flags);
+	if (psc->lock)
+		spin_unlock_irqrestore(psc->lock, flags);
 }
-EXPORT_SYMBOL(clk_disable);
 
-static unsigned long get_uart_rate(struct clk *clk)
-{
-	unsigned long rate = clk_get_rate(clk->parent);
-	u32 value;
+static const struct clk_ops clk_ep93xx_gate_ops = {
+	.enable = ep93xx_clk_enable,
+	.disable = ep93xx_clk_disable,
+	.is_enabled = ep93xx_clk_is_enabled,
+};
 
-	value = __raw_readl(EP93XX_SYSCON_PWRCNT);
-	if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
-		return rate;
-	else
-		return rate / 2;
+static struct clk_hw *ep93xx_clk_register_gate(const char *name,
+				    const char *parent_name,
+				    void __iomem *reg,
+				    u8 bit_idx)
+{
+	struct clk_init_data init;
+	struct clk_psc *psc;
+	struct clk *clk;
+
+	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+	if (!psc)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_ep93xx_gate_ops;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	psc->reg = reg;
+	psc->bit_idx = bit_idx;
+	psc->hw.init = &init;
+	psc->lock = &clk_lock;
+
+	clk = clk_register(NULL, &psc->hw);
+	if (IS_ERR(clk))
+		kfree(psc);
+
+	return &psc->hw;
 }
 
-unsigned long clk_get_rate(struct clk *clk)
+static u8 ep93xx_mux_get_parent(struct clk_hw *hw)
 {
-	if (clk->get_rate)
-		return clk->get_rate(clk);
+	struct clk_psc *psc = to_clk_psc(hw);
+	u32 val = __raw_readl(psc->reg);
 
-	return clk->rate;
+	if (!(val & EP93XX_SYSCON_CLKDIV_ESEL))
+		return 0;
+
+	if (!(val & EP93XX_SYSCON_CLKDIV_PSEL))
+		return 1;
+
+	return 2;
 }
-EXPORT_SYMBOL(clk_get_rate);
 
-static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
+static int ep93xx_mux_set_parent_lock(struct clk_hw *hw, u8 index)
 {
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long flags = 0;
 	u32 val;
-	u32 div_bit;
 
-	val = __raw_readl(clk->enable_reg);
+	if (index >= ARRAY_SIZE(mux_parents))
+		return -EINVAL;
 
-	/*
-	 * The Key Matrix and ADC clocks are configured using the same
-	 * System Controller register.  The clock used will be either
-	 * 1/4 or 1/16 the external clock rate depending on the
-	 * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
-	 * bit being set or cleared.
-	 */
-	div_bit = clk->enable_mask >> 15;
+	if (psc->lock)
+		spin_lock_irqsave(psc->lock, flags);
 
-	if (rate == EP93XX_KEYTCHCLK_DIV4)
-		val |= div_bit;
-	else if (rate == EP93XX_KEYTCHCLK_DIV16)
-		val &= ~div_bit;
-	else
-		return -EINVAL;
+	val = __raw_readl(psc->reg);
+	val &= ~(EP93XX_SYSCON_CLKDIV_ESEL | EP93XX_SYSCON_CLKDIV_PSEL);
+
+
+	if (index != 0) {
+		val |= EP93XX_SYSCON_CLKDIV_ESEL;
+		val |= (index - 1) ? EP93XX_SYSCON_CLKDIV_PSEL : 0;
+	}
+
+	ep93xx_syscon_swlocked_write(val, psc->reg);
+
+	if (psc->lock)
+		spin_unlock_irqrestore(psc->lock, flags);
 
-	ep93xx_syscon_swlocked_write(val, clk->enable_reg);
-	clk->rate = rate;
 	return 0;
 }
 
-static int calc_clk_div(struct clk *clk, unsigned long rate,
-			int *psel, int *esel, int *pdiv, int *div)
+static bool is_best(unsigned long rate, unsigned long now,
+		     unsigned long best)
 {
-	struct clk *mclk;
-	unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
-	int i, found = 0, __div = 0, __pdiv = 0;
+	return abs(rate - now) < abs(rate - best);
+}
 
-	/* Don't exceed the maximum rate */
-	max_rate = max3(clk_pll1.rate / 4, clk_pll2.rate / 4, clk_xtali.rate / 4);
-	rate = min(rate, max_rate);
+static int ep93xx_mux_determine_rate(struct clk_hw *hw,
+				struct clk_rate_request *req)
+{
+	unsigned long rate = req->rate;
+	struct clk *best_parent = 0;
+	unsigned long __parent_rate;
+	unsigned long best_rate = 0, actual_rate, mclk_rate;
+	unsigned long best_parent_rate;
+	int __div = 0, __pdiv = 0;
+	int i;
 
 	/*
 	 * Try the two pll's and the external clock
@@ -376,14 +223,11 @@ static int calc_clk_div(struct clk *clk, unsigned long rate,
 	 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
 	 *
 	 */
-	for (i = 0; i < 3; i++) {
-		if (i == 0)
-			mclk = &clk_xtali;
-		else if (i == 1)
-			mclk = &clk_pll1;
-		else
-			mclk = &clk_pll2;
-		mclk_rate = mclk->rate * 2;
+	for (i = 0; i < ARRAY_SIZE(mux_parents); i++) {
+		struct clk *parent = clk_get_sys(mux_parents[i], NULL);
+
+		__parent_rate = clk_get_rate(parent);
+		mclk_rate = __parent_rate * 2;
 
 		/* Try each predivider value */
 		for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
@@ -392,197 +236,494 @@ static int calc_clk_div(struct clk *clk, unsigned long rate,
 				continue;
 
 			actual_rate = mclk_rate / (__pdiv * __div);
-
-			if (!found || abs(actual_rate - rate) < rate_err) {
-				*pdiv = __pdiv - 3;
-				*div = __div;
-				*psel = (i == 2);
-				*esel = (i != 0);
-				clk->parent = mclk;
-				clk->rate = actual_rate;
-				rate_err = abs(actual_rate - rate);
-				found = 1;
+			if (is_best(rate, actual_rate, best_rate)) {
+				best_rate = actual_rate;
+				best_parent_rate = __parent_rate;
+				best_parent = parent;
 			}
 		}
 	}
 
-	if (!found)
+	if (!best_parent)
 		return -EINVAL;
 
+	req->best_parent_rate = best_parent_rate;
+	req->best_parent_hw = __clk_get_hw(best_parent);
+	req->rate = best_rate;
+
 	return 0;
 }
 
-static int set_div_rate(struct clk *clk, unsigned long rate)
+static unsigned long ep93xx_ddiv_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
 {
-	int err, psel = 0, esel = 0, pdiv = 0, div = 0;
-	u32 val;
-
-	err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
-	if (err)
-		return err;
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long rate = 0;
+	u32 val = __raw_readl(psc->reg);
+	int __pdiv = ((val >> EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) & 0x03);
+	int __div = val & 0x7f;
 
-	/* Clear the esel, psel, pdiv and div bits */
-	val = __raw_readl(clk->enable_reg);
-	val &= ~0x7fff;
+	if (__div > 0)
+		rate = (parent_rate * 2) / ((__pdiv + 3) * __div);
 
-	/* Set the new esel, psel, pdiv and div bits for the new clock rate */
-	val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
-		(psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
-		(pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
-	ep93xx_syscon_swlocked_write(val, clk->enable_reg);
-	return 0;
+	return rate;
 }
 
-static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
+static int ep93xx_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
 {
-	unsigned val = __raw_readl(clk->enable_reg);
-
-	if (rate == clk_i2s_mclk.rate / 2)
-		ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV, 
-					     clk->enable_reg);
-	else if (rate == clk_i2s_mclk.rate / 4)
-		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV, 
-					     clk->enable_reg);
-	else
+	struct clk_psc *psc = to_clk_psc(hw);
+	int pdiv = 0, div = 0;
+	unsigned long best_rate = 0, actual_rate, mclk_rate;
+	int __div = 0, __pdiv = 0;
+	u32 val;
+
+	mclk_rate = parent_rate * 2;
+
+	for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
+		__div = mclk_rate / (rate * __pdiv);
+		if (__div < 2 || __div > 127)
+			continue;
+
+		actual_rate = mclk_rate / (__pdiv * __div);
+		if (is_best(rate, actual_rate, best_rate)) {
+			pdiv = __pdiv - 3;
+			div = __div;
+			best_rate = actual_rate;
+		}
+	}
+
+	if (!best_rate)
 		return -EINVAL;
 
-	clk_i2s_sclk.rate = rate;
+	val = __raw_readl(psc->reg);
+
+	/* Clear old dividers */
+	val &= ~0x37f;
+
+	/* Set the new pdiv and div bits for the new clock rate */
+	val |= (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
+	ep93xx_syscon_swlocked_write(val, psc->reg);
+
 	return 0;
 }
 
-static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned val = __raw_readl(clk->enable_reg) & 
-		~EP93XX_I2SCLKDIV_LRDIV_MASK;
-	
-	if (rate == clk_i2s_sclk.rate / 32)
-		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
-					     clk->enable_reg);
-	else if (rate == clk_i2s_sclk.rate / 64)
-		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
-					     clk->enable_reg);
-	else if (rate == clk_i2s_sclk.rate / 128)
-		ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
-					     clk->enable_reg);
-	else
-		return -EINVAL;
+static const struct clk_ops clk_ddiv_ops = {
+	.enable = ep93xx_clk_enable,
+	.disable = ep93xx_clk_disable,
+	.is_enabled = ep93xx_clk_is_enabled,
+	.get_parent = ep93xx_mux_get_parent,
+	.set_parent = ep93xx_mux_set_parent_lock,
+	.determine_rate = ep93xx_mux_determine_rate,
+	.recalc_rate = ep93xx_ddiv_recalc_rate,
+	.set_rate = ep93xx_ddiv_set_rate,
+};
 
-	clk_i2s_lrclk.rate = rate;
-	return 0;
+static struct clk_hw *clk_hw_register_ddiv(const char *name,
+					  void __iomem *reg,
+					  u8 bit_idx)
+{
+	struct clk_init_data init;
+	struct clk_psc *psc;
+	struct clk *clk;
+
+	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+	if (!psc)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_ddiv_ops;
+	init.flags = 0;
+	init.parent_names = mux_parents;
+	init.num_parents = ARRAY_SIZE(mux_parents);
+
+	psc->reg = reg;
+	psc->bit_idx = bit_idx;
+	psc->lock = &clk_lock;
+	psc->hw.init = &init;
+
+	clk = clk_register(NULL, &psc->hw);
+	if (IS_ERR(clk))
+		kfree(psc);
+
+	return &psc->hw;
 }
 
-int clk_set_rate(struct clk *clk, unsigned long rate)
+static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
 {
-	if (clk->set_rate)
-		return clk->set_rate(clk, rate);
+	struct clk_psc *psc = to_clk_psc(hw);
+	u32 val = __raw_readl(psc->reg);
+	u8 index = (val & psc->mask) >> psc->shift;
 
-	return -EINVAL;
+	if (index > psc->num_div)
+		return 0;
+
+	return DIV_ROUND_UP_ULL(parent_rate, psc->div[index]);
 }
-EXPORT_SYMBOL(clk_set_rate);
 
-long clk_round_rate(struct clk *clk, unsigned long rate)
+static long ep93xx_div_round_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long *parent_rate)
 {
-	WARN_ON(clk);
-	return 0;
+	struct clk_psc *psc = to_clk_psc(hw);
+	unsigned long best = 0, now, maxdiv;
+	int i;
+
+	maxdiv = psc->div[psc->num_div - 1];
+
+	for (i = 0; i < psc->num_div; i++) {
+		if ((rate * psc->div[i]) == *parent_rate)
+			return DIV_ROUND_UP_ULL((u64)*parent_rate, psc->div[i]);
+
+		now = DIV_ROUND_UP_ULL((u64)*parent_rate, psc->div[i]);
+
+		if (is_best(rate, now, best))
+			best = now;
+	}
+
+	if (!best)
+		best = DIV_ROUND_UP_ULL(*parent_rate, maxdiv);
+
+	return best;
 }
-EXPORT_SYMBOL(clk_round_rate);
 
-int clk_set_parent(struct clk *clk, struct clk *parent)
+static int ep93xx_div_set_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long parent_rate)
 {
-	WARN_ON(clk);
+	struct clk_psc *psc = to_clk_psc(hw);
+	u32 val = __raw_readl(psc->reg) & ~psc->mask;
+	int i;
+
+	for (i = 0; i < psc->num_div; i++)
+		if (rate == parent_rate / psc->div[i]) {
+			val |= i << psc->shift;
+			break;
+		}
+
+	if (i == psc->num_div)
+		return -EINVAL;
+
+	ep93xx_syscon_swlocked_write(val, psc->reg);
+
 	return 0;
 }
-EXPORT_SYMBOL(clk_set_parent);
 
-struct clk *clk_get_parent(struct clk *clk)
+static const struct clk_ops ep93xx_div_ops = {
+	.enable = ep93xx_clk_enable,
+	.disable = ep93xx_clk_disable,
+	.is_enabled = ep93xx_clk_is_enabled,
+	.recalc_rate = ep93xx_div_recalc_rate,
+	.round_rate = ep93xx_div_round_rate,
+	.set_rate = ep93xx_div_set_rate,
+};
+
+static struct clk_hw *clk_hw_register_div(const char *name,
+					  const char *parent_name,
+					  void __iomem *reg,
+					  u8 enable_bit,
+					  u8 shift,
+					  u8 width,
+					  char *clk_divisors,
+					  u8 num_div)
 {
-	return clk->parent;
+	struct clk_init_data init;
+	struct clk_psc *psc;
+	struct clk *clk;
+
+	psc = kzalloc(sizeof(*psc), GFP_KERNEL);
+	if (!psc)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &ep93xx_div_ops;
+	init.flags = 0;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = 1;
+
+	psc->reg = reg;
+	psc->bit_idx = enable_bit;
+	psc->mask = GENMASK(shift + width - 1, shift);
+	psc->shift = shift;
+	psc->div = clk_divisors;
+	psc->num_div = num_div;
+	psc->lock = &clk_lock;
+	psc->hw.init = &init;
+
+	clk = clk_register(NULL, &psc->hw);
+	if (IS_ERR(clk))
+		kfree(psc);
+
+	return &psc->hw;
 }
-EXPORT_SYMBOL(clk_get_parent);
 
+struct ep93xx_gate {
+	unsigned int bit;
+	const char *dev_id;
+	const char *con_id;
+};
 
-static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
-static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
-static char pclk_divisors[] = { 1, 2, 4, 8 };
+static struct ep93xx_gate ep93xx_uarts[] = {
+	{EP93XX_SYSCON_DEVCFG_U1EN, "apb:uart1", NULL},
+	{EP93XX_SYSCON_DEVCFG_U2EN, "apb:uart2", NULL},
+	{EP93XX_SYSCON_DEVCFG_U3EN, "apb:uart3", NULL},
+};
 
-/*
- * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
- */
-static unsigned long calc_pll_rate(u32 config_word)
+static void __init ep93xx_uart_clock_init(void)
 {
-	unsigned long long rate;
-	int i;
+	unsigned int i;
+	struct clk_hw *hw;
+	u32 value;
+	unsigned int clk_uart_div;
 
-	rate = clk_xtali.rate;
-	rate *= ((config_word >> 11) & 0x1f) + 1;		/* X1FBD */
-	rate *= ((config_word >> 5) & 0x3f) + 1;		/* X2FBD */
-	do_div(rate, (config_word & 0x1f) + 1);			/* X2IPD */
-	for (i = 0; i < ((config_word >> 16) & 3); i++)		/* PS */
-		rate >>= 1;
+	value = __raw_readl(EP93XX_SYSCON_PWRCNT);
+	if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
+		clk_uart_div = 1;
+	else
+		clk_uart_div = 2;
 
-	return (unsigned long)rate;
+	hw = clk_hw_register_fixed_factor(NULL, "uart", "xtali", 0, 1, clk_uart_div);
+
+	/* parenting uart gate clocks to uart clock */
+	for (i = 0; i < ARRAY_SIZE(ep93xx_uarts); i++) {
+		hw = ep93xx_clk_register_gate(ep93xx_uarts[i].dev_id,
+					"uart",
+					EP93XX_SYSCON_DEVCFG,
+					ep93xx_uarts[i].bit);
+
+		clk_hw_register_clkdev(hw, NULL, ep93xx_uarts[i].dev_id);
+	}
 }
 
+static struct ep93xx_gate ep93xx_dmas[] = {
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P0, NULL, "m2p0"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P1, NULL, "m2p1"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P2, NULL, "m2p2"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P3, NULL, "m2p3"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P4, NULL, "m2p4"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P5, NULL, "m2p5"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P6, NULL, "m2p6"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P7, NULL, "m2p7"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P8, NULL, "m2p8"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2P9, NULL, "m2p9"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2M0, NULL, "m2m0"},
+	{EP93XX_SYSCON_PWRCNT_DMA_M2M1, NULL, "m2m1"},
+};
+
 static void __init ep93xx_dma_clock_init(void)
 {
-	clk_m2p0.rate = clk_h.rate;
-	clk_m2p1.rate = clk_h.rate;
-	clk_m2p2.rate = clk_h.rate;
-	clk_m2p3.rate = clk_h.rate;
-	clk_m2p4.rate = clk_h.rate;
-	clk_m2p5.rate = clk_h.rate;
-	clk_m2p6.rate = clk_h.rate;
-	clk_m2p7.rate = clk_h.rate;
-	clk_m2p8.rate = clk_h.rate;
-	clk_m2p9.rate = clk_h.rate;
-	clk_m2m0.rate = clk_h.rate;
-	clk_m2m1.rate = clk_h.rate;
+	unsigned int i;
+	struct clk_hw *hw;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(ep93xx_dmas); i++) {
+		hw = clk_hw_register_gate(NULL, ep93xx_dmas[i].con_id,
+					"hclk", 0,
+					EP93XX_SYSCON_PWRCNT,
+					ep93xx_dmas[i].bit,
+					0,
+					&clk_lock);
+
+		ret = clk_hw_register_clkdev(hw, ep93xx_dmas[i].con_id, NULL);
+		if (ret)
+			pr_err("%s: failed to register lookup %s\n",
+			       __func__, ep93xx_dmas[i].con_id);
+	}
 }
 
 static int __init ep93xx_clock_init(void)
 {
 	u32 value;
+	struct clk_hw *hw;
+	unsigned long clk_pll1_rate;
+	unsigned long clk_f_rate;
+	unsigned long clk_h_rate;
+	unsigned long clk_p_rate;
+	unsigned long clk_pll2_rate;
+	unsigned int clk_f_div;
+	unsigned int clk_h_div;
+	unsigned int clk_p_div;
+	unsigned int clk_usb_div;
+	unsigned long clk_spi_div;
+
+	hw = clk_hw_register_fixed_rate(NULL, "xtali", NULL, 0, EP93XX_EXT_CLK_RATE);
+	clk_hw_register_clkdev(hw, NULL, "xtali");
 
 	/* Determine the bootloader configured pll1 rate */
 	value = __raw_readl(EP93XX_SYSCON_CLKSET1);
 	if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
-		clk_pll1.rate = clk_xtali.rate;
+		clk_pll1_rate = EP93XX_EXT_CLK_RATE;
 	else
-		clk_pll1.rate = calc_pll_rate(value);
+		clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
+
+	hw = clk_hw_register_fixed_rate(NULL, "pll1", "xtali", 0, clk_pll1_rate);
+	clk_hw_register_clkdev(hw, NULL, "pll1");
 
 	/* Initialize the pll1 derived clocks */
-	clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
-	clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
-	clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
+	clk_f_div = fclk_divisors[(value >> 25) & 0x7];
+	clk_h_div = hclk_divisors[(value >> 20) & 0x7];
+	clk_p_div = pclk_divisors[(value >> 18) & 0x3];
+
+	hw = clk_hw_register_fixed_factor(NULL, "fclk", "pll1", 0, 1, clk_f_div);
+	clk_f_rate = clk_get_rate(hw->clk);
+	hw = clk_hw_register_fixed_factor(NULL, "hclk", "pll1", 0, 1, clk_h_div);
+	clk_h_rate = clk_get_rate(hw->clk);
+	hw = clk_hw_register_fixed_factor(NULL, "pclk", "hclk", 0, 1, clk_p_div);
+	clk_p_rate = clk_get_rate(hw->clk);
+
+	clk_hw_register_clkdev(hw, "apb_pclk", NULL);
+
 	ep93xx_dma_clock_init();
 
 	/* Determine the bootloader configured pll2 rate */
 	value = __raw_readl(EP93XX_SYSCON_CLKSET2);
 	if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
-		clk_pll2.rate = clk_xtali.rate;
+		clk_pll2_rate = EP93XX_EXT_CLK_RATE;
 	else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
-		clk_pll2.rate = calc_pll_rate(value);
+		clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
 	else
-		clk_pll2.rate = 0;
+		clk_pll2_rate = 0;
+
+	hw = clk_hw_register_fixed_rate(NULL, "pll2", "xtali", 0, clk_pll2_rate);
+	clk_hw_register_clkdev(hw, NULL, "pll2");
 
 	/* Initialize the pll2 derived clocks */
-	clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
+	/*
+	 * These four bits set the divide ratio between the PLL2
+	 * output and the USB clock.
+	 * 0000 - Divide by 1
+	 * 0001 - Divide by 2
+	 * 0010 - Divide by 3
+	 * 0011 - Divide by 4
+	 * 0100 - Divide by 5
+	 * 0101 - Divide by 6
+	 * 0110 - Divide by 7
+	 * 0111 - Divide by 8
+	 * 1000 - Divide by 9
+	 * 1001 - Divide by 10
+	 * 1010 - Divide by 11
+	 * 1011 - Divide by 12
+	 * 1100 - Divide by 13
+	 * 1101 - Divide by 14
+	 * 1110 - Divide by 15
+	 * 1111 - Divide by 1
+	 * On power-on-reset these bits are reset to 0000b.
+	 */
+	clk_usb_div = (((value >> 28) & 0xf) + 1);
+	hw = clk_hw_register_fixed_factor(NULL, "usb_clk", "pll2", 0, 1, clk_usb_div);
+	hw = clk_hw_register_gate(NULL, "ohci-platform",
+				"usb_clk", 0,
+				EP93XX_SYSCON_PWRCNT,
+				EP93XX_SYSCON_PWRCNT_USH_EN,
+				0,
+				&clk_lock);
+	clk_hw_register_clkdev(hw, NULL, "ohci-platform");
 
 	/*
 	 * EP93xx SSP clock rate was doubled in version E2. For more information
 	 * see:
 	 *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
 	 */
+	clk_spi_div = 1;
 	if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
-		clk_spi.rate /= 2;
+		clk_spi_div = 2;
+	hw = clk_hw_register_fixed_factor(NULL, "ep93xx-spi.0", "xtali", 0, 1, clk_spi_div);
+	clk_hw_register_clkdev(hw, NULL, "ep93xx-spi.0");
+
+	/* pwm clock */
+	hw = clk_hw_register_fixed_factor(NULL, "pwm_clk", "xtali", 0, 1, 1);
+	clk_hw_register_clkdev(hw, "pwm_clk", NULL);
 
 	pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
-		clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
+		clk_pll1_rate / 1000000, clk_pll2_rate / 1000000);
 	pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
-		clk_f.rate / 1000000, clk_h.rate / 1000000,
-		clk_p.rate / 1000000);
+		clk_f_rate / 1000000, clk_h_rate / 1000000,
+		clk_p_rate / 1000000);
+
+	ep93xx_uart_clock_init();
+
+	/* touchscreen/adc clock */
+	hw = clk_hw_register_div("ep93xx-adc",
+				"xtali",
+				EP93XX_SYSCON_KEYTCHCLKDIV,
+				EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
+				EP93XX_SYSCON_KEYTCHCLKDIV_ADIV,
+				1,
+				adc_divisors,
+				ARRAY_SIZE(adc_divisors));
+
+	clk_hw_register_clkdev(hw, NULL, "ep93xx-adc");
+
+	/* keypad clock */
+	hw = clk_hw_register_div("ep93xx-keypad",
+				"xtali",
+				EP93XX_SYSCON_KEYTCHCLKDIV,
+				EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
+				EP93XX_SYSCON_KEYTCHCLKDIV_KDIV,
+				1,
+				adc_divisors,
+				ARRAY_SIZE(adc_divisors));
+
+	clk_hw_register_clkdev(hw, NULL, "ep93xx-keypad");
+
+	/* On reset PDIV and VDIV is set to zero, while PDIV zero
+	 * means clock disable, VDIV shouldn't be zero.
+	 * So i set both dividers to minimum.
+	 */
+	/* ENA - Enable CLK divider. */
+	/* PDIV - 00 - Disable clock */
+	/* VDIV - at least 2 */
+	/* Check and enable video clk registers */
+	value = __raw_readl(EP93XX_SYSCON_VIDCLKDIV);
+	value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
+	ep93xx_syscon_swlocked_write(value, EP93XX_SYSCON_VIDCLKDIV);
+
+	/* check and enable i2s clk registers */
+	value = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
+	value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
+	ep93xx_syscon_swlocked_write(value, EP93XX_SYSCON_I2SCLKDIV);
+
+	/* video clk */
+	hw = clk_hw_register_ddiv("ep93xx-fb",
+				EP93XX_SYSCON_VIDCLKDIV,
+				EP93XX_SYSCON_CLKDIV_ENABLE);
+
+	clk_hw_register_clkdev(hw, NULL, "ep93xx-fb");
+
+	/* i2s clk */
+	hw = clk_hw_register_ddiv("mclk",
+				EP93XX_SYSCON_I2SCLKDIV,
+				EP93XX_SYSCON_CLKDIV_ENABLE);
+
+	clk_hw_register_clkdev(hw, "mclk", "ep93xx-i2s");
+
+	/* i2s sclk */
+#define EP93XX_I2SCLKDIV_SDIV_SHIFT	16
+#define EP93XX_I2SCLKDIV_SDIV_WIDTH	1
+	hw = clk_hw_register_div("sclk",
+				"mclk",
+				EP93XX_SYSCON_I2SCLKDIV,
+				EP93XX_SYSCON_I2SCLKDIV_SENA,
+				EP93XX_I2SCLKDIV_SDIV_SHIFT,
+				EP93XX_I2SCLKDIV_SDIV_WIDTH,
+				sclk_divisors,
+				ARRAY_SIZE(sclk_divisors));
+
+	clk_hw_register_clkdev(hw, "sclk", "ep93xx-i2s");
+
+	/* i2s lrclk */
+#define EP93XX_I2SCLKDIV_LRDIV32_SHIFT	17
+#define EP93XX_I2SCLKDIV_LRDIV32_WIDTH	3
+	hw = clk_hw_register_div("lrclk",
+				"sclk",
+				EP93XX_SYSCON_I2SCLKDIV,
+				EP93XX_SYSCON_I2SCLKDIV_SENA,
+				EP93XX_I2SCLKDIV_LRDIV32_SHIFT,
+				EP93XX_I2SCLKDIV_LRDIV32_WIDTH,
+				lrclk_divisors,
+				ARRAY_SIZE(lrclk_divisors));
+
+	clk_hw_register_clkdev(hw, "lrclk", "ep93xx-i2s");
 
-	clkdev_add_table(clocks, ARRAY_SIZE(clocks));
 	return 0;
 }
 postcore_initcall(ep93xx_clock_init);
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 6fb19a393fd2..bbb79f263331 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -214,7 +214,7 @@ static int ep93xx_ohci_power_on(struct platform_device *pdev)
 			return PTR_ERR(ep93xx_ohci_host_clock);
 	}
 
-	return clk_enable(ep93xx_ohci_host_clock);
+	return clk_prepare_enable(ep93xx_ohci_host_clock);
 }
 
 static void ep93xx_ohci_power_off(struct platform_device *pdev)
diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h
index f2dace1c9154..94ef7f275f94 100644
--- a/arch/arm/mach-ep93xx/soc.h
+++ b/arch/arm/mach-ep93xx/soc.h
@@ -111,19 +111,19 @@
 #define EP93XX_SYSCON_PWRCNT		EP93XX_SYSCON_REG(0x04)
 #define EP93XX_SYSCON_PWRCNT_FIR_EN	(1<<31)
 #define EP93XX_SYSCON_PWRCNT_UARTBAUD	(1<<29)
-#define EP93XX_SYSCON_PWRCNT_USH_EN	(1<<28)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2M1	(1<<27)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2M0	(1<<26)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P8	(1<<25)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P9	(1<<24)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P6	(1<<23)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P7	(1<<22)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P4	(1<<21)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P5	(1<<20)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P2	(1<<19)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P3	(1<<18)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P0	(1<<17)
-#define EP93XX_SYSCON_PWRCNT_DMA_M2P1	(1<<16)
+#define EP93XX_SYSCON_PWRCNT_USH_EN	28
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M1	27
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M0	26
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P8	25
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P9	24
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P6	23
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P7	22
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P4	21
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P5	20
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P2	19
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P3	18
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P0	17
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P1	16
 #define EP93XX_SYSCON_HALT		EP93XX_SYSCON_REG(0x08)
 #define EP93XX_SYSCON_STANDBY		EP93XX_SYSCON_REG(0x0c)
 #define EP93XX_SYSCON_CLKSET1		EP93XX_SYSCON_REG(0x20)
@@ -139,13 +139,13 @@
 #define EP93XX_SYSCON_DEVCFG_GONK	(1<<27)
 #define EP93XX_SYSCON_DEVCFG_TONG	(1<<26)
 #define EP93XX_SYSCON_DEVCFG_MONG	(1<<25)
-#define EP93XX_SYSCON_DEVCFG_U3EN	(1<<24)
+#define EP93XX_SYSCON_DEVCFG_U3EN	24
 #define EP93XX_SYSCON_DEVCFG_CPENA	(1<<23)
 #define EP93XX_SYSCON_DEVCFG_A2ONG	(1<<22)
 #define EP93XX_SYSCON_DEVCFG_A1ONG	(1<<21)
-#define EP93XX_SYSCON_DEVCFG_U2EN	(1<<20)
+#define EP93XX_SYSCON_DEVCFG_U2EN	20
 #define EP93XX_SYSCON_DEVCFG_EXVC	(1<<19)
-#define EP93XX_SYSCON_DEVCFG_U1EN	(1<<18)
+#define EP93XX_SYSCON_DEVCFG_U1EN	18
 #define EP93XX_SYSCON_DEVCFG_TIN	(1<<17)
 #define EP93XX_SYSCON_DEVCFG_HC3IN	(1<<15)
 #define EP93XX_SYSCON_DEVCFG_HC3EN	(1<<14)
@@ -163,12 +163,12 @@
 #define EP93XX_SYSCON_DEVCFG_KEYS	(1<<1)
 #define EP93XX_SYSCON_DEVCFG_SHENA	(1<<0)
 #define EP93XX_SYSCON_VIDCLKDIV		EP93XX_SYSCON_REG(0x84)
-#define EP93XX_SYSCON_CLKDIV_ENABLE	(1<<15)
+#define EP93XX_SYSCON_CLKDIV_ENABLE	15
 #define EP93XX_SYSCON_CLKDIV_ESEL	(1<<14)
 #define EP93XX_SYSCON_CLKDIV_PSEL	(1<<13)
 #define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT	8
 #define EP93XX_SYSCON_I2SCLKDIV		EP93XX_SYSCON_REG(0x8c)
-#define EP93XX_SYSCON_I2SCLKDIV_SENA	(1<<31)
+#define EP93XX_SYSCON_I2SCLKDIV_SENA	31
 #define EP93XX_SYSCON_I2SCLKDIV_ORIDE   (1<<29)
 #define EP93XX_SYSCON_I2SCLKDIV_SPOL	(1<<19)
 #define EP93XX_I2SCLKDIV_SDIV		(1 << 16)
@@ -177,9 +177,9 @@
 #define EP93XX_I2SCLKDIV_LRDIV128	(2 << 17)
 #define EP93XX_I2SCLKDIV_LRDIV_MASK	(3 << 17)
 #define EP93XX_SYSCON_KEYTCHCLKDIV	EP93XX_SYSCON_REG(0x90)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN	(1<<31)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV	(1<<16)
-#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN	(1<<15)
+#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN	31
+#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV	16
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN	15
 #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV	(1<<0)
 #define EP93XX_SYSCON_SYSCFG		EP93XX_SYSCON_REG(0x9c)
 #define EP93XX_SYSCON_SYSCFG_REV_MASK	(0xf0000000)
-- 
2.26.2


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

* Re: [PATCH v2 2/8] spi: spi-ep93xx: Prepare clock before using it
  2021-07-26 13:59   ` [PATCH v2 2/8] spi: spi-ep93xx: " Nikita Shubin
@ 2021-07-26 16:51     ` Mark Brown
  2021-08-02  7:36       ` Alexander Sverdlin
  2021-09-13 21:36       ` Alexander Sverdlin
  0 siblings, 2 replies; 46+ messages in thread
From: Mark Brown @ 2021-07-26 16:51 UTC (permalink / raw)
  To: Nikita Shubin
  Cc: Alexander Sverdlin, Geert Uytterhoeven, open list:SPI SUBSYSTEM,
	open list

[-- Attachment #1: Type: text/plain, Size: 962 bytes --]

On Mon, Jul 26, 2021 at 04:59:50PM +0300, Nikita Shubin wrote:
> From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> 
> Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
> to Common Clock Framework, otherwise the following is visible:

Acked-by: Mark Brown <broonie@kernel.org>

> 
> WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
> Enabling unprepared ep93xx-spi.0
> ...
> Hardware name: Cirrus Logic EDB9302 Evaluation Board
> ...
> clk_core_enable
> clk_core_enable_lock
> ep93xx_spi_prepare_hardware

Please think hard before including complete backtraces in upstream
reports, they are very large and contain almost no useful information
relative to their size so often obscure the relevant content in your
message. If part of the backtrace is usefully illustrative (it often is
for search engines if nothing else) then it's usually better to pull out
the relevant sections.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v2 6/8] ASoC: cirrus: i2s: Prepare clock before using it
  2021-07-26 13:59   ` [PATCH v2 6/8] ASoC: cirrus: i2s: " Nikita Shubin
@ 2021-07-26 16:51     ` Mark Brown
  2021-09-13 21:43       ` Alexander Sverdlin
  0 siblings, 1 reply; 46+ messages in thread
From: Mark Brown @ 2021-07-26 16:51 UTC (permalink / raw)
  To: Nikita Shubin
  Cc: Alexander Sverdlin, Geert Uytterhoeven, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Kuninori Morimoto,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	open list

[-- Attachment #1: Type: text/plain, Size: 316 bytes --]

On Mon, Jul 26, 2021 at 04:59:54PM +0300, Nikita Shubin wrote:
> From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> 
> Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
> to Common Clock Framework, otherwise the following is visible:

Acked-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 0/8] arm: ep93xx: CCF conversion
  2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                   ` (8 preceding siblings ...)
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
@ 2021-07-31 22:04 ` Linus Walleij
  9 siblings, 0 replies; 46+ messages in thread
From: Linus Walleij @ 2021-07-31 22:04 UTC (permalink / raw)
  To: Nikita Shubin
  Cc: Alexander Sverdlin, Geert Uytterhoeven,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	Andrew Morton, Andrzej Pietrasiewicz, Anshuman Khandual,
	Ard Biesheuvel, Arnd Bergmann,
	open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, Dmitry Torokhov,
	open list:FRAMEBUFFER LAYER, Geert Uytterhoeven,
	Jonathan Cameron, Krzysztof Kozlowski, Krzysztof Kozlowski,
	Kuninori Morimoto, Lars-Peter Clausen, moderated list:ARM PORT,
	open list:FRAMEBUFFER LAYER, open list:IIO SUBSYSTEM AND DRIVERS,
	open list:INPUT (KEYBOARD, MOUSE, JOYSTICK, TOUCHSCREEN)...,
	open list, open list:PWM SUBSYSTEM, open list:SPI SUBSYSTEM,
	Mark Brown, Mike Rapoport, Russell King, Uwe Kleine-König,
	YiFei Zhu

On Mon, Jul 26, 2021 at 1:51 PM Nikita Shubin <nikita.shubin@maquefel.me> wrote:

> This series series of patches converts ep93xx to Common Clock Framework.
>
> It consists of preparation patches to use clk_prepare_enable where it is
> needed, instead of clk_enable used in ep93xx drivers prior to CCF and
> a patch converting mach-ep93xx/clock.c to CCF.
>
> Link: https://lore.kernel.org/patchwork/cover/1445563/
> Link: https://lore.kernel.org/patchwork/patch/1435884/
>
> Alexander Sverdlin (7):
>   iio: ep93xx: Prepare clock before using it
>   spi: spi-ep93xx: Prepare clock before using it
>   Input: ep93xx_keypad: Prepare clock before using it
>   video: ep93xx: Prepare clock before using it
>   dmaengine: ep93xx: Prepare clock before using it
>   ASoC: cirrus: i2s: Prepare clock before using it
>   pwm: ep93xx: Prepare clock before using it
>
> Nikita Shubin (1):
>   ep93xx: clock: convert in-place to COMMON_CLK

This series is looking very good.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

I suppose the per-subsystem patches can be picked up by
each subsystem maintainer and then you can send the "big patch"
to the SoC tree.

Yours,
Linus Walleij

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

* Re: [PATCH v2 5/8] dmaengine: ep93xx: Prepare clock before using it
  2021-07-26 13:59   ` [PATCH v2 5/8] dmaengine: " Nikita Shubin
@ 2021-08-02  6:57     ` Vinod Koul
  0 siblings, 0 replies; 46+ messages in thread
From: Vinod Koul @ 2021-08-02  6:57 UTC (permalink / raw)
  To: Nikita Shubin
  Cc: Alexander Sverdlin, Geert Uytterhoeven,
	open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM, open list

On 26-07-21, 16:59, Nikita Shubin wrote:
> From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> 
> Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
> to Common Clock Framework, otherwise the following is visible:
> 
> WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
> Enabling unprepared m2p0
> ...
> Hardware name: Cirrus Logic EDB9302 Evaluation Board
> ...
> clk_core_enable
> clk_core_enable_lock
> ep93xx_dma_alloc_chan_resources
> dma_chan_get
> find_candidate
> __dma_request_channel
> snd_dmaengine_pcm_request_channel
> dmaengine_pcm_new
> snd_soc_pcm_component_new
> soc_new_pcm
> snd_soc_bind_card
> edb93xx_probe
> ...
> ep93xx-i2s ep93xx-i2s: Missing dma channel for stream: 0
> ep93xx-i2s ep93xx-i2s: ASoC: error at snd_soc_pcm_component_new on ep93xx-i2s: -22
> edb93xx-audio edb93xx-audio: ASoC: can't create pcm CS4271 HiFi :-22
> edb93xx-audio edb93xx-audio: snd_soc_register_card() failed: -22
> edb93xx-audio: probe of edb93xx-audio failed with error -22

Applied, thanks

-- 
~Vinod

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

* Re: [PATCH v2 2/8] spi: spi-ep93xx: Prepare clock before using it
  2021-07-26 16:51     ` Mark Brown
@ 2021-08-02  7:36       ` Alexander Sverdlin
  2021-09-13 21:36       ` Alexander Sverdlin
  1 sibling, 0 replies; 46+ messages in thread
From: Alexander Sverdlin @ 2021-08-02  7:36 UTC (permalink / raw)
  To: Mark Brown, Nikita Shubin
  Cc: Geert Uytterhoeven, open list:SPI SUBSYSTEM, open list

Hello Mark,

On 26/07/2021 18:51, Mark Brown wrote:
> On Mon, Jul 26, 2021 at 04:59:50PM +0300, Nikita Shubin wrote:
>> From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
>>
>> Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
>> to Common Clock Framework, otherwise the following is visible:
> Acked-by: Mark Brown <broonie@kernel.org>

It looks like we didn't manage to bring the whole series as one lot to any
maintainer and two patches were applied to two different trees.
Could you please take this one to your tree as well?

>> WARNING: CPU: 0 PID: 1 at drivers/clk/clk.c:1011 clk_core_enable+0x9c/0xbc
>> Enabling unprepared ep93xx-spi.0
>> ...
>> Hardware name: Cirrus Logic EDB9302 Evaluation Board
>> ...
>> clk_core_enable
>> clk_core_enable_lock
>> ep93xx_spi_prepare_hardware
> Please think hard before including complete backtraces in upstream
> reports, they are very large and contain almost no useful information
> relative to their size so often obscure the relevant content in your
> message. If part of the backtrace is usefully illustrative (it often is
> for search engines if nothing else) then it's usually better to pull out
> the relevant sections.

Yes, I noted your comment first time and this was already stripped version
of the backtrace, but please feel free to strip it even harder if you
take the patch.

Thank you for the review,
--
Alex.

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

* Re: (subset) [PATCH v2 0/8] arm: ep93xx: CCF conversion
  2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
                     ` (7 preceding siblings ...)
  2021-07-26 13:59   ` [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK Nikita Shubin
@ 2021-08-03 22:35   ` Mark Brown
  8 siblings, 0 replies; 46+ messages in thread
From: Mark Brown @ 2021-08-03 22:35 UTC (permalink / raw)
  To: Alexander Sverdlin, Geert Uytterhoeven, Nikita Shubin
  Cc: Mark Brown, open list:PWM SUBSYSTEM, open list,
	Andrzej Pietrasiewicz, Anshuman Khandual, Russell King,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	open list:INPUT KEYBOARD, MOUSE, JOYSTICK , TOUCHSCREEN...,
	YiFei Zhu, Geert Uytterhoeven, Lars-Peter Clausen, Linus Walleij,
	Krzysztof Kozlowski, moderated list:ARM PORT, Ard Biesheuvel,
	Arnd Bergmann, Dmitry Torokhov, Kuninori Morimoto,
	open list:FRAMEBUFFER LAYER, Mike Rapoport,
	Uwe Kleine-König, open list:SPI SUBSYSTEM,
	Krzysztof Kozlowski, Andrew Morton, Jonathan Cameron,
	open list:DMA GENERIC OFFLOAD ENGINE SUBSYSTEM,
	open list:FRAMEBUFFER LAYER, open list:IIO SUBSYSTEM AND DRIVERS

On Mon, 26 Jul 2021 16:59:48 +0300, Nikita Shubin wrote:
> This series series of patches converts ep93xx to Common Clock Framework.
> 
> It consists of preparation patches to use clk_prepare_enable where it is
> needed, instead of clk_enable used in ep93xx drivers prior to CCF and
> a patch converting mach-ep93xx/clock.c to CCF.
> 
> Link: https://lore.kernel.org/patchwork/cover/1445563/
> Link: https://lore.kernel.org/patchwork/patch/1435884/
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[2/8] spi: spi-ep93xx: Prepare clock before using it
      commit: 7c72dc56a631b87043e3c5838f5094db30d8c58d

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

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

* Re: [PATCH v2 2/8] spi: spi-ep93xx: Prepare clock before using it
  2021-07-26 16:51     ` Mark Brown
  2021-08-02  7:36       ` Alexander Sverdlin
@ 2021-09-13 21:36       ` Alexander Sverdlin
  2021-09-13 21:37         ` Alexander Sverdlin
  2021-09-14 10:32         ` Mark Brown
  1 sibling, 2 replies; 46+ messages in thread
From: Alexander Sverdlin @ 2021-09-13 21:36 UTC (permalink / raw)
  To: Mark Brown, Nikita Shubin
  Cc: Geert Uytterhoeven, open list:SPI SUBSYSTEM, open list

Hello Mark,

On Mon, 2021-07-26 at 17:51 +0100, Mark Brown wrote:
> > From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> > 
> > Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
> > to Common Clock Framework, otherwise the following is visible:
> 
> Acked-by: Mark Brown <broonie@kernel.org>

would you take the patch to a tree of yours, please?

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 2/8] spi: spi-ep93xx: Prepare clock before using it
  2021-09-13 21:36       ` Alexander Sverdlin
@ 2021-09-13 21:37         ` Alexander Sverdlin
  2021-09-14 10:32         ` Mark Brown
  1 sibling, 0 replies; 46+ messages in thread
From: Alexander Sverdlin @ 2021-09-13 21:37 UTC (permalink / raw)
  To: Mark Brown, Nikita Shubin
  Cc: Geert Uytterhoeven, open list:SPI SUBSYSTEM, open list

On Mon, 2021-09-13 at 23:36 +0200, Alexander Sverdlin wrote:
> > > From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> > > 
> > > Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
> > > to Common Clock Framework, otherwise the following is visible:
> > 
> > Acked-by: Mark Brown <broonie@kernel.org>
> 
> would you take the patch to a tree of yours, please?

Please ignore this request, I've mixed up the patches, sorry!

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 6/8] ASoC: cirrus: i2s: Prepare clock before using it
  2021-07-26 16:51     ` Mark Brown
@ 2021-09-13 21:43       ` Alexander Sverdlin
  2021-10-12  7:25         ` Alexander Sverdlin
  0 siblings, 1 reply; 46+ messages in thread
From: Alexander Sverdlin @ 2021-09-13 21:43 UTC (permalink / raw)
  To: Mark Brown, Nikita Shubin
  Cc: Geert Uytterhoeven, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Kuninori Morimoto,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	open list

Hello Mark,

On Mon, 2021-07-26 at 17:51 +0100, Mark Brown wrote:
> On Mon, Jul 26, 2021 at 04:59:54PM +0300, Nikita Shubin wrote:
> > From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> > 
> > Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
> > to Common Clock Framework, otherwise the following is visible:
> 
> Acked-by: Mark Brown <broonie@kernel.org>

would you take the patch to a tree of yours, please?

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 2/8] spi: spi-ep93xx: Prepare clock before using it
  2021-09-13 21:36       ` Alexander Sverdlin
  2021-09-13 21:37         ` Alexander Sverdlin
@ 2021-09-14 10:32         ` Mark Brown
  1 sibling, 0 replies; 46+ messages in thread
From: Mark Brown @ 2021-09-14 10:32 UTC (permalink / raw)
  To: Alexander Sverdlin
  Cc: Nikita Shubin, Geert Uytterhoeven, open list:SPI SUBSYSTEM, open list

[-- Attachment #1: Type: text/plain, Size: 418 bytes --]

On Mon, Sep 13, 2021 at 11:36:30PM +0200, Alexander Sverdlin wrote:
> On Mon, 2021-07-26 at 17:51 +0100, Mark Brown wrote:

> > > Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
> > > to Common Clock Framework, otherwise the following is visible:

> > Acked-by: Mark Brown <broonie@kernel.org>

> would you take the patch to a tree of yours, please?

What's the story with the dependencies?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v2 6/8] ASoC: cirrus: i2s: Prepare clock before using it
  2021-09-13 21:43       ` Alexander Sverdlin
@ 2021-10-12  7:25         ` Alexander Sverdlin
  2021-10-12 10:40           ` Mark Brown
  0 siblings, 1 reply; 46+ messages in thread
From: Alexander Sverdlin @ 2021-10-12  7:25 UTC (permalink / raw)
  To: Mark Brown, Nikita Shubin
  Cc: Geert Uytterhoeven, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Kuninori Morimoto,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	open list

Hello Mark,

On Mon, 2021-09-13 at 23:43 +0200, Alexander Sverdlin wrote:
> On Mon, 2021-07-26 at 17:51 +0100, Mark Brown wrote:
> > On Mon, Jul 26, 2021 at 04:59:54PM +0300, Nikita Shubin wrote:
> > > From: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> > > 
> > > Use clk_prepare_enable()/clk_disable_unprepare() in preparation for switch
> > > to Common Clock Framework, otherwise the following is visible:
> > 
> > Acked-by: Mark Brown <broonie@kernel.org>
> 
> would you take the patch to a tree of yours, please?

I still cannot find this patch in any of your trees, but I've found this one:

commit 726e6f31b1026f62206f1d32b5cbb7e9582c4d03
Merge: b09bff2676be 7c72dc56a631
Author: Mark Brown <broonie@kernel.org>
Date:   Tue Aug 3 23:27:27 2021 +0100

    Merge series "arm: ep93xx: CCF conversion" from Nikita Shubin <nikita.shubin@maquefel.me>:
    
    This series series of patches converts ep93xx to Common Clock Framework.
    
    It consists of preparation patches to use clk_prepare_enable where it is
    needed, instead of clk_enable used in ep93xx drivers prior to CCF and
    a patch converting mach-ep93xx/clock.c to CCF.
    
    Link: https://lore.kernel.org/patchwork/cover/1445563/
    Link: https://lore.kernel.org/patchwork/patch/1435884/
    
    v1->v2:
    - added SoB
    
    Alexander Sverdlin (7):
      iio: ep93xx: Prepare clock before using it
      spi: spi-ep93xx: Prepare clock before using it
      Input: ep93xx_keypad: Prepare clock before using it
      video: ep93xx: Prepare clock before using it
      dmaengine: ep93xx: Prepare clock before using it
      ASoC: cirrus: i2s: Prepare clock before using it
      pwm: ep93xx: Prepare clock before using it
    
    Nikita Shubin (1):
      ep93xx: clock: convert in-place to COMMON_CLK


... which claims to merge both "ASoC: cirrus: i2s: Prepare clock before using it"
and "ep93xx: clock: convert in-place to COMMON_CLK", but they are actually not
merged.

Could you please consider ASoC patch, while I will resubmit the final clock conversion?

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-07-26 13:59   ` [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK Nikita Shubin
@ 2021-10-12  8:03     ` Alexander Sverdlin
  2021-10-12  8:29       ` Arnd Bergmann
  0 siblings, 1 reply; 46+ messages in thread
From: Alexander Sverdlin @ 2021-10-12  8:03 UTC (permalink / raw)
  To: Russell King, Arnd Bergmann
  Cc: Hartley Sweeten, Linus Walleij, Ard Biesheuvel, Andrew Morton,
	Krzysztof Kozlowski, Anshuman Khandual, Geert Uytterhoeven,
	YiFei Zhu, Mike Rapoport, Uwe Kleine-König,
	moderated list:ARM PORT, open list, Nikita Shubin,
	Geert Uytterhoeven

Hello Russel, Arnd,

On Mon, 2021-07-26 at 16:59 +0300, Nikita Shubin wrote:
> Converted in-place without moving file to drivers/clk.
> 
> tested on ts7250 (EP9302).
> 
> Only setting rate and change parent tested for, as they
> are missing on ts7250:
> - video
> - I2S
> - ADC/KEYPAD
> - PWM
> 
> Only video and I2S clock are interesting, as they are
> GATE + double DIV + MUX, all other are pretty much
> common but require ep93xx_syscon_swlocked_write to set
> registers.
> 
> Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>

with an
Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
and
Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>

shall I add this patch to the Russels patch system, or would
Arnd take it to the SoC tree?

There is already a merge commit 726e6f31b102 upstream which
claims to merge it, but it's actually not in.

> ---
>  arch/arm/Kconfig             |   2 +-
>  arch/arm/mach-ep93xx/clock.c | 975 ++++++++++++++++++++---------------
>  arch/arm/mach-ep93xx/core.c  |   2 +-
>  arch/arm/mach-ep93xx/soc.h   |  42 +-
>  4 files changed, 581 insertions(+), 440 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 24804f11302d..8f4a74a37406 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -357,7 +357,7 @@ config ARCH_EP93XX
>         select CLKSRC_MMIO
>         select CPU_ARM920T
>         select GPIOLIB
> -       select HAVE_LEGACY_CLK
> +       select COMMON_CLK
>         help
>           This enables support for the Cirrus EP93xx series of CPUs.
>  
> diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
> index 2810eb5b2aca..cc75087134d3 100644
> --- a/arch/arm/mach-ep93xx/clock.c
> +++ b/arch/arm/mach-ep93xx/clock.c
> @@ -16,6 +16,7 @@
>  #include <linux/io.h>
>  #include <linux/spinlock.h>
>  #include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
>  #include <linux/soc/cirrus/ep93xx.h>
>  
>  #include "hardware.h"
> @@ -24,348 +25,194 @@
>  
>  #include "soc.h"
>  
> -struct clk {
> -       struct clk      *parent;
> -       unsigned long   rate;
> -       int             users;
> -       int             sw_locked;
> -       void __iomem    *enable_reg;
> -       u32             enable_mask;
> -
> -       unsigned long   (*get_rate)(struct clk *clk);
> -       int             (*set_rate)(struct clk *clk, unsigned long rate);
> -};
> -
> -
> -static unsigned long get_uart_rate(struct clk *clk);
> -
> -static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
> -static int set_div_rate(struct clk *clk, unsigned long rate);
> -static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate);
> -static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate);
> +static DEFINE_SPINLOCK(clk_lock);
>  
> -static struct clk clk_xtali = {
> -       .rate           = EP93XX_EXT_CLK_RATE,
> -};
> -static struct clk clk_uart1 = {
> -       .parent         = &clk_xtali,
> -       .sw_locked      = 1,
> -       .enable_reg     = EP93XX_SYSCON_DEVCFG,
> -       .enable_mask    = EP93XX_SYSCON_DEVCFG_U1EN,
> -       .get_rate       = get_uart_rate,
> -};
> -static struct clk clk_uart2 = {
> -       .parent         = &clk_xtali,
> -       .sw_locked      = 1,
> -       .enable_reg     = EP93XX_SYSCON_DEVCFG,
> -       .enable_mask    = EP93XX_SYSCON_DEVCFG_U2EN,
> -       .get_rate       = get_uart_rate,
> -};
> -static struct clk clk_uart3 = {
> -       .parent         = &clk_xtali,
> -       .sw_locked      = 1,
> -       .enable_reg     = EP93XX_SYSCON_DEVCFG,
> -       .enable_mask    = EP93XX_SYSCON_DEVCFG_U3EN,
> -       .get_rate       = get_uart_rate,
> -};
> -static struct clk clk_pll1 = {
> -       .parent         = &clk_xtali,
> -};
> -static struct clk clk_f = {
> -       .parent         = &clk_pll1,
> -};
> -static struct clk clk_h = {
> -       .parent         = &clk_pll1,
> -};
> -static struct clk clk_p = {
> -       .parent         = &clk_pll1,
> -};
> -static struct clk clk_pll2 = {
> -       .parent         = &clk_xtali,
> -};
> -static struct clk clk_usb_host = {
> -       .parent         = &clk_pll2,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_USH_EN,
> -};
> -static struct clk clk_keypad = {
> -       .parent         = &clk_xtali,
> -       .sw_locked      = 1,
> -       .enable_reg     = EP93XX_SYSCON_KEYTCHCLKDIV,
> -       .enable_mask    = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
> -       .set_rate       = set_keytchclk_rate,
> -};
> -static struct clk clk_adc = {
> -       .parent         = &clk_xtali,
> -       .sw_locked      = 1,
> -       .enable_reg     = EP93XX_SYSCON_KEYTCHCLKDIV,
> -       .enable_mask    = EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
> -       .set_rate       = set_keytchclk_rate,
> -};
> -static struct clk clk_spi = {
> -       .parent         = &clk_xtali,
> -       .rate           = EP93XX_EXT_CLK_RATE,
> -};
> -static struct clk clk_pwm = {
> -       .parent         = &clk_xtali,
> -       .rate           = EP93XX_EXT_CLK_RATE,
> -};
> +static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
> +static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
> +static char pclk_divisors[] = { 1, 2, 4, 8 };
>  
> -static struct clk clk_video = {
> -       .sw_locked      = 1,
> -       .enable_reg     = EP93XX_SYSCON_VIDCLKDIV,
> -       .enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
> -       .set_rate       = set_div_rate,
> -};
> +static char adc_divisors[] = { 16, 4 };
> +static char sclk_divisors[] = { 2, 4 };
> +static char lrclk_divisors[] = { 32, 64, 128 };
>  
> -static struct clk clk_i2s_mclk = {
> -       .sw_locked      = 1,
> -       .enable_reg     = EP93XX_SYSCON_I2SCLKDIV,
> -       .enable_mask    = EP93XX_SYSCON_CLKDIV_ENABLE,
> -       .set_rate       = set_div_rate,
> +static const char * const mux_parents[] = {
> +       "xtali",
> +       "pll1",
> +       "pll2"
>  };
>  
> -static struct clk clk_i2s_sclk = {
> -       .sw_locked      = 1,
> -       .parent         = &clk_i2s_mclk,
> -       .enable_reg     = EP93XX_SYSCON_I2SCLKDIV,
> -       .enable_mask    = EP93XX_SYSCON_I2SCLKDIV_SENA,
> -       .set_rate       = set_i2s_sclk_rate,
> -};
> +/*
> + * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
> + */
> +static unsigned long calc_pll_rate(unsigned long long rate, u32 config_word)
> +{
> +       int i;
>  
> -static struct clk clk_i2s_lrclk = {
> -       .sw_locked      = 1,
> -       .parent         = &clk_i2s_sclk,
> -       .enable_reg     = EP93XX_SYSCON_I2SCLKDIV,
> -       .enable_mask    = EP93XX_SYSCON_I2SCLKDIV_SENA,
> -       .set_rate       = set_i2s_lrclk_rate,
> -};
> +       rate *= ((config_word >> 11) & 0x1f) + 1;               /* X1FBD */
> +       rate *= ((config_word >> 5) & 0x3f) + 1;                /* X2FBD */
> +       do_div(rate, (config_word & 0x1f) + 1);                 /* X2IPD */
> +       for (i = 0; i < ((config_word >> 16) & 3); i++)         /* PS */
> +               rate >>= 1;
>  
> -/* DMA Clocks */
> -static struct clk clk_m2p0 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
> -};
> -static struct clk clk_m2p1 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
> -};
> -static struct clk clk_m2p2 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
> -};
> -static struct clk clk_m2p3 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
> -};
> -static struct clk clk_m2p4 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
> -};
> -static struct clk clk_m2p5 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
> -};
> -static struct clk clk_m2p6 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
> -};
> -static struct clk clk_m2p7 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
> -};
> -static struct clk clk_m2p8 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
> -};
> -static struct clk clk_m2p9 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
> -};
> -static struct clk clk_m2m0 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
> -};
> -static struct clk clk_m2m1 = {
> -       .parent         = &clk_h,
> -       .enable_reg     = EP93XX_SYSCON_PWRCNT,
> -       .enable_mask    = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
> -};
> +       return (unsigned long)rate;
> +}
>  
> -#define INIT_CK(dev,con,ck)                                    \
> -       { .dev_id = dev, .con_id = con, .clk = ck }
> -
> -static struct clk_lookup clocks[] = {
> -       INIT_CK(NULL,                   "xtali",        &clk_xtali),
> -       INIT_CK("apb:uart1",            NULL,           &clk_uart1),
> -       INIT_CK("apb:uart2",            NULL,           &clk_uart2),
> -       INIT_CK("apb:uart3",            NULL,           &clk_uart3),
> -       INIT_CK(NULL,                   "pll1",         &clk_pll1),
> -       INIT_CK(NULL,                   "fclk",         &clk_f),
> -       INIT_CK(NULL,                   "hclk",         &clk_h),
> -       INIT_CK(NULL,                   "apb_pclk",     &clk_p),
> -       INIT_CK(NULL,                   "pll2",         &clk_pll2),
> -       INIT_CK("ohci-platform",        NULL,           &clk_usb_host),
> -       INIT_CK("ep93xx-keypad",        NULL,           &clk_keypad),
> -       INIT_CK("ep93xx-adc",           NULL,           &clk_adc),
> -       INIT_CK("ep93xx-fb",            NULL,           &clk_video),
> -       INIT_CK("ep93xx-spi.0",         NULL,           &clk_spi),
> -       INIT_CK("ep93xx-i2s",           "mclk",         &clk_i2s_mclk),
> -       INIT_CK("ep93xx-i2s",           "sclk",         &clk_i2s_sclk),
> -       INIT_CK("ep93xx-i2s",           "lrclk",        &clk_i2s_lrclk),
> -       INIT_CK(NULL,                   "pwm_clk",      &clk_pwm),
> -       INIT_CK(NULL,                   "m2p0",         &clk_m2p0),
> -       INIT_CK(NULL,                   "m2p1",         &clk_m2p1),
> -       INIT_CK(NULL,                   "m2p2",         &clk_m2p2),
> -       INIT_CK(NULL,                   "m2p3",         &clk_m2p3),
> -       INIT_CK(NULL,                   "m2p4",         &clk_m2p4),
> -       INIT_CK(NULL,                   "m2p5",         &clk_m2p5),
> -       INIT_CK(NULL,                   "m2p6",         &clk_m2p6),
> -       INIT_CK(NULL,                   "m2p7",         &clk_m2p7),
> -       INIT_CK(NULL,                   "m2p8",         &clk_m2p8),
> -       INIT_CK(NULL,                   "m2p9",         &clk_m2p9),
> -       INIT_CK(NULL,                   "m2m0",         &clk_m2m0),
> -       INIT_CK(NULL,                   "m2m1",         &clk_m2m1),
> +struct clk_psc {
> +       struct clk_hw hw;
> +       void __iomem *reg;
> +       u8 bit_idx;
> +       u32 mask;
> +       u8 shift;
> +       u8 width;
> +       char *div;
> +       u8 num_div;
> +       spinlock_t *lock;
>  };
>  
> -static DEFINE_SPINLOCK(clk_lock);
> +#define to_clk_psc(_hw) container_of(_hw, struct clk_psc, hw)
>  
> -static void __clk_enable(struct clk *clk)
> +static int ep93xx_clk_is_enabled(struct clk_hw *hw)
>  {
> -       if (!clk->users++) {
> -               if (clk->parent)
> -                       __clk_enable(clk->parent);
> -
> -               if (clk->enable_reg) {
> -                       u32 v;
> -
> -                       v = __raw_readl(clk->enable_reg);
> -                       v |= clk->enable_mask;
> -                       if (clk->sw_locked)
> -                               ep93xx_syscon_swlocked_write(v, clk->enable_reg);
> -                       else
> -                               __raw_writel(v, clk->enable_reg);
> -               }
> -       }
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       u32 val = readl(psc->reg);
> +
> +       return (val & BIT(psc->bit_idx)) ? 1 : 0;
>  }
>  
> -int clk_enable(struct clk *clk)
> +static int ep93xx_clk_enable(struct clk_hw *hw)
>  {
> -       unsigned long flags;
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       unsigned long flags = 0;
> +       u32 val;
>  
> -       if (!clk)
> -               return -EINVAL;
> +       if (psc->lock)
> +               spin_lock_irqsave(psc->lock, flags);
> +
> +       val = __raw_readl(psc->reg);
> +       val |= BIT(psc->bit_idx);
> +
> +       ep93xx_syscon_swlocked_write(val, psc->reg);
>  
> -       spin_lock_irqsave(&clk_lock, flags);
> -       __clk_enable(clk);
> -       spin_unlock_irqrestore(&clk_lock, flags);
> +       if (psc->lock)
> +               spin_unlock_irqrestore(psc->lock, flags);
>  
>         return 0;
>  }
> -EXPORT_SYMBOL(clk_enable);
>  
> -static void __clk_disable(struct clk *clk)
> +static void ep93xx_clk_disable(struct clk_hw *hw)
>  {
> -       if (!--clk->users) {
> -               if (clk->enable_reg) {
> -                       u32 v;
> -
> -                       v = __raw_readl(clk->enable_reg);
> -                       v &= ~clk->enable_mask;
> -                       if (clk->sw_locked)
> -                               ep93xx_syscon_swlocked_write(v, clk->enable_reg);
> -                       else
> -                               __raw_writel(v, clk->enable_reg);
> -               }
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       unsigned long flags = 0;
> +       u32 val;
>  
> -               if (clk->parent)
> -                       __clk_disable(clk->parent);
> -       }
> -}
> +       if (psc->lock)
> +               spin_lock_irqsave(psc->lock, flags);
>  
> -void clk_disable(struct clk *clk)
> -{
> -       unsigned long flags;
> +       val = __raw_readl(psc->reg);
> +       val &= ~BIT(psc->bit_idx);
>  
> -       if (!clk)
> -               return;
> +       ep93xx_syscon_swlocked_write(val, psc->reg);
>  
> -       spin_lock_irqsave(&clk_lock, flags);
> -       __clk_disable(clk);
> -       spin_unlock_irqrestore(&clk_lock, flags);
> +       if (psc->lock)
> +               spin_unlock_irqrestore(psc->lock, flags);
>  }
> -EXPORT_SYMBOL(clk_disable);
>  
> -static unsigned long get_uart_rate(struct clk *clk)
> -{
> -       unsigned long rate = clk_get_rate(clk->parent);
> -       u32 value;
> +static const struct clk_ops clk_ep93xx_gate_ops = {
> +       .enable = ep93xx_clk_enable,
> +       .disable = ep93xx_clk_disable,
> +       .is_enabled = ep93xx_clk_is_enabled,
> +};
>  
> -       value = __raw_readl(EP93XX_SYSCON_PWRCNT);
> -       if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
> -               return rate;
> -       else
> -               return rate / 2;
> +static struct clk_hw *ep93xx_clk_register_gate(const char *name,
> +                                   const char *parent_name,
> +                                   void __iomem *reg,
> +                                   u8 bit_idx)
> +{
> +       struct clk_init_data init;
> +       struct clk_psc *psc;
> +       struct clk *clk;
> +
> +       psc = kzalloc(sizeof(*psc), GFP_KERNEL);
> +       if (!psc)
> +               return ERR_PTR(-ENOMEM);
> +
> +       init.name = name;
> +       init.ops = &clk_ep93xx_gate_ops;
> +       init.flags = CLK_SET_RATE_PARENT;
> +       init.parent_names = (parent_name ? &parent_name : NULL);
> +       init.num_parents = (parent_name ? 1 : 0);
> +
> +       psc->reg = reg;
> +       psc->bit_idx = bit_idx;
> +       psc->hw.init = &init;
> +       psc->lock = &clk_lock;
> +
> +       clk = clk_register(NULL, &psc->hw);
> +       if (IS_ERR(clk))
> +               kfree(psc);
> +
> +       return &psc->hw;
>  }
>  
> -unsigned long clk_get_rate(struct clk *clk)
> +static u8 ep93xx_mux_get_parent(struct clk_hw *hw)
>  {
> -       if (clk->get_rate)
> -               return clk->get_rate(clk);
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       u32 val = __raw_readl(psc->reg);
>  
> -       return clk->rate;
> +       if (!(val & EP93XX_SYSCON_CLKDIV_ESEL))
> +               return 0;
> +
> +       if (!(val & EP93XX_SYSCON_CLKDIV_PSEL))
> +               return 1;
> +
> +       return 2;
>  }
> -EXPORT_SYMBOL(clk_get_rate);
>  
> -static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
> +static int ep93xx_mux_set_parent_lock(struct clk_hw *hw, u8 index)
>  {
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       unsigned long flags = 0;
>         u32 val;
> -       u32 div_bit;
>  
> -       val = __raw_readl(clk->enable_reg);
> +       if (index >= ARRAY_SIZE(mux_parents))
> +               return -EINVAL;
>  
> -       /*
> -        * The Key Matrix and ADC clocks are configured using the same
> -        * System Controller register.  The clock used will be either
> -        * 1/4 or 1/16 the external clock rate depending on the
> -        * EP93XX_SYSCON_KEYTCHCLKDIV_KDIV/EP93XX_SYSCON_KEYTCHCLKDIV_ADIV
> -        * bit being set or cleared.
> -        */
> -       div_bit = clk->enable_mask >> 15;
> +       if (psc->lock)
> +               spin_lock_irqsave(psc->lock, flags);
>  
> -       if (rate == EP93XX_KEYTCHCLK_DIV4)
> -               val |= div_bit;
> -       else if (rate == EP93XX_KEYTCHCLK_DIV16)
> -               val &= ~div_bit;
> -       else
> -               return -EINVAL;
> +       val = __raw_readl(psc->reg);
> +       val &= ~(EP93XX_SYSCON_CLKDIV_ESEL | EP93XX_SYSCON_CLKDIV_PSEL);
> +
> +
> +       if (index != 0) {
> +               val |= EP93XX_SYSCON_CLKDIV_ESEL;
> +               val |= (index - 1) ? EP93XX_SYSCON_CLKDIV_PSEL : 0;
> +       }
> +
> +       ep93xx_syscon_swlocked_write(val, psc->reg);
> +
> +       if (psc->lock)
> +               spin_unlock_irqrestore(psc->lock, flags);
>  
> -       ep93xx_syscon_swlocked_write(val, clk->enable_reg);
> -       clk->rate = rate;
>         return 0;
>  }
>  
> -static int calc_clk_div(struct clk *clk, unsigned long rate,
> -                       int *psel, int *esel, int *pdiv, int *div)
> +static bool is_best(unsigned long rate, unsigned long now,
> +                    unsigned long best)
>  {
> -       struct clk *mclk;
> -       unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
> -       int i, found = 0, __div = 0, __pdiv = 0;
> +       return abs(rate - now) < abs(rate - best);
> +}
>  
> -       /* Don't exceed the maximum rate */
> -       max_rate = max3(clk_pll1.rate / 4, clk_pll2.rate / 4, clk_xtali.rate / 4);
> -       rate = min(rate, max_rate);
> +static int ep93xx_mux_determine_rate(struct clk_hw *hw,
> +                               struct clk_rate_request *req)
> +{
> +       unsigned long rate = req->rate;
> +       struct clk *best_parent = 0;
> +       unsigned long __parent_rate;
> +       unsigned long best_rate = 0, actual_rate, mclk_rate;
> +       unsigned long best_parent_rate;
> +       int __div = 0, __pdiv = 0;
> +       int i;
>  
>         /*
>          * Try the two pll's and the external clock
> @@ -376,14 +223,11 @@ static int calc_clk_div(struct clk *clk, unsigned long rate,
>          * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
>          *
>          */
> -       for (i = 0; i < 3; i++) {
> -               if (i == 0)
> -                       mclk = &clk_xtali;
> -               else if (i == 1)
> -                       mclk = &clk_pll1;
> -               else
> -                       mclk = &clk_pll2;
> -               mclk_rate = mclk->rate * 2;
> +       for (i = 0; i < ARRAY_SIZE(mux_parents); i++) {
> +               struct clk *parent = clk_get_sys(mux_parents[i], NULL);
> +
> +               __parent_rate = clk_get_rate(parent);
> +               mclk_rate = __parent_rate * 2;
>  
>                 /* Try each predivider value */
>                 for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
> @@ -392,197 +236,494 @@ static int calc_clk_div(struct clk *clk, unsigned long rate,
>                                 continue;
>  
>                         actual_rate = mclk_rate / (__pdiv * __div);
> -
> -                       if (!found || abs(actual_rate - rate) < rate_err) {
> -                               *pdiv = __pdiv - 3;
> -                               *div = __div;
> -                               *psel = (i == 2);
> -                               *esel = (i != 0);
> -                               clk->parent = mclk;
> -                               clk->rate = actual_rate;
> -                               rate_err = abs(actual_rate - rate);
> -                               found = 1;
> +                       if (is_best(rate, actual_rate, best_rate)) {
> +                               best_rate = actual_rate;
> +                               best_parent_rate = __parent_rate;
> +                               best_parent = parent;
>                         }
>                 }
>         }
>  
> -       if (!found)
> +       if (!best_parent)
>                 return -EINVAL;
>  
> +       req->best_parent_rate = best_parent_rate;
> +       req->best_parent_hw = __clk_get_hw(best_parent);
> +       req->rate = best_rate;
> +
>         return 0;
>  }
>  
> -static int set_div_rate(struct clk *clk, unsigned long rate)
> +static unsigned long ep93xx_ddiv_recalc_rate(struct clk_hw *hw,
> +                                               unsigned long parent_rate)
>  {
> -       int err, psel = 0, esel = 0, pdiv = 0, div = 0;
> -       u32 val;
> -
> -       err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
> -       if (err)
> -               return err;
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       unsigned long rate = 0;
> +       u32 val = __raw_readl(psc->reg);
> +       int __pdiv = ((val >> EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) & 0x03);
> +       int __div = val & 0x7f;
>  
> -       /* Clear the esel, psel, pdiv and div bits */
> -       val = __raw_readl(clk->enable_reg);
> -       val &= ~0x7fff;
> +       if (__div > 0)
> +               rate = (parent_rate * 2) / ((__pdiv + 3) * __div);
>  
> -       /* Set the new esel, psel, pdiv and div bits for the new clock rate */
> -       val |= (esel ? EP93XX_SYSCON_CLKDIV_ESEL : 0) |
> -               (psel ? EP93XX_SYSCON_CLKDIV_PSEL : 0) |
> -               (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
> -       ep93xx_syscon_swlocked_write(val, clk->enable_reg);
> -       return 0;
> +       return rate;
>  }
>  
> -static int set_i2s_sclk_rate(struct clk *clk, unsigned long rate)
> +static int ep93xx_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
> +                               unsigned long parent_rate)
>  {
> -       unsigned val = __raw_readl(clk->enable_reg);
> -
> -       if (rate == clk_i2s_mclk.rate / 2)
> -               ep93xx_syscon_swlocked_write(val & ~EP93XX_I2SCLKDIV_SDIV, 
> -                                            clk->enable_reg);
> -       else if (rate == clk_i2s_mclk.rate / 4)
> -               ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_SDIV, 
> -                                            clk->enable_reg);
> -       else
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       int pdiv = 0, div = 0;
> +       unsigned long best_rate = 0, actual_rate, mclk_rate;
> +       int __div = 0, __pdiv = 0;
> +       u32 val;
> +
> +       mclk_rate = parent_rate * 2;
> +
> +       for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
> +               __div = mclk_rate / (rate * __pdiv);
> +               if (__div < 2 || __div > 127)
> +                       continue;
> +
> +               actual_rate = mclk_rate / (__pdiv * __div);
> +               if (is_best(rate, actual_rate, best_rate)) {
> +                       pdiv = __pdiv - 3;
> +                       div = __div;
> +                       best_rate = actual_rate;
> +               }
> +       }
> +
> +       if (!best_rate)
>                 return -EINVAL;
>  
> -       clk_i2s_sclk.rate = rate;
> +       val = __raw_readl(psc->reg);
> +
> +       /* Clear old dividers */
> +       val &= ~0x37f;
> +
> +       /* Set the new pdiv and div bits for the new clock rate */
> +       val |= (pdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | div;
> +       ep93xx_syscon_swlocked_write(val, psc->reg);
> +
>         return 0;
>  }
>  
> -static int set_i2s_lrclk_rate(struct clk *clk, unsigned long rate)
> -{
> -       unsigned val = __raw_readl(clk->enable_reg) & 
> -               ~EP93XX_I2SCLKDIV_LRDIV_MASK;
> -       
> -       if (rate == clk_i2s_sclk.rate / 32)
> -               ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV32,
> -                                            clk->enable_reg);
> -       else if (rate == clk_i2s_sclk.rate / 64)
> -               ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV64,
> -                                            clk->enable_reg);
> -       else if (rate == clk_i2s_sclk.rate / 128)
> -               ep93xx_syscon_swlocked_write(val | EP93XX_I2SCLKDIV_LRDIV128,
> -                                            clk->enable_reg);
> -       else
> -               return -EINVAL;
> +static const struct clk_ops clk_ddiv_ops = {
> +       .enable = ep93xx_clk_enable,
> +       .disable = ep93xx_clk_disable,
> +       .is_enabled = ep93xx_clk_is_enabled,
> +       .get_parent = ep93xx_mux_get_parent,
> +       .set_parent = ep93xx_mux_set_parent_lock,
> +       .determine_rate = ep93xx_mux_determine_rate,
> +       .recalc_rate = ep93xx_ddiv_recalc_rate,
> +       .set_rate = ep93xx_ddiv_set_rate,
> +};
>  
> -       clk_i2s_lrclk.rate = rate;
> -       return 0;
> +static struct clk_hw *clk_hw_register_ddiv(const char *name,
> +                                         void __iomem *reg,
> +                                         u8 bit_idx)
> +{
> +       struct clk_init_data init;
> +       struct clk_psc *psc;
> +       struct clk *clk;
> +
> +       psc = kzalloc(sizeof(*psc), GFP_KERNEL);
> +       if (!psc)
> +               return ERR_PTR(-ENOMEM);
> +
> +       init.name = name;
> +       init.ops = &clk_ddiv_ops;
> +       init.flags = 0;
> +       init.parent_names = mux_parents;
> +       init.num_parents = ARRAY_SIZE(mux_parents);
> +
> +       psc->reg = reg;
> +       psc->bit_idx = bit_idx;
> +       psc->lock = &clk_lock;
> +       psc->hw.init = &init;
> +
> +       clk = clk_register(NULL, &psc->hw);
> +       if (IS_ERR(clk))
> +               kfree(psc);
> +
> +       return &psc->hw;
>  }
>  
> -int clk_set_rate(struct clk *clk, unsigned long rate)
> +static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw,
> +                                           unsigned long parent_rate)
>  {
> -       if (clk->set_rate)
> -               return clk->set_rate(clk, rate);
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       u32 val = __raw_readl(psc->reg);
> +       u8 index = (val & psc->mask) >> psc->shift;
>  
> -       return -EINVAL;
> +       if (index > psc->num_div)
> +               return 0;
> +
> +       return DIV_ROUND_UP_ULL(parent_rate, psc->div[index]);
>  }
> -EXPORT_SYMBOL(clk_set_rate);
>  
> -long clk_round_rate(struct clk *clk, unsigned long rate)
> +static long ep93xx_div_round_rate(struct clk_hw *hw, unsigned long rate,
> +                                  unsigned long *parent_rate)
>  {
> -       WARN_ON(clk);
> -       return 0;
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       unsigned long best = 0, now, maxdiv;
> +       int i;
> +
> +       maxdiv = psc->div[psc->num_div - 1];
> +
> +       for (i = 0; i < psc->num_div; i++) {
> +               if ((rate * psc->div[i]) == *parent_rate)
> +                       return DIV_ROUND_UP_ULL((u64)*parent_rate, psc->div[i]);
> +
> +               now = DIV_ROUND_UP_ULL((u64)*parent_rate, psc->div[i]);
> +
> +               if (is_best(rate, now, best))
> +                       best = now;
> +       }
> +
> +       if (!best)
> +               best = DIV_ROUND_UP_ULL(*parent_rate, maxdiv);
> +
> +       return best;
>  }
> -EXPORT_SYMBOL(clk_round_rate);
>  
> -int clk_set_parent(struct clk *clk, struct clk *parent)
> +static int ep93xx_div_set_rate(struct clk_hw *hw, unsigned long rate,
> +                              unsigned long parent_rate)
>  {
> -       WARN_ON(clk);
> +       struct clk_psc *psc = to_clk_psc(hw);
> +       u32 val = __raw_readl(psc->reg) & ~psc->mask;
> +       int i;
> +
> +       for (i = 0; i < psc->num_div; i++)
> +               if (rate == parent_rate / psc->div[i]) {
> +                       val |= i << psc->shift;
> +                       break;
> +               }
> +
> +       if (i == psc->num_div)
> +               return -EINVAL;
> +
> +       ep93xx_syscon_swlocked_write(val, psc->reg);
> +
>         return 0;
>  }
> -EXPORT_SYMBOL(clk_set_parent);
>  
> -struct clk *clk_get_parent(struct clk *clk)
> +static const struct clk_ops ep93xx_div_ops = {
> +       .enable = ep93xx_clk_enable,
> +       .disable = ep93xx_clk_disable,
> +       .is_enabled = ep93xx_clk_is_enabled,
> +       .recalc_rate = ep93xx_div_recalc_rate,
> +       .round_rate = ep93xx_div_round_rate,
> +       .set_rate = ep93xx_div_set_rate,
> +};
> +
> +static struct clk_hw *clk_hw_register_div(const char *name,
> +                                         const char *parent_name,
> +                                         void __iomem *reg,
> +                                         u8 enable_bit,
> +                                         u8 shift,
> +                                         u8 width,
> +                                         char *clk_divisors,
> +                                         u8 num_div)
>  {
> -       return clk->parent;
> +       struct clk_init_data init;
> +       struct clk_psc *psc;
> +       struct clk *clk;
> +
> +       psc = kzalloc(sizeof(*psc), GFP_KERNEL);
> +       if (!psc)
> +               return ERR_PTR(-ENOMEM);
> +
> +       init.name = name;
> +       init.ops = &ep93xx_div_ops;
> +       init.flags = 0;
> +       init.parent_names = (parent_name ? &parent_name : NULL);
> +       init.num_parents = 1;
> +
> +       psc->reg = reg;
> +       psc->bit_idx = enable_bit;
> +       psc->mask = GENMASK(shift + width - 1, shift);
> +       psc->shift = shift;
> +       psc->div = clk_divisors;
> +       psc->num_div = num_div;
> +       psc->lock = &clk_lock;
> +       psc->hw.init = &init;
> +
> +       clk = clk_register(NULL, &psc->hw);
> +       if (IS_ERR(clk))
> +               kfree(psc);
> +
> +       return &psc->hw;
>  }
> -EXPORT_SYMBOL(clk_get_parent);
>  
> +struct ep93xx_gate {
> +       unsigned int bit;
> +       const char *dev_id;
> +       const char *con_id;
> +};
>  
> -static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
> -static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
> -static char pclk_divisors[] = { 1, 2, 4, 8 };
> +static struct ep93xx_gate ep93xx_uarts[] = {
> +       {EP93XX_SYSCON_DEVCFG_U1EN, "apb:uart1", NULL},
> +       {EP93XX_SYSCON_DEVCFG_U2EN, "apb:uart2", NULL},
> +       {EP93XX_SYSCON_DEVCFG_U3EN, "apb:uart3", NULL},
> +};
>  
> -/*
> - * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
> - */
> -static unsigned long calc_pll_rate(u32 config_word)
> +static void __init ep93xx_uart_clock_init(void)
>  {
> -       unsigned long long rate;
> -       int i;
> +       unsigned int i;
> +       struct clk_hw *hw;
> +       u32 value;
> +       unsigned int clk_uart_div;
>  
> -       rate = clk_xtali.rate;
> -       rate *= ((config_word >> 11) & 0x1f) + 1;               /* X1FBD */
> -       rate *= ((config_word >> 5) & 0x3f) + 1;                /* X2FBD */
> -       do_div(rate, (config_word & 0x1f) + 1);                 /* X2IPD */
> -       for (i = 0; i < ((config_word >> 16) & 3); i++)         /* PS */
> -               rate >>= 1;
> +       value = __raw_readl(EP93XX_SYSCON_PWRCNT);
> +       if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
> +               clk_uart_div = 1;
> +       else
> +               clk_uart_div = 2;
>  
> -       return (unsigned long)rate;
> +       hw = clk_hw_register_fixed_factor(NULL, "uart", "xtali", 0, 1, clk_uart_div);
> +
> +       /* parenting uart gate clocks to uart clock */
> +       for (i = 0; i < ARRAY_SIZE(ep93xx_uarts); i++) {
> +               hw = ep93xx_clk_register_gate(ep93xx_uarts[i].dev_id,
> +                                       "uart",
> +                                       EP93XX_SYSCON_DEVCFG,
> +                                       ep93xx_uarts[i].bit);
> +
> +               clk_hw_register_clkdev(hw, NULL, ep93xx_uarts[i].dev_id);
> +       }
>  }
>  
> +static struct ep93xx_gate ep93xx_dmas[] = {
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P0, NULL, "m2p0"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P1, NULL, "m2p1"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P2, NULL, "m2p2"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P3, NULL, "m2p3"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P4, NULL, "m2p4"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P5, NULL, "m2p5"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P6, NULL, "m2p6"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P7, NULL, "m2p7"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P8, NULL, "m2p8"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2P9, NULL, "m2p9"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2M0, NULL, "m2m0"},
> +       {EP93XX_SYSCON_PWRCNT_DMA_M2M1, NULL, "m2m1"},
> +};
> +
>  static void __init ep93xx_dma_clock_init(void)
>  {
> -       clk_m2p0.rate = clk_h.rate;
> -       clk_m2p1.rate = clk_h.rate;
> -       clk_m2p2.rate = clk_h.rate;
> -       clk_m2p3.rate = clk_h.rate;
> -       clk_m2p4.rate = clk_h.rate;
> -       clk_m2p5.rate = clk_h.rate;
> -       clk_m2p6.rate = clk_h.rate;
> -       clk_m2p7.rate = clk_h.rate;
> -       clk_m2p8.rate = clk_h.rate;
> -       clk_m2p9.rate = clk_h.rate;
> -       clk_m2m0.rate = clk_h.rate;
> -       clk_m2m1.rate = clk_h.rate;
> +       unsigned int i;
> +       struct clk_hw *hw;
> +       int ret;
> +
> +       for (i = 0; i < ARRAY_SIZE(ep93xx_dmas); i++) {
> +               hw = clk_hw_register_gate(NULL, ep93xx_dmas[i].con_id,
> +                                       "hclk", 0,
> +                                       EP93XX_SYSCON_PWRCNT,
> +                                       ep93xx_dmas[i].bit,
> +                                       0,
> +                                       &clk_lock);
> +
> +               ret = clk_hw_register_clkdev(hw, ep93xx_dmas[i].con_id, NULL);
> +               if (ret)
> +                       pr_err("%s: failed to register lookup %s\n",
> +                              __func__, ep93xx_dmas[i].con_id);
> +       }
>  }
>  
>  static int __init ep93xx_clock_init(void)
>  {
>         u32 value;
> +       struct clk_hw *hw;
> +       unsigned long clk_pll1_rate;
> +       unsigned long clk_f_rate;
> +       unsigned long clk_h_rate;
> +       unsigned long clk_p_rate;
> +       unsigned long clk_pll2_rate;
> +       unsigned int clk_f_div;
> +       unsigned int clk_h_div;
> +       unsigned int clk_p_div;
> +       unsigned int clk_usb_div;
> +       unsigned long clk_spi_div;
> +
> +       hw = clk_hw_register_fixed_rate(NULL, "xtali", NULL, 0, EP93XX_EXT_CLK_RATE);
> +       clk_hw_register_clkdev(hw, NULL, "xtali");
>  
>         /* Determine the bootloader configured pll1 rate */
>         value = __raw_readl(EP93XX_SYSCON_CLKSET1);
>         if (!(value & EP93XX_SYSCON_CLKSET1_NBYP1))
> -               clk_pll1.rate = clk_xtali.rate;
> +               clk_pll1_rate = EP93XX_EXT_CLK_RATE;
>         else
> -               clk_pll1.rate = calc_pll_rate(value);
> +               clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
> +
> +       hw = clk_hw_register_fixed_rate(NULL, "pll1", "xtali", 0, clk_pll1_rate);
> +       clk_hw_register_clkdev(hw, NULL, "pll1");
>  
>         /* Initialize the pll1 derived clocks */
> -       clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
> -       clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
> -       clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
> +       clk_f_div = fclk_divisors[(value >> 25) & 0x7];
> +       clk_h_div = hclk_divisors[(value >> 20) & 0x7];
> +       clk_p_div = pclk_divisors[(value >> 18) & 0x3];
> +
> +       hw = clk_hw_register_fixed_factor(NULL, "fclk", "pll1", 0, 1, clk_f_div);
> +       clk_f_rate = clk_get_rate(hw->clk);
> +       hw = clk_hw_register_fixed_factor(NULL, "hclk", "pll1", 0, 1, clk_h_div);
> +       clk_h_rate = clk_get_rate(hw->clk);
> +       hw = clk_hw_register_fixed_factor(NULL, "pclk", "hclk", 0, 1, clk_p_div);
> +       clk_p_rate = clk_get_rate(hw->clk);
> +
> +       clk_hw_register_clkdev(hw, "apb_pclk", NULL);
> +
>         ep93xx_dma_clock_init();
>  
>         /* Determine the bootloader configured pll2 rate */
>         value = __raw_readl(EP93XX_SYSCON_CLKSET2);
>         if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))
> -               clk_pll2.rate = clk_xtali.rate;
> +               clk_pll2_rate = EP93XX_EXT_CLK_RATE;
>         else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)
> -               clk_pll2.rate = calc_pll_rate(value);
> +               clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);
>         else
> -               clk_pll2.rate = 0;
> +               clk_pll2_rate = 0;
> +
> +       hw = clk_hw_register_fixed_rate(NULL, "pll2", "xtali", 0, clk_pll2_rate);
> +       clk_hw_register_clkdev(hw, NULL, "pll2");
>  
>         /* Initialize the pll2 derived clocks */
> -       clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
> +       /*
> +        * These four bits set the divide ratio between the PLL2
> +        * output and the USB clock.
> +        * 0000 - Divide by 1
> +        * 0001 - Divide by 2
> +        * 0010 - Divide by 3
> +        * 0011 - Divide by 4
> +        * 0100 - Divide by 5
> +        * 0101 - Divide by 6
> +        * 0110 - Divide by 7
> +        * 0111 - Divide by 8
> +        * 1000 - Divide by 9
> +        * 1001 - Divide by 10
> +        * 1010 - Divide by 11
> +        * 1011 - Divide by 12
> +        * 1100 - Divide by 13
> +        * 1101 - Divide by 14
> +        * 1110 - Divide by 15
> +        * 1111 - Divide by 1
> +        * On power-on-reset these bits are reset to 0000b.
> +        */
> +       clk_usb_div = (((value >> 28) & 0xf) + 1);
> +       hw = clk_hw_register_fixed_factor(NULL, "usb_clk", "pll2", 0, 1, clk_usb_div);
> +       hw = clk_hw_register_gate(NULL, "ohci-platform",
> +                               "usb_clk", 0,
> +                               EP93XX_SYSCON_PWRCNT,
> +                               EP93XX_SYSCON_PWRCNT_USH_EN,
> +                               0,
> +                               &clk_lock);
> +       clk_hw_register_clkdev(hw, NULL, "ohci-platform");
>  
>         /*
>          * EP93xx SSP clock rate was doubled in version E2. For more information
>          * see:
>          *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
>          */
> +       clk_spi_div = 1;
>         if (ep93xx_chip_revision() < EP93XX_CHIP_REV_E2)
> -               clk_spi.rate /= 2;
> +               clk_spi_div = 2;
> +       hw = clk_hw_register_fixed_factor(NULL, "ep93xx-spi.0", "xtali", 0, 1, clk_spi_div);
> +       clk_hw_register_clkdev(hw, NULL, "ep93xx-spi.0");
> +
> +       /* pwm clock */
> +       hw = clk_hw_register_fixed_factor(NULL, "pwm_clk", "xtali", 0, 1, 1);
> +       clk_hw_register_clkdev(hw, "pwm_clk", NULL);
>  
>         pr_info("PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
> -               clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
> +               clk_pll1_rate / 1000000, clk_pll2_rate / 1000000);
>         pr_info("FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
> -               clk_f.rate / 1000000, clk_h.rate / 1000000,
> -               clk_p.rate / 1000000);
> +               clk_f_rate / 1000000, clk_h_rate / 1000000,
> +               clk_p_rate / 1000000);
> +
> +       ep93xx_uart_clock_init();
> +
> +       /* touchscreen/adc clock */
> +       hw = clk_hw_register_div("ep93xx-adc",
> +                               "xtali",
> +                               EP93XX_SYSCON_KEYTCHCLKDIV,
> +                               EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
> +                               EP93XX_SYSCON_KEYTCHCLKDIV_ADIV,
> +                               1,
> +                               adc_divisors,
> +                               ARRAY_SIZE(adc_divisors));
> +
> +       clk_hw_register_clkdev(hw, NULL, "ep93xx-adc");
> +
> +       /* keypad clock */
> +       hw = clk_hw_register_div("ep93xx-keypad",
> +                               "xtali",
> +                               EP93XX_SYSCON_KEYTCHCLKDIV,
> +                               EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
> +                               EP93XX_SYSCON_KEYTCHCLKDIV_KDIV,
> +                               1,
> +                               adc_divisors,
> +                               ARRAY_SIZE(adc_divisors));
> +
> +       clk_hw_register_clkdev(hw, NULL, "ep93xx-keypad");
> +
> +       /* On reset PDIV and VDIV is set to zero, while PDIV zero
> +        * means clock disable, VDIV shouldn't be zero.
> +        * So i set both dividers to minimum.
> +        */
> +       /* ENA - Enable CLK divider. */
> +       /* PDIV - 00 - Disable clock */
> +       /* VDIV - at least 2 */
> +       /* Check and enable video clk registers */
> +       value = __raw_readl(EP93XX_SYSCON_VIDCLKDIV);
> +       value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
> +       ep93xx_syscon_swlocked_write(value, EP93XX_SYSCON_VIDCLKDIV);
> +
> +       /* check and enable i2s clk registers */
> +       value = __raw_readl(EP93XX_SYSCON_I2SCLKDIV);
> +       value |= (1 << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
> +       ep93xx_syscon_swlocked_write(value, EP93XX_SYSCON_I2SCLKDIV);
> +
> +       /* video clk */
> +       hw = clk_hw_register_ddiv("ep93xx-fb",
> +                               EP93XX_SYSCON_VIDCLKDIV,
> +                               EP93XX_SYSCON_CLKDIV_ENABLE);
> +
> +       clk_hw_register_clkdev(hw, NULL, "ep93xx-fb");
> +
> +       /* i2s clk */
> +       hw = clk_hw_register_ddiv("mclk",
> +                               EP93XX_SYSCON_I2SCLKDIV,
> +                               EP93XX_SYSCON_CLKDIV_ENABLE);
> +
> +       clk_hw_register_clkdev(hw, "mclk", "ep93xx-i2s");
> +
> +       /* i2s sclk */
> +#define EP93XX_I2SCLKDIV_SDIV_SHIFT    16
> +#define EP93XX_I2SCLKDIV_SDIV_WIDTH    1
> +       hw = clk_hw_register_div("sclk",
> +                               "mclk",
> +                               EP93XX_SYSCON_I2SCLKDIV,
> +                               EP93XX_SYSCON_I2SCLKDIV_SENA,
> +                               EP93XX_I2SCLKDIV_SDIV_SHIFT,
> +                               EP93XX_I2SCLKDIV_SDIV_WIDTH,
> +                               sclk_divisors,
> +                               ARRAY_SIZE(sclk_divisors));
> +
> +       clk_hw_register_clkdev(hw, "sclk", "ep93xx-i2s");
> +
> +       /* i2s lrclk */
> +#define EP93XX_I2SCLKDIV_LRDIV32_SHIFT 17
> +#define EP93XX_I2SCLKDIV_LRDIV32_WIDTH 3
> +       hw = clk_hw_register_div("lrclk",
> +                               "sclk",
> +                               EP93XX_SYSCON_I2SCLKDIV,
> +                               EP93XX_SYSCON_I2SCLKDIV_SENA,
> +                               EP93XX_I2SCLKDIV_LRDIV32_SHIFT,
> +                               EP93XX_I2SCLKDIV_LRDIV32_WIDTH,
> +                               lrclk_divisors,
> +                               ARRAY_SIZE(lrclk_divisors));
> +
> +       clk_hw_register_clkdev(hw, "lrclk", "ep93xx-i2s");
>  
> -       clkdev_add_table(clocks, ARRAY_SIZE(clocks));
>         return 0;
>  }
>  postcore_initcall(ep93xx_clock_init);
> diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
> index 6fb19a393fd2..bbb79f263331 100644
> --- a/arch/arm/mach-ep93xx/core.c
> +++ b/arch/arm/mach-ep93xx/core.c
> @@ -214,7 +214,7 @@ static int ep93xx_ohci_power_on(struct platform_device *pdev)
>                         return PTR_ERR(ep93xx_ohci_host_clock);
>         }
>  
> -       return clk_enable(ep93xx_ohci_host_clock);
> +       return clk_prepare_enable(ep93xx_ohci_host_clock);
>  }
>  
>  static void ep93xx_ohci_power_off(struct platform_device *pdev)
> diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h
> index f2dace1c9154..94ef7f275f94 100644
> --- a/arch/arm/mach-ep93xx/soc.h
> +++ b/arch/arm/mach-ep93xx/soc.h
> @@ -111,19 +111,19 @@
>  #define EP93XX_SYSCON_PWRCNT           EP93XX_SYSCON_REG(0x04)
>  #define EP93XX_SYSCON_PWRCNT_FIR_EN    (1<<31)
>  #define EP93XX_SYSCON_PWRCNT_UARTBAUD  (1<<29)
> -#define EP93XX_SYSCON_PWRCNT_USH_EN    (1<<28)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2M1  (1<<27)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2M0  (1<<26)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P8  (1<<25)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P9  (1<<24)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P6  (1<<23)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P7  (1<<22)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P4  (1<<21)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P5  (1<<20)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P2  (1<<19)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P3  (1<<18)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P0  (1<<17)
> -#define EP93XX_SYSCON_PWRCNT_DMA_M2P1  (1<<16)
> +#define EP93XX_SYSCON_PWRCNT_USH_EN    28
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2M1  27
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2M0  26
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P8  25
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P9  24
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P6  23
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P7  22
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P4  21
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P5  20
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P2  19
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P3  18
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P0  17
> +#define EP93XX_SYSCON_PWRCNT_DMA_M2P1  16
>  #define EP93XX_SYSCON_HALT             EP93XX_SYSCON_REG(0x08)
>  #define EP93XX_SYSCON_STANDBY          EP93XX_SYSCON_REG(0x0c)
>  #define EP93XX_SYSCON_CLKSET1          EP93XX_SYSCON_REG(0x20)
> @@ -139,13 +139,13 @@
>  #define EP93XX_SYSCON_DEVCFG_GONK      (1<<27)
>  #define EP93XX_SYSCON_DEVCFG_TONG      (1<<26)
>  #define EP93XX_SYSCON_DEVCFG_MONG      (1<<25)
> -#define EP93XX_SYSCON_DEVCFG_U3EN      (1<<24)
> +#define EP93XX_SYSCON_DEVCFG_U3EN      24
>  #define EP93XX_SYSCON_DEVCFG_CPENA     (1<<23)
>  #define EP93XX_SYSCON_DEVCFG_A2ONG     (1<<22)
>  #define EP93XX_SYSCON_DEVCFG_A1ONG     (1<<21)
> -#define EP93XX_SYSCON_DEVCFG_U2EN      (1<<20)
> +#define EP93XX_SYSCON_DEVCFG_U2EN      20
>  #define EP93XX_SYSCON_DEVCFG_EXVC      (1<<19)
> -#define EP93XX_SYSCON_DEVCFG_U1EN      (1<<18)
> +#define EP93XX_SYSCON_DEVCFG_U1EN      18
>  #define EP93XX_SYSCON_DEVCFG_TIN       (1<<17)
>  #define EP93XX_SYSCON_DEVCFG_HC3IN     (1<<15)
>  #define EP93XX_SYSCON_DEVCFG_HC3EN     (1<<14)
> @@ -163,12 +163,12 @@
>  #define EP93XX_SYSCON_DEVCFG_KEYS      (1<<1)
>  #define EP93XX_SYSCON_DEVCFG_SHENA     (1<<0)
>  #define EP93XX_SYSCON_VIDCLKDIV                EP93XX_SYSCON_REG(0x84)
> -#define EP93XX_SYSCON_CLKDIV_ENABLE    (1<<15)
> +#define EP93XX_SYSCON_CLKDIV_ENABLE    15
>  #define EP93XX_SYSCON_CLKDIV_ESEL      (1<<14)
>  #define EP93XX_SYSCON_CLKDIV_PSEL      (1<<13)
>  #define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT        8
>  #define EP93XX_SYSCON_I2SCLKDIV                EP93XX_SYSCON_REG(0x8c)
> -#define EP93XX_SYSCON_I2SCLKDIV_SENA   (1<<31)
> +#define EP93XX_SYSCON_I2SCLKDIV_SENA   31
>  #define EP93XX_SYSCON_I2SCLKDIV_ORIDE   (1<<29)
>  #define EP93XX_SYSCON_I2SCLKDIV_SPOL   (1<<19)
>  #define EP93XX_I2SCLKDIV_SDIV          (1 << 16)
> @@ -177,9 +177,9 @@
>  #define EP93XX_I2SCLKDIV_LRDIV128      (2 << 17)
>  #define EP93XX_I2SCLKDIV_LRDIV_MASK    (3 << 17)
>  #define EP93XX_SYSCON_KEYTCHCLKDIV     EP93XX_SYSCON_REG(0x90)
> -#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN        (1<<31)
> -#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV        (1<<16)
> -#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
> +#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN        31
> +#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV        16
> +#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN 15
>  #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV        (1<<0)
>  #define EP93XX_SYSCON_SYSCFG           EP93XX_SYSCON_REG(0x9c)
>  #define EP93XX_SYSCON_SYSCFG_REV_MASK  (0xf0000000)

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12  8:03     ` Alexander Sverdlin
@ 2021-10-12  8:29       ` Arnd Bergmann
  2021-10-12  8:37         ` Alexander Sverdlin
  0 siblings, 1 reply; 46+ messages in thread
From: Arnd Bergmann @ 2021-10-12  8:29 UTC (permalink / raw)
  To: Alexander Sverdlin
  Cc: Russell King, Arnd Bergmann, Hartley Sweeten, Linus Walleij,
	Ard Biesheuvel, Andrew Morton, Krzysztof Kozlowski,
	Anshuman Khandual, Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin, Geert Uytterhoeven

On Tue, Oct 12, 2021 at 10:03 AM Alexander Sverdlin
<alexander.sverdlin@gmail.com> wrote:
>
> Hello Russel, Arnd,
>
> On Mon, 2021-07-26 at 16:59 +0300, Nikita Shubin wrote:
> > Converted in-place without moving file to drivers/clk.
> >
> > tested on ts7250 (EP9302).
> >
> > Only setting rate and change parent tested for, as they
> > are missing on ts7250:
> > - video
> > - I2S
> > - ADC/KEYPAD
> > - PWM
> >
> > Only video and I2S clock are interesting, as they are
> > GATE + double DIV + MUX, all other are pretty much
> > common but require ep93xx_syscon_swlocked_write to set
> > registers.
> >
> > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
>
> with an
> Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> and
> Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
>
> shall I add this patch to the Russels patch system, or would
> Arnd take it to the SoC tree?

The SoC tree is the right place here.

Please resend the patches you want me to apply to soc@kernel.org
so they make it into patchwork and I can get them from there.

> There is already a merge commit 726e6f31b102 upstream which
> claims to merge it, but it's actually not in.

It looks like this is just the drivers/spi/ bit of the series. Are
there any other driver changes that are needed along with
the arch/arm/ patches, or is it just the actual clock support now?

       Arnd

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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12  8:29       ` Arnd Bergmann
@ 2021-10-12  8:37         ` Alexander Sverdlin
  2021-10-12  9:05           ` Arnd Bergmann
  0 siblings, 1 reply; 46+ messages in thread
From: Alexander Sverdlin @ 2021-10-12  8:37 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Russell King, Hartley Sweeten, Linus Walleij, Ard Biesheuvel,
	Andrew Morton, Krzysztof Kozlowski, Anshuman Khandual,
	Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin, Geert Uytterhoeven

Hello Arnd,

thanks for the quick reply!

On Tue, 2021-10-12 at 10:29 +0200, Arnd Bergmann wrote:
> > > Converted in-place without moving file to drivers/clk.
> > > 
> > > tested on ts7250 (EP9302).
> > > 
> > > Only setting rate and change parent tested for, as they
> > > are missing on ts7250:
> > > - video
> > > - I2S
> > > - ADC/KEYPAD
> > > - PWM
> > > 
> > > Only video and I2S clock are interesting, as they are
> > > GATE + double DIV + MUX, all other are pretty much
> > > common but require ep93xx_syscon_swlocked_write to set
> > > registers.
> > > 
> > > Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
> > 
> > with an
> > Acked-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> > and
> > Tested-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
> > 
> > shall I add this patch to the Russels patch system, or would
> > Arnd take it to the SoC tree?
> 
> The SoC tree is the right place here.
> 
> Please resend the patches you want me to apply to soc@kernel.org
> so they make it into patchwork and I can get them from there.
> 
> > There is already a merge commit 726e6f31b102 upstream which
> > claims to merge it, but it's actually not in.
> 
> It looks like this is just the drivers/spi/ bit of the series. Are
> there any other driver changes that are needed along with
> the arch/arm/ patches, or is it just the actual clock support now?

There is "ASoC: cirrus: i2s: Prepare clock before using it" still
unmerged as well with an ACK from Mark Brown, I did remind him
about it again this morning, but I can resend it to you if you wish.

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12  8:37         ` Alexander Sverdlin
@ 2021-10-12  9:05           ` Arnd Bergmann
  2021-10-12 10:26             ` Mark Brown
  0 siblings, 1 reply; 46+ messages in thread
From: Arnd Bergmann @ 2021-10-12  9:05 UTC (permalink / raw)
  To: Alexander Sverdlin
  Cc: Arnd Bergmann, Russell King, Hartley Sweeten, Linus Walleij,
	Ard Biesheuvel, Andrew Morton, Krzysztof Kozlowski,
	Anshuman Khandual, Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin, Geert Uytterhoeven, Mark Brown

On Tue, Oct 12, 2021 at 10:37 AM Alexander Sverdlin
<alexander.sverdlin@gmail.com> wrote:
> On Tue, 2021-10-12 at 10:29 +0200, Arnd Bergmann wrote:
> > > > Converted in-place without moving file to drivers/clk.
> > It looks like this is just the drivers/spi/ bit of the series. Are
> > there any other driver changes that are needed along with
> > the arch/arm/ patches, or is it just the actual clock support now?
>
> There is "ASoC: cirrus: i2s: Prepare clock before using it" still
> unmerged as well with an ACK from Mark Brown, I did remind him
> about it again this morning, but I can resend it to you if you wish.

(adding Mark to cc)

Let's wait for him to reply then. I don't think it matters much either
way, since the series is not doing an atomic conversion if the other
drivers are merged through different trees, and Mark has given
an Ack for the driver.

       Arnd

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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12  9:05           ` Arnd Bergmann
@ 2021-10-12 10:26             ` Mark Brown
  2021-10-12 10:36               ` Alexander Sverdlin
  0 siblings, 1 reply; 46+ messages in thread
From: Mark Brown @ 2021-10-12 10:26 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Alexander Sverdlin, Russell King, Hartley Sweeten, Linus Walleij,
	Ard Biesheuvel, Andrew Morton, Krzysztof Kozlowski,
	Anshuman Khandual, Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 710 bytes --]

On Tue, Oct 12, 2021 at 11:05:08AM +0200, Arnd Bergmann wrote:
> On Tue, Oct 12, 2021 at 10:37 AM Alexander Sverdlin

> > There is "ASoC: cirrus: i2s: Prepare clock before using it" still
> > unmerged as well with an ACK from Mark Brown, I did remind him
> > about it again this morning, but I can resend it to you if you wish.

> (adding Mark to cc)

> Let's wait for him to reply then. I don't think it matters much either
> way, since the series is not doing an atomic conversion if the other
> drivers are merged through different trees, and Mark has given
> an Ack for the driver.

You're going to have to tell me what's going on here:

   https://lore.kernel.org/all/20210914103212.GB4434@sirena.org.uk/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12 10:26             ` Mark Brown
@ 2021-10-12 10:36               ` Alexander Sverdlin
  2021-10-12 10:43                 ` Mark Brown
  0 siblings, 1 reply; 46+ messages in thread
From: Alexander Sverdlin @ 2021-10-12 10:36 UTC (permalink / raw)
  To: Mark Brown, Arnd Bergmann
  Cc: Russell King, Hartley Sweeten, Linus Walleij, Ard Biesheuvel,
	Andrew Morton, Krzysztof Kozlowski, Anshuman Khandual,
	Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin, Geert Uytterhoeven

Hello Mark,

On Tue, 2021-10-12 at 11:26 +0100, Mark Brown wrote:
> On Tue, Oct 12, 2021 at 11:05:08AM +0200, Arnd Bergmann wrote:
> > On Tue, Oct 12, 2021 at 10:37 AM Alexander Sverdlin
> 
> > > There is "ASoC: cirrus: i2s: Prepare clock before using it" still
> > > unmerged as well with an ACK from Mark Brown, I did remind him
> > > about it again this morning, but I can resend it to you if you wish.
> 
> > (adding Mark to cc)
> 
> > Let's wait for him to reply then. I don't think it matters much either
> > way, since the series is not doing an atomic conversion if the other
> > drivers are merged through different trees, and Mark has given
> > an Ack for the driver.
> 
> You're going to have to tell me what's going on here:
> 
>    https://lore.kernel.org/all/20210914103212.GB4434@sirena.org.uk/

here you were asking about "spi: spi-ep93xx: Prepare clock before using it"
which you've already applied (as 7c72dc56a631).

Nevertheless, there are no dependencies in the patches 1..7, they are all
pre-requsites for the last patch 8/8.

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 6/8] ASoC: cirrus: i2s: Prepare clock before using it
  2021-10-12  7:25         ` Alexander Sverdlin
@ 2021-10-12 10:40           ` Mark Brown
  0 siblings, 0 replies; 46+ messages in thread
From: Mark Brown @ 2021-10-12 10:40 UTC (permalink / raw)
  To: Alexander Sverdlin
  Cc: Nikita Shubin, Geert Uytterhoeven, Liam Girdwood,
	Jaroslav Kysela, Takashi Iwai, Kuninori Morimoto,
	moderated list:SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEM...,
	open list

[-- Attachment #1: Type: text/plain, Size: 1241 bytes --]

On Tue, Oct 12, 2021 at 09:25:15AM +0200, Alexander Sverdlin wrote:
> On Mon, 2021-09-13 at 23:43 +0200, Alexander Sverdlin wrote:

> > would you take the patch to a tree of yours, please?

> I still cannot find this patch in any of your trees, but I've found this one:

You ignored my question about dependencies:

    https://lore.kernel.org/all/20210914103212.GB4434@sirena.org.uk/

so I've no idea if it's safe to apply or if other people might need this
one patch from the middle of the series.

>       video: ep93xx: Prepare clock before using it
>       dmaengine: ep93xx: Prepare clock before using it
>       ASoC: cirrus: i2s: Prepare clock before using it
>       pwm: ep93xx: Prepare clock before using it
>     
>     Nikita Shubin (1):
>       ep93xx: clock: convert in-place to COMMON_CLK
> 
> 
> ... which claims to merge both "ASoC: cirrus: i2s: Prepare clock before using it"
> and "ep93xx: clock: convert in-place to COMMON_CLK", but they are actually not
> merged.

No, it doesn't - that's the cover letter from your series.

> Could you please consider ASoC patch, while I will resubmit the final clock conversion?

So please answer my question then: what's the story with dependencies?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12 10:36               ` Alexander Sverdlin
@ 2021-10-12 10:43                 ` Mark Brown
  2021-10-12 11:03                   ` Alexander Sverdlin
  0 siblings, 1 reply; 46+ messages in thread
From: Mark Brown @ 2021-10-12 10:43 UTC (permalink / raw)
  To: Alexander Sverdlin
  Cc: Arnd Bergmann, Russell King, Hartley Sweeten, Linus Walleij,
	Ard Biesheuvel, Andrew Morton, Krzysztof Kozlowski,
	Anshuman Khandual, Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 768 bytes --]

On Tue, Oct 12, 2021 at 12:36:54PM +0200, Alexander Sverdlin wrote:
> On Tue, 2021-10-12 at 11:26 +0100, Mark Brown wrote:
> > On Tue, Oct 12, 2021 at 11:05:08AM +0200, Arnd Bergmann wrote:

> > You're going to have to tell me what's going on here:

> >    https://lore.kernel.org/all/20210914103212.GB4434@sirena.org.uk/

> here you were asking about "spi: spi-ep93xx: Prepare clock before using it"
> which you've already applied (as 7c72dc56a631).

Right, you asked me to do the same thing on two patches so I didn't send
the same thing over and over again.

> Nevertheless, there are no dependencies in the patches 1..7, they are all
> pre-requsites for the last patch 8/8.

So what's going on with patch 8 then?  Is there some plan to merge it?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12 10:43                 ` Mark Brown
@ 2021-10-12 11:03                   ` Alexander Sverdlin
  2021-10-12 11:21                     ` Mark Brown
  0 siblings, 1 reply; 46+ messages in thread
From: Alexander Sverdlin @ 2021-10-12 11:03 UTC (permalink / raw)
  To: Mark Brown
  Cc: Arnd Bergmann, Russell King, Hartley Sweeten, Linus Walleij,
	Ard Biesheuvel, Andrew Morton, Krzysztof Kozlowski,
	Anshuman Khandual, Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin, Geert Uytterhoeven

Hello Mark,

thanks for looking into it!

On Tue, 2021-10-12 at 11:43 +0100, Mark Brown wrote:
> > > You're going to have to tell me what's going on here:
> 
> > >    https://lore.kernel.org/all/20210914103212.GB4434@sirena.org.uk/
> 
> > here you were asking about "spi: spi-ep93xx: Prepare clock before using it"
> > which you've already applied (as 7c72dc56a631).
> 
> Right, you asked me to do the same thing on two patches so I didn't send
> the same thing over and over again.
> 
> > Nevertheless, there are no dependencies in the patches 1..7, they are all
> > pre-requsites for the last patch 8/8.
> 
> So what's going on with patch 8 then?  Is there some plan to merge it?

Looks like Arnd is ready to pick it, and the only dependency which is
not yet merged into Linus's tree is "ASoC: cirrus: i2s: Prepare clock before using it".

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12 11:03                   ` Alexander Sverdlin
@ 2021-10-12 11:21                     ` Mark Brown
  2021-10-12 11:26                       ` Alexander Sverdlin
  0 siblings, 1 reply; 46+ messages in thread
From: Mark Brown @ 2021-10-12 11:21 UTC (permalink / raw)
  To: Alexander Sverdlin
  Cc: Arnd Bergmann, Russell King, Hartley Sweeten, Linus Walleij,
	Ard Biesheuvel, Andrew Morton, Krzysztof Kozlowski,
	Anshuman Khandual, Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 697 bytes --]

On Tue, Oct 12, 2021 at 01:03:56PM +0200, Alexander Sverdlin wrote:
> On Tue, 2021-10-12 at 11:43 +0100, Mark Brown wrote:

> > > Nevertheless, there are no dependencies in the patches 1..7, they are all
> > > pre-requsites for the last patch 8/8.

> > So what's going on with patch 8 then?  Is there some plan to merge it?

> Looks like Arnd is ready to pick it, and the only dependency which is
> not yet merged into Linus's tree is "ASoC: cirrus: i2s: Prepare clock before using it".

OK, so I'm still unclear as to what's going on here.  Arnd's mail where
I got copied into this subthread suggested that things were getting
merged by individual trees which is generally easiest?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12 11:21                     ` Mark Brown
@ 2021-10-12 11:26                       ` Alexander Sverdlin
  2021-10-12 11:30                         ` Geert Uytterhoeven
  0 siblings, 1 reply; 46+ messages in thread
From: Alexander Sverdlin @ 2021-10-12 11:26 UTC (permalink / raw)
  To: Mark Brown
  Cc: Arnd Bergmann, Russell King, Hartley Sweeten, Linus Walleij,
	Ard Biesheuvel, Andrew Morton, Krzysztof Kozlowski,
	Anshuman Khandual, Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin, Geert Uytterhoeven

Hello Mark,

On Tue, 2021-10-12 at 12:21 +0100, Mark Brown wrote:
>  Looks like Arnd is ready to pick it, and the only dependency which is
> > not yet merged into Linus's tree is "ASoC: cirrus: i2s: Prepare clock before using it".
> 
> OK, so I'm still unclear as to what's going on here.  Arnd's mail where
> I got copied into this subthread suggested that things were getting
> merged by individual trees which is generally easiest?

I only wanted to ask you to pick ASoC patch, I can resend it if you'd like.
It has no dependencies and all the previous patches were already picked
and are visible in the Linus's master.

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12 11:26                       ` Alexander Sverdlin
@ 2021-10-12 11:30                         ` Geert Uytterhoeven
  2021-10-12 12:39                           ` Arnd Bergmann
  2021-10-15 22:32                           ` Mark Brown
  0 siblings, 2 replies; 46+ messages in thread
From: Geert Uytterhoeven @ 2021-10-12 11:30 UTC (permalink / raw)
  To: Alexander Sverdlin
  Cc: Mark Brown, Arnd Bergmann, Russell King, Hartley Sweeten,
	Linus Walleij, Ard Biesheuvel, Andrew Morton,
	Krzysztof Kozlowski, Anshuman Khandual, Geert Uytterhoeven,
	YiFei Zhu, Mike Rapoport, Uwe Kleine-König,
	moderated list:ARM PORT, open list, Nikita Shubin

Hi Alexander,

On Tue, Oct 12, 2021 at 1:26 PM Alexander Sverdlin
<alexander.sverdlin@gmail.com> wrote:
> On Tue, 2021-10-12 at 12:21 +0100, Mark Brown wrote:
> >  Looks like Arnd is ready to pick it, and the only dependency which is
> > > not yet merged into Linus's tree is "ASoC: cirrus: i2s: Prepare clock before using it".
> >
> > OK, so I'm still unclear as to what's going on here.  Arnd's mail where
> > I got copied into this subthread suggested that things were getting
> > merged by individual trees which is generally easiest?
>
> I only wanted to ask you to pick ASoC patch, I can resend it if you'd like.
> It has no dependencies and all the previous patches were already picked
> and are visible in the Linus's master.

So it might be better for Arnd to pick up the ASoC patch, too.
Else he has to postpone the final CCF conversion patch one more cycle,
to avoid regressions.

Gr{oetje,eeting}s,

                        Geert

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

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

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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12 11:30                         ` Geert Uytterhoeven
@ 2021-10-12 12:39                           ` Arnd Bergmann
  2021-10-12 12:57                             ` Alexander Sverdlin
  2021-10-15 22:32                           ` Mark Brown
  1 sibling, 1 reply; 46+ messages in thread
From: Arnd Bergmann @ 2021-10-12 12:39 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Alexander Sverdlin, Mark Brown, Arnd Bergmann, Russell King,
	Hartley Sweeten, Linus Walleij, Ard Biesheuvel, Andrew Morton,
	Krzysztof Kozlowski, Anshuman Khandual, Geert Uytterhoeven,
	YiFei Zhu, Mike Rapoport, Uwe Kleine-König,
	moderated list:ARM PORT, open list, Nikita Shubin

On Tue, Oct 12, 2021 at 1:30 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Tue, Oct 12, 2021 at 1:26 PM Alexander Sverdlin <alexander.sverdlin@gmail.com> wrote:
> > On Tue, 2021-10-12 at 12:21 +0100, Mark Brown wrote:
> > >  Looks like Arnd is ready to pick it, and the only dependency which is
> > > > not yet merged into Linus's tree is "ASoC: cirrus: i2s: Prepare clock before using it".
> > >
> > > OK, so I'm still unclear as to what's going on here.  Arnd's mail where
> > > I got copied into this subthread suggested that things were getting
> > > merged by individual trees which is generally easiest?
> >
> > I only wanted to ask you to pick ASoC patch, I can resend it if you'd like.
> > It has no dependencies and all the previous patches were already picked
> > and are visible in the Linus's master.
>
> So it might be better for Arnd to pick up the ASoC patch, too.
> Else he has to postpone the final CCF conversion patch one more cycle,
> to avoid regressions.

Right, if everything else is in mainline, then having the last two patches
in the soc tree gets the job done the quickest.

If any of the other patches are only in linux-next but not in mainline yet,
then it seems best for Mark to take the ASoC/i2s patch for v5.16, and I'll
take the last one for v5.17, or maybe queue it separately from the rest
and send that in the second half of the 5.16 merge window after everything
else has landed.

       Arnd

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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12 12:39                           ` Arnd Bergmann
@ 2021-10-12 12:57                             ` Alexander Sverdlin
  0 siblings, 0 replies; 46+ messages in thread
From: Alexander Sverdlin @ 2021-10-12 12:57 UTC (permalink / raw)
  To: Arnd Bergmann, Geert Uytterhoeven
  Cc: Mark Brown, Russell King, Hartley Sweeten, Linus Walleij,
	Ard Biesheuvel, Andrew Morton, Krzysztof Kozlowski,
	Anshuman Khandual, Geert Uytterhoeven, YiFei Zhu, Mike Rapoport,
	Uwe Kleine-König, moderated list:ARM PORT, open list,
	Nikita Shubin

Hi Arnd,

On Tue, 2021-10-12 at 14:39 +0200, Arnd Bergmann wrote:
> Right, if everything else is in mainline, then having the last two patches
> in the soc tree gets the job done the quickest.
> 
> If any of the other patches are only in linux-next but not in mainline yet,
> then it seems best for Mark to take the ASoC/i2s patch for v5.16, and I'll
> take the last one for v5.17, or maybe queue it separately from the rest
> and send that in the second half of the 5.16 merge window after everything
> else has landed.

correct, everything else is in mainline, only these two left floating.
Should I resend them for soc patchwork?

-- 
Alexander Sverdlin.



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

* Re: [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK
  2021-10-12 11:30                         ` Geert Uytterhoeven
  2021-10-12 12:39                           ` Arnd Bergmann
@ 2021-10-15 22:32                           ` Mark Brown
  1 sibling, 0 replies; 46+ messages in thread
From: Mark Brown @ 2021-10-15 22:32 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Alexander Sverdlin, Arnd Bergmann, Russell King, Hartley Sweeten,
	Linus Walleij, Ard Biesheuvel, Andrew Morton,
	Krzysztof Kozlowski, Anshuman Khandual, Geert Uytterhoeven,
	YiFei Zhu, Mike Rapoport, Uwe Kleine-König,
	moderated list:ARM PORT, open list, Nikita Shubin

[-- Attachment #1: Type: text/plain, Size: 669 bytes --]

On Tue, Oct 12, 2021 at 01:30:19PM +0200, Geert Uytterhoeven wrote:
> On Tue, Oct 12, 2021 at 1:26 PM Alexander Sverdlin

> > I only wanted to ask you to pick ASoC patch, I can resend it if you'd like.
> > It has no dependencies and all the previous patches were already picked
> > and are visible in the Linus's master.

> So it might be better for Arnd to pick up the ASoC patch, too.
> Else he has to postpone the final CCF conversion patch one more cycle,
> to avoid regressions.

Yes, I think that makes sense and I already acked both patches so I
think if those plus the final conversion patch are good to go then the
best thing is to merge them all via arm-soc.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2021-10-15 22:32 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-26 11:50 [PATCH 0/8] arm: ep93xx: CCF conversion Nikita Shubin
2021-07-26 11:50 ` [PATCH 1/8] iio: ep93xx: Prepare clock before using it Nikita Shubin
2021-07-26 11:50 ` [PATCH 2/8] spi: spi-ep93xx: " Nikita Shubin
2021-07-26 12:01   ` Mark Brown
2021-07-26 11:50 ` [PATCH 3/8] Input: ep93xx_keypad: " Nikita Shubin
2021-07-26 11:50 ` [PATCH 4/8] video: ep93xx: " Nikita Shubin
2021-07-26 11:50 ` [PATCH 5/8] dmaengine: " Nikita Shubin
2021-07-26 11:50 ` [PATCH 6/8] ASoC: cirrus: i2s: " Nikita Shubin
2021-07-26 11:50 ` [PATCH 7/8] pwm: ep93xx: " Nikita Shubin
2021-07-26 11:50 ` [PATCH 8/8] ep93xx: clock: convert in-place to COMMON_CLK Nikita Shubin
2021-07-26 11:57   ` Alexander Sverdlin
2021-07-26 13:59 ` [PATCH v2 0/8] arm: ep93xx: CCF conversion Nikita Shubin
2021-07-26 13:59   ` [PATCH v2 1/8] iio: ep93xx: Prepare clock before using it Nikita Shubin
2021-07-26 13:59   ` [PATCH v2 2/8] spi: spi-ep93xx: " Nikita Shubin
2021-07-26 16:51     ` Mark Brown
2021-08-02  7:36       ` Alexander Sverdlin
2021-09-13 21:36       ` Alexander Sverdlin
2021-09-13 21:37         ` Alexander Sverdlin
2021-09-14 10:32         ` Mark Brown
2021-07-26 13:59   ` [PATCH v2 3/8] Input: ep93xx_keypad: " Nikita Shubin
2021-07-26 13:59   ` [PATCH v2 4/8] video: ep93xx: " Nikita Shubin
2021-07-26 13:59   ` [PATCH v2 5/8] dmaengine: " Nikita Shubin
2021-08-02  6:57     ` Vinod Koul
2021-07-26 13:59   ` [PATCH v2 6/8] ASoC: cirrus: i2s: " Nikita Shubin
2021-07-26 16:51     ` Mark Brown
2021-09-13 21:43       ` Alexander Sverdlin
2021-10-12  7:25         ` Alexander Sverdlin
2021-10-12 10:40           ` Mark Brown
2021-07-26 13:59   ` [PATCH v2 7/8] pwm: ep93xx: " Nikita Shubin
2021-07-26 13:59   ` [PATCH v2 8/8] ep93xx: clock: convert in-place to COMMON_CLK Nikita Shubin
2021-10-12  8:03     ` Alexander Sverdlin
2021-10-12  8:29       ` Arnd Bergmann
2021-10-12  8:37         ` Alexander Sverdlin
2021-10-12  9:05           ` Arnd Bergmann
2021-10-12 10:26             ` Mark Brown
2021-10-12 10:36               ` Alexander Sverdlin
2021-10-12 10:43                 ` Mark Brown
2021-10-12 11:03                   ` Alexander Sverdlin
2021-10-12 11:21                     ` Mark Brown
2021-10-12 11:26                       ` Alexander Sverdlin
2021-10-12 11:30                         ` Geert Uytterhoeven
2021-10-12 12:39                           ` Arnd Bergmann
2021-10-12 12:57                             ` Alexander Sverdlin
2021-10-15 22:32                           ` Mark Brown
2021-08-03 22:35   ` (subset) [PATCH v2 0/8] arm: ep93xx: CCF conversion Mark Brown
2021-07-31 22:04 ` [PATCH " Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).