diff mbox series

[v2] ARM: OMAP1: Prepare for conversion of OMAP1 clocks to CCF

Message ID 20220321215416.236250-1-jmkrzyszt@gmail.com
State New
Headers show
Series [v2] ARM: OMAP1: Prepare for conversion of OMAP1 clocks to CCF | expand

Commit Message

Janusz Krzysztofik March 21, 2022, 9:54 p.m. UTC
In preparation for conversion of OMAP1 clocks to common clock framework,
identify users of those clocks which don't call clk_prepare/unprepare()
and update them to call clk_prepare_enable/clk_disable_unprepare() instead
of just clk_enable/disable(), as required by CCF implementation of clock
API.

v2: update still a few more OMAP specific drivers missed in v1,
  - call clk_prepare/unprepare() just after/before clk_get/put() where it
    can make more sense than merging prepare/unprepare with enable/disable.

Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
---
 arch/arm/mach-omap1/mcbsp.c       |  8 ++++----
 arch/arm/mach-omap1/ocpi.c        |  4 ++--
 arch/arm/mach-omap1/serial.c      |  6 +++---
 arch/arm/mach-omap1/timer32k.c    |  2 +-
 drivers/mmc/host/omap.c           | 23 ++++++++++++++---------
 drivers/usb/gadget/udc/omap_udc.c | 14 ++++++++------
 drivers/usb/host/ohci-omap.c      | 18 ++++++++++++++++--
 drivers/video/fbdev/omap/hwa742.c |  6 +++---
 drivers/video/fbdev/omap/lcdc.c   |  6 +++---
 drivers/video/fbdev/omap/sossi.c  |  5 +++--
 sound/soc/ti/osk5912.c            |  9 ++++++++-
 11 files changed, 65 insertions(+), 36 deletions(-)

Comments

Mark Brown March 22, 2022, 12:02 p.m. UTC | #1
On Mon, Mar 21, 2022 at 10:54:16PM +0100, Janusz Krzysztofik wrote:
> In preparation for conversion of OMAP1 clocks to common clock framework,
> identify users of those clocks which don't call clk_prepare/unprepare()
> and update them to call clk_prepare_enable/clk_disable_unprepare() instead
> of just clk_enable/disable(), as required by CCF implementation of clock
> API.

Acked-by: Mark Brown <broonie@kernel.org>
Aaro Koskinen March 22, 2022, 4:36 p.m. UTC | #2
Hi,

On Mon, Mar 21, 2022 at 10:54:16PM +0100, Janusz Krzysztofik wrote:
> In preparation for conversion of OMAP1 clocks to common clock framework,
> identify users of those clocks which don't call clk_prepare/unprepare()
> and update them to call clk_prepare_enable/clk_disable_unprepare() instead
> of just clk_enable/disable(), as required by CCF implementation of clock
> API.
> 
> v2: update still a few more OMAP specific drivers missed in v1,
>   - call clk_prepare/unprepare() just after/before clk_get/put() where it
>     can make more sense than merging prepare/unprepare with enable/disable.

Something is still broken. When doing kexec (using CCF kernel), the
kexec'ed kernel now hangs early (on 770):

[    0.853912] MUX: initialized W4_USB_PUEN
[    0.858001] MUX: initialized V6_USB0_TXD
[    0.862060] MUX: initialized W5_USB0_SE0
[    0.866210] MUX: initialized Y5_USB0_RCV
[    0.870269] MUX: initialized AA9_USB0_VP
[    0.874389] MUX: initialized R9_USB0_VM
[    0.878356] USB: hmc 16, usb0 6 wires (dev), Mini-AB on usb0
[    0.886230] initcall customize_machine+0x0/0x30 returned 0 after 29296 usecs
[    0.893707] calling  init_atags_procfs+0x0/0xe8 @ 1
[    0.898864] initcall init_atags_procfs+0x0/0xe8 returned 0 after 0 usecs
[    0.905883] calling  exceptions_init+0x0/0x8c @ 1
[    0.910797] initcall exceptions_init+0x0/0x8c returned 0 after 0 usecs
[    0.917602] calling  omap_init+0x0/0xc @ 1
[    0.922393] initcall omap_init+0x0/0xc returned 0 after 9765 usecs
[    0.928863] calling  omap1_init_devices+0x0/0x2c @ 1
[    2.568664] random: fast init done

Probably something is now disabled that has been previously always
enabled by default/bootloader. I'll try adding some printk()s to see
the exact place where it hangs...

A.
Janusz Krzysztofik March 26, 2022, 9:17 p.m. UTC | #3
Hi Aaro,

Dnia wtorek, 22 marca 2022 20:07:53 CET Aaro Koskinen pisze:
> Hi,
> 
> On Tue, Mar 22, 2022 at 06:36:48PM +0200, Aaro Koskinen wrote:
> > On Mon, Mar 21, 2022 at 10:54:16PM +0100, Janusz Krzysztofik wrote:
> > > In preparation for conversion of OMAP1 clocks to common clock framework,
> > > identify users of those clocks which don't call clk_prepare/unprepare()
> > > and update them to call clk_prepare_enable/clk_disable_unprepare() instead
> > > of just clk_enable/disable(), as required by CCF implementation of clock
> > > API.
> > > 
> > > v2: update still a few more OMAP specific drivers missed in v1,
> > >   - call clk_prepare/unprepare() just after/before clk_get/put() where it
> > >     can make more sense than merging prepare/unprepare with enable/disable.
> > 
> > Something is still broken. When doing kexec (using CCF kernel), the
> > kexec'ed kernel now hangs early (on 770):
> [...]
> > [    0.928863] calling  omap1_init_devices+0x0/0x2c @ 1
> 
> It hangs in omap_sram_reprogram_clock() (<- omap1_select_table_rate()
> <- omap1_clk_late_init()).

I've reviewed my changes but haven't found anything suspicious.  Could you 
please provide:
- dmesg from both cold start and kexec, both non-CCF and CCF version, 
- contents of /sys/kernel/debug/clock/summary (non-CCF) after boot/kexec,
- contents of /sys/kernel/debug/clk/clk_summary (CCF) after boot?

Thanks,
Janusz

> 
> A.
>
Ulf Hansson March 31, 2022, 9:19 a.m. UTC | #4
On Mon, 21 Mar 2022 at 22:54, Janusz Krzysztofik <jmkrzyszt@gmail.com> wrote:
>
> In preparation for conversion of OMAP1 clocks to common clock framework,
> identify users of those clocks which don't call clk_prepare/unprepare()
> and update them to call clk_prepare_enable/clk_disable_unprepare() instead
> of just clk_enable/disable(), as required by CCF implementation of clock
> API.
>
> v2: update still a few more OMAP specific drivers missed in v1,
>   - call clk_prepare/unprepare() just after/before clk_get/put() where it
>     can make more sense than merging prepare/unprepare with enable/disable.
>
> Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>

Is there a specific reason why you can't split this into a per subsystem patch?

Don't get me wrong, if you need my ack you have it, but I just wanted
to know why this is?

Kind regards
Uffe

> ---
>  arch/arm/mach-omap1/mcbsp.c       |  8 ++++----
>  arch/arm/mach-omap1/ocpi.c        |  4 ++--
>  arch/arm/mach-omap1/serial.c      |  6 +++---
>  arch/arm/mach-omap1/timer32k.c    |  2 +-
>  drivers/mmc/host/omap.c           | 23 ++++++++++++++---------
>  drivers/usb/gadget/udc/omap_udc.c | 14 ++++++++------
>  drivers/usb/host/ohci-omap.c      | 18 ++++++++++++++++--
>  drivers/video/fbdev/omap/hwa742.c |  6 +++---
>  drivers/video/fbdev/omap/lcdc.c   |  6 +++---
>  drivers/video/fbdev/omap/sossi.c  |  5 +++--
>  sound/soc/ti/osk5912.c            |  9 ++++++++-
>  11 files changed, 65 insertions(+), 36 deletions(-)
>
> diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
> index f36c34f47f11..3ec2badff6af 100644
> --- a/arch/arm/mach-omap1/mcbsp.c
> +++ b/arch/arm/mach-omap1/mcbsp.c
> @@ -44,8 +44,8 @@ static void omap1_mcbsp_request(unsigned int id)
>                         api_clk = clk_get(NULL, "api_ck");
>                         dsp_clk = clk_get(NULL, "dsp_ck");
>                         if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
> -                               clk_enable(api_clk);
> -                               clk_enable(dsp_clk);
> +                               clk_prepare_enable(api_clk);
> +                               clk_prepare_enable(dsp_clk);
>
>                                 /*
>                                  * DSP external peripheral reset
> @@ -63,11 +63,11 @@ static void omap1_mcbsp_free(unsigned int id)
>         if (id == 0 || id == 2) {
>                 if (--dsp_use == 0) {
>                         if (!IS_ERR(api_clk)) {
> -                               clk_disable(api_clk);
> +                               clk_disable_unprepare(api_clk);
>                                 clk_put(api_clk);
>                         }
>                         if (!IS_ERR(dsp_clk)) {
> -                               clk_disable(dsp_clk);
> +                               clk_disable_unprepare(dsp_clk);
>                                 clk_put(dsp_clk);
>                         }
>                 }
> diff --git a/arch/arm/mach-omap1/ocpi.c b/arch/arm/mach-omap1/ocpi.c
> index 380ea2de58c1..03cc48024fd6 100644
> --- a/arch/arm/mach-omap1/ocpi.c
> +++ b/arch/arm/mach-omap1/ocpi.c
> @@ -73,7 +73,7 @@ static int __init omap_ocpi_init(void)
>         if (IS_ERR(ocpi_ck))
>                 return PTR_ERR(ocpi_ck);
>
> -       clk_enable(ocpi_ck);
> +       clk_prepare_enable(ocpi_ck);
>         ocpi_enable();
>         pr_info("OMAP OCPI interconnect driver loaded\n");
>
> @@ -87,7 +87,7 @@ static void __exit omap_ocpi_exit(void)
>         if (!cpu_is_omap16xx())
>                 return;
>
> -       clk_disable(ocpi_ck);
> +       clk_disable_unprepare(ocpi_ck);
>         clk_put(ocpi_ck);
>  }
>
> diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
> index 9eb591fbfd89..5f591a836ab5 100644
> --- a/arch/arm/mach-omap1/serial.c
> +++ b/arch/arm/mach-omap1/serial.c
> @@ -141,7 +141,7 @@ void __init omap_serial_init(void)
>                         if (IS_ERR(uart1_ck))
>                                 printk("Could not get uart1_ck\n");
>                         else {
> -                               clk_enable(uart1_ck);
> +                               clk_prepare_enable(uart1_ck);
>                                 if (cpu_is_omap15xx())
>                                         clk_set_rate(uart1_ck, 12000000);
>                         }
> @@ -151,7 +151,7 @@ void __init omap_serial_init(void)
>                         if (IS_ERR(uart2_ck))
>                                 printk("Could not get uart2_ck\n");
>                         else {
> -                               clk_enable(uart2_ck);
> +                               clk_prepare_enable(uart2_ck);
>                                 if (cpu_is_omap15xx())
>                                         clk_set_rate(uart2_ck, 12000000);
>                                 else
> @@ -163,7 +163,7 @@ void __init omap_serial_init(void)
>                         if (IS_ERR(uart3_ck))
>                                 printk("Could not get uart3_ck\n");
>                         else {
> -                               clk_enable(uart3_ck);
> +                               clk_prepare_enable(uart3_ck);
>                                 if (cpu_is_omap15xx())
>                                         clk_set_rate(uart3_ck, 12000000);
>                         }
> diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
> index 780fdf03c3ce..049c7b7f28c4 100644
> --- a/arch/arm/mach-omap1/timer32k.c
> +++ b/arch/arm/mach-omap1/timer32k.c
> @@ -180,7 +180,7 @@ int __init omap_32k_timer_init(void)
>
>                 sync32k_ick = clk_get(NULL, "omap_32ksync_ick");
>                 if (!IS_ERR(sync32k_ick))
> -                       clk_enable(sync32k_ick);
> +                       clk_prepare_enable(sync32k_ick);
>
>                 ret = omap_init_clocksource_32k(base);
>         }
> diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
> index 5e5af34090f1..57d39283924d 100644
> --- a/drivers/mmc/host/omap.c
> +++ b/drivers/mmc/host/omap.c
> @@ -1374,7 +1374,7 @@ static int mmc_omap_probe(struct platform_device *pdev)
>         host->iclk = clk_get(&pdev->dev, "ick");
>         if (IS_ERR(host->iclk))
>                 return PTR_ERR(host->iclk);
> -       clk_enable(host->iclk);
> +       clk_prepare_enable(host->iclk);
>
>         host->fclk = clk_get(&pdev->dev, "fck");
>         if (IS_ERR(host->fclk)) {
> @@ -1382,16 +1382,18 @@ static int mmc_omap_probe(struct platform_device *pdev)
>                 goto err_free_iclk;
>         }
>
> +       ret = clk_prepare(host->fclk);
> +       if (ret)
> +               goto err_put_fclk;
> +
>         host->dma_tx_burst = -1;
>         host->dma_rx_burst = -1;
>
>         host->dma_tx = dma_request_chan(&pdev->dev, "tx");
>         if (IS_ERR(host->dma_tx)) {
>                 ret = PTR_ERR(host->dma_tx);
> -               if (ret == -EPROBE_DEFER) {
> -                       clk_put(host->fclk);
> -                       goto err_free_iclk;
> -               }
> +               if (ret == -EPROBE_DEFER)
> +                       goto err_free_fclk;
>
>                 host->dma_tx = NULL;
>                 dev_warn(host->dev, "TX DMA channel request failed\n");
> @@ -1403,8 +1405,7 @@ static int mmc_omap_probe(struct platform_device *pdev)
>                 if (ret == -EPROBE_DEFER) {
>                         if (host->dma_tx)
>                                 dma_release_channel(host->dma_tx);
> -                       clk_put(host->fclk);
> -                       goto err_free_iclk;
> +                       goto err_free_fclk;
>                 }
>
>                 host->dma_rx = NULL;
> @@ -1454,9 +1455,12 @@ static int mmc_omap_probe(struct platform_device *pdev)
>                 dma_release_channel(host->dma_tx);
>         if (host->dma_rx)
>                 dma_release_channel(host->dma_rx);
> +err_free_fclk:
> +       clk_unprepare(host->fclk);
> +err_put_fclk:
>         clk_put(host->fclk);
>  err_free_iclk:
> -       clk_disable(host->iclk);
> +       clk_disable_unprepare(host->iclk);
>         clk_put(host->iclk);
>         return ret;
>  }
> @@ -1476,8 +1480,9 @@ static int mmc_omap_remove(struct platform_device *pdev)
>
>         mmc_omap_fclk_enable(host, 0);
>         free_irq(host->irq, host);
> +       clk_unprepare(host->fclk);
>         clk_put(host->fclk);
> -       clk_disable(host->iclk);
> +       clk_disable_unprepare(host->iclk);
>         clk_put(host->iclk);
>
>         if (host->dma_tx)
> diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c
> index 494da00398d7..8768a3280e19 100644
> --- a/drivers/usb/gadget/udc/omap_udc.c
> +++ b/drivers/usb/gadget/udc/omap_udc.c
> @@ -2604,6 +2604,8 @@ static void omap_udc_release(struct device *dev)
>         if (udc->dc_clk) {
>                 if (udc->clk_requested)
>                         omap_udc_enable_clock(0);
> +               clk_unprepare(udc->hhc_clk);
> +               clk_unprepare(udc->dc_clk);
>                 clk_put(udc->hhc_clk);
>                 clk_put(udc->dc_clk);
>         }
> @@ -2768,8 +2770,8 @@ static int omap_udc_probe(struct platform_device *pdev)
>                 hhc_clk = clk_get(&pdev->dev, "usb_hhc_ck");
>                 BUG_ON(IS_ERR(dc_clk) || IS_ERR(hhc_clk));
>                 /* can't use omap_udc_enable_clock yet */
> -               clk_enable(dc_clk);
> -               clk_enable(hhc_clk);
> +               clk_prepare_enable(dc_clk);
> +               clk_prepare_enable(hhc_clk);
>                 udelay(100);
>         }
>
> @@ -2778,8 +2780,8 @@ static int omap_udc_probe(struct platform_device *pdev)
>                 hhc_clk = clk_get(&pdev->dev, "l3_ocpi_ck");
>                 BUG_ON(IS_ERR(dc_clk) || IS_ERR(hhc_clk));
>                 /* can't use omap_udc_enable_clock yet */
> -               clk_enable(dc_clk);
> -               clk_enable(hhc_clk);
> +               clk_prepare_enable(dc_clk);
> +               clk_prepare_enable(hhc_clk);
>                 udelay(100);
>         }
>
> @@ -2927,8 +2929,8 @@ static int omap_udc_probe(struct platform_device *pdev)
>                 usb_put_phy(xceiv);
>
>         if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
> -               clk_disable(hhc_clk);
> -               clk_disable(dc_clk);
> +               clk_disable_unprepare(hhc_clk);
> +               clk_disable_unprepare(dc_clk);
>                 clk_put(hhc_clk);
>                 clk_put(dc_clk);
>         }
> diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
> index 45dcf8292072..2ab2e089a2b7 100644
> --- a/drivers/usb/host/ohci-omap.c
> +++ b/drivers/usb/host/ohci-omap.c
> @@ -281,6 +281,10 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev)
>                 goto err_put_hcd;
>         }
>
> +       retval = clk_prepare(priv->usb_host_ck);
> +       if (retval)
> +               goto err_put_host_ck;
> +
>         if (!cpu_is_omap15xx())
>                 priv->usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck");
>         else
> @@ -288,13 +292,17 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev)
>
>         if (IS_ERR(priv->usb_dc_ck)) {
>                 retval = PTR_ERR(priv->usb_dc_ck);
> -               goto err_put_host_ck;
> +               goto err_unprepare_host_ck;
>         }
>
> +       retval = clk_prepare(priv->usb_dc_ck);
> +       if (retval)
> +               goto err_put_dc_ck;
> +
>         if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
>                 dev_dbg(&pdev->dev, "request_mem_region failed\n");
>                 retval = -EBUSY;
> -               goto err_put_dc_ck;
> +               goto err_unprepare_dc_ck;
>         }
>
>         hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
> @@ -319,8 +327,12 @@ static int ohci_hcd_omap_probe(struct platform_device *pdev)
>         iounmap(hcd->regs);
>  err2:
>         release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
> +err_unprepare_dc_ck:
> +       clk_unprepare(priv->usb_dc_ck);
>  err_put_dc_ck:
>         clk_put(priv->usb_dc_ck);
> +err_unprepare_host_ck:
> +       clk_unprepare(priv->usb_host_ck);
>  err_put_host_ck:
>         clk_put(priv->usb_host_ck);
>  err_put_hcd:
> @@ -355,7 +367,9 @@ static int ohci_hcd_omap_remove(struct platform_device *pdev)
>         }
>         iounmap(hcd->regs);
>         release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
> +       clk_unprepare(priv->usb_dc_ck);
>         clk_put(priv->usb_dc_ck);
> +       clk_unprepare(priv->usb_host_ck);
>         clk_put(priv->usb_host_ck);
>         usb_put_hcd(hcd);
>         return 0;
> diff --git a/drivers/video/fbdev/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c
> index b191bef22d98..9d9fe5c3a7a1 100644
> --- a/drivers/video/fbdev/omap/hwa742.c
> +++ b/drivers/video/fbdev/omap/hwa742.c
> @@ -964,7 +964,7 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
>         if ((r = calc_extif_timings(ext_clk, &extif_mem_div)) < 0)
>                 goto err3;
>         hwa742.extif->set_timings(&hwa742.reg_timings);
> -       clk_enable(hwa742.sys_ck);
> +       clk_prepare_enable(hwa742.sys_ck);
>
>         calc_hwa742_clk_rates(ext_clk, &sys_clk, &pix_clk);
>         if ((r = calc_extif_timings(sys_clk, &extif_mem_div)) < 0)
> @@ -1023,7 +1023,7 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
>
>         return 0;
>  err4:
> -       clk_disable(hwa742.sys_ck);
> +       clk_disable_unprepare(hwa742.sys_ck);
>  err3:
>         hwa742.extif->cleanup();
>  err2:
> @@ -1037,7 +1037,7 @@ static void hwa742_cleanup(void)
>         hwa742_set_update_mode(OMAPFB_UPDATE_DISABLED);
>         hwa742.extif->cleanup();
>         hwa742.int_ctrl->cleanup();
> -       clk_disable(hwa742.sys_ck);
> +       clk_disable_unprepare(hwa742.sys_ck);
>  }
>
>  struct lcd_ctrl hwa742_ctrl = {
> diff --git a/drivers/video/fbdev/omap/lcdc.c b/drivers/video/fbdev/omap/lcdc.c
> index 7317c9aad677..97d20dc0d1d0 100644
> --- a/drivers/video/fbdev/omap/lcdc.c
> +++ b/drivers/video/fbdev/omap/lcdc.c
> @@ -711,7 +711,7 @@ static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode,
>                 dev_err(fbdev->dev, "failed to adjust LCD rate\n");
>                 goto fail1;
>         }
> -       clk_enable(lcdc.lcd_ck);
> +       clk_prepare_enable(lcdc.lcd_ck);
>
>         r = request_irq(OMAP_LCDC_IRQ, lcdc_irq_handler, 0, MODULE_NAME, fbdev);
>         if (r) {
> @@ -746,7 +746,7 @@ static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode,
>  fail3:
>         free_irq(OMAP_LCDC_IRQ, lcdc.fbdev);
>  fail2:
> -       clk_disable(lcdc.lcd_ck);
> +       clk_disable_unprepare(lcdc.lcd_ck);
>  fail1:
>         clk_put(lcdc.lcd_ck);
>  fail0:
> @@ -760,7 +760,7 @@ static void omap_lcdc_cleanup(void)
>         free_fbmem();
>         omap_free_lcd_dma();
>         free_irq(OMAP_LCDC_IRQ, lcdc.fbdev);
> -       clk_disable(lcdc.lcd_ck);
> +       clk_disable_unprepare(lcdc.lcd_ck);
>         clk_put(lcdc.lcd_ck);
>  }
>
> diff --git a/drivers/video/fbdev/omap/sossi.c b/drivers/video/fbdev/omap/sossi.c
> index 80ac67f27f0d..b9cb8b386627 100644
> --- a/drivers/video/fbdev/omap/sossi.c
> +++ b/drivers/video/fbdev/omap/sossi.c
> @@ -598,7 +598,7 @@ static int sossi_init(struct omapfb_device *fbdev)
>         l &= ~CONF_SOSSI_RESET_R;
>         omap_writel(l, MOD_CONF_CTRL_1);
>
> -       clk_enable(sossi.fck);
> +       clk_prepare_enable(sossi.fck);
>         l = omap_readl(ARM_IDLECT2);
>         l &= ~(1 << 8);                 /* DMACK_REQ */
>         omap_writel(l, ARM_IDLECT2);
> @@ -649,7 +649,7 @@ static int sossi_init(struct omapfb_device *fbdev)
>         return 0;
>
>  err:
> -       clk_disable(sossi.fck);
> +       clk_disable_unprepare(sossi.fck);
>         clk_put(sossi.fck);
>         return r;
>  }
> @@ -657,6 +657,7 @@ static int sossi_init(struct omapfb_device *fbdev)
>  static void sossi_cleanup(void)
>  {
>         omap_lcdc_free_dma_callback();
> +       clk_unprepare(sossi.fck);
>         clk_put(sossi.fck);
>         iounmap(sossi.base);
>  }
> diff --git a/sound/soc/ti/osk5912.c b/sound/soc/ti/osk5912.c
> index 40e29dda7e7a..22da3b335e81 100644
> --- a/sound/soc/ti/osk5912.c
> +++ b/sound/soc/ti/osk5912.c
> @@ -134,6 +134,10 @@ static int __init osk_soc_init(void)
>                 goto err2;
>         }
>
> +       err = clk_prepare(tlv320aic23_mclk);
> +       if (err)
> +               goto err3;
> +
>         /*
>          * Configure 12 MHz output on MCLK.
>          */
> @@ -142,7 +146,7 @@ static int __init osk_soc_init(void)
>                 if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) {
>                         printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
>                         err = -ECANCELED;
> -                       goto err3;
> +                       goto err4;
>                 }
>         }
>
> @@ -151,6 +155,8 @@ static int __init osk_soc_init(void)
>
>         return 0;
>
> +err4:
> +       clk_unprepare(tlv320aic23_mclk);
>  err3:
>         clk_put(tlv320aic23_mclk);
>  err2:
> @@ -164,6 +170,7 @@ static int __init osk_soc_init(void)
>
>  static void __exit osk_soc_exit(void)
>  {
> +       clk_unprepare(tlv320aic23_mclk);
>         clk_put(tlv320aic23_mclk);
>         platform_device_unregister(osk_snd_device);
>  }
> --
> 2.35.1
>
Janusz Krzysztofik April 6, 2022, 6:48 p.m. UTC | #5
Dnia środa, 6 kwietnia 2022 15:21:49 CEST Aaro Koskinen pisze:
> Hi,
> 
> On Sat, Mar 26, 2022 at 10:17:49PM +0100, Janusz Krzysztofik wrote:
> > Dnia wtorek, 22 marca 2022 20:07:53 CET Aaro Koskinen pisze:
> > > On Tue, Mar 22, 2022 at 06:36:48PM +0200, Aaro Koskinen wrote:
> > > > Something is still broken. When doing kexec (using CCF kernel), the
> > > > kexec'ed kernel now hangs early (on 770):
> > > [...]
> > > > [    0.928863] calling  omap1_init_devices+0x0/0x2c @ 1
> > > 
> > > It hangs in omap_sram_reprogram_clock() (<- omap1_select_table_rate()
> > > <- omap1_clk_late_init()).
> > 
> > I've reviewed my changes but haven't found anything suspicious.
> 
> The below change is fixing the kexec boot. Based on the comment in the
> code, it seems this clock is needed for the SRAM to work.
> 
> diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c
> index e33e11f826af..b8b4876ff935 100644
> --- a/arch/arm/mach-omap1/clock_data.c
> +++ b/arch/arm/mach-omap1/clock_data.c
> @@ -285,7 +285,7 @@ static struct omap1_clk tc1_ck = {
>   */
>  
>  static struct omap1_clk tc2_ck = {
> -	.hw.init	= CLK_HW_INIT("tc2_ck", "tc_ck", &omap1_clk_gate_ops, 0),
> +	.hw.init	= CLK_HW_INIT("tc2_ck", "tc_ck", &omap1_clk_gate_ops, CLK_IS_CRITICAL),
>  	.ops		= &clkops_generic,
>  	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
>  	.enable_bit	= EN_TC2_CK,
> 
> A.
> 

Thank you Aaro.  Will you submit this as a separate fix, or should I submit 
v2 of my patch 4/4 with your fix included?

Thanks,
Janusz
Aaro Koskinen April 6, 2022, 8 p.m. UTC | #6
Hi,

On Wed, Apr 06, 2022 at 08:48:14PM +0200, Janusz Krzysztofik wrote:
> Dnia środa, 6 kwietnia 2022 15:21:49 CEST Aaro Koskinen pisze:
> > On Sat, Mar 26, 2022 at 10:17:49PM +0100, Janusz Krzysztofik wrote:
> > > Dnia wtorek, 22 marca 2022 20:07:53 CET Aaro Koskinen pisze:
> > > > On Tue, Mar 22, 2022 at 06:36:48PM +0200, Aaro Koskinen wrote:
> > > > > Something is still broken. When doing kexec (using CCF kernel), the
> > > > > kexec'ed kernel now hangs early (on 770):
> > > > [...]
> > > > > [    0.928863] calling  omap1_init_devices+0x0/0x2c @ 1
> > > > 
> > > > It hangs in omap_sram_reprogram_clock() (<- omap1_select_table_rate()
> > > > <- omap1_clk_late_init()).
> > > 
> > > I've reviewed my changes but haven't found anything suspicious.
> > 
> > The below change is fixing the kexec boot. Based on the comment in the
> > code, it seems this clock is needed for the SRAM to work.
> > 
> > diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c
> > index e33e11f826af..b8b4876ff935 100644
> > --- a/arch/arm/mach-omap1/clock_data.c
> > +++ b/arch/arm/mach-omap1/clock_data.c
> > @@ -285,7 +285,7 @@ static struct omap1_clk tc1_ck = {
> >   */
> >  
> >  static struct omap1_clk tc2_ck = {
> > -	.hw.init	= CLK_HW_INIT("tc2_ck", "tc_ck", &omap1_clk_gate_ops, 0),
> > +	.hw.init	= CLK_HW_INIT("tc2_ck", "tc_ck", &omap1_clk_gate_ops, CLK_IS_CRITICAL),
> >  	.ops		= &clkops_generic,
> >  	.enable_reg	= OMAP1_IO_ADDRESS(ARM_IDLECT3),
> >  	.enable_bit	= EN_TC2_CK,
> > 
> > A.
> > 
> 
> Thank you Aaro.  Will you submit this as a separate fix, or should I submit 
> v2 of my patch 4/4 with your fix included?

Please send a new version with the fix included.

A.
diff mbox series

Patch

diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index f36c34f47f11..3ec2badff6af 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -44,8 +44,8 @@  static void omap1_mcbsp_request(unsigned int id)
 			api_clk = clk_get(NULL, "api_ck");
 			dsp_clk = clk_get(NULL, "dsp_ck");
 			if (!IS_ERR(api_clk) && !IS_ERR(dsp_clk)) {
-				clk_enable(api_clk);
-				clk_enable(dsp_clk);
+				clk_prepare_enable(api_clk);
+				clk_prepare_enable(dsp_clk);
 
 				/*
 				 * DSP external peripheral reset
@@ -63,11 +63,11 @@  static void omap1_mcbsp_free(unsigned int id)
 	if (id == 0 || id == 2) {
 		if (--dsp_use == 0) {
 			if (!IS_ERR(api_clk)) {
-				clk_disable(api_clk);
+				clk_disable_unprepare(api_clk);
 				clk_put(api_clk);
 			}
 			if (!IS_ERR(dsp_clk)) {
-				clk_disable(dsp_clk);
+				clk_disable_unprepare(dsp_clk);
 				clk_put(dsp_clk);
 			}
 		}
diff --git a/arch/arm/mach-omap1/ocpi.c b/arch/arm/mach-omap1/ocpi.c
index 380ea2de58c1..03cc48024fd6 100644
--- a/arch/arm/mach-omap1/ocpi.c
+++ b/arch/arm/mach-omap1/ocpi.c
@@ -73,7 +73,7 @@  static int __init omap_ocpi_init(void)
 	if (IS_ERR(ocpi_ck))
 		return PTR_ERR(ocpi_ck);
 
-	clk_enable(ocpi_ck);
+	clk_prepare_enable(ocpi_ck);
 	ocpi_enable();
 	pr_info("OMAP OCPI interconnect driver loaded\n");
 
@@ -87,7 +87,7 @@  static void __exit omap_ocpi_exit(void)
 	if (!cpu_is_omap16xx())
 		return;
 
-	clk_disable(ocpi_ck);
+	clk_disable_unprepare(ocpi_ck);
 	clk_put(ocpi_ck);
 }
 
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 9eb591fbfd89..5f591a836ab5 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -141,7 +141,7 @@  void __init omap_serial_init(void)
 			if (IS_ERR(uart1_ck))
 				printk("Could not get uart1_ck\n");
 			else {
-				clk_enable(uart1_ck);
+				clk_prepare_enable(uart1_ck);
 				if (cpu_is_omap15xx())
 					clk_set_rate(uart1_ck, 12000000);
 			}
@@ -151,7 +151,7 @@  void __init omap_serial_init(void)
 			if (IS_ERR(uart2_ck))
 				printk("Could not get uart2_ck\n");
 			else {
-				clk_enable(uart2_ck);
+				clk_prepare_enable(uart2_ck);
 				if (cpu_is_omap15xx())
 					clk_set_rate(uart2_ck, 12000000);
 				else
@@ -163,7 +163,7 @@  void __init omap_serial_init(void)
 			if (IS_ERR(uart3_ck))
 				printk("Could not get uart3_ck\n");
 			else {
-				clk_enable(uart3_ck);
+				clk_prepare_enable(uart3_ck);
 				if (cpu_is_omap15xx())
 					clk_set_rate(uart3_ck, 12000000);
 			}
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 780fdf03c3ce..049c7b7f28c4 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -180,7 +180,7 @@  int __init omap_32k_timer_init(void)
 
 		sync32k_ick = clk_get(NULL, "omap_32ksync_ick");
 		if (!IS_ERR(sync32k_ick))
-			clk_enable(sync32k_ick);
+			clk_prepare_enable(sync32k_ick);
 
 		ret = omap_init_clocksource_32k(base);
 	}
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 5e5af34090f1..57d39283924d 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -1374,7 +1374,7 @@  static int mmc_omap_probe(struct platform_device *pdev)
 	host->iclk = clk_get(&pdev->dev, "ick");
 	if (IS_ERR(host->iclk))
 		return PTR_ERR(host->iclk);
-	clk_enable(host->iclk);
+	clk_prepare_enable(host->iclk);
 
 	host->fclk = clk_get(&pdev->dev, "fck");
 	if (IS_ERR(host->fclk)) {
@@ -1382,16 +1382,18 @@  static int mmc_omap_probe(struct platform_device *pdev)
 		goto err_free_iclk;
 	}
 
+	ret = clk_prepare(host->fclk);
+	if (ret)
+		goto err_put_fclk;
+
 	host->dma_tx_burst = -1;
 	host->dma_rx_burst = -1;
 
 	host->dma_tx = dma_request_chan(&pdev->dev, "tx");
 	if (IS_ERR(host->dma_tx)) {
 		ret = PTR_ERR(host->dma_tx);
-		if (ret == -EPROBE_DEFER) {
-			clk_put(host->fclk);
-			goto err_free_iclk;
-		}
+		if (ret == -EPROBE_DEFER)
+			goto err_free_fclk;
 
 		host->dma_tx = NULL;
 		dev_warn(host->dev, "TX DMA channel request failed\n");
@@ -1403,8 +1405,7 @@  static int mmc_omap_probe(struct platform_device *pdev)
 		if (ret == -EPROBE_DEFER) {
 			if (host->dma_tx)
 				dma_release_channel(host->dma_tx);
-			clk_put(host->fclk);
-			goto err_free_iclk;
+			goto err_free_fclk;
 		}
 
 		host->dma_rx = NULL;
@@ -1454,9 +1455,12 @@  static int mmc_omap_probe(struct platform_device *pdev)
 		dma_release_channel(host->dma_tx);
 	if (host->dma_rx)
 		dma_release_channel(host->dma_rx);
+err_free_fclk:
+	clk_unprepare(host->fclk);
+err_put_fclk:
 	clk_put(host->fclk);
 err_free_iclk:
-	clk_disable(host->iclk);
+	clk_disable_unprepare(host->iclk);
 	clk_put(host->iclk);
 	return ret;
 }
@@ -1476,8 +1480,9 @@  static int mmc_omap_remove(struct platform_device *pdev)
 
 	mmc_omap_fclk_enable(host, 0);
 	free_irq(host->irq, host);
+	clk_unprepare(host->fclk);
 	clk_put(host->fclk);
-	clk_disable(host->iclk);
+	clk_disable_unprepare(host->iclk);
 	clk_put(host->iclk);
 
 	if (host->dma_tx)
diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c
index 494da00398d7..8768a3280e19 100644
--- a/drivers/usb/gadget/udc/omap_udc.c
+++ b/drivers/usb/gadget/udc/omap_udc.c
@@ -2604,6 +2604,8 @@  static void omap_udc_release(struct device *dev)
 	if (udc->dc_clk) {
 		if (udc->clk_requested)
 			omap_udc_enable_clock(0);
+		clk_unprepare(udc->hhc_clk);
+		clk_unprepare(udc->dc_clk);
 		clk_put(udc->hhc_clk);
 		clk_put(udc->dc_clk);
 	}
@@ -2768,8 +2770,8 @@  static int omap_udc_probe(struct platform_device *pdev)
 		hhc_clk = clk_get(&pdev->dev, "usb_hhc_ck");
 		BUG_ON(IS_ERR(dc_clk) || IS_ERR(hhc_clk));
 		/* can't use omap_udc_enable_clock yet */
-		clk_enable(dc_clk);
-		clk_enable(hhc_clk);
+		clk_prepare_enable(dc_clk);
+		clk_prepare_enable(hhc_clk);
 		udelay(100);
 	}
 
@@ -2778,8 +2780,8 @@  static int omap_udc_probe(struct platform_device *pdev)
 		hhc_clk = clk_get(&pdev->dev, "l3_ocpi_ck");
 		BUG_ON(IS_ERR(dc_clk) || IS_ERR(hhc_clk));
 		/* can't use omap_udc_enable_clock yet */
-		clk_enable(dc_clk);
-		clk_enable(hhc_clk);
+		clk_prepare_enable(dc_clk);
+		clk_prepare_enable(hhc_clk);
 		udelay(100);
 	}
 
@@ -2927,8 +2929,8 @@  static int omap_udc_probe(struct platform_device *pdev)
 		usb_put_phy(xceiv);
 
 	if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
-		clk_disable(hhc_clk);
-		clk_disable(dc_clk);
+		clk_disable_unprepare(hhc_clk);
+		clk_disable_unprepare(dc_clk);
 		clk_put(hhc_clk);
 		clk_put(dc_clk);
 	}
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 45dcf8292072..2ab2e089a2b7 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -281,6 +281,10 @@  static int ohci_hcd_omap_probe(struct platform_device *pdev)
 		goto err_put_hcd;
 	}
 
+	retval = clk_prepare(priv->usb_host_ck);
+	if (retval)
+		goto err_put_host_ck;
+
 	if (!cpu_is_omap15xx())
 		priv->usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck");
 	else
@@ -288,13 +292,17 @@  static int ohci_hcd_omap_probe(struct platform_device *pdev)
 
 	if (IS_ERR(priv->usb_dc_ck)) {
 		retval = PTR_ERR(priv->usb_dc_ck);
-		goto err_put_host_ck;
+		goto err_unprepare_host_ck;
 	}
 
+	retval = clk_prepare(priv->usb_dc_ck);
+	if (retval)
+		goto err_put_dc_ck;
+
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
 		dev_dbg(&pdev->dev, "request_mem_region failed\n");
 		retval = -EBUSY;
-		goto err_put_dc_ck;
+		goto err_unprepare_dc_ck;
 	}
 
 	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
@@ -319,8 +327,12 @@  static int ohci_hcd_omap_probe(struct platform_device *pdev)
 	iounmap(hcd->regs);
 err2:
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_unprepare_dc_ck:
+	clk_unprepare(priv->usb_dc_ck);
 err_put_dc_ck:
 	clk_put(priv->usb_dc_ck);
+err_unprepare_host_ck:
+	clk_unprepare(priv->usb_host_ck);
 err_put_host_ck:
 	clk_put(priv->usb_host_ck);
 err_put_hcd:
@@ -355,7 +367,9 @@  static int ohci_hcd_omap_remove(struct platform_device *pdev)
 	}
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	clk_unprepare(priv->usb_dc_ck);
 	clk_put(priv->usb_dc_ck);
+	clk_unprepare(priv->usb_host_ck);
 	clk_put(priv->usb_host_ck);
 	usb_put_hcd(hcd);
 	return 0;
diff --git a/drivers/video/fbdev/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c
index b191bef22d98..9d9fe5c3a7a1 100644
--- a/drivers/video/fbdev/omap/hwa742.c
+++ b/drivers/video/fbdev/omap/hwa742.c
@@ -964,7 +964,7 @@  static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
 	if ((r = calc_extif_timings(ext_clk, &extif_mem_div)) < 0)
 		goto err3;
 	hwa742.extif->set_timings(&hwa742.reg_timings);
-	clk_enable(hwa742.sys_ck);
+	clk_prepare_enable(hwa742.sys_ck);
 
 	calc_hwa742_clk_rates(ext_clk, &sys_clk, &pix_clk);
 	if ((r = calc_extif_timings(sys_clk, &extif_mem_div)) < 0)
@@ -1023,7 +1023,7 @@  static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
 
 	return 0;
 err4:
-	clk_disable(hwa742.sys_ck);
+	clk_disable_unprepare(hwa742.sys_ck);
 err3:
 	hwa742.extif->cleanup();
 err2:
@@ -1037,7 +1037,7 @@  static void hwa742_cleanup(void)
 	hwa742_set_update_mode(OMAPFB_UPDATE_DISABLED);
 	hwa742.extif->cleanup();
 	hwa742.int_ctrl->cleanup();
-	clk_disable(hwa742.sys_ck);
+	clk_disable_unprepare(hwa742.sys_ck);
 }
 
 struct lcd_ctrl hwa742_ctrl = {
diff --git a/drivers/video/fbdev/omap/lcdc.c b/drivers/video/fbdev/omap/lcdc.c
index 7317c9aad677..97d20dc0d1d0 100644
--- a/drivers/video/fbdev/omap/lcdc.c
+++ b/drivers/video/fbdev/omap/lcdc.c
@@ -711,7 +711,7 @@  static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode,
 		dev_err(fbdev->dev, "failed to adjust LCD rate\n");
 		goto fail1;
 	}
-	clk_enable(lcdc.lcd_ck);
+	clk_prepare_enable(lcdc.lcd_ck);
 
 	r = request_irq(OMAP_LCDC_IRQ, lcdc_irq_handler, 0, MODULE_NAME, fbdev);
 	if (r) {
@@ -746,7 +746,7 @@  static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode,
 fail3:
 	free_irq(OMAP_LCDC_IRQ, lcdc.fbdev);
 fail2:
-	clk_disable(lcdc.lcd_ck);
+	clk_disable_unprepare(lcdc.lcd_ck);
 fail1:
 	clk_put(lcdc.lcd_ck);
 fail0:
@@ -760,7 +760,7 @@  static void omap_lcdc_cleanup(void)
 	free_fbmem();
 	omap_free_lcd_dma();
 	free_irq(OMAP_LCDC_IRQ, lcdc.fbdev);
-	clk_disable(lcdc.lcd_ck);
+	clk_disable_unprepare(lcdc.lcd_ck);
 	clk_put(lcdc.lcd_ck);
 }
 
diff --git a/drivers/video/fbdev/omap/sossi.c b/drivers/video/fbdev/omap/sossi.c
index 80ac67f27f0d..b9cb8b386627 100644
--- a/drivers/video/fbdev/omap/sossi.c
+++ b/drivers/video/fbdev/omap/sossi.c
@@ -598,7 +598,7 @@  static int sossi_init(struct omapfb_device *fbdev)
 	l &= ~CONF_SOSSI_RESET_R;
 	omap_writel(l, MOD_CONF_CTRL_1);
 
-	clk_enable(sossi.fck);
+	clk_prepare_enable(sossi.fck);
 	l = omap_readl(ARM_IDLECT2);
 	l &= ~(1 << 8);			/* DMACK_REQ */
 	omap_writel(l, ARM_IDLECT2);
@@ -649,7 +649,7 @@  static int sossi_init(struct omapfb_device *fbdev)
 	return 0;
 
 err:
-	clk_disable(sossi.fck);
+	clk_disable_unprepare(sossi.fck);
 	clk_put(sossi.fck);
 	return r;
 }
@@ -657,6 +657,7 @@  static int sossi_init(struct omapfb_device *fbdev)
 static void sossi_cleanup(void)
 {
 	omap_lcdc_free_dma_callback();
+	clk_unprepare(sossi.fck);
 	clk_put(sossi.fck);
 	iounmap(sossi.base);
 }
diff --git a/sound/soc/ti/osk5912.c b/sound/soc/ti/osk5912.c
index 40e29dda7e7a..22da3b335e81 100644
--- a/sound/soc/ti/osk5912.c
+++ b/sound/soc/ti/osk5912.c
@@ -134,6 +134,10 @@  static int __init osk_soc_init(void)
 		goto err2;
 	}
 
+	err = clk_prepare(tlv320aic23_mclk);
+	if (err)
+		goto err3;
+
 	/*
 	 * Configure 12 MHz output on MCLK.
 	 */
@@ -142,7 +146,7 @@  static int __init osk_soc_init(void)
 		if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) {
 			printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
 			err = -ECANCELED;
-			goto err3;
+			goto err4;
 		}
 	}
 
@@ -151,6 +155,8 @@  static int __init osk_soc_init(void)
 
 	return 0;
 
+err4:
+	clk_unprepare(tlv320aic23_mclk);
 err3:
 	clk_put(tlv320aic23_mclk);
 err2:
@@ -164,6 +170,7 @@  static int __init osk_soc_init(void)
 
 static void __exit osk_soc_exit(void)
 {
+	clk_unprepare(tlv320aic23_mclk);
 	clk_put(tlv320aic23_mclk);
 	platform_device_unregister(osk_snd_device);
 }