linux/arch/arm/mach-omap2/omap2-restart.c
Tony Lindgren 8dd5ea72b0 ARM: OMAP2+: Change core_initcall levels to postcore_initcall
We want to be able to probe a few selected device drivers before hwmod
code populates the clocks in omap_hwmod_setup_all(). This allows us to
convert most of the clock drivers into regular device drivers.

We only need a few minimal clock drivers early for the system timers to
select between the 32KiHz clock and the high frequency oscillator.

With these changes, initializing the clock drivers can be just done at
core_initcall time with something like:

np = of_find_node_by_name(NULL, "plls");
if (np)
	of_platform_populate(np, NULL, NULL, NULL);

And then these clocks will be available for the interconnect code to use.

Having most of the clock drivers being regular device drivers allows
us to use the nice things like devm_* functions and dev_err and dev_dbg.
As an extra bonus, this also allows us to develop the clock drivers for
new SoCs as loadable modules initially for cases where we can boot up
the system based on the bootloader configured clocks.

To do this, let's change the core_initcalls to postcore_initcall under
mach-omap2.

Cc: Felipe Balbi <balbi@ti.com>
Cc: Grygorii Strashko <grygorii.strashko@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
2015-12-03 11:38:09 -08:00

66 lines
1.7 KiB
C

/*
* omap2-restart.c - code common to all OMAP2xxx machines.
*
* Copyright (C) 2012 Texas Instruments
* Paul Walmsley
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/io.h>
#include "soc.h"
#include "common.h"
#include "prm.h"
/*
* reset_virt_prcm_set_ck, reset_sys_ck: pointers to the virt_prcm_set
* clock and the sys_ck. Used during the reset process
*/
static struct clk *reset_virt_prcm_set_ck, *reset_sys_ck;
/* Reboot handling */
/**
* omap2xxx_restart - Set DPLL to bypass mode for reboot to work
*
* Set the DPLL to bypass so that reboot completes successfully. No
* return value.
*/
void omap2xxx_restart(enum reboot_mode mode, const char *cmd)
{
u32 rate;
rate = clk_get_rate(reset_sys_ck);
clk_set_rate(reset_virt_prcm_set_ck, rate);
/* XXX Should save the cmd argument for use after the reboot */
omap_prm_reset_system();
}
/**
* omap2xxx_common_look_up_clks_for_reset - look up clocks needed for restart
*
* Some clocks need to be looked up in advance for the SoC restart
* operation to work - see omap2xxx_restart(). Returns -EINVAL upon
* error or 0 upon success.
*/
static int __init omap2xxx_common_look_up_clks_for_reset(void)
{
reset_virt_prcm_set_ck = clk_get(NULL, "virt_prcm_set");
if (IS_ERR(reset_virt_prcm_set_ck))
return -EINVAL;
reset_sys_ck = clk_get(NULL, "sys_ck");
if (IS_ERR(reset_sys_ck))
return -EINVAL;
return 0;
}
omap_postcore_initcall(omap2xxx_common_look_up_clks_for_reset);