Dear Community,
I'm trying to shut down i.MX28 custom board using kernel 3.18.22.
Code added to arch/arm/mach-mxs/pm.c as follows:
#define REGS_POWER_BASE 0x80044000
#define POWER_RESET_UNLOCK_KEY (0x3e77 << 16)
#define MX28_HW_POWER_RESET 0x100
#define MX28_HW_POWER_RESET_SET 0x104
(...)
static void customMX28_pm_power_off(void)
{
writel(POWER_RESET_UNLOCK_KEY, REGS_POWER_BASE + MX28_HW_POWER_RESET_SET );
writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, REGS_POWER_BASE + MX28_HW_POWER_RESET_SET );
}
(...)
void __init mxs_pm_init(void)
{
pm_power_off = customMX28_pm_power_off;
suspend_set_ops(&mxs_suspend_ops);
}
When I tried to poweroff device, kernel Oops message appears:
Unable to handle kernel paging request at virtual address 80044104
What am I doing wrong?
Regards
Andrzej
Hi Andrzej
in general it should work, however had this register IO mapped smth like
#define MX6Q_IO_ADDRESS(x) | IOMEM(MX6Q_IO_P2V(x)) |
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Igor,
thanks for your hint. I've modified source code as below
#define IMX_IO_P2V(x) ( | \ | |
(((x) & 0x80000000) >> 7) | | \ | |
(0xf4000000 + | \ | |
(((x) & 0x50000000) >> 6) + | \ | |
(((x) & 0x0b000000) >> 4) + | \ | |
(((x) & 0x000fffff)))) |
#define IMX_IO_ADDRESS(x) IOMEM(IMX_IO_P2V(x))
#define REGS_POWER_BASE_PADDR 0x80044000
#define REGS_POWER_BASE_VADDR IMX_IO_ADDRESS(REGS_POWER_BASE_PADDR))
#define POWER_RESET_SET (REGS_POWER_BASE_VADDR + MX28_HW_POWER_RESET_SET)
and then I call
writel(POWER_RESET_UNLOCK_KEY, POWER_RESET_SET );
but unfortunately I've got very similar kernel oops as at begin, this time pointing to proper virtual address:
Unable to handle kernel paging request at virtual address f5044104
pgd = c7a38000
[f5044104] *pgd=00000000
Internal error: Oops - BUG: 805 [#1] PREEMPT ARM
Hi Andrzej,
better use the devicetree to get the virtual address:
np = of_find_compatible_node(NULL, NULL, "fsl,imx28-power");
of_address_to_resource(np, 0, &res);
paddr = ioremap(res.start, resource_size(&res));
Regards Stefan