OMAP2430 kernel hangs on call to omap2xxx_restart

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Good morning,

I have a legacy project that runs on an OMAP2430 and is based on the linux-omap repo (tag v2.6.28-omap1).  I am in the process of upgrading the project to mainline v5.10.  I have hit a problem with calling /sbin/reboot which eventually calls omap2xxx_restart which attempts to set a clock rate, but when it does is dereferences a null pointer because the clock was never registered successfully:

[   21.966247] 8<--- cut here ---
[   21.969360] Unable to handle kernel NULL pointer dereference at virtual address 00000016
[   21.977508] pgd = 61c95805
[   21.980255] [00000016] *pgd=81857831, *pte=00000000, *ppte=00000000
[   21.986633] Internal error: Oops: 17 [#1] PREEMPT ARM
[   21.991729] CPU: 0 PID: 904 Comm: linuxrc Not tainted 5.10.0-bsp-5.8.23 #3
[   21.998657] Hardware name: BKR-5000
[   22.002197] PC is at clk_set_rate+0x18/0x5c
[   22.006439] LR is at __mutex_trylock+0x50/0x7c
[   22.010925] pc : [<c02ae184>]    lr : [<c0145dec>]    psr: 60000093
[   22.017242] sp : c18c1e60  ip : 00000000  fp : 00000000
[   22.022521] r10: 00000000  r9 : c18c0000  r8 : 00000000
[   22.027770] r7 : c090c734  r6 : 4321fedc  r5 : fffffffe  r4 : 00000000
[   22.034362] r3 : 00000001  r2 : c19f1580  r1 : 00000000  r0 : 00000001
[   22.040924] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   22.048217] Control: 00c5387d  Table: 81860000  DAC: 00000051
[   22.054016] Process linuxrc (pid: 904, stack limit = 0x31ca9ab0)
[   22.060058] Stack: (0xc18c1e60 to 0xc18c2000)
[   22.064483] 1e60: c0113110 c098e308 c0903208 c011312c 01234567 c01075a4 c11285d9 01234567
[   22.072723] 1e80: c0903208 c0138af4 00000000 00000000 00000000 00000000 00000000 00000000
[   22.080993] 1ea0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   22.089233] 1ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   22.097473] 1ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   22.105743] 1f00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   22.113983] 1f20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   22.122253] 1f40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   22.130493] 1f60: 00000000 00000000 c18c1f94 c013be7c 00000000 00000000 00000000 00000000
[   22.138732] 1f80: 00000000 00000000 00000000 c11285d9 00000000 00000000 ffffffff 00000058
[   22.147003] 1fa0: c0100244 c0100060 00000000 00000000 fee1dead 28121969 01234567 00000000
[   22.155242] 1fc0: 00000000 00000000 ffffffff 00000058 00000071 00000000 b6ffd000 00000000
[   22.163513] 1fe0: 000bd14c befff990 000815e0 b6eb9c68 60000010 fee1dead 00000000 00000000
[   22.171813] [<c02ae184>] (clk_set_rate) from [<c011312c>] (omap2xxx_restart+0x1c/0x28)
[   22.179809] [<c011312c>] (omap2xxx_restart) from [<c01075a4>] (machine_restart+0x28/0x74)
[   22.188079] [<c01075a4>] (machine_restart) from [<c0138af4>] (__do_sys_reboot+0xdc/0x1cc)
[   22.196350] [<c0138af4>] (__do_sys_reboot) from [<c0100060>] (ret_fast_syscall+0x0/0x54)
[   22.204498] Exception stack(0xc18c1fa8 to 0xc18c1ff0)
[   22.209594] 1fa0:                   00000000 00000000 fee1dead 28121969 01234567 00000000
[   22.217834] 1fc0: 00000000 00000000 ffffffff 00000058 00000071 00000000 b6ffd000 00000000
[   22.226104] 1fe0: 000bd14c befff990 000815e0 b6eb9c68
[   22.231201] Code: e92d4038 e1a05000 e1a04001 ebfff649 (e5953018)
[   22.237365] ---[ end trace 6de58b88c9253e89 ]—

In arch/arm/mach-omap2/omap2-restart.c is the restart code:

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();
}

I have found that when the kernel is first started the “virt_prcm_set” clock is registered in arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c:

/**
 * omap2xxx_clkt_vps_init - initialize virt_prcm_set clock
 *
 * Does a manual init for the virtual prcm DVFS clock for OMAP2. This
 * function is called only from omap2 DT clock init, as the virtual
 * node is not modelled in the DT clock data.
 */
void omap2xxx_clkt_vps_init(void)
{
        struct clk_init_data init = { NULL };
        struct clk_hw_omap *hw = NULL;
        struct clk *clk;
        const char *parent_name = "mpu_ck";
        struct clk *reset_virt_prcm_set_ck;

        omap2xxx_clkt_vps_late_init();
        omap2xxx_clkt_vps_check_bootloader_rates();

        hw = kzalloc(sizeof(*hw), GFP_KERNEL);
        if (!hw)
                goto cleanup;
        init.name = "virt_prcm_set";
        init.ops = &virt_prcm_set_ops;
        init.parent_names = &parent_name;
        init.num_parents = 1;

        hw->hw.init = &init;

        clk = clk_register(NULL, &hw->hw);
        clkdev_create(clk, "cpufreq_ck", NULL);
        return;
cleanup:
        kfree(hw);
}

I added a call to get the “virt_prcm_set” clock and it came back null so the register does not seem to be working.  I thought this was a worthwhile problem to pose here in the event someone more familiar with this functionality knows the problem.

Regards,

Dave





[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux