From 342fd144292a6b64ea869e4052eb250486c8f326 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Wed, 24 Aug 2011 19:11:39 +0530 Subject: [PATCH 01/31] OMAP: Improve register access in L3 Error handler. * Changed the way of accessing L3 target registers from standard base rather than relative to STDERRLOG_MAIN. * Use ffs() to find error source from the L3_FLAGMUX_REGERRn register. * Remove extra l3_base[] entry. * Modified L3 custom error message. Signed-off-by: Todd Poynor Signed-off-by: sricharan Signed-off-by: Santosh Shilimkar --- arch/arm/mach-omap2/omap_l3_noc.c | 43 ++++++++-------- arch/arm/mach-omap2/omap_l3_noc.h | 86 +++++++++++++++---------------- arch/arm/mach-omap2/omap_l3_smx.c | 5 +- arch/arm/mach-omap2/omap_l3_smx.h | 2 +- 4 files changed, 65 insertions(+), 71 deletions(-) diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c index 7b9f1909ddb2..d560c8894e1f 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.c +++ b/arch/arm/mach-omap2/omap_l3_noc.c @@ -56,10 +56,9 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) { struct omap4_l3 *l3 = _l3; - int inttype, i, j; + int inttype, i; int err_src = 0; - u32 std_err_main_addr, std_err_main, err_reg; - u32 base, slave_addr, clear; + u32 std_err_main, err_reg, clear, base, l3_targ_base; char *source_name; /* Get the Type of interrupt */ @@ -71,42 +70,43 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) * to determine the source */ base = (u32)l3->l3_base[i]; - err_reg = readl(base + l3_flagmux[i] + (inttype << 3)); + err_reg = readl(base + l3_flagmux[i] + + + L3_FLAGMUX_REGERR0 + (inttype << 3)); /* Get the corresponding error and analyse */ if (err_reg) { /* Identify the source from control status register */ - for (j = 0; !(err_reg & (1 << j)); j++) - ; + err_src = __ffs(err_reg); - err_src = j; /* Read the stderrlog_main_source from clk domain */ - std_err_main_addr = base + *(l3_targ[i] + err_src); - std_err_main = readl(std_err_main_addr); + l3_targ_base = base + *(l3_targ[i] + err_src); + std_err_main = readl(l3_targ_base + + L3_TARG_STDERRLOG_MAIN); switch (std_err_main & CUSTOM_ERROR) { case STANDARD_ERROR: source_name = - l3_targ_stderrlog_main_name[i][err_src]; - - slave_addr = std_err_main_addr + - L3_SLAVE_ADDRESS_OFFSET; + l3_targ_inst_name[i][err_src]; WARN(true, "L3 standard error: SOURCE:%s at address 0x%x\n", - source_name, readl(slave_addr)); + source_name, + readl(l3_targ_base + + L3_TARG_STDERRLOG_SLVOFSLSB)); /* clear the std error log*/ clear = std_err_main | CLEAR_STDERR_LOG; - writel(clear, std_err_main_addr); + writel(clear, l3_targ_base + + L3_TARG_STDERRLOG_MAIN); break; case CUSTOM_ERROR: source_name = - l3_targ_stderrlog_main_name[i][err_src]; + l3_targ_inst_name[i][err_src]; - WARN(true, "CUSTOM SRESP error with SOURCE:%s\n", - source_name); + WARN(true, "L3 custom error: SOURCE:%s\n", + source_name); /* clear the std error log*/ clear = std_err_main | CLEAR_STDERR_LOG; - writel(clear, std_err_main_addr); + writel(clear, l3_targ_base + + L3_TARG_STDERRLOG_MAIN); break; default: @@ -123,9 +123,8 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) static int __init omap4_l3_probe(struct platform_device *pdev) { static struct omap4_l3 *l3; - struct resource *res; - int ret; - int irq; + struct resource *res; + int ret, irq; l3 = kzalloc(sizeof(*l3), GFP_KERNEL); if (!l3) diff --git a/arch/arm/mach-omap2/omap_l3_noc.h b/arch/arm/mach-omap2/omap_l3_noc.h index 359b83348aed..22c0d57ee3d9 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.h +++ b/arch/arm/mach-omap2/omap_l3_noc.h @@ -23,63 +23,60 @@ #ifndef __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H #define __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H -/* - * L3 register offsets - */ #define L3_MODULES 3 #define CLEAR_STDERR_LOG (1 << 31) #define CUSTOM_ERROR 0x2 #define STANDARD_ERROR 0x0 #define INBAND_ERROR 0x0 -#define EMIF_KERRLOG_OFFSET 0x10 -#define L3_SLAVE_ADDRESS_OFFSET 0x14 -#define LOGICAL_ADDR_ERRORLOG 0x4 #define L3_APPLICATION_ERROR 0x0 #define L3_DEBUG_ERROR 0x1 +/* L3 TARG register offsets */ +#define L3_TARG_STDERRLOG_MAIN 0x48 +#define L3_TARG_STDERRLOG_SLVOFSLSB 0x5c +#define L3_FLAGMUX_REGERR0 0xc + u32 l3_flagmux[L3_MODULES] = { - 0x50C, - 0x100C, - 0X020C + 0x500, + 0x1000, + 0X0200 }; -/* - * L3 Target standard Error register offsets - */ -u32 l3_targ_stderrlog_main_clk1[] = { - 0x148, /* DMM1 */ - 0x248, /* DMM2 */ - 0x348, /* ABE */ - 0x448, /* L4CFG */ - 0x648 /* CLK2 PWR DISC */ +/* L3 Target standard Error register offsets */ +u32 l3_targ_inst_clk1[] = { + 0x100, /* DMM1 */ + 0x200, /* DMM2 */ + 0x300, /* ABE */ + 0x400, /* L4CFG */ + 0x600 /* CLK2 PWR DISC */ }; -u32 l3_targ_stderrlog_main_clk2[] = { - 0x548, /* CORTEX M3 */ - 0x348, /* DSS */ - 0x148, /* GPMC */ - 0x448, /* ISS */ - 0x748, /* IVAHD */ - 0xD48, /* missing in TRM corresponds to AES1*/ - 0x948, /* L4 PER0*/ - 0x248, /* OCMRAM */ - 0x148, /* missing in TRM corresponds to GPMC sERROR*/ - 0x648, /* SGX */ - 0x848, /* SL2 */ - 0x1648, /* C2C */ - 0x1148, /* missing in TRM corresponds PWR DISC CLK1*/ - 0xF48, /* missing in TRM corrsponds to SHA1*/ - 0xE48, /* missing in TRM corresponds to AES2*/ - 0xC48, /* L4 PER3 */ - 0xA48, /* L4 PER1*/ - 0xB48 /* L4 PER2*/ +u32 l3_targ_inst_clk2[] = { + 0x500, /* CORTEX M3 */ + 0x300, /* DSS */ + 0x100, /* GPMC */ + 0x400, /* ISS */ + 0x700, /* IVAHD */ + 0xD00, /* missing in TRM corresponds to AES1*/ + 0x900, /* L4 PER0*/ + 0x200, /* OCMRAM */ + 0x100, /* missing in TRM corresponds to GPMC sERROR*/ + 0x600, /* SGX */ + 0x800, /* SL2 */ + 0x1600, /* C2C */ + 0x1100, /* missing in TRM corresponds PWR DISC CLK1*/ + 0xF00, /* missing in TRM corrsponds to SHA1*/ + 0xE00, /* missing in TRM corresponds to AES2*/ + 0xC00, /* L4 PER3 */ + 0xA00, /* L4 PER1*/ + 0xB00 /* L4 PER2*/ }; -u32 l3_targ_stderrlog_main_clk3[] = { - 0x0148 /* EMUSS */ +u32 l3_targ_inst_clk3[] = { + 0x0100 /* EMUSS */ }; -char *l3_targ_stderrlog_main_name[L3_MODULES][18] = { +char *l3_targ_inst_name[L3_MODULES][18] = { { "DMM1", "DMM2", @@ -113,9 +110,9 @@ char *l3_targ_stderrlog_main_name[L3_MODULES][18] = { }; u32 *l3_targ[L3_MODULES] = { - l3_targ_stderrlog_main_clk1, - l3_targ_stderrlog_main_clk2, - l3_targ_stderrlog_main_clk3, + l3_targ_inst_clk1, + l3_targ_inst_clk2, + l3_targ_inst_clk3, }; struct omap4_l3 { @@ -123,10 +120,9 @@ struct omap4_l3 { struct clk *ick; /* memory base */ - void __iomem *l3_base[4]; + void __iomem *l3_base[L3_MODULES]; int debug_irq; int app_irq; }; - #endif diff --git a/arch/arm/mach-omap2/omap_l3_smx.c b/arch/arm/mach-omap2/omap_l3_smx.c index 873c0e33b512..fa07edf938b2 100644 --- a/arch/arm/mach-omap2/omap_l3_smx.c +++ b/arch/arm/mach-omap2/omap_l3_smx.c @@ -191,10 +191,9 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) } /* identify the error source */ - for (err_source = 0; !(status & (1 << err_source)); err_source++) - ; + err_source = __ffs(status); - base = l3->rt + *(omap3_l3_bases[int_type] + err_source); + base = l3->rt + omap3_l3_bases[int_type][err_source]; error = omap3_l3_readll(base, L3_ERROR_LOG); if (error) { error_addr = omap3_l3_readll(base, L3_ERROR_LOG_ADDR); diff --git a/arch/arm/mach-omap2/omap_l3_smx.h b/arch/arm/mach-omap2/omap_l3_smx.h index ba2ed9a850cc..185d77ad4b2e 100644 --- a/arch/arm/mach-omap2/omap_l3_smx.h +++ b/arch/arm/mach-omap2/omap_l3_smx.h @@ -40,7 +40,7 @@ #define L3_SI_CONTROL 0x020 #define L3_SI_FLAG_STATUS_0 0x510 -const u64 shift = 1; +static const u64 shift = 1; #define L3_STATUS_0_MPUIA_BRST (shift << 0) #define L3_STATUS_0_MPUIA_RSP (shift << 1) From c1df2dcc90dc6f5110726e9bdcd2353db989c29d Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Mon, 29 Aug 2011 17:42:23 +0530 Subject: [PATCH 02/31] OMAP: Fix a BUG in l3 error handler. With the current sequence of registering the irq and assigning it to the app_irq, debug_irq driver variables, there can be corner cases where the pending irq gets triggered immediately after registering, handler gets called resulting in a crash. So changed this sequence. Signed-off-by: sricharan Signed-off-by: Todd Poynor Signed-off-by: Santosh Shilimkar --- arch/arm/mach-omap2/omap_l3_noc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c index d560c8894e1f..cf237dd4dba5 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.c +++ b/arch/arm/mach-omap2/omap_l3_noc.c @@ -124,7 +124,7 @@ static int __init omap4_l3_probe(struct platform_device *pdev) { static struct omap4_l3 *l3; struct resource *res; - int ret, irq; + int ret; l3 = kzalloc(sizeof(*l3), GFP_KERNEL); if (!l3) @@ -176,8 +176,8 @@ static int __init omap4_l3_probe(struct platform_device *pdev) /* * Setup interrupt Handlers */ - irq = platform_get_irq(pdev, 0); - ret = request_irq(irq, + l3->debug_irq = platform_get_irq(pdev, 0); + ret = request_irq(l3->debug_irq, l3_interrupt_handler, IRQF_DISABLED, "l3-dbg-irq", l3); if (ret) { @@ -185,10 +185,9 @@ static int __init omap4_l3_probe(struct platform_device *pdev) OMAP44XX_IRQ_L3_DBG); goto err3; } - l3->debug_irq = irq; - irq = platform_get_irq(pdev, 1); - ret = request_irq(irq, + l3->app_irq = platform_get_irq(pdev, 1); + ret = request_irq(l3->app_irq, l3_interrupt_handler, IRQF_DISABLED, "l3-app-irq", l3); if (ret) { @@ -196,7 +195,6 @@ static int __init omap4_l3_probe(struct platform_device *pdev) OMAP44XX_IRQ_L3_APP); goto err4; } - l3->app_irq = irq; return 0; From ed0e352073ff86c876ff7820ad0b6bac123082b5 Mon Sep 17 00:00:00 2001 From: sricharan Date: Wed, 24 Aug 2011 20:07:45 +0530 Subject: [PATCH 03/31] OMAP: Fix indentation issues in l3 error handler. The indentation problems in the l3 noc and smx error handler files are fixed. Signed-off-by: sricharan Signed-off-by: Santosh Shilimkar Reported-by: Paul Walmsley --- arch/arm/mach-omap2/omap_l3_noc.c | 58 +++++------ arch/arm/mach-omap2/omap_l3_noc.h | 106 ++++++++++---------- arch/arm/mach-omap2/omap_l3_smx.c | 86 ++++++++-------- arch/arm/mach-omap2/omap_l3_smx.h | 156 +++++++++++++++--------------- 4 files changed, 202 insertions(+), 204 deletions(-) diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c index cf237dd4dba5..1f68e95c3e80 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.c +++ b/arch/arm/mach-omap2/omap_l3_noc.c @@ -1,25 +1,25 @@ /* - * OMAP4XXX L3 Interconnect error handling driver - * - * Copyright (C) 2011 Texas Corporation - * Santosh Shilimkar - * Sricharan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ + * OMAP4XXX L3 Interconnect error handling driver + * + * Copyright (C) 2011 Texas Corporation + * Santosh Shilimkar + * Sricharan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ #include #include #include @@ -55,7 +55,7 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) { - struct omap4_l3 *l3 = _l3; + struct omap4_l3 *l3 = _l3; int inttype, i; int err_src = 0; u32 std_err_main, err_reg, clear, base, l3_targ_base; @@ -122,7 +122,7 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) static int __init omap4_l3_probe(struct platform_device *pdev) { - static struct omap4_l3 *l3; + static struct omap4_l3 *l3; struct resource *res; int ret; @@ -182,7 +182,7 @@ static int __init omap4_l3_probe(struct platform_device *pdev) IRQF_DISABLED, "l3-dbg-irq", l3); if (ret) { pr_crit("L3: request_irq failed to register for 0x%x\n", - OMAP44XX_IRQ_L3_DBG); + OMAP44XX_IRQ_L3_DBG); goto err3; } @@ -192,7 +192,7 @@ static int __init omap4_l3_probe(struct platform_device *pdev) IRQF_DISABLED, "l3-app-irq", l3); if (ret) { pr_crit("L3: request_irq failed to register for 0x%x\n", - OMAP44XX_IRQ_L3_APP); + OMAP44XX_IRQ_L3_APP); goto err4; } @@ -213,7 +213,7 @@ err0: static int __exit omap4_l3_remove(struct platform_device *pdev) { - struct omap4_l3 *l3 = platform_get_drvdata(pdev); + struct omap4_l3 *l3 = platform_get_drvdata(pdev); free_irq(l3->app_irq, l3); free_irq(l3->debug_irq, l3); @@ -226,9 +226,9 @@ static int __exit omap4_l3_remove(struct platform_device *pdev) } static struct platform_driver omap4_l3_driver = { - .remove = __exit_p(omap4_l3_remove), - .driver = { - .name = "omap_l3_noc", + .remove = __exit_p(omap4_l3_remove), + .driver = { + .name = "omap_l3_noc", }, }; diff --git a/arch/arm/mach-omap2/omap_l3_noc.h b/arch/arm/mach-omap2/omap_l3_noc.h index 22c0d57ee3d9..9120e70aa08a 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.h +++ b/arch/arm/mach-omap2/omap_l3_noc.h @@ -1,25 +1,25 @@ - /* - * OMAP4XXX L3 Interconnect error handling driver header - * - * Copyright (C) 2011 Texas Corporation - * Santosh Shilimkar - * sricharan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ +/* + * OMAP4XXX L3 Interconnect error handling driver header + * + * Copyright (C) 2011 Texas Corporation + * Santosh Shilimkar + * sricharan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ #ifndef __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H #define __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H @@ -32,9 +32,9 @@ #define L3_DEBUG_ERROR 0x1 /* L3 TARG register offsets */ -#define L3_TARG_STDERRLOG_MAIN 0x48 -#define L3_TARG_STDERRLOG_SLVOFSLSB 0x5c -#define L3_FLAGMUX_REGERR0 0xc +#define L3_TARG_STDERRLOG_MAIN 0x48 +#define L3_TARG_STDERRLOG_SLVOFSLSB 0x5c +#define L3_FLAGMUX_REGERR0 0xc u32 l3_flagmux[L3_MODULES] = { 0x500, @@ -78,34 +78,34 @@ u32 l3_targ_inst_clk3[] = { char *l3_targ_inst_name[L3_MODULES][18] = { { - "DMM1", - "DMM2", - "ABE", - "L4CFG", - "CLK2 PWR DISC", + "DMM1", + "DMM2", + "ABE", + "L4CFG", + "CLK2 PWR DISC", }, { - "CORTEX M3" , - "DSS ", - "GPMC ", - "ISS ", - "IVAHD ", - "AES1", - "L4 PER0", - "OCMRAM ", - "GPMC sERROR", - "SGX ", - "SL2 ", - "C2C ", - "PWR DISC CLK1", - "SHA1", - "AES2", - "L4 PER3", - "L4 PER1", - "L4 PER2", + "CORTEX M3" , + "DSS ", + "GPMC ", + "ISS ", + "IVAHD ", + "AES1", + "L4 PER0", + "OCMRAM ", + "GPMC sERROR", + "SGX ", + "SL2 ", + "C2C ", + "PWR DISC CLK1", + "SHA1", + "AES2", + "L4 PER3", + "L4 PER1", + "L4 PER2", }, { - "EMUSS", + "EMUSS", }, }; @@ -116,13 +116,13 @@ u32 *l3_targ[L3_MODULES] = { }; struct omap4_l3 { - struct device *dev; - struct clk *ick; + struct device *dev; + struct clk *ick; /* memory base */ void __iomem *l3_base[L3_MODULES]; - int debug_irq; - int app_irq; + int debug_irq; + int app_irq; }; #endif diff --git a/arch/arm/mach-omap2/omap_l3_smx.c b/arch/arm/mach-omap2/omap_l3_smx.c index fa07edf938b2..a05a62f9ee5b 100644 --- a/arch/arm/mach-omap2/omap_l3_smx.c +++ b/arch/arm/mach-omap2/omap_l3_smx.c @@ -1,26 +1,26 @@ - /* - * OMAP3XXX L3 Interconnect Driver - * - * Copyright (C) 2011 Texas Corporation - * Felipe Balbi - * Santosh Shilimkar - * Sricharan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ +/* + * OMAP3XXX L3 Interconnect Driver + * + * Copyright (C) 2011 Texas Corporation + * Felipe Balbi + * Santosh Shilimkar + * Sricharan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ #include #include @@ -135,7 +135,7 @@ static char *omap3_l3_initiator_string(u8 initid) } } -/** +/* * omap3_l3_block_irq - handles a register block's irq * @l3: struct omap3_l3 * * @base: register block base address @@ -150,30 +150,29 @@ static char *omap3_l3_initiator_string(u8 initid) static irqreturn_t omap3_l3_block_irq(struct omap3_l3 *l3, u64 error, int error_addr) { - u8 code = omap3_l3_decode_error_code(error); - u8 initid = omap3_l3_decode_initid(error); - u8 multi = error & L3_ERROR_LOG_MULTI; - u32 address = omap3_l3_decode_addr(error_addr); + u8 code = omap3_l3_decode_error_code(error); + u8 initid = omap3_l3_decode_initid(error); + u8 multi = error & L3_ERROR_LOG_MULTI; + u32 address = omap3_l3_decode_addr(error_addr); WARN(true, "%s seen by %s %s at address %x\n", - omap3_l3_code_string(code), - omap3_l3_initiator_string(initid), - multi ? "Multiple Errors" : "", - address); + omap3_l3_code_string(code), + omap3_l3_initiator_string(initid), + multi ? "Multiple Errors" : "", address); return IRQ_HANDLED; } static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) { - struct omap3_l3 *l3 = _l3; - u64 status, clear; - u64 error; - u64 error_addr; - u64 err_source = 0; - void __iomem *base; - int int_type; - irqreturn_t ret = IRQ_NONE; + struct omap3_l3 *l3 = _l3; + u64 status, clear; + u64 error; + u64 error_addr; + u64 err_source = 0; + void __iomem *base; + int int_type; + irqreturn_t ret = IRQ_NONE; int_type = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR; if (!int_type) { @@ -197,7 +196,6 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) error = omap3_l3_readll(base, L3_ERROR_LOG); if (error) { error_addr = omap3_l3_readll(base, L3_ERROR_LOG_ADDR); - ret |= omap3_l3_block_irq(l3, error, error_addr); } @@ -214,9 +212,9 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) static int __init omap3_l3_probe(struct platform_device *pdev) { - struct omap3_l3 *l3; - struct resource *res; - int ret; + struct omap3_l3 *l3; + struct resource *res; + int ret; l3 = kzalloc(sizeof(*l3), GFP_KERNEL); if (!l3) diff --git a/arch/arm/mach-omap2/omap_l3_smx.h b/arch/arm/mach-omap2/omap_l3_smx.h index 185d77ad4b2e..18e5ec2629ca 100644 --- a/arch/arm/mach-omap2/omap_l3_smx.h +++ b/arch/arm/mach-omap2/omap_l3_smx.h @@ -1,26 +1,26 @@ - /* - * OMAP3XXX L3 Interconnect Driver header - * - * Copyright (C) 2011 Texas Corporation - * Felipe Balbi - * Santosh Shilimkar - * sricharan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ +/* + * OMAP3XXX L3 Interconnect Driver header + * + * Copyright (C) 2011 Texas Corporation + * Felipe Balbi + * Santosh Shilimkar + * sricharan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ #ifndef __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H #define __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H @@ -78,32 +78,32 @@ static const u64 shift = 1; #define L3_STATUS_0_L4EMUTA_REQ (shift << 60) #define L3_STATUS_0_MAD2DTA_REQ (shift << 61) -#define L3_STATUS_0_TIMEOUT_MASK (L3_STATUS_0_MPUIA_BRST \ - | L3_STATUS_0_MPUIA_RSP \ - | L3_STATUS_0_IVAIA_BRST \ - | L3_STATUS_0_IVAIA_RSP \ - | L3_STATUS_0_SGXIA_BRST \ - | L3_STATUS_0_SGXIA_RSP \ - | L3_STATUS_0_CAMIA_BRST \ - | L3_STATUS_0_CAMIA_RSP \ - | L3_STATUS_0_DISPIA_BRST \ - | L3_STATUS_0_DISPIA_RSP \ - | L3_STATUS_0_DMARDIA_BRST \ - | L3_STATUS_0_DMARDIA_RSP \ - | L3_STATUS_0_DMAWRIA_BRST \ - | L3_STATUS_0_DMAWRIA_RSP \ - | L3_STATUS_0_USBOTGIA_BRST \ - | L3_STATUS_0_USBOTGIA_RSP \ - | L3_STATUS_0_USBHOSTIA_BRST \ - | L3_STATUS_0_SMSTA_REQ \ - | L3_STATUS_0_GPMCTA_REQ \ - | L3_STATUS_0_OCMRAMTA_REQ \ - | L3_STATUS_0_OCMROMTA_REQ \ - | L3_STATUS_0_IVATA_REQ \ - | L3_STATUS_0_SGXTA_REQ \ - | L3_STATUS_0_L4CORETA_REQ \ - | L3_STATUS_0_L4PERTA_REQ \ - | L3_STATUS_0_L4EMUTA_REQ \ +#define L3_STATUS_0_TIMEOUT_MASK (L3_STATUS_0_MPUIA_BRST \ + | L3_STATUS_0_MPUIA_RSP \ + | L3_STATUS_0_IVAIA_BRST \ + | L3_STATUS_0_IVAIA_RSP \ + | L3_STATUS_0_SGXIA_BRST \ + | L3_STATUS_0_SGXIA_RSP \ + | L3_STATUS_0_CAMIA_BRST \ + | L3_STATUS_0_CAMIA_RSP \ + | L3_STATUS_0_DISPIA_BRST \ + | L3_STATUS_0_DISPIA_RSP \ + | L3_STATUS_0_DMARDIA_BRST \ + | L3_STATUS_0_DMARDIA_RSP \ + | L3_STATUS_0_DMAWRIA_BRST \ + | L3_STATUS_0_DMAWRIA_RSP \ + | L3_STATUS_0_USBOTGIA_BRST \ + | L3_STATUS_0_USBOTGIA_RSP \ + | L3_STATUS_0_USBHOSTIA_BRST \ + | L3_STATUS_0_SMSTA_REQ \ + | L3_STATUS_0_GPMCTA_REQ \ + | L3_STATUS_0_OCMRAMTA_REQ \ + | L3_STATUS_0_OCMROMTA_REQ \ + | L3_STATUS_0_IVATA_REQ \ + | L3_STATUS_0_SGXTA_REQ \ + | L3_STATUS_0_L4CORETA_REQ \ + | L3_STATUS_0_L4PERTA_REQ \ + | L3_STATUS_0_L4EMUTA_REQ \ | L3_STATUS_0_MAD2DTA_REQ) #define L3_SI_FLAG_STATUS_1 0x530 @@ -137,19 +137,19 @@ static const u64 shift = 1; enum omap3_l3_initiator_id { /* LCD has 1 ID */ - OMAP_L3_LCD = 29, + OMAP_L3_LCD = 29, /* SAD2D has 1 ID */ - OMAP_L3_SAD2D = 28, + OMAP_L3_SAD2D = 28, /* MPU has 5 IDs */ - OMAP_L3_IA_MPU_SS_1 = 27, - OMAP_L3_IA_MPU_SS_2 = 26, - OMAP_L3_IA_MPU_SS_3 = 25, - OMAP_L3_IA_MPU_SS_4 = 24, - OMAP_L3_IA_MPU_SS_5 = 23, + OMAP_L3_IA_MPU_SS_1 = 27, + OMAP_L3_IA_MPU_SS_2 = 26, + OMAP_L3_IA_MPU_SS_3 = 25, + OMAP_L3_IA_MPU_SS_4 = 24, + OMAP_L3_IA_MPU_SS_5 = 23, /* IVA2.2 SS has 3 IDs*/ - OMAP_L3_IA_IVA_SS_1 = 22, - OMAP_L3_IA_IVA_SS_2 = 21, - OMAP_L3_IA_IVA_SS_3 = 20, + OMAP_L3_IA_IVA_SS_1 = 22, + OMAP_L3_IA_IVA_SS_2 = 21, + OMAP_L3_IA_IVA_SS_3 = 20, /* IVA 2.2 SS DMA has 6 IDS */ OMAP_L3_IA_IVA_SS_DMA_1 = 19, OMAP_L3_IA_IVA_SS_DMA_2 = 18, @@ -158,25 +158,25 @@ enum omap3_l3_initiator_id { OMAP_L3_IA_IVA_SS_DMA_5 = 15, OMAP_L3_IA_IVA_SS_DMA_6 = 14, /* SGX has 1 ID */ - OMAP_L3_IA_SGX = 13, + OMAP_L3_IA_SGX = 13, /* CAM has 3 ID */ - OMAP_L3_IA_CAM_1 = 12, - OMAP_L3_IA_CAM_2 = 11, - OMAP_L3_IA_CAM_3 = 10, + OMAP_L3_IA_CAM_1 = 12, + OMAP_L3_IA_CAM_2 = 11, + OMAP_L3_IA_CAM_3 = 10, /* DAP has 1 ID */ - OMAP_L3_IA_DAP = 9, + OMAP_L3_IA_DAP = 9, /* SDMA WR has 2 IDs */ - OMAP_L3_SDMA_WR_1 = 8, - OMAP_L3_SDMA_WR_2 = 7, + OMAP_L3_SDMA_WR_1 = 8, + OMAP_L3_SDMA_WR_2 = 7, /* SDMA RD has 4 IDs */ - OMAP_L3_SDMA_RD_1 = 6, - OMAP_L3_SDMA_RD_2 = 5, - OMAP_L3_SDMA_RD_3 = 4, - OMAP_L3_SDMA_RD_4 = 3, + OMAP_L3_SDMA_RD_1 = 6, + OMAP_L3_SDMA_RD_2 = 5, + OMAP_L3_SDMA_RD_3 = 4, + OMAP_L3_SDMA_RD_4 = 3, /* HSUSB OTG has 1 ID */ - OMAP_L3_USBOTG = 2, + OMAP_L3_USBOTG = 2, /* HSUSB HOST has 1 ID */ - OMAP_L3_USBHOST = 1, + OMAP_L3_USBHOST = 1, }; enum omap3_l3_code { @@ -192,17 +192,17 @@ enum omap3_l3_code { }; struct omap3_l3 { - struct device *dev; - struct clk *ick; + struct device *dev; + struct clk *ick; /* memory base*/ - void __iomem *rt; + void __iomem *rt; - int debug_irq; - int app_irq; + int debug_irq; + int app_irq; /* true when and inband functional error occurs */ - unsigned inband:1; + unsigned inband:1; }; /* offsets for l3 agents in order with the Flag status register */ From 6616aac66d798f3f185d90d9057e47abd7d3c9b3 Mon Sep 17 00:00:00 2001 From: sricharan Date: Tue, 23 Aug 2011 12:58:48 +0530 Subject: [PATCH 04/31] OMAP: Fix sparse warnings in l3 error handler. Fix below sparse warnings from the l3-noc and l3-smx error handlers files. arch/arm/mach-omap2/omap_l3_smx.h:209:22: warning: symbol 'omap3_l3_app_bases' was not declared. Should it be static? arch/arm/mach-omap2/omap_l3_smx.h:308:22: warning: symbol 'omap3_l3_debug_bases' was not declared. Should it be static? arch/arm/mach-omap2/omap_l3_smx.h:325:2: warning: incorrect type in initializer (different address spaces) arch/arm/mach-omap2/omap_l3_smx.h:325:2: expected unsigned int [usertype] * arch/arm/mach-omap2/omap_l3_smx.h:325:2: got unsigned int [noderef] [toplevel] * arch/arm/mach-omap2/omap_l3_smx.h:326:2: warning: incorrect type in initializer (different address spaces) arch/arm/mach-omap2/omap_l3_smx.h:326:2: expected unsigned int [usertype] * arch/arm/mach-omap2/omap_l3_smx.h:326:2: got unsigned int [noderef] [toplevel] * arch/arm/mach-omap2/omap_l3_smx.h:324:5: warning: symbol 'omap3_l3_bases' was not declared. Should it be static? CC arch/arm/mach-omap2/omap_l3_smx.o CHECK arch/arm/mach-omap2/omap_l3_noc.c arch/arm/mach-omap2/omap_l3_noc.c:73:13: warning: symbol '__v' shadows an earlier one arch/arm/mach-omap2/omap_l3_noc.c:73:13: originally declared here arch/arm/mach-omap2/omap_l3_noc.c:83:20: warning: symbol '__v' shadows an earlier one arch/arm/mach-omap2/omap_l3_noc.c:83:20: originally declared here arch/arm/mach-omap2/omap_l3_noc.c:90:5: warning: symbol '__v' shadows an earlier one arch/arm/mach-omap2/omap_l3_noc.c:90:5: originally declared here arch/arm/mach-omap2/omap_l3_noc.h:39:5: warning: symbol 'l3_flagmux' was not declared. Should it be static? arch/arm/mach-omap2/omap_l3_noc.h:46:5: warning: symbol 'l3_targ_inst_clk1' was not declared. Should it be static? arch/arm/mach-omap2/omap_l3_noc.h:54:5: warning: symbol 'l3_targ_inst_clk2' was not declared. Should it be static? arch/arm/mach-omap2/omap_l3_noc.h:75:5: warning: symbol 'l3_targ_inst_clk3' was not declared. Should it be static? arch/arm/mach-omap2/omap_l3_noc.h:79:6: warning: symbol 'l3_targ_inst_name' was not declared. Should it be static? arch/arm/mach-omap2/omap_l3_noc.h:112:5: warning: symbol 'l3_targ' was not declared. Should it be static? arch/arm/mach-omap2/omap_l3_noc.c:72:11: warning: cast removes address space of expression arch/arm/mach-omap2/omap_l3_noc.c:73:13: warning: incorrect type in argument 1 (different base types) arch/arm/mach-omap2/omap_l3_noc.c:73:13: expected void const volatile [noderef] * arch/arm/mach-omap2/omap_l3_noc.c:73:13: got unsigned int arch/arm/mach-omap2/omap_l3_noc.c:83:20: warning: incorrect type in argument 1 (different base types) arch/arm/mach-omap2/omap_l3_noc.c:83:20: expected void const volatile [noderef] * arch/arm/mach-omap2/omap_l3_noc.c:83:20: got unsigned int arch/arm/mach-omap2/omap_l3_noc.c:90:5: warning: incorrect type in argument 1 (different base types) arch/arm/mach-omap2/omap_l3_noc.c:90:5: expected void const volatile [noderef] * arch/arm/mach-omap2/omap_l3_noc.c:90:5: got unsigned int arch/arm/mach-omap2/omap_l3_noc.c:96:5: warning: incorrect type in argument 1 (different base types) arch/arm/mach-omap2/omap_l3_noc.c:96:5: expected void const volatile [noderef] * arch/arm/mach-omap2/omap_l3_noc.c:96:5: got unsigned int arch/arm/mach-omap2/omap_l3_noc.c:108:5: warning: incorrect type in argument 1 (different base types) arch/arm/mach-omap2/omap_l3_noc.c:108:5: expected void const volatile [noderef] * arch/arm/mach-omap2/omap_l3_noc.c:108:5: got unsigned int Signed-off-by: sricharan Signed-off-by: Santosh Shilimkar Reported-by: Paul Walmsley Reviewed-by: Paul Walmsley --- arch/arm/mach-omap2/omap_l3_noc.c | 11 ++++++----- arch/arm/mach-omap2/omap_l3_noc.h | 12 ++++++------ arch/arm/mach-omap2/omap_l3_smx.h | 6 +++--- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c index 1f68e95c3e80..8f1835711676 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.c +++ b/arch/arm/mach-omap2/omap_l3_noc.c @@ -58,7 +58,8 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) struct omap4_l3 *l3 = _l3; int inttype, i; int err_src = 0; - u32 std_err_main, err_reg, clear, base, l3_targ_base; + u32 std_err_main, err_reg, clear; + void __iomem *base, *l3_targ_base; char *source_name; /* Get the Type of interrupt */ @@ -69,8 +70,8 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) * Read the regerr register of the clock domain * to determine the source */ - base = (u32)l3->l3_base[i]; - err_reg = readl(base + l3_flagmux[i] + + base = l3->l3_base[i]; + err_reg = __raw_readl(base + l3_flagmux[i] + + L3_FLAGMUX_REGERR0 + (inttype << 3)); /* Get the corresponding error and analyse */ @@ -80,7 +81,7 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) /* Read the stderrlog_main_source from clk domain */ l3_targ_base = base + *(l3_targ[i] + err_src); - std_err_main = readl(l3_targ_base + + std_err_main = __raw_readl(l3_targ_base + L3_TARG_STDERRLOG_MAIN); switch (std_err_main & CUSTOM_ERROR) { @@ -89,7 +90,7 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) l3_targ_inst_name[i][err_src]; WARN(true, "L3 standard error: SOURCE:%s at address 0x%x\n", source_name, - readl(l3_targ_base + + __raw_readl(l3_targ_base + L3_TARG_STDERRLOG_SLVOFSLSB)); /* clear the std error log*/ clear = std_err_main | CLEAR_STDERR_LOG; diff --git a/arch/arm/mach-omap2/omap_l3_noc.h b/arch/arm/mach-omap2/omap_l3_noc.h index 9120e70aa08a..74c16434f2bc 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.h +++ b/arch/arm/mach-omap2/omap_l3_noc.h @@ -36,14 +36,14 @@ #define L3_TARG_STDERRLOG_SLVOFSLSB 0x5c #define L3_FLAGMUX_REGERR0 0xc -u32 l3_flagmux[L3_MODULES] = { +static u32 l3_flagmux[L3_MODULES] = { 0x500, 0x1000, 0X0200 }; /* L3 Target standard Error register offsets */ -u32 l3_targ_inst_clk1[] = { +static u32 l3_targ_inst_clk1[] = { 0x100, /* DMM1 */ 0x200, /* DMM2 */ 0x300, /* ABE */ @@ -51,7 +51,7 @@ u32 l3_targ_inst_clk1[] = { 0x600 /* CLK2 PWR DISC */ }; -u32 l3_targ_inst_clk2[] = { +static u32 l3_targ_inst_clk2[] = { 0x500, /* CORTEX M3 */ 0x300, /* DSS */ 0x100, /* GPMC */ @@ -72,11 +72,11 @@ u32 l3_targ_inst_clk2[] = { 0xB00 /* L4 PER2*/ }; -u32 l3_targ_inst_clk3[] = { +static u32 l3_targ_inst_clk3[] = { 0x0100 /* EMUSS */ }; -char *l3_targ_inst_name[L3_MODULES][18] = { +static char *l3_targ_inst_name[L3_MODULES][18] = { { "DMM1", "DMM2", @@ -109,7 +109,7 @@ char *l3_targ_inst_name[L3_MODULES][18] = { }, }; -u32 *l3_targ[L3_MODULES] = { +static u32 *l3_targ[L3_MODULES] = { l3_targ_inst_clk1, l3_targ_inst_clk2, l3_targ_inst_clk3, diff --git a/arch/arm/mach-omap2/omap_l3_smx.h b/arch/arm/mach-omap2/omap_l3_smx.h index 18e5ec2629ca..4f3cebca4179 100644 --- a/arch/arm/mach-omap2/omap_l3_smx.h +++ b/arch/arm/mach-omap2/omap_l3_smx.h @@ -206,7 +206,7 @@ struct omap3_l3 { }; /* offsets for l3 agents in order with the Flag status register */ -unsigned int __iomem omap3_l3_app_bases[] = { +static unsigned int omap3_l3_app_bases[] = { /* MPU IA */ 0x1400, 0x1400, @@ -305,7 +305,7 @@ unsigned int __iomem omap3_l3_app_bases[] = { 0, }; -unsigned int __iomem omap3_l3_debug_bases[] = { +static unsigned int omap3_l3_debug_bases[] = { /* MPU DATA IA */ 0x1400, /* RESERVED */ @@ -321,7 +321,7 @@ unsigned int __iomem omap3_l3_debug_bases[] = { /* REST RESERVED */ }; -u32 *omap3_l3_bases[] = { +static u32 *omap3_l3_bases[] = { omap3_l3_app_bases, omap3_l3_debug_bases, }; From 551a9fa9b1f01aa16f9007337b3cc12216c732fa Mon Sep 17 00:00:00 2001 From: sricharan Date: Wed, 7 Sep 2011 17:25:16 +0530 Subject: [PATCH 05/31] OMAP: Print Initiator name for l3 custom error. The initiator id gets logged in the l3 target registers for custom error. So print it to aid debugging. Based on a internal patch by Devaraj Rangasamy Signed-off-by: sricharan Signed-off-by: Santosh Shilimkar --- arch/arm/mach-omap2/omap_l3_noc.c | 26 ++++++++++++++--------- arch/arm/mach-omap2/omap_l3_noc.h | 34 +++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c index 8f1835711676..07a3d3ede768 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.c +++ b/arch/arm/mach-omap2/omap_l3_noc.c @@ -56,11 +56,11 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) { struct omap4_l3 *l3 = _l3; - int inttype, i; + int inttype, i, k; int err_src = 0; - u32 std_err_main, err_reg, clear; + u32 std_err_main, err_reg, clear, masterid; void __iomem *base, *l3_targ_base; - char *source_name; + char *target_name, *master_name = "UN IDENTIFIED"; /* Get the Type of interrupt */ inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR; @@ -83,13 +83,15 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) l3_targ_base = base + *(l3_targ[i] + err_src); std_err_main = __raw_readl(l3_targ_base + L3_TARG_STDERRLOG_MAIN); + masterid = __raw_readl(l3_targ_base + + L3_TARG_STDERRLOG_MSTADDR); switch (std_err_main & CUSTOM_ERROR) { case STANDARD_ERROR: - source_name = + target_name = l3_targ_inst_name[i][err_src]; - WARN(true, "L3 standard error: SOURCE:%s at address 0x%x\n", - source_name, + WARN(true, "L3 standard error: TARGET:%s at address 0x%x\n", + target_name, __raw_readl(l3_targ_base + L3_TARG_STDERRLOG_SLVOFSLSB)); /* clear the std error log*/ @@ -99,11 +101,15 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) break; case CUSTOM_ERROR: - source_name = + target_name = l3_targ_inst_name[i][err_src]; - - WARN(true, "L3 custom error: SOURCE:%s\n", - source_name); + for (k = 0; k < NUM_OF_L3_MASTERS; k++) { + if (masterid == l3_masters[k].id) + master_name = + l3_masters[k].name; + } + WARN(true, "L3 custom error: MASTER:%s TARGET:%s\n", + master_name, target_name); /* clear the std error log*/ clear = std_err_main | CLEAR_STDERR_LOG; writel(clear, l3_targ_base + diff --git a/arch/arm/mach-omap2/omap_l3_noc.h b/arch/arm/mach-omap2/omap_l3_noc.h index 74c16434f2bc..90b50984cd2e 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.h +++ b/arch/arm/mach-omap2/omap_l3_noc.h @@ -34,8 +34,11 @@ /* L3 TARG register offsets */ #define L3_TARG_STDERRLOG_MAIN 0x48 #define L3_TARG_STDERRLOG_SLVOFSLSB 0x5c +#define L3_TARG_STDERRLOG_MSTADDR 0x68 #define L3_FLAGMUX_REGERR0 0xc +#define NUM_OF_L3_MASTERS (sizeof(l3_masters)/sizeof(l3_masters[0])) + static u32 l3_flagmux[L3_MODULES] = { 0x500, 0x1000, @@ -76,6 +79,37 @@ static u32 l3_targ_inst_clk3[] = { 0x0100 /* EMUSS */ }; +static struct l3_masters_data { + u32 id; + char name[10]; +} l3_masters[] = { + { 0x0 , "MPU"}, + { 0x10, "CS_ADP"}, + { 0x14, "xxx"}, + { 0x20, "DSP"}, + { 0x30, "IVAHD"}, + { 0x40, "ISS"}, + { 0x44, "DucatiM3"}, + { 0x48, "FaceDetect"}, + { 0x50, "SDMA_Rd"}, + { 0x54, "SDMA_Wr"}, + { 0x58, "xxx"}, + { 0x5C, "xxx"}, + { 0x60, "SGX"}, + { 0x70, "DSS"}, + { 0x80, "C2C"}, + { 0x88, "xxx"}, + { 0x8C, "xxx"}, + { 0x90, "HSI"}, + { 0xA0, "MMC1"}, + { 0xA4, "MMC2"}, + { 0xA8, "MMC6"}, + { 0xB0, "UNIPRO1"}, + { 0xC0, "USBHOSTHS"}, + { 0xC4, "USBOTGHS"}, + { 0xC8, "USBHOSTFS"} +}; + static char *l3_targ_inst_name[L3_MODULES][18] = { { "DMM1", From cefcadeaa7d5681b88b3ee2272d961c23a70a091 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 24 Jun 2011 20:31:27 -0500 Subject: [PATCH 06/31] OMAP4: Fix the emif and dmm virtual mapping Fix the address overlap with Emulation domain (EMU). The previous mapping was entering into EMU mapping and was not as per comments. Fix the mapping accordingly. Signed-off-by: Girish S G Signed-off-by: Santosh Shilimkar --- arch/arm/plat-omap/include/plat/io.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index d72ec85c97e6..fb5fd246897b 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -228,13 +228,13 @@ #define OMAP44XX_EMIF2_PHYS OMAP44XX_EMIF2_BASE /* 0x4d000000 --> 0xfd200000 */ -#define OMAP44XX_EMIF2_VIRT (OMAP44XX_EMIF2_PHYS + OMAP4_L3_PER_IO_OFFSET) #define OMAP44XX_EMIF2_SIZE SZ_1M +#define OMAP44XX_EMIF2_VIRT (OMAP44XX_EMIF1_VIRT + OMAP44XX_EMIF1_SIZE) #define OMAP44XX_DMM_PHYS OMAP44XX_DMM_BASE /* 0x4e000000 --> 0xfd300000 */ -#define OMAP44XX_DMM_VIRT (OMAP44XX_DMM_PHYS + OMAP4_L3_PER_IO_OFFSET) #define OMAP44XX_DMM_SIZE SZ_1M +#define OMAP44XX_DMM_VIRT (OMAP44XX_EMIF2_VIRT + OMAP44XX_EMIF2_SIZE) /* * ---------------------------------------------------------------------------- * Omap specific register access From 1f8a7d5207a2a343af7c3b18fcc65dc6aa1fb068 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Wed, 27 Jul 2011 15:02:32 -0500 Subject: [PATCH 07/31] ARM: OMAP: omap_device: Add omap_device_get_by_hwmod_name An API which translates a standard hwmod name to corresponding platform_device is useful for drivers when they need to look up the device associated with a hwmod name to map back into the device structure pointers. These ideally should be used by drivers in mach directory. Using a generic hwmod name like "gpu" instead of the actual device name which could change in the future, allows us to: a) Could in effect help replace apis such as omap2_get_mpuss_device, omap2_get_iva_device, omap2_get_l3_device, omap4_get_dsp_device, etc.. b) Scale to more devices rather than be restricted to named functions c) Simplify driver's platform_data from passing additional fields all doing the same thing with different function pointer names just for accessing a different device name. Signed-off-by: Nishanth Menon [b-cousson@ti.com: Adapt it to the new pdev pointer inside od, remove the unneeded helpers, and fold the next patch here] Signed-off-by: Benoit Cousson Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/include/plat/omap_device.h | 1 + arch/arm/plat-omap/omap_device.c | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index d4d9b96f961e..12c5b0c345bf 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h @@ -101,6 +101,7 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, int pm_lats_cnt, int is_early_device); void __iomem *omap_device_get_rt_va(struct omap_device *od); +struct device *omap_device_get_by_hwmod_name(const char *oh_name); /* OMAP PM interface */ int omap_device_align_pm_lat(struct platform_device *pdev, diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 26aee5cc1fc1..f832f92013b2 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -844,6 +844,42 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od) return omap_hwmod_get_mpu_rt_va(od->hwmods[0]); } +/** + * omap_device_get_by_hwmod_name() - convert a hwmod name to + * device pointer. + * @oh_name: name of the hwmod device + * + * Returns back a struct device * pointer associated with a hwmod + * device represented by a hwmod_name + */ +struct device *omap_device_get_by_hwmod_name(const char *oh_name) +{ + struct omap_hwmod *oh; + + if (!oh_name) { + WARN(1, "%s: no hwmod name!\n", __func__); + return ERR_PTR(-EINVAL); + } + + oh = omap_hwmod_lookup(oh_name); + if (IS_ERR_OR_NULL(oh)) { + WARN(1, "%s: no hwmod for %s\n", __func__, + oh_name); + return ERR_PTR(oh ? PTR_ERR(oh) : -ENODEV); + } + if (IS_ERR_OR_NULL(oh->od)) { + WARN(1, "%s: no omap_device for %s\n", __func__, + oh_name); + return ERR_PTR(oh->od ? PTR_ERR(oh->od) : -ENODEV); + } + + if (IS_ERR_OR_NULL(oh->od->pdev)) + return ERR_PTR(oh->od->pdev ? PTR_ERR(oh->od->pdev) : -ENODEV); + + return &oh->od->pdev->dev; +} +EXPORT_SYMBOL(omap_device_get_by_hwmod_name); + /* * Public functions intended for use in omap_device_pm_latency * .activate_func and .deactivate_func function pointers From b1621fc80123e4f113c3dc1bc6dbad53ebd0c888 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 16 Aug 2011 14:01:23 +0200 Subject: [PATCH 08/31] ARM: OMAP3: beagle-board: Use the omap_hwmod_name_get_dev API Replace the multiple omap2_get_XXX_device APIs with the new omap_hwmod_name_get_dev that uses the hwmod name to get the proper device. Signed-off-by: Benoit Cousson Cc: Nishanth Menon Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/board-omap3beagle.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index e085371eb494..4a5d75f11610 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -486,8 +486,8 @@ static void __init beagle_opp_init(void) if (cpu_is_omap3630()) { struct device *mpu_dev, *iva_dev; - mpu_dev = omap2_get_mpuss_device(); - iva_dev = omap2_get_iva_device(); + mpu_dev = omap_device_get_by_hwmod_name("mpu"); + iva_dev = omap_device_get_by_hwmod_name("iva"); if (!mpu_dev || !iva_dev) { pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", From 0f7aa005c85917f114c376e937d88f5d941fb389 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 16 Aug 2011 15:02:20 +0200 Subject: [PATCH 09/31] ARM: OMAP2+: pm: Use hwmod name instead of dev pointer Replace the struct device parameter of omap2_set_init_voltage by the hwmod name. It will avoid having to store explicitely the device pointer into a static variable. Moreover, it will be a little bit more scalable if we introduce new DVFS devices. Signed-off-by: Benoit Cousson Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 0844e2ecfb4a..7c038ea42093 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -169,18 +169,26 @@ err: * in the opp entry */ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name, - struct device *dev) + const char *oh_name) { struct voltagedomain *voltdm; struct clk *clk; struct opp *opp; unsigned long freq, bootup_volt; + struct device *dev; - if (!vdd_name || !clk_name || !dev) { + if (!vdd_name || !clk_name || !oh_name) { pr_err("%s: invalid parameters\n", __func__); goto exit; } + dev = omap_device_get_by_hwmod_name(oh_name); + if (IS_ERR(dev)) { + pr_err("%s: Unable to get dev pointer for hwmod %s\n", + __func__, oh_name); + goto exit; + } + voltdm = voltdm_lookup(vdd_name); if (IS_ERR(voltdm)) { pr_err("%s: unable to get vdd pointer for vdd_%s\n", @@ -224,8 +232,8 @@ static void __init omap3_init_voltages(void) if (!cpu_is_omap34xx()) return; - omap2_set_init_voltage("mpu_iva", "dpll1_ck", mpu_dev); - omap2_set_init_voltage("core", "l3_ick", l3_dev); + omap2_set_init_voltage("mpu_iva", "dpll1_ck", "mpu"); + omap2_set_init_voltage("core", "l3_ick", "l3_main"); } static void __init omap4_init_voltages(void) @@ -233,9 +241,9 @@ static void __init omap4_init_voltages(void) if (!cpu_is_omap44xx()) return; - omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev); - omap2_set_init_voltage("core", "l3_div_ck", l3_dev); - omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev); + omap2_set_init_voltage("mpu", "dpll_mpu_ck", "mpu"); + omap2_set_init_voltage("core", "l3_div_ck", "l3_main_1"); + omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva"); } static int __init omap2_common_pm_init(void) From 766e7afc38754e4bdcbf948fa523af8999a6296f Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 16 Aug 2011 15:03:59 +0200 Subject: [PATCH 10/31] ARM: OMAP2+: pm: Remove static devices variable for mpu, dsp, iva and l3 PM Since the device pointer is now retrieved using the hwmod name, remove the static variables used to store the device pointers for DSP, MPU, IVA and L3 devices for PM/DVFS usage. Signed-off-by: Benoit Cousson Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/pm.c | 47 ++++++---------------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 7c038ea42093..9e78261fbfba 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -26,38 +26,7 @@ static struct omap_device_pm_latency *pm_lats; -static struct device *mpu_dev; -static struct device *iva_dev; -static struct device *l3_dev; -static struct device *dsp_dev; - -struct device *omap2_get_mpuss_device(void) -{ - WARN_ON_ONCE(!mpu_dev); - return mpu_dev; -} - -struct device *omap2_get_iva_device(void) -{ - WARN_ON_ONCE(!iva_dev); - return iva_dev; -} - -struct device *omap2_get_l3_device(void) -{ - WARN_ON_ONCE(!l3_dev); - return l3_dev; -} - -struct device *omap4_get_dsp_device(void) -{ - WARN_ON_ONCE(!dsp_dev); - return dsp_dev; -} -EXPORT_SYMBOL(omap4_get_dsp_device); - -/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */ -static int _init_omap_device(char *name, struct device **new_dev) +static int _init_omap_device(char *name) { struct omap_hwmod *oh; struct platform_device *pdev; @@ -72,8 +41,6 @@ static int _init_omap_device(char *name, struct device **new_dev) __func__, name)) return -ENODEV; - *new_dev = &pdev->dev; - return 0; } @@ -82,16 +49,16 @@ static int _init_omap_device(char *name, struct device **new_dev) */ static void omap2_init_processor_devices(void) { - _init_omap_device("mpu", &mpu_dev); + _init_omap_device("mpu"); if (omap3_has_iva()) - _init_omap_device("iva", &iva_dev); + _init_omap_device("iva"); if (cpu_is_omap44xx()) { - _init_omap_device("l3_main_1", &l3_dev); - _init_omap_device("dsp", &dsp_dev); - _init_omap_device("iva", &iva_dev); + _init_omap_device("l3_main_1"); + _init_omap_device("dsp"); + _init_omap_device("iva"); } else { - _init_omap_device("l3_main", &l3_dev); + _init_omap_device("l3_main"); } } From b7b5bc91d422ff51ff84dfd5949e9d2f17a550c8 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 9 Aug 2011 16:54:19 +0200 Subject: [PATCH 11/31] ARM: OMAP: omap_device: Create a default omap_device_pm_latency Most devices are using the same default omap_device_pm_latency structure during device built. In order to avoid the duplication of the same structure everywhere, add a default structure that will be used if the device does not have an explicit one. Next patches will clean the duplicated structures. Signed-off-by: Benoit Cousson Cc: Paul Walmsley Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/omap_device.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index f832f92013b2..cd8d9778b14e 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -97,6 +97,14 @@ static int omap_device_register(struct platform_device *pdev); static int omap_early_device_register(struct platform_device *pdev); +static struct omap_device_pm_latency omap_default_latency[] = { + { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, + } +}; + /* Private functions */ /** @@ -510,8 +518,17 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, if (ret) goto odbs_exit3; - od->pm_lats = pm_lats; + if (!pm_lats) { + pm_lats = omap_default_latency; + pm_lats_cnt = ARRAY_SIZE(omap_default_latency); + } + od->pm_lats_cnt = pm_lats_cnt; + od->pm_lats = kmemdup(pm_lats, + sizeof(struct omap_device_pm_latency) * pm_lats_cnt, + GFP_KERNEL); + if (!od->pm_lats) + goto odbs_exit3; for (i = 0; i < oh_cnt; i++) { hwmods[i]->od = od; From f718e2c034bf6ff872106344935006230764cb12 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Wed, 10 Aug 2011 15:30:09 +0200 Subject: [PATCH 12/31] ARM: OMAP2+: devices: Remove all omap_device_pm_latency structures Remove all these duplicated structures since a default one is now available. Signed-off-by: Benoit Cousson Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/devices.c | 46 +++----------------------------- arch/arm/mach-omap2/display.c | 11 +------- arch/arm/mach-omap2/dma.c | 11 +------- arch/arm/mach-omap2/gpio.c | 12 +-------- arch/arm/mach-omap2/hsmmc.c | 18 +------------ arch/arm/mach-omap2/hwspinlock.c | 12 +-------- arch/arm/mach-omap2/mcbsp.c | 11 +------- arch/arm/mach-omap2/serial.c | 25 +---------------- arch/arm/mach-omap2/sr_device.c | 11 +------- arch/arm/mach-omap2/usb-musb.c | 11 +------- arch/arm/plat-omap/i2c.c | 10 +------ 11 files changed, 14 insertions(+), 164 deletions(-) diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 10adf66be7ba..2d4a1998d5d9 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -221,14 +221,6 @@ static inline void omap_init_camera(void) #endif } -struct omap_device_pm_latency omap_keyboard_latency[] = { - { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - int __init omap4_keyboard_init(struct omap4_keypad_platform_data *sdp4430_keypad_data, struct omap_board_data *bdata) { @@ -248,9 +240,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data keypad_data = sdp4430_keypad_data; pdev = omap_device_build(name, id, oh, keypad_data, - sizeof(struct omap4_keypad_platform_data), - omap_keyboard_latency, - ARRAY_SIZE(omap_keyboard_latency), 0); + sizeof(struct omap4_keypad_platform_data), NULL, 0, 0); if (IS_ERR(pdev)) { WARN(1, "Can't build omap_device for %s:%s.\n", @@ -263,14 +253,6 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data } #if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) -static struct omap_device_pm_latency mbox_latencies[] = { - [0] = { - .activate_func = omap_device_enable_hwmods, - .deactivate_func = omap_device_idle_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - static inline void omap_init_mbox(void) { struct omap_hwmod *oh; @@ -282,8 +264,7 @@ static inline void omap_init_mbox(void) return; } - pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, - mbox_latencies, ARRAY_SIZE(mbox_latencies), 0); + pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, NULL, 0, 0); WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n", __func__, PTR_ERR(pdev)); } @@ -334,14 +315,6 @@ static inline void omap_init_audio(void) {} #include -struct omap_device_pm_latency omap_mcspi_latency[] = { - [0] = { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) { struct platform_device *pdev; @@ -372,8 +345,7 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) spi_num++; pdev = omap_device_build(name, spi_num, oh, pdata, - sizeof(*pdata), omap_mcspi_latency, - ARRAY_SIZE(omap_mcspi_latency), 0); + sizeof(*pdata), NULL, 0, 0); WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", name, oh->name); kfree(pdata); @@ -698,14 +670,6 @@ static int __init omap2_init_devices(void) arch_initcall(omap2_init_devices); #if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE) -static struct omap_device_pm_latency omap_wdt_latency[] = { - [0] = { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - static int __init omap_init_wdt(void) { int id = -1; @@ -723,9 +687,7 @@ static int __init omap_init_wdt(void) return -EINVAL; } - pdev = omap_device_build(dev_name, id, oh, NULL, 0, - omap_wdt_latency, - ARRAY_SIZE(omap_wdt_latency), 0); + pdev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0); WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", dev_name, oh->name); return 0; diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 18693f6de041..8ad0a2f0367d 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -35,14 +35,6 @@ static struct platform_device omap_display_device = { }, }; -static struct omap_device_pm_latency omap_dss_latency[] = { - [0] = { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - struct omap_dss_hwmod_data { const char *oh_name; const char *dev_name; @@ -111,8 +103,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) pdev = omap_device_build(curr_dss_hwmod[i].dev_name, curr_dss_hwmod[i].id, oh, &pdata, sizeof(struct omap_display_platform_data), - omap_dss_latency, - ARRAY_SIZE(omap_dss_latency), 0); + NULL, 0, 0); if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n", curr_dss_hwmod[i].oh_name)) diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index ae8cb3fb1830..a59a45a0096e 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -87,14 +87,6 @@ static u16 reg_map[] = { [CCDN] = 0xd8, }; -static struct omap_device_pm_latency omap2_dma_latency[] = { - { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - static void __iomem *dma_base; static inline void dma_write(u32 val, int reg, int lch) { @@ -258,8 +250,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) p->errata = configure_dma_errata(); - pdev = omap_device_build(name, 0, oh, p, sizeof(*p), - omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0); + pdev = omap_device_build(name, 0, oh, p, sizeof(*p), NULL, 0, 0); kfree(p); if (IS_ERR(pdev)) { pr_err("%s: Can't build omap_device for %s:%s.\n", diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 652ccc574196..8cbfbc2918ce 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -24,14 +24,6 @@ #include #include -static struct omap_device_pm_latency omap_gpio_latency[] = { - [0] = { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) { struct platform_device *pdev; @@ -108,9 +100,7 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused) } pdev = omap_device_build(name, id - 1, oh, pdata, - sizeof(*pdata), omap_gpio_latency, - ARRAY_SIZE(omap_gpio_latency), - false); + sizeof(*pdata), NULL, 0, false); kfree(pdata); if (IS_ERR(pdev)) { diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 2dc002a388b3..77085847e4e7 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -409,31 +409,17 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, return 0; } -static struct omap_device_pm_latency omap_hsmmc_latency[] = { - [0] = { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, - /* - * XXX There should also be an entry here to power off/on the - * MMC regulators/PBIAS cells, etc. - */ -}; - #define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) { struct omap_hwmod *oh; struct platform_device *pdev; - struct omap_device_pm_latency *ohl; char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; struct omap_mmc_platform_data *mmc_data; struct omap_mmc_dev_attr *mmc_dev_attr; char *name; int l; - int ohl_cnt = 0; mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); if (!mmc_data) { @@ -448,8 +434,6 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) omap_hsmmc_mux(mmc_data, (ctrl_nr - 1)); name = "omap_hsmmc"; - ohl = omap_hsmmc_latency; - ohl_cnt = ARRAY_SIZE(omap_hsmmc_latency); l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN, "mmc%d", ctrl_nr); @@ -468,7 +452,7 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) } pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data, - sizeof(struct omap_mmc_platform_data), ohl, ohl_cnt, false); + sizeof(struct omap_mmc_platform_data), NULL, 0, false); if (IS_ERR(pdev)) { WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name); kfree(mmc_data->slots[0].name); diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c index 0b3ae9d9c3b3..36e21091b06a 100644 --- a/arch/arm/mach-omap2/hwspinlock.c +++ b/arch/arm/mach-omap2/hwspinlock.c @@ -23,14 +23,6 @@ #include #include -struct omap_device_pm_latency omap_spinlock_latency[] = { - { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - } -}; - int __init hwspinlocks_init(void) { int retval = 0; @@ -48,9 +40,7 @@ int __init hwspinlocks_init(void) if (oh == NULL) return -EINVAL; - pdev = omap_device_build(dev_name, 0, oh, NULL, 0, - omap_spinlock_latency, - ARRAY_SIZE(omap_spinlock_latency), false); + pdev = omap_device_build(dev_name, 0, oh, NULL, 0, NULL, 0, false); if (IS_ERR(pdev)) { pr_err("Can't build omap_device for %s:%s\n", dev_name, oh_name); diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index 5063f253c4b9..292eee3be15f 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -122,14 +122,6 @@ static int omap3_enable_st_clock(unsigned int id, bool enable) return 0; } -struct omap_device_pm_latency omap2_mcbsp_latency[] = { - { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) { int id, count = 1; @@ -175,8 +167,7 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) count++; } pdev = omap_device_build_ss(name, id, oh_device, count, pdata, - sizeof(*pdata), omap2_mcbsp_latency, - ARRAY_SIZE(omap2_mcbsp_latency), false); + sizeof(*pdata), NULL, 0, false); kfree(pdata); if (IS_ERR(pdev)) { pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 3d1c1d393f8f..9992dbfdfdb3 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -107,28 +107,6 @@ struct omap_uart_state { static LIST_HEAD(uart_list); static u8 num_uarts; -static int uart_idle_hwmod(struct omap_device *od) -{ - omap_hwmod_idle(od->hwmods[0]); - - return 0; -} - -static int uart_enable_hwmod(struct omap_device *od) -{ - omap_hwmod_enable(od->hwmods[0]); - - return 0; -} - -static struct omap_device_pm_latency omap_uart_latency[] = { - { - .deactivate_func = uart_idle_hwmod, - .activate_func = uart_enable_hwmod, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - static inline unsigned int __serial_read_reg(struct uart_port *up, int offset) { @@ -800,8 +778,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata) return; pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size, - omap_uart_latency, - ARRAY_SIZE(omap_uart_latency), false); + NULL, 0, false); WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n", name, oh->name); diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index eba9f9a8ab65..9f43fcc05d3e 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -31,14 +31,6 @@ static bool sr_enable_on_init; -static struct omap_device_pm_latency omap_sr_latency[] = { - { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST - }, -}; - /* Read EFUSE values from control registers for OMAP3430 */ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, struct omap_sr_data *sr_data) @@ -121,8 +113,7 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user) sr_data->enable_on_init = sr_enable_on_init; pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), - omap_sr_latency, - ARRAY_SIZE(omap_sr_latency), 0); + NULL, 0, 0); if (IS_ERR(pdev)) pr_warning("%s: Could not build omap_device for %s: %s.\n\n", __func__, name, oh->name); diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index d86af3cda8c7..47fb5d607630 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -60,14 +60,6 @@ static struct musb_hdrc_platform_data musb_plat = { static u64 musb_dmamask = DMA_BIT_MASK(32); -static struct omap_device_pm_latency omap_musb_latency[] = { - { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - static void usb_musb_mux_init(struct omap_musb_board_data *board_data) { switch (board_data->interface_type) { @@ -150,8 +142,7 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data) return; pdev = omap_device_build(name, bus_id, oh, &musb_plat, - sizeof(musb_plat), omap_musb_latency, - ARRAY_SIZE(omap_musb_latency), false); + sizeof(musb_plat), NULL, 0, false); if (IS_ERR(pdev)) { pr_err("Could not build omap_device for %s %s\n", name, oh_name); diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 0c7caf2458b4..c20beb8ed38b 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -123,14 +123,6 @@ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) omap_pm_set_max_mpu_wakeup_lat(dev, t); } -static struct omap_device_pm_latency omap_i2c_latency[] = { - [0] = { - .deactivate_func = omap_device_idle_hwmods, - .activate_func = omap_device_enable_hwmods, - .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -}; - static inline int omap2_i2c_add_bus(int bus_id) { int l; @@ -162,7 +154,7 @@ static inline int omap2_i2c_add_bus(int bus_id) pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(struct omap_i2c_bus_platform_data), - omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0); + NULL, 0, 0); WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name); return PTR_ERR(pdev); From 4fcd15a032cec4b2684a32c86e895b50cdbee50c Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 27 Sep 2011 17:45:43 +0200 Subject: [PATCH 13/31] of: Add helpers to get one string in multiple strings property Add of_property_read_string_index and of_property_count_strings to retrieve one string inside a property that will contains severals strings. Signed-off-by: Benoit Cousson Acked-by: Grant Likely Signed-off-by: Kevin Hilman --- drivers/of/base.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/of.h | 18 ++++++++++ 2 files changed, 102 insertions(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index 3ff22e32b602..f7239b33d762 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -661,6 +661,90 @@ int of_property_read_string(struct device_node *np, const char *propname, } EXPORT_SYMBOL_GPL(of_property_read_string); +/** + * of_property_read_string_index - Find and read a string from a multiple + * strings property. + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @index: index of the string in the list of strings + * @out_string: pointer to null terminated return string, modified only if + * return value is 0. + * + * Search for a property in a device tree node and retrieve a null + * terminated string value (pointer to data, not a copy) in the list of strings + * contained in that property. + * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if + * property does not have a value, and -EILSEQ if the string is not + * null-terminated within the length of the property data. + * + * The out_string pointer is modified only if a valid string can be decoded. + */ +int of_property_read_string_index(struct device_node *np, const char *propname, + int index, const char **output) +{ + struct property *prop = of_find_property(np, propname, NULL); + int i = 0; + size_t l = 0, total = 0; + const char *p; + + if (!prop) + return -EINVAL; + if (!prop->value) + return -ENODATA; + if (strnlen(prop->value, prop->length) >= prop->length) + return -EILSEQ; + + p = prop->value; + + for (i = 0; total < prop->length; total += l, p += l) { + l = strlen(p) + 1; + if ((*p != 0) && (i++ == index)) { + *output = p; + return 0; + } + } + return -ENODATA; +} +EXPORT_SYMBOL_GPL(of_property_read_string_index); + + +/** + * of_property_count_strings - Find and return the number of strings from a + * multiple strings property. + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * + * Search for a property in a device tree node and retrieve the number of null + * terminated string contain in it. Returns the number of strings on + * success, -EINVAL if the property does not exist, -ENODATA if property + * does not have a value, and -EILSEQ if the string is not null-terminated + * within the length of the property data. + */ +int of_property_count_strings(struct device_node *np, const char *propname) +{ + struct property *prop = of_find_property(np, propname, NULL); + int i = 0; + size_t l = 0, total = 0; + const char *p; + + if (!prop) + return -EINVAL; + if (!prop->value) + return -ENODATA; + if (strnlen(prop->value, prop->length) >= prop->length) + return -EILSEQ; + + p = prop->value; + + for (i = 0; total < prop->length; total += l, p += l) { + l = strlen(p) + 1; + if (*p != 0) + i++; + } + return i; +} +EXPORT_SYMBOL_GPL(of_property_count_strings); + /** * of_parse_phandle - Resolve a phandle property to a device_node pointer * @np: Pointer to device node holding phandle property diff --git a/include/linux/of.h b/include/linux/of.h index 9180dc5cb00b..5dfe2d5a8b5d 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -203,6 +203,11 @@ extern int of_property_read_u32_array(const struct device_node *np, extern int of_property_read_string(struct device_node *np, const char *propname, const char **out_string); +extern int of_property_read_string_index(struct device_node *np, + const char *propname, + int index, const char **output); +extern int of_property_count_strings(struct device_node *np, + const char *propname); extern int of_device_is_compatible(const struct device_node *device, const char *); extern int of_device_is_available(const struct device_node *device); @@ -256,6 +261,19 @@ static inline int of_property_read_string(struct device_node *np, return -ENOSYS; } +static inline int of_property_read_string_index(struct device_node *np, + const char *propname, int index, + const char **out_string) +{ + return -ENOSYS; +} + +static inline int of_property_count_strings(struct device_node *np, + const char *propname) +{ + return -ENOSYS; +} + static inline const void *of_get_property(const struct device_node *node, const char *name, int *lenp) From a4f6cdb0672fe9f171b1e8a0faa121b5d76e1c4a Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 9 Aug 2011 16:47:01 +0200 Subject: [PATCH 14/31] ARM: OMAP: omap_device: Add omap_device_[alloc|delete] for DT integration Split the omap_device_build_ss into two smaller functions that will allow to populate a platform_device already allocated by device-tree. The functionality of the omap_device_build_ss is still the same, but the omap_device_alloc will be usable with devices already built by device-tree. Signed-off-by: Benoit Cousson Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/omap_device.c | 177 +++++++++++++++++++++---------- 1 file changed, 119 insertions(+), 58 deletions(-) diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index cd8d9778b14e..6725c72b0cd0 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -96,6 +96,11 @@ static int omap_device_register(struct platform_device *pdev); static int omap_early_device_register(struct platform_device *pdev); +static struct omap_device *omap_device_alloc(struct platform_device *pdev, + struct omap_hwmod **ohs, int oh_cnt, + struct omap_device_pm_latency *pm_lats, + int pm_lats_cnt); + static struct omap_device_pm_latency omap_default_latency[] = { { @@ -396,6 +401,110 @@ static int omap_device_fill_resources(struct omap_device *od, return 0; } +/** + * omap_device_alloc - allocate an omap_device + * @pdev: platform_device that will be included in this omap_device + * @oh: ptr to the single omap_hwmod that backs this omap_device + * @pdata: platform_data ptr to associate with the platform_device + * @pdata_len: amount of memory pointed to by @pdata + * @pm_lats: pointer to a omap_device_pm_latency array for this device + * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats + * + * Convenience function for allocating an omap_device structure and filling + * hwmods, resources and pm_latency attributes. + * + * Returns an struct omap_device pointer or ERR_PTR() on error; + */ +static struct omap_device *omap_device_alloc(struct platform_device *pdev, + struct omap_hwmod **ohs, int oh_cnt, + struct omap_device_pm_latency *pm_lats, + int pm_lats_cnt) +{ + int ret = -ENOMEM; + struct omap_device *od; + struct resource *res = NULL; + int i, res_count; + struct omap_hwmod **hwmods; + + od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); + if (!od) { + ret = -ENOMEM; + goto oda_exit1; + } + od->hwmods_cnt = oh_cnt; + + hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); + if (!hwmods) + goto oda_exit2; + + od->hwmods = hwmods; + od->pdev = pdev; + + /* + * HACK: Ideally the resources from DT should match, and hwmod + * should just add the missing ones. Since the name is not + * properly populated by DT, stick to hwmod resources only. + */ + if (pdev->num_resources && pdev->resource) + dev_warn(&pdev->dev, "%s(): resources already allocated %d\n", + __func__, pdev->num_resources); + + res_count = omap_device_count_resources(od); + if (res_count > 0) { + dev_dbg(&pdev->dev, "%s(): resources allocated from hwmod %d\n", + __func__, res_count); + res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); + if (!res) + goto oda_exit3; + + omap_device_fill_resources(od, res); + + ret = platform_device_add_resources(pdev, res, res_count); + kfree(res); + + if (ret) + goto oda_exit3; + } + + if (!pm_lats) { + pm_lats = omap_default_latency; + pm_lats_cnt = ARRAY_SIZE(omap_default_latency); + } + + od->pm_lats_cnt = pm_lats_cnt; + od->pm_lats = kmemdup(pm_lats, + sizeof(struct omap_device_pm_latency) * pm_lats_cnt, + GFP_KERNEL); + if (!od->pm_lats) + goto oda_exit3; + + pdev->archdata.od = od; + + for (i = 0; i < oh_cnt; i++) { + hwmods[i]->od = od; + _add_hwmod_clocks_clkdev(od, hwmods[i]); + } + + return od; + +oda_exit3: + kfree(hwmods); +oda_exit2: + kfree(od); +oda_exit1: + dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret); + + return ERR_PTR(ret); +} + +static void omap_device_delete(struct omap_device *od) +{ + od->pdev->archdata.od = NULL; + kfree(od->pm_lats); + kfree(od->hwmods); + kfree(od); +} + /** * omap_device_build - build and register an omap_device with one omap_hwmod * @pdev_name: name of the platform_device driver to use @@ -455,9 +564,6 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, int ret = -ENOMEM; struct platform_device *pdev; struct omap_device *od; - struct resource *res = NULL; - int i, res_count; - struct omap_hwmod **hwmods; if (!ohs || oh_cnt == 0 || !pdev_name) return ERR_PTR(-EINVAL); @@ -471,76 +577,31 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id, goto odbs_exit; } - pr_debug("omap_device: %s: building with %d hwmods\n", pdev_name, - oh_cnt); + /* Set the dev_name early to allow dev_xxx in omap_device_alloc */ + if (pdev->id != -1) + dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); + else + dev_set_name(&pdev->dev, "%s", pdev->name); - od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); - if (!od) { - ret = -ENOMEM; + od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt); + if (!od) goto odbs_exit1; - } - od->hwmods_cnt = oh_cnt; - - hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, - GFP_KERNEL); - if (!hwmods) - goto odbs_exit2; - - memcpy(hwmods, ohs, sizeof(struct omap_hwmod *) * oh_cnt); - od->hwmods = hwmods; - od->pdev = pdev; - - res_count = omap_device_count_resources(od); - if (res_count > 0) { - res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL); - if (!res) - goto odbs_exit3; - - omap_device_fill_resources(od, res); - - ret = platform_device_add_resources(pdev, res, res_count); - kfree(res); - - if (ret) - goto odbs_exit3; - } ret = platform_device_add_data(pdev, pdata, pdata_len); if (ret) - goto odbs_exit3; - - pdev->archdata.od = od; + goto odbs_exit2; if (is_early_device) ret = omap_early_device_register(pdev); else ret = omap_device_register(pdev); if (ret) - goto odbs_exit3; - - if (!pm_lats) { - pm_lats = omap_default_latency; - pm_lats_cnt = ARRAY_SIZE(omap_default_latency); - } - - od->pm_lats_cnt = pm_lats_cnt; - od->pm_lats = kmemdup(pm_lats, - sizeof(struct omap_device_pm_latency) * pm_lats_cnt, - GFP_KERNEL); - if (!od->pm_lats) - goto odbs_exit3; - - for (i = 0; i < oh_cnt; i++) { - hwmods[i]->od = od; - _add_hwmod_clocks_clkdev(od, hwmods[i]); - } + goto odbs_exit2; return pdev; -odbs_exit3: - kfree(hwmods); odbs_exit2: - kfree(od); + omap_device_delete(od); odbs_exit1: platform_device_put(pdev); odbs_exit: From dc2d07ebaea839a6e0fa47588c7984931f3c9c71 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Wed, 10 Aug 2011 13:32:08 +0200 Subject: [PATCH 15/31] ARM: OMAP: omap_device: Add a method to build an omap_device from a DT node Add a notifier called during device_add phase. If an of_node is present, retrieve the hwmod entry in order to populate properly the omap_device structure. For the moment the resource from the device-tree are overloaded. DT does not support named resource yet, and thus, most driver will not work without that information. Add a documentation to capture the specifics OMAP bindings needed for device-tree support. Signed-off-by: Benoit Cousson Cc: Grant Likely Signed-off-by: Kevin Hilman --- .../devicetree/bindings/arm/omap/omap.txt | 43 ++++++++ arch/arm/plat-omap/omap_device.c | 101 ++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/omap/omap.txt diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt new file mode 100644 index 000000000000..dbdab40ed3a6 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/omap.txt @@ -0,0 +1,43 @@ +* Texas Instruments OMAP + +OMAP is currently using a static file per SoC family to describe the +IPs present in the SoC. +On top of that an omap_device is created to extend the platform_device +capabilities and to allow binding with one or several hwmods. +The hwmods will contain all the information to build the device: +adresse range, irq lines, dma lines, interconnect, PRCM register, +clock domain, input clocks. +For the moment just point to the existing hwmod, the next step will be +to move data from hwmod to device-tree representation. + + +Required properties: +- compatible: Every devices present in OMAP SoC should be in the + form: "ti,XXX" +- ti,hwmods: list of hwmod names (ascii strings), that comes from the OMAP + HW documentation, attached to a device. Must contain at least + one hwmod. + +Optional properties: +- ti,no_idle_on_suspend: When present, it prevents the PM to idle the module + during suspend. + + +Example: + +spinlock@1 { + compatible = "ti,omap4-spinlock"; + ti,hwmods = "spinlock"; +}; + + +Boards: + +- OMAP3 BeagleBoard : Low cost community board + compatible = "ti,omap3-beagle", "ti,omap3" + +- OMAP4 SDP : Software Developement Board + compatible = "ti,omap4-sdp", "ti,omap4430" + +- OMAP4 PandaBoard : Low cost community board + compatible = "ti,omap4-panda", "ti,omap4430" diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index 6725c72b0cd0..cd90bedd9306 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -85,6 +85,8 @@ #include #include #include +#include +#include #include #include @@ -100,6 +102,7 @@ static struct omap_device *omap_device_alloc(struct platform_device *pdev, struct omap_hwmod **ohs, int oh_cnt, struct omap_device_pm_latency *pm_lats, int pm_lats_cnt); +static void omap_device_delete(struct omap_device *od); static struct omap_device_pm_latency omap_default_latency[] = { @@ -316,6 +319,96 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od, } +static struct dev_pm_domain omap_device_pm_domain; + +/** + * omap_device_build_from_dt - build an omap_device with multiple hwmods + * @pdev_name: name of the platform_device driver to use + * @pdev_id: this platform_device's connection ID + * @oh: ptr to the single omap_hwmod that backs this omap_device + * @pdata: platform_data ptr to associate with the platform_device + * @pdata_len: amount of memory pointed to by @pdata + * @pm_lats: pointer to a omap_device_pm_latency array for this device + * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats + * @is_early_device: should the device be registered as an early device or not + * + * Function for building an omap_device already registered from device-tree + * + * Returns 0 or PTR_ERR() on error. + */ +static int omap_device_build_from_dt(struct platform_device *pdev) +{ + struct omap_hwmod **hwmods; + struct omap_device *od; + struct omap_hwmod *oh; + struct device_node *node = pdev->dev.of_node; + const char *oh_name; + int oh_cnt, i, ret = 0; + + oh_cnt = of_property_count_strings(node, "ti,hwmods"); + if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) { + dev_warn(&pdev->dev, "No 'hwmods' to build omap_device\n"); + return -ENODEV; + } + + hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); + if (!hwmods) { + ret = -ENOMEM; + goto odbfd_exit; + } + + for (i = 0; i < oh_cnt; i++) { + of_property_read_string_index(node, "ti,hwmods", i, &oh_name); + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n", + oh_name); + ret = -EINVAL; + goto odbfd_exit1; + } + hwmods[i] = oh; + } + + od = omap_device_alloc(pdev, hwmods, oh_cnt, NULL, 0); + if (!od) { + dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", + oh_name); + ret = PTR_ERR(od); + goto odbfd_exit1; + } + + if (of_get_property(node, "ti,no_idle_on_suspend", NULL)) + omap_device_disable_idle_on_suspend(pdev); + + pdev->dev.pm_domain = &omap_device_pm_domain; + +odbfd_exit1: + kfree(hwmods); +odbfd_exit: + return ret; +} + +static int _omap_device_notifier_call(struct notifier_block *nb, + unsigned long event, void *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + switch (event) { + case BUS_NOTIFY_ADD_DEVICE: + if (pdev->dev.of_node) + omap_device_build_from_dt(pdev); + break; + + case BUS_NOTIFY_DEL_DEVICE: + if (pdev->archdata.od) + omap_device_delete(pdev->archdata.od); + break; + } + + return NOTIFY_DONE; +} + + /* Public functions for use by core code */ /** @@ -499,6 +592,9 @@ oda_exit1: static void omap_device_delete(struct omap_device *od) { + if (!od) + return; + od->pdev->archdata.od = NULL; kfree(od->pm_lats); kfree(od->hwmods); @@ -1038,8 +1134,13 @@ struct device omap_device_parent = { .parent = &platform_bus, }; +static struct notifier_block platform_nb = { + .notifier_call = _omap_device_notifier_call, +}; + static int __init omap_device_init(void) { + bus_register_notifier(&platform_bus_type, &platform_nb); return device_register(&omap_device_parent); } core_initcall(omap_device_init); From d9fda07af7fbb989cf68ba7d2f370320f05664d8 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 9 Aug 2011 17:15:17 +0200 Subject: [PATCH 16/31] arm/dts: Add initial device tree support for OMAP4 SoC Add initial device-tree support for OMAP4 SoC. This is based on the original panda board patch done by Manju: http://permalink.gmane.org/gmane.linux.ports.arm.omap/60393 Add the generic GIC interrupt-controller from ARM. Add an empty "soc" node to contain non memory mapped IPs (DSP, MPU, IPU...). Note: Since reg, irq and dma are provided by hwmod for the moment, these attributes will not be present at all in DTS to highlight the gap. They will be added as soon as dma bindings will be there and drivers will be adapted. Signed-off-by: Benoit Cousson Acked-by: Grant Likely Cc: G, Manjunath Kondaiah --- arch/arm/boot/dts/omap4.dtsi | 79 ++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 arch/arm/boot/dts/omap4.dtsi diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi new file mode 100644 index 000000000000..d4131e36aefb --- /dev/null +++ b/arch/arm/boot/dts/omap4.dtsi @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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. + */ + +/* + * Carveout for multimedia usecases + * It should be the last 48MB of the first 512MB memory part + * In theory, it should not even exist. That zone should be reserved + * dynamically during the .reserve callback. + */ +/memreserve/ 0x9d000000 0x03000000; + +/include/ "skeleton.dtsi" + +/ { + compatible = "ti,omap4430", "ti,omap4"; + interrupt-parent = <&gic>; + + aliases { + }; + + /* + * The soc node represents the soc top level view. It is uses for IPs + * that are not memory mapped in the MPU view or for the MPU itself. + */ + soc { + compatible = "ti,omap-infra"; + }; + + /* + * XXX: Use a flat representation of the OMAP4 interconnect. + * The real OMAP interconnect network is quite complex. + * + * MPU -+-- MPU_PRIVATE - GIC, L2 + * | + * +----------------+----------+ + * | | | + * + +- EMIF - DDR | + * | | | + * | + +--------+ + * | | | + * | +- L4_ABE - AESS, MCBSP, TIMERs... + * | | + * +- L3_MAIN --+- L4_CORE - IPs... + * | + * +- L4_PER - IPs... + * | + * +- L4_CFG -+- L4_WKUP - IPs... + * | | + * | +- IPs... + * +- IPU ----+ + * | | + * +- DSP ----+ + * | | + * +- DSS ----+ + * + * Since that will not bring real advantage to represent that in DT for + * the moment, just use a fake OCP bus entry to represent the whole bus + * hierarchy. + */ + ocp { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gic: interrupt-controller@48241000 { + compatible = "arm,cortex-a9-gic"; + interrupt-controller; + #interrupt-cells = <1>; + reg = <0x48241000 0x1000>, + <0x48240100 0x0100>; + }; + }; +}; From 38eb2ae65859b8c1bbb0cd07a173ad19de39b746 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 16 Aug 2011 15:57:51 +0200 Subject: [PATCH 17/31] arm/dts: Add support for OMAP4 PandaBoard Based on the original omap4-panda.dts file from Manju. http://www.spinics.net/lists/linux-omap/msg55836.html Add memory information and a default bootargs to allow a boot from RAMDISK. Signed-off-by: Benoit Cousson Acked-by: Grant Likely Cc: G, Manjunath Kondaiah --- arch/arm/boot/dts/omap4-panda.dts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 arch/arm/boot/dts/omap4-panda.dts diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts new file mode 100644 index 000000000000..c7026578ce7d --- /dev/null +++ b/arch/arm/boot/dts/omap4-panda.dts @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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. + */ +/dts-v1/; + +/include/ "omap4.dtsi" + +/ { + model = "TI OMAP4 PandaBoard"; + compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4"; + + /* + * Since the initial device tree board file does not create any + * devices (MMC, network...), the only way to boot is to provide a + * ramdisk. + */ + chosen { + bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug"; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x40000000>; /* 1 GB */ + }; +}; From 492beedfd80e48be48211b5e7bce9b85fb141a81 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 16 Aug 2011 15:59:52 +0200 Subject: [PATCH 18/31] arm/dts: Add support for OMAP4 SDP board Add the SDP/Blaze (Software Development Board) support with device tree. That file is based on the omap4-panda.dts. Signed-off-by: Benoit Cousson Acked-by: Grant Likely Cc: G, Manjunath Kondaiah --- arch/arm/boot/dts/omap4-sdp.dts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 arch/arm/boot/dts/omap4-sdp.dts diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts new file mode 100644 index 000000000000..066e28c90328 --- /dev/null +++ b/arch/arm/boot/dts/omap4-sdp.dts @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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. + */ +/dts-v1/; + +/include/ "omap4.dtsi" + +/ { + model = "TI OMAP4 SDP board"; + compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4"; + + /* + * Since the initial device tree board file does not create any + * devices (MMC, network...), the only way to boot is to provide a + * ramdisk. + */ + chosen { + bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug"; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x40000000>; /* 1 GB */ + }; +}; From 189892f496cd01bf1af149bd6f7f380fcf67489d Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 16 Aug 2011 21:02:01 +0530 Subject: [PATCH 19/31] arm/dts: Add initial device tree support for OMAP3 SoC Add initial OMAP3 soc file with empty ocp bus. Based on initial patch from Manju: http://www.spinics.net/lists/linux-omap/msg55830.html Signed-off-by: Benoit Cousson Acked-by: Grant Likely Cc: G, Manjunath Kondaiah --- arch/arm/boot/dts/omap3.dtsi | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 arch/arm/boot/dts/omap3.dtsi diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi new file mode 100644 index 000000000000..d558785c8b2c --- /dev/null +++ b/arch/arm/boot/dts/omap3.dtsi @@ -0,0 +1,44 @@ +/* + * Device Tree Source for OMAP3 SoC + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/include/ "skeleton.dtsi" + +/ { + compatible = "ti,omap3430", "ti,omap3"; + + /* + * The soc node represents the soc top level view. It is uses for IPs + * that are not memory mapped in the MPU view or for the MPU itself. + */ + soc { + compatible = "ti,omap-infra"; + }; + + /* + * XXX: Use a flat representation of the OMAP3 interconnect. + * The real OMAP interconnect network is quite complex. + * Since that will not bring real advantage to represent that in DT for + * the moment, just use a fake OCP bus entry to represent the whole bus + * hierarchy. + */ + ocp { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "l3_main"; + + intc: interrupt-controller@1 { + compatible = "ti,omap3-intc"; + interrupt-controller; + #interrupt-cells = <1>; + }; + }; +}; From 295e98c60b8cee05e02f0a055dbc12a08b0378c1 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 14 Jul 2011 01:44:54 +0530 Subject: [PATCH 20/31] arm/dts: Add support for OMAP3 Beagle board Add OMAP3 beagleboard DTS file to use the omap3.dtsi SoC file. Add a default bootargs line to allow a boot from RAMDISK. Add memory node information. Signed-off-by: Benoit Cousson Acked-by: Grant Likely Cc: G, Manjunath Kondaiah --- arch/arm/boot/dts/omap3-beagle.dts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 arch/arm/boot/dts/omap3-beagle.dts diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts new file mode 100644 index 000000000000..9486be62bcdd --- /dev/null +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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. + */ +/dts-v1/; + +/include/ "omap3.dtsi" + +/ { + model = "TI OMAP3 BeagleBoard"; + compatible = "ti,omap3-beagle", "ti,omap3"; + + /* + * Since the initial device tree board file does not create any + * devices (MMC, network...), the only way to boot is to provide a + * ramdisk. + */ + chosen { + bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk"; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512 MB */ + }; +}; From 8d61649ddf6707d89fc10028f9d1bd1a2ea37b4f Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 20 Sep 2011 21:24:47 +0200 Subject: [PATCH 21/31] ARM: OMAP2+: board-generic: Add DT support to generic board Re-cycle the original board-generic.c file to support Device Tree for every OMAP2+ variants. The current approach is an intermediate step before having only one machine descriptor that will use some generic DT aware functions. Signed-off-by: Benoit Cousson Cc: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 8 +- arch/arm/mach-omap2/board-generic.c | 127 ++++++++++++++++++---------- 2 files changed, 90 insertions(+), 45 deletions(-) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 57b66d590c52..e0a318df95bc 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -106,9 +106,13 @@ comment "OMAP Board Type" depends on ARCH_OMAP2PLUS config MACH_OMAP_GENERIC - bool "Generic OMAP board" - depends on ARCH_OMAP2 + bool "Generic OMAP2+ board" + depends on ARCH_OMAP2PLUS + select USE_OF default y + help + Support for generic TI OMAP2+ boards using Flattened Device Tree. + More information at Documentation/devicetree config MACH_OMAP2_TUSB6010 bool diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 5223898f50e4..62c6b2e8b5d7 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -1,76 +1,117 @@ /* - * linux/arch/arm/mach-omap2/board-generic.c - * * Copyright (C) 2005 Nokia Corporation * Author: Paul Mundt * - * Modified from mach-omap/omap1/board-generic.c + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * - * Code for generic OMAP2 board. Should work on many OMAP2 systems where - * the bootloader passes the board-specific data to the kernel. - * Do not put any board specific code to this file; create a new machine - * type if you need custom low-level initializations. + * Modified from the original mach-omap/omap2/board-generic.c did by Paul + * to support the OMAP2+ device tree boards with an unique board file. * * 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 -#include -#include +#include +#include +#include #include -#include #include -#include -#include -#include #include #include +#include -static struct omap_board_config_kernel generic_config[] = { + +static struct of_device_id omap_dt_match_table[] __initdata = { + { .compatible = "simple-bus", }, + { .compatible = "ti,omap-infra", }, + { } }; -static void __init omap_generic_init_early(void) -{ - omap2_init_common_infrastructure(); -} +static struct of_device_id intc_match[] __initdata = { + { .compatible = "ti,omap3-intc", }, + { .compatible = "arm,cortex-a9-gic", }, + { } +}; static void __init omap_generic_init(void) { + struct device_node *node = of_find_matching_node(NULL, intc_match); + if (node) + irq_domain_add_simple(node, 0); + omap_serial_init(); omap_sdrc_init(NULL, NULL); - omap_board_config = generic_config; - omap_board_config_size = ARRAY_SIZE(generic_config); + + of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); } -static void __init omap_generic_map_io(void) -{ - if (cpu_is_omap242x()) { - omap2_set_globals_242x(); - omap242x_map_common_io(); - } else if (cpu_is_omap243x()) { - omap2_set_globals_243x(); - omap243x_map_common_io(); - } else if (cpu_is_omap34xx()) { - omap2_set_globals_3xxx(); - omap34xx_map_common_io(); - } else if (cpu_is_omap44xx()) { - omap2_set_globals_443x(); - omap44xx_map_common_io(); - } -} +#if defined(CONFIG_SOC_OMAP2420) +static const char *omap242x_boards_compat[] __initdata = { + "ti,omap2420", + NULL, +}; -/* XXX This machine entry name should be updated */ -MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") - /* Maintainer: Paul Mundt */ - .boot_params = 0x80000100, +DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)") .reserve = omap_reserve, - .map_io = omap_generic_map_io, - .init_early = omap_generic_init_early, + .map_io = omap242x_map_io, + .init_early = omap2420_init_early, .init_irq = omap2_init_irq, .init_machine = omap_generic_init, .timer = &omap2_timer, + .dt_compat = omap242x_boards_compat, MACHINE_END +#endif + +#if defined(CONFIG_SOC_OMAP2430) +static const char *omap243x_boards_compat[] __initdata = { + "ti,omap2430", + NULL, +}; + +DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap243x_map_io, + .init_early = omap2430_init_early, + .init_irq = omap2_init_irq, + .init_machine = omap_generic_init, + .timer = &omap2_timer, + .dt_compat = omap243x_boards_compat, +MACHINE_END +#endif + +#if defined(CONFIG_ARCH_OMAP3) +static const char *omap3_boards_compat[] __initdata = { + "ti,omap3", + NULL, +}; + +DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3430_init_early, + .init_irq = omap3_init_irq, + .init_machine = omap_generic_init, + .timer = &omap3_timer, + .dt_compat = omap3_boards_compat, +MACHINE_END +#endif + +#if defined(CONFIG_ARCH_OMAP4) +static const char *omap4_boards_compat[] __initdata = { + "ti,omap4", + NULL, +}; + +DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") + .reserve = omap_reserve, + .map_io = omap4_map_io, + .init_early = omap4430_init_early, + .init_irq = gic_init_irq, + .init_machine = omap_generic_init, + .timer = &omap4_timer, + .dt_compat = omap4_boards_compat, +MACHINE_END +#endif From a7cbb9b15d55dff0488b1a6d93929c2386d8632b Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Thu, 22 Sep 2011 21:52:02 +0200 Subject: [PATCH 22/31] ARM: OMAP2+: board-generic: Add i2c static init Still needed to boot until the i2c & twl driver is adapted to device-tree. Otherwise the voltage control code will try to access the twl and crash. Signed-off-by: Benoit Cousson Cc: Tony Lindgren --- arch/arm/mach-omap2/board-generic.c | 41 +++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 62c6b2e8b5d7..d9ccb9d98e15 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -22,7 +23,31 @@ #include #include #include +#include "common-board-devices.h" +/* + * XXX: Still needed to boot until the i2c & twl driver is adapted to + * device-tree + */ +static struct twl4030_platform_data sdp4430_twldata = { + .irq_base = TWL6030_IRQ_BASE, + .irq_end = TWL6030_IRQ_END, +}; + +static void __init omap4_i2c_init(void) +{ + omap4_pmic_init("twl6030", &sdp4430_twldata); +} + +static struct twl4030_platform_data beagle_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, +}; + +static void __init omap3_i2c_init(void) +{ + omap3_pmic_init("twl4030", &beagle_twldata); +} static struct of_device_id omap_dt_match_table[] __initdata = { { .compatible = "simple-bus", }, @@ -48,6 +73,18 @@ static void __init omap_generic_init(void) of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); } +static void __init omap4_init(void) +{ + omap4_i2c_init(); + omap_generic_init(); +} + +static void __init omap3_init(void) +{ + omap3_i2c_init(); + omap_generic_init(); +} + #if defined(CONFIG_SOC_OMAP2420) static const char *omap242x_boards_compat[] __initdata = { "ti,omap2420", @@ -93,7 +130,7 @@ DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)") .map_io = omap3_map_io, .init_early = omap3430_init_early, .init_irq = omap3_init_irq, - .init_machine = omap_generic_init, + .init_machine = omap3_init, .timer = &omap3_timer, .dt_compat = omap3_boards_compat, MACHINE_END @@ -110,7 +147,7 @@ DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)") .map_io = omap4_map_io, .init_early = omap4430_init_early, .init_irq = gic_init_irq, - .init_machine = omap_generic_init, + .init_machine = omap4_init, .timer = &omap4_timer, .dt_compat = omap4_boards_compat, MACHINE_END From d039c5b9fb2315ef942944439da6f0fbaf2f1941 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Fri, 12 Aug 2011 13:52:50 +0200 Subject: [PATCH 23/31] ARM: OMAP2+: l3-noc: Add support for device-tree Add device-tree support for the l3-noc driver. Use platform_driver_register to defer the probing at device init time. Add documentation for the l3-noc bindings. Signed-off-by: Benoit Cousson Cc: Tony Lindgren Cc: Santosh Shilimkar --- .../devicetree/bindings/arm/omap/l3-noc.txt | 19 ++++++++++++++ arch/arm/mach-omap2/omap_l3_noc.c | 25 ++++++++++++++----- 2 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/omap/l3-noc.txt diff --git a/Documentation/devicetree/bindings/arm/omap/l3-noc.txt b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt new file mode 100644 index 000000000000..6888a5efc860 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt @@ -0,0 +1,19 @@ +* TI - L3 Network On Chip (NoC) + +This version is an implementation of the generic NoC IP +provided by Arteris. + +Required properties: +- compatible : Should be "ti,omap3-l3-smx" for OMAP3 family + Should be "ti,omap4-l3-noc" for OMAP4 family +- ti,hwmods: "l3_main_1", ... One hwmod for each noc domain. + +Examples: + +ocp { + compatible = "ti,omap4-l3-noc", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3"; +}; diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c index 07a3d3ede768..c8b1bef92e5a 100644 --- a/arch/arm/mach-omap2/omap_l3_noc.c +++ b/arch/arm/mach-omap2/omap_l3_noc.c @@ -127,7 +127,7 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3) return IRQ_HANDLED; } -static int __init omap4_l3_probe(struct platform_device *pdev) +static int __devinit omap4_l3_probe(struct platform_device *pdev) { static struct omap4_l3 *l3; struct resource *res; @@ -218,7 +218,7 @@ err0: return ret; } -static int __exit omap4_l3_remove(struct platform_device *pdev) +static int __devexit omap4_l3_remove(struct platform_device *pdev) { struct omap4_l3 *l3 = platform_get_drvdata(pdev); @@ -232,16 +232,29 @@ static int __exit omap4_l3_remove(struct platform_device *pdev) return 0; } +#if defined(CONFIG_OF) +static const struct of_device_id l3_noc_match[] = { + {.compatible = "ti,omap4-l3-noc", }, + {}, +} +MODULE_DEVICE_TABLE(of, l3_noc_match); +#else +#define l3_noc_match NULL +#endif + static struct platform_driver omap4_l3_driver = { - .remove = __exit_p(omap4_l3_remove), - .driver = { - .name = "omap_l3_noc", + .probe = omap4_l3_probe, + .remove = __devexit_p(omap4_l3_remove), + .driver = { + .name = "omap_l3_noc", + .owner = THIS_MODULE, + .of_match_table = l3_noc_match, }, }; static int __init omap4_l3_init(void) { - return platform_driver_probe(&omap4_l3_driver, omap4_l3_probe); + return platform_driver_register(&omap4_l3_driver); } postcore_initcall_sync(omap4_l3_init); From ad8dfac66fb1995014060302bda19a15bc62bd6d Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Fri, 12 Aug 2011 13:48:47 +0200 Subject: [PATCH 24/31] arm/dts: OMAP4: Add a main ocp entry bound to l3-noc driver Used the main OCP node to add bindings with the l3_noc driver. Remove l3_noc static device creation if DT is populated. Signed-off-by: Benoit Cousson Acked-by: Grant Likely Cc: Tony Lindgren Cc: Santosh Shilimkar --- arch/arm/boot/dts/omap4.dtsi | 3 ++- arch/arm/mach-omap2/devices.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index d4131e36aefb..b85a39debbea 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -63,10 +63,11 @@ * hierarchy. */ ocp { - compatible = "simple-bus"; + compatible = "ti,omap4-l3-noc", "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; + ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3"; gic: interrupt-controller@48241000 { compatible = "arm,cortex-a9-gic"; diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 2d4a1998d5d9..0f8e0eb18166 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,10 @@ static int __init omap4_l3_init(void) struct platform_device *pdev; char oh_name[L3_MODULES_MAX_LEN]; + /* If dtb is there, the devices will be created dynamically */ + if (of_have_populated_dt()) + return -ENODEV; + /* * To avoid code running on other OMAPs in * multi-omap builds From 476b679a5d785d1244f6b43ad26877acf278cd18 Mon Sep 17 00:00:00 2001 From: Benoit Cousson Date: Tue, 16 Aug 2011 11:49:08 +0200 Subject: [PATCH 25/31] arm/dts: OMAP3+: Add mpu, dsp and iva nodes Add nodes for devices used by PM code (mpu, dsp, iva). Add a cpus node as well as recommended in the DT spec. Remove mpu, dsp, iva devices init if is populated. Signed-off-by: Benoit Cousson Acked-by: Grant Likely Cc: Kevin Hilman --- .../devicetree/bindings/arm/omap/dsp.txt | 14 ++++++++++ .../devicetree/bindings/arm/omap/iva.txt | 19 +++++++++++++ .../devicetree/bindings/arm/omap/mpu.txt | 27 +++++++++++++++++++ arch/arm/boot/dts/omap3.dtsi | 19 +++++++++++++ arch/arm/boot/dts/omap4.dtsi | 23 ++++++++++++++++ arch/arm/mach-omap2/pm.c | 3 ++- 6 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/arm/omap/dsp.txt create mode 100644 Documentation/devicetree/bindings/arm/omap/iva.txt create mode 100644 Documentation/devicetree/bindings/arm/omap/mpu.txt diff --git a/Documentation/devicetree/bindings/arm/omap/dsp.txt b/Documentation/devicetree/bindings/arm/omap/dsp.txt new file mode 100644 index 000000000000..d3830a32ce08 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/dsp.txt @@ -0,0 +1,14 @@ +* TI - DSP (Digital Signal Processor) + +TI DSP included in OMAP SoC + +Required properties: +- compatible : Should be "ti,omap3-c64" for OMAP3 & 4 +- ti,hwmods: "dsp" + +Examples: + +dsp { + compatible = "ti,omap3-c64"; + ti,hwmods = "dsp"; +}; diff --git a/Documentation/devicetree/bindings/arm/omap/iva.txt b/Documentation/devicetree/bindings/arm/omap/iva.txt new file mode 100644 index 000000000000..6d6295171358 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/iva.txt @@ -0,0 +1,19 @@ +* TI - IVA (Imaging and Video Accelerator) subsystem + +The IVA contain various audio, video or imaging HW accelerator +depending of the version. + +Required properties: +- compatible : Should be: + - "ti,ivahd" for OMAP4 + - "ti,iva2.2" for OMAP3 + - "ti,iva2.1" for OMAP2430 + - "ti,iva1" for OMAP2420 +- ti,hwmods: "iva" + +Examples: + +iva { + compatible = "ti,ivahd", "ti,iva"; + ti,hwmods = "iva"; +}; diff --git a/Documentation/devicetree/bindings/arm/omap/mpu.txt b/Documentation/devicetree/bindings/arm/omap/mpu.txt new file mode 100644 index 000000000000..1a5a42ce21bb --- /dev/null +++ b/Documentation/devicetree/bindings/arm/omap/mpu.txt @@ -0,0 +1,27 @@ +* TI - MPU (Main Processor Unit) subsystem + +The MPU subsystem contain one or several ARM cores +depending of the version. +The MPU contain CPUs, GIC, L2 cache and a local PRCM. + +Required properties: +- compatible : Should be "ti,omap3-mpu" for OMAP3 + Should be "ti,omap4-mpu" for OMAP4 +- ti,hwmods: "mpu" + +Examples: + +- For an OMAP4 SMP system: + +mpu { + compatible = "ti,omap4-mpu"; + ti,hwmods = "mpu"; +}; + + +- For an OMAP3 monocore system: + +mpu { + compatible = "ti,omap3-mpu"; + ti,hwmods = "mpu"; +}; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index d558785c8b2c..d202bb5ec7ef 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -13,12 +13,31 @@ / { compatible = "ti,omap3430", "ti,omap3"; + cpus { + cpu@0 { + compatible = "arm,cortex-a8"; + }; + }; + /* * The soc node represents the soc top level view. It is uses for IPs * that are not memory mapped in the MPU view or for the MPU itself. */ soc { compatible = "ti,omap-infra"; + mpu { + compatible = "ti,omap3-mpu"; + ti,hwmods = "mpu"; + }; + + iva { + compatible = "ti,iva2.2"; + ti,hwmods = "iva"; + + dsp { + compatible = "ti,omap3-c64"; + }; + }; }; /* diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index b85a39debbea..4c61c829043a 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -23,12 +23,35 @@ aliases { }; + cpus { + cpu@0 { + compatible = "arm,cortex-a9"; + }; + cpu@1 { + compatible = "arm,cortex-a9"; + }; + }; + /* * The soc node represents the soc top level view. It is uses for IPs * that are not memory mapped in the MPU view or for the MPU itself. */ soc { compatible = "ti,omap-infra"; + mpu { + compatible = "ti,omap4-mpu"; + ti,hwmods = "mpu"; + }; + + dsp { + compatible = "ti,omap3-c64"; + ti,hwmods = "dsp"; + }; + + iva { + compatible = "ti,ivahd"; + ti,hwmods = "iva"; + }; }; /* diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 9e78261fbfba..2ab7a9e17fe2 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -215,7 +215,8 @@ static void __init omap4_init_voltages(void) static int __init omap2_common_pm_init(void) { - omap2_init_processor_devices(); + if (!of_have_populated_dt()) + omap2_init_processor_devices(); omap_pm_if_init(); return 0; From 7b88e62f5d219a86d81bdf4388012c97dc42e8f8 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 5 Oct 2011 15:14:02 -0700 Subject: [PATCH 26/31] ARM: OMAP1: Use generic map_io, init_early and init_irq This allows removing omap hacks for map_io allowing generic map_io. Note that in the future we can't do cpu_is_omapxxxx detection until in init_early. This means that board-innovator.c now assumes 15xx only, and board-generic.c assumes 16xx only. This is best fixed later on by passing the SoC type from device tree. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-ams-delta.c | 16 +--- arch/arm/mach-omap1/board-fsample.c | 114 +++++++++++++------------- arch/arm/mach-omap1/board-generic.c | 16 +--- arch/arm/mach-omap1/board-h2.c | 16 +--- arch/arm/mach-omap1/board-h3.c | 16 +--- arch/arm/mach-omap1/board-htcherald.c | 12 +-- arch/arm/mach-omap1/board-innovator.c | 34 ++++---- arch/arm/mach-omap1/board-nokia770.c | 34 +++----- arch/arm/mach-omap1/board-osk.c | 16 +--- arch/arm/mach-omap1/board-palmte.c | 16 +--- arch/arm/mach-omap1/board-palmtt.c | 16 +--- arch/arm/mach-omap1/board-palmz71.c | 18 +--- arch/arm/mach-omap1/board-perseus2.c | 101 +++++++++++------------ arch/arm/mach-omap1/board-sx1.c | 17 +--- arch/arm/mach-omap1/board-voiceblue.c | 16 +--- arch/arm/mach-omap1/io.c | 72 ++++++++-------- arch/arm/plat-omap/include/plat/io.h | 27 +++++- 17 files changed, 222 insertions(+), 335 deletions(-) diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 312ea6b0409d..44277370806e 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -135,12 +135,6 @@ void ams_delta_latch2_write(u16 mask, u16 value) *(volatile __u16 *) AMS_DELTA_LATCH2_VIRT = ams_delta_latch2_reg; } -static void __init ams_delta_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - static struct map_desc ams_delta_io_desc[] __initdata = { /* AMS_DELTA_LATCH1 */ { @@ -379,17 +373,13 @@ static int __init ams_delta_modem_init(void) } arch_initcall(ams_delta_modem_init); -static void __init ams_delta_map_io(void) -{ - omap1_map_common_io(); -} - MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)") /* Maintainer: Jonathan McDowell */ .boot_params = 0x10000100, - .map_io = ams_delta_map_io, + .map_io = omap15xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = ams_delta_init_irq, + .init_irq = omap1_init_irq, .init_machine = ams_delta_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c index a6b1bea50371..b09dfe6d6e8d 100644 --- a/arch/arm/mach-omap1/board-fsample.c +++ b/arch/arm/mach-omap1/board-fsample.c @@ -297,63 +297,6 @@ static struct omap_board_config_kernel fsample_config[] __initdata = { static void __init omap_fsample_init(void) { - fsample_init_smc91x(); - - if (gpio_request(FSAMPLE_NAND_RB_GPIO_PIN, "NAND ready") < 0) - BUG(); - gpio_direction_input(FSAMPLE_NAND_RB_GPIO_PIN); - - omap_cfg_reg(L3_1610_FLASH_CS2B_OE); - omap_cfg_reg(M8_1610_FLASH_CS2B_WE); - - /* Mux pins for keypad */ - omap_cfg_reg(E2_7XX_KBR0); - omap_cfg_reg(J7_7XX_KBR1); - omap_cfg_reg(E1_7XX_KBR2); - omap_cfg_reg(F3_7XX_KBR3); - omap_cfg_reg(D2_7XX_KBR4); - omap_cfg_reg(C2_7XX_KBC0); - omap_cfg_reg(D3_7XX_KBC1); - omap_cfg_reg(E4_7XX_KBC2); - omap_cfg_reg(F4_7XX_KBC3); - omap_cfg_reg(E3_7XX_KBC4); - - platform_add_devices(devices, ARRAY_SIZE(devices)); - - omap_board_config = fsample_config; - omap_board_config_size = ARRAY_SIZE(fsample_config); - omap_serial_init(); - omap_register_i2c_bus(1, 100, NULL, 0); -} - -static void __init omap_fsample_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - -/* Only FPGA needs to be mapped here. All others are done with ioremap */ -static struct map_desc omap_fsample_io_desc[] __initdata = { - { - .virtual = H2P2_DBG_FPGA_BASE, - .pfn = __phys_to_pfn(H2P2_DBG_FPGA_START), - .length = H2P2_DBG_FPGA_SIZE, - .type = MT_DEVICE - }, - { - .virtual = FSAMPLE_CPLD_BASE, - .pfn = __phys_to_pfn(FSAMPLE_CPLD_START), - .length = FSAMPLE_CPLD_SIZE, - .type = MT_DEVICE - } -}; - -static void __init omap_fsample_map_io(void) -{ - omap1_map_common_io(); - iotable_init(omap_fsample_io_desc, - ARRAY_SIZE(omap_fsample_io_desc)); - /* Early, board-dependent init */ /* @@ -384,15 +327,68 @@ static void __init omap_fsample_map_io(void) * Configure MPU_EXT_NIRQ IO in IO_CONF9 register, * It is used as the Ethernet controller interrupt */ - omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF, OMAP7XX_IO_CONF_9); + omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF, + OMAP7XX_IO_CONF_9); + + fsample_init_smc91x(); + + if (gpio_request(FSAMPLE_NAND_RB_GPIO_PIN, "NAND ready") < 0) + BUG(); + gpio_direction_input(FSAMPLE_NAND_RB_GPIO_PIN); + + omap_cfg_reg(L3_1610_FLASH_CS2B_OE); + omap_cfg_reg(M8_1610_FLASH_CS2B_WE); + + /* Mux pins for keypad */ + omap_cfg_reg(E2_7XX_KBR0); + omap_cfg_reg(J7_7XX_KBR1); + omap_cfg_reg(E1_7XX_KBR2); + omap_cfg_reg(F3_7XX_KBR3); + omap_cfg_reg(D2_7XX_KBR4); + omap_cfg_reg(C2_7XX_KBC0); + omap_cfg_reg(D3_7XX_KBC1); + omap_cfg_reg(E4_7XX_KBC2); + omap_cfg_reg(F4_7XX_KBC3); + omap_cfg_reg(E3_7XX_KBC4); + + platform_add_devices(devices, ARRAY_SIZE(devices)); + + omap_board_config = fsample_config; + omap_board_config_size = ARRAY_SIZE(fsample_config); + omap_serial_init(); + omap_register_i2c_bus(1, 100, NULL, 0); +} + +/* Only FPGA needs to be mapped here. All others are done with ioremap */ +static struct map_desc omap_fsample_io_desc[] __initdata = { + { + .virtual = H2P2_DBG_FPGA_BASE, + .pfn = __phys_to_pfn(H2P2_DBG_FPGA_START), + .length = H2P2_DBG_FPGA_SIZE, + .type = MT_DEVICE + }, + { + .virtual = FSAMPLE_CPLD_BASE, + .pfn = __phys_to_pfn(FSAMPLE_CPLD_START), + .length = FSAMPLE_CPLD_SIZE, + .type = MT_DEVICE + } +}; + +static void __init omap_fsample_map_io(void) +{ + omap15xx_map_io(); + iotable_init(omap_fsample_io_desc, + ARRAY_SIZE(omap_fsample_io_desc)); } MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample") /* Maintainer: Brian Swetland */ .boot_params = 0x10000100, .map_io = omap_fsample_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = omap_fsample_init_irq, + .init_irq = omap1_init_irq, .init_machine = omap_fsample_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index 04fc356c40fa..cc0cca7ee199 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c @@ -28,12 +28,6 @@ #include #include -static void __init omap_generic_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - /* assume no Mini-AB port */ #ifdef CONFIG_ARCH_OMAP15XX @@ -87,17 +81,13 @@ static void __init omap_generic_init(void) omap_register_i2c_bus(1, 100, NULL, 0); } -static void __init omap_generic_map_io(void) -{ - omap1_map_common_io(); -} - MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") /* Maintainer: Tony Lindgren */ .boot_params = 0x10000100, - .map_io = omap_generic_map_io, + .map_io = omap16xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = omap_generic_init_irq, + .init_irq = omap1_init_irq, .init_machine = omap_generic_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index cb7fb1aa3dca..248a5b8e2865 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -373,12 +373,6 @@ static struct i2c_board_info __initdata h2_i2c_board_info[] = { }, }; -static void __init h2_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - static struct omap_usb_config h2_usb_config __initdata = { /* usb1 has a Mini-AB port and external isp1301 transceiver */ .otg = 2, @@ -454,17 +448,13 @@ static void __init h2_init(void) h2_mmc_init(); } -static void __init h2_map_io(void) -{ - omap1_map_common_io(); -} - MACHINE_START(OMAP_H2, "TI-H2") /* Maintainer: Imre Deak */ .boot_params = 0x10000100, - .map_io = h2_map_io, + .map_io = omap16xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = h2_init_irq, + .init_irq = omap1_init_irq, .init_machine = h2_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index 31f34875ffad..f28f05fe7676 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -436,23 +436,13 @@ static void __init h3_init(void) h3_mmc_init(); } -static void __init h3_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - -static void __init h3_map_io(void) -{ - omap1_map_common_io(); -} - MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") /* Maintainer: Texas Instruments, Inc. */ .boot_params = 0x10000100, - .map_io = h3_map_io, + .map_io = omap16xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = h3_init_irq, + .init_irq = omap1_init_irq, .init_machine = h3_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c index 36e06ea7ec65..67798dfc4f8d 100644 --- a/arch/arm/mach-omap1/board-htcherald.c +++ b/arch/arm/mach-omap1/board-htcherald.c @@ -500,7 +500,7 @@ static void __init htcherald_lcd_init(void) static void __init htcherald_map_io(void) { - omap1_map_common_io(); + omap7xx_map_io(); /* * The LCD panel must be disabled and DMA turned off here, as doing @@ -601,20 +601,14 @@ static void __init htcherald_init(void) #endif } -static void __init htcherald_init_irq(void) -{ - printk(KERN_INFO "htcherald_init_irq.\n"); - omap1_init_common_hw(); - omap1_init_irq(); -} - MACHINE_START(HERALD, "HTC Herald") /* Maintainer: Cory Maccarrone */ /* Maintainer: wing-linux.sourceforge.net */ .boot_params = 0x10000100, .map_io = htcherald_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = htcherald_init_irq, + .init_irq = omap1_init_irq, .init_machine = htcherald_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index 0b1ba462d388..3e349d0ce32c 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c @@ -289,12 +289,6 @@ static void __init innovator_init_smc91x(void) } } -static void __init innovator_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - #ifdef CONFIG_ARCH_OMAP15XX static struct omap_usb_config innovator1510_usb_config __initdata = { /* for bundled non-standard host and peripheral cables */ @@ -439,30 +433,32 @@ static void __init innovator_init(void) innovator_mmc_init(); } +/* + * REVISIT: Assume 15xx for now, we don't want to do revision check + * until later on. The right way to fix this is to set up a different + * machine_id for 16xx Innovator, or use device tree. + */ static void __init innovator_map_io(void) { - omap1_map_common_io(); + omap15xx_map_io(); -#ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap1510()) { - iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc)); - udelay(10); /* Delay needed for FPGA */ + iotable_init(innovator1510_io_desc, ARRAY_SIZE(innovator1510_io_desc)); + udelay(10); /* Delay needed for FPGA */ - /* Dump the Innovator FPGA rev early - useful info for support. */ - printk("Innovator FPGA Rev %d.%d Board Rev %d\n", - fpga_read(OMAP1510_FPGA_REV_HIGH), - fpga_read(OMAP1510_FPGA_REV_LOW), - fpga_read(OMAP1510_FPGA_BOARD_REV)); - } -#endif + /* Dump the Innovator FPGA rev early - useful info for support. */ + pr_debug("Innovator FPGA Rev %d.%d Board Rev %d\n", + fpga_read(OMAP1510_FPGA_REV_HIGH), + fpga_read(OMAP1510_FPGA_REV_LOW), + fpga_read(OMAP1510_FPGA_BOARD_REV)); } MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") /* Maintainer: MontaVista Software, Inc. */ .boot_params = 0x10000100, .map_io = innovator_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = innovator_init_irq, + .init_irq = omap1_init_irq, .init_machine = innovator_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 5469ce247ffe..9b348b6ee3ee 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -39,21 +39,6 @@ #define ADS7846_PENDOWN_GPIO 15 -static void __init omap_nokia770_init_irq(void) -{ - /* On Nokia 770, the SleepX signal is masked with an - * MPUIO line by default. It has to be unmasked for it - * to become functional */ - - /* SleepX mask direction */ - omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); - /* Unmask SleepX signal */ - omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); - - omap1_init_common_hw(); - omap1_init_irq(); -} - static const unsigned int nokia770_keymap[] = { KEY(1, 0, GROUP_0 | KEY_UP), KEY(2, 0, GROUP_1 | KEY_F5), @@ -246,6 +231,15 @@ static inline void nokia770_mmc_init(void) static void __init omap_nokia770_init(void) { + /* On Nokia 770, the SleepX signal is masked with an + * MPUIO line by default. It has to be unmasked for it + * to become functional */ + + /* SleepX mask direction */ + omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); + /* Unmask SleepX signal */ + omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); + platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices)); spi_register_board_info(nokia770_spi_board_info, ARRAY_SIZE(nokia770_spi_board_info)); @@ -258,16 +252,12 @@ static void __init omap_nokia770_init(void) nokia770_mmc_init(); } -static void __init omap_nokia770_map_io(void) -{ - omap1_map_common_io(); -} - MACHINE_START(NOKIA770, "Nokia 770") .boot_params = 0x10000100, - .map_io = omap_nokia770_map_io, + .map_io = omap16xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = omap_nokia770_init_irq, + .init_irq = omap1_init_irq, .init_machine = omap_nokia770_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index b08a21380772..562986e1874f 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -279,12 +279,6 @@ static void __init osk_init_cf(void) irq_set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING); } -static void __init osk_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - static struct omap_usb_config osk_usb_config __initdata = { /* has usb host connector (A) ... for development it can also * be used, with a NONSTANDARD gender-bending cable/dongle, as @@ -576,17 +570,13 @@ static void __init osk_init(void) osk_mistral_init(); } -static void __init osk_map_io(void) -{ - omap1_map_common_io(); -} - MACHINE_START(OMAP_OSK, "TI-OSK") /* Maintainer: Dirk Behme */ .boot_params = 0x10000100, - .map_io = osk_map_io, + .map_io = omap16xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = osk_init_irq, + .init_irq = omap1_init_irq, .init_machine = osk_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 459cb6bfed55..fc9edd8595e9 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -59,12 +59,6 @@ #define PALMTE_MMC2_GPIO OMAP_MPUIO(7) #define PALMTE_MMC3_GPIO OMAP_MPUIO(11) -static void __init omap_palmte_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - static const unsigned int palmte_keymap[] = { KEY(0, 0, KEY_F1), /* Calendar */ KEY(1, 0, KEY_F2), /* Contacts */ @@ -269,16 +263,12 @@ static void __init omap_palmte_init(void) omap_register_i2c_bus(1, 100, NULL, 0); } -static void __init omap_palmte_map_io(void) -{ - omap1_map_common_io(); -} - MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") .boot_params = 0x10000100, - .map_io = omap_palmte_map_io, + .map_io = omap15xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = omap_palmte_init_irq, + .init_irq = omap1_init_irq, .init_machine = omap_palmte_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c index b214f45f646c..5ff3def49a85 100644 --- a/arch/arm/mach-omap1/board-palmtt.c +++ b/arch/arm/mach-omap1/board-palmtt.c @@ -263,12 +263,6 @@ static struct spi_board_info __initdata palmtt_boardinfo[] = { } }; -static void __init omap_palmtt_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - static struct omap_usb_config palmtt_usb_config __initdata = { .register_dev = 1, .hmc_mode = 0, @@ -315,16 +309,12 @@ static void __init omap_palmtt_init(void) omap_register_i2c_bus(1, 100, NULL, 0); } -static void __init omap_palmtt_map_io(void) -{ - omap1_map_common_io(); -} - MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T") .boot_params = 0x10000100, - .map_io = omap_palmtt_map_io, + .map_io = omap15xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = omap_palmtt_init_irq, + .init_irq = omap1_init_irq, .init_machine = omap_palmtt_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c index 9b0ea48d35fd..8e0887375f7e 100644 --- a/arch/arm/mach-omap1/board-palmz71.c +++ b/arch/arm/mach-omap1/board-palmz71.c @@ -57,13 +57,6 @@ #define PALMZ71_SLIDER_GPIO OMAP_MPUIO(3) #define PALMZ71_MMC_IN_GPIO OMAP_MPUIO(4) -static void __init -omap_palmz71_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - static const unsigned int palmz71_keymap[] = { KEY(0, 0, KEY_F1), KEY(1, 0, KEY_F2), @@ -334,17 +327,12 @@ omap_palmz71_init(void) palmz71_gpio_setup(0); } -static void __init -omap_palmz71_map_io(void) -{ - omap1_map_common_io(); -} - MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71") .boot_params = 0x10000100, - .map_io = omap_palmz71_map_io, + .map_io = omap15xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = omap_palmz71_init_irq, + .init_irq = omap1_init_irq, .init_machine = omap_palmz71_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 67acd4142639..6ed649b8b8d3 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c @@ -265,56 +265,6 @@ static void __init perseus2_init_smc91x(void) static void __init omap_perseus2_init(void) { - perseus2_init_smc91x(); - - if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0) - BUG(); - gpio_direction_input(P2_NAND_RB_GPIO_PIN); - - omap_cfg_reg(L3_1610_FLASH_CS2B_OE); - omap_cfg_reg(M8_1610_FLASH_CS2B_WE); - - /* Mux pins for keypad */ - omap_cfg_reg(E2_7XX_KBR0); - omap_cfg_reg(J7_7XX_KBR1); - omap_cfg_reg(E1_7XX_KBR2); - omap_cfg_reg(F3_7XX_KBR3); - omap_cfg_reg(D2_7XX_KBR4); - omap_cfg_reg(C2_7XX_KBC0); - omap_cfg_reg(D3_7XX_KBC1); - omap_cfg_reg(E4_7XX_KBC2); - omap_cfg_reg(F4_7XX_KBC3); - omap_cfg_reg(E3_7XX_KBC4); - - platform_add_devices(devices, ARRAY_SIZE(devices)); - - omap_board_config = perseus2_config; - omap_board_config_size = ARRAY_SIZE(perseus2_config); - omap_serial_init(); - omap_register_i2c_bus(1, 100, NULL, 0); -} - -static void __init omap_perseus2_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} -/* Only FPGA needs to be mapped here. All others are done with ioremap */ -static struct map_desc omap_perseus2_io_desc[] __initdata = { - { - .virtual = H2P2_DBG_FPGA_BASE, - .pfn = __phys_to_pfn(H2P2_DBG_FPGA_START), - .length = H2P2_DBG_FPGA_SIZE, - .type = MT_DEVICE - } -}; - -static void __init omap_perseus2_map_io(void) -{ - omap1_map_common_io(); - iotable_init(omap_perseus2_io_desc, - ARRAY_SIZE(omap_perseus2_io_desc)); - /* Early, board-dependent init */ /* @@ -345,15 +295,62 @@ static void __init omap_perseus2_map_io(void) * Configure MPU_EXT_NIRQ IO in IO_CONF9 register, * It is used as the Ethernet controller interrupt */ - omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF, OMAP7XX_IO_CONF_9); + omap_writel(omap_readl(OMAP7XX_IO_CONF_9) & 0x1FFFFFFF, + OMAP7XX_IO_CONF_9); + + perseus2_init_smc91x(); + + if (gpio_request(P2_NAND_RB_GPIO_PIN, "NAND ready") < 0) + BUG(); + gpio_direction_input(P2_NAND_RB_GPIO_PIN); + + omap_cfg_reg(L3_1610_FLASH_CS2B_OE); + omap_cfg_reg(M8_1610_FLASH_CS2B_WE); + + /* Mux pins for keypad */ + omap_cfg_reg(E2_7XX_KBR0); + omap_cfg_reg(J7_7XX_KBR1); + omap_cfg_reg(E1_7XX_KBR2); + omap_cfg_reg(F3_7XX_KBR3); + omap_cfg_reg(D2_7XX_KBR4); + omap_cfg_reg(C2_7XX_KBC0); + omap_cfg_reg(D3_7XX_KBC1); + omap_cfg_reg(E4_7XX_KBC2); + omap_cfg_reg(F4_7XX_KBC3); + omap_cfg_reg(E3_7XX_KBC4); + + platform_add_devices(devices, ARRAY_SIZE(devices)); + + omap_board_config = perseus2_config; + omap_board_config_size = ARRAY_SIZE(perseus2_config); + omap_serial_init(); + omap_register_i2c_bus(1, 100, NULL, 0); +} + +/* Only FPGA needs to be mapped here. All others are done with ioremap */ +static struct map_desc omap_perseus2_io_desc[] __initdata = { + { + .virtual = H2P2_DBG_FPGA_BASE, + .pfn = __phys_to_pfn(H2P2_DBG_FPGA_START), + .length = H2P2_DBG_FPGA_SIZE, + .type = MT_DEVICE + } +}; + +static void __init omap_perseus2_map_io(void) +{ + omap7xx_map_io(); + iotable_init(omap_perseus2_io_desc, + ARRAY_SIZE(omap_perseus2_io_desc)); } MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") /* Maintainer: Kevin Hilman */ .boot_params = 0x10000100, .map_io = omap_perseus2_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = omap_perseus2_init_irq, + .init_irq = omap1_init_irq, .init_machine = omap_perseus2_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 9c3b7c52d9cf..23326e04d6b9 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -407,24 +407,13 @@ static void __init omap_sx1_init(void) gpio_direction_output(11, 0); /*A_SWITCH = 0 */ gpio_direction_output(15, 0); /*A_USB_ON = 0 */ } -/*----------------------------------------*/ -static void __init omap_sx1_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} -/*----------------------------------------*/ - -static void __init omap_sx1_map_io(void) -{ - omap1_map_common_io(); -} MACHINE_START(SX1, "OMAP310 based Siemens SX1") .boot_params = 0x10000100, - .map_io = omap_sx1_map_io, + .map_io = omap15xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = omap_sx1_init_irq, + .init_irq = omap1_init_irq, .init_machine = omap_sx1_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 036edc0ee9b6..1444ce846ab7 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c @@ -159,17 +159,6 @@ static struct omap_usb_config voiceblue_usb_config __initdata = { static struct omap_board_config_kernel voiceblue_config[] = { }; -static void __init voiceblue_init_irq(void) -{ - omap1_init_common_hw(); - omap1_init_irq(); -} - -static void __init voiceblue_map_io(void) -{ - omap1_map_common_io(); -} - #define MACHINE_PANICED 1 #define MACHINE_REBOOTING 2 #define MACHINE_REBOOT 4 @@ -302,9 +291,10 @@ static void __init voiceblue_init(void) MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") /* Maintainer: Ladislav Michl */ .boot_params = 0x10000100, - .map_io = voiceblue_map_io, + .map_io = omap15xx_map_io, + .init_early = omap1_init_early, .reserve = omap_reserve, - .init_irq = voiceblue_init_irq, + .init_irq = omap1_init_irq, .init_machine = voiceblue_init, .timer = &omap1_timer, MACHINE_END diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index 870886a29594..a16aab71922c 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -85,50 +85,44 @@ static struct map_desc omap16xx_io_desc[] __initdata = { #endif /* - * Maps common IO regions for omap1. This should only get called from - * board specific init. + * Maps common IO regions for omap1 */ -void __init omap1_map_common_io(void) +static void __init omap1_map_common_io(void) { iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); - - /* Normally devicemaps_init() would flush caches and tlb after - * mdesc->map_io(), but we must also do it here because of the CPU - * revision check below. - */ - local_flush_tlb_all(); - flush_cache_all(); - - /* We want to check CPU revision early for cpu_is_omapxxxx() macros. - * IO space mapping must be initialized before we can do that. - */ - omap_check_revision(); - -#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850) - if (cpu_is_omap7xx()) { - iotable_init(omap7xx_io_desc, ARRAY_SIZE(omap7xx_io_desc)); - } -#endif -#ifdef CONFIG_ARCH_OMAP15XX - if (cpu_is_omap15xx()) { - iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); - } -#endif -#if defined(CONFIG_ARCH_OMAP16XX) - if (cpu_is_omap16xx()) { - iotable_init(omap16xx_io_desc, ARRAY_SIZE(omap16xx_io_desc)); - } -#endif - - omap_sram_init(); } -/* - * Common low-level hardware init for omap1. This should only get called from - * board specific init. - */ -void __init omap1_init_common_hw(void) +#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850) +void __init omap7xx_map_io(void) { + omap1_map_common_io(); + iotable_init(omap7xx_io_desc, ARRAY_SIZE(omap7xx_io_desc)); +} +#endif + +#ifdef CONFIG_ARCH_OMAP15XX +void __init omap15xx_map_io(void) +{ + omap1_map_common_io(); + iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); +} +#endif + +#if defined(CONFIG_ARCH_OMAP16XX) +void __init omap16xx_map_io(void) +{ + omap1_map_common_io(); + iotable_init(omap16xx_io_desc, ARRAY_SIZE(omap16xx_io_desc)); +} +#endif + +/* + * Common low-level hardware init for omap1. + */ +void omap1_init_early(void) +{ + omap_check_revision(); + /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort * on a Posted Write in the TIPB Bridge". */ @@ -138,8 +132,8 @@ void __init omap1_init_common_hw(void) /* Must init clocks early to assure that timer interrupt works */ omap1_clk_init(); - omap1_mux_init(); + omap_sram_init(); } /* diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index 6591875486d5..c0c785073141 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -256,8 +256,31 @@ extern void omap_writel(u32 v, u32 pa); struct omap_sdrc_params; -extern void omap1_map_common_io(void); -extern void omap1_init_common_hw(void); +#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) +void omap7xx_map_io(void); +#else +static inline void omap_map_io(void) +{ +} +#endif + +#ifdef CONFIG_ARCH_OMAP15XX +void omap15xx_map_io(void); +#else +static inline void omap15xx_map_io(void) +{ +} +#endif + +#ifdef CONFIG_ARCH_OMAP16XX +void omap16xx_map_io(void); +#else +static inline void omap16xx_map_io(void) +{ +} +#endif + +void omap1_init_early(void); #ifdef CONFIG_SOC_OMAP2420 extern void omap242x_map_common_io(void); From 7b250aff1ce346b6c7bc0329a2350334d1c66525 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 4 Oct 2011 18:26:28 -0700 Subject: [PATCH 27/31] ARM: OMAP: Avoid cpu_is_omapxxxx usage until map_io is done This way we don't need to initialize SoC detection early and can start using generic map_io. Reviewed-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-omap3beagle.c | 7 +- arch/arm/mach-omap2/io.c | 95 ++++++++++++------------ arch/arm/plat-omap/include/plat/common.h | 1 + 3 files changed, 50 insertions(+), 53 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c index 4a5d75f11610..4c25742ebf6d 100644 --- a/arch/arm/mach-omap2/board-omap3beagle.c +++ b/arch/arm/mach-omap2/board-omap3beagle.c @@ -444,11 +444,6 @@ static struct platform_device keys_gpio = { }, }; -static void __init omap3_beagle_init_early(void) -{ - omap2_init_common_infrastructure(); -} - static struct platform_device *omap3_beagle_devices[] __initdata = { &leds_gpio, &keys_gpio, @@ -555,7 +550,7 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") .boot_params = 0x80000100, .reserve = omap_reserve, .map_io = omap3_map_io, - .init_early = omap3_beagle_init_early, + .init_early = omap3_init_early, .init_irq = omap3_init_irq, .init_machine = omap3_beagle_init, .timer = &omap3_secure_timer, diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 15f91c42be66..e8123d010307 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -248,9 +248,6 @@ static void __init _omap2_map_common_io(void) */ local_flush_tlb_all(); flush_cache_all(); - - omap2_check_revision(); - omap_sram_init(); } #ifdef CONFIG_SOC_OMAP2420 @@ -337,34 +334,16 @@ static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data) /* See irq.c, omap4-common.c and entry-macro.S */ void __iomem *omap_irq_base; -void __init omap2_init_common_infrastructure(void) +static void __init omap_common_init_early(void) +{ + omap2_check_revision(); + omap_sram_init(); +} + +static void __init omap_hwmod_init_postsetup(void) { u8 postsetup_state; - if (cpu_is_omap242x()) { - omap2xxx_voltagedomains_init(); - omap242x_powerdomains_init(); - omap242x_clockdomains_init(); - omap2420_hwmod_init(); - } else if (cpu_is_omap243x()) { - omap2xxx_voltagedomains_init(); - omap243x_powerdomains_init(); - omap243x_clockdomains_init(); - omap2430_hwmod_init(); - } else if (cpu_is_omap34xx()) { - omap3xxx_voltagedomains_init(); - omap3xxx_powerdomains_init(); - omap3xxx_clockdomains_init(); - omap3xxx_hwmod_init(); - } else if (cpu_is_omap44xx()) { - omap44xx_voltagedomains_init(); - omap44xx_powerdomains_init(); - omap44xx_clockdomains_init(); - omap44xx_hwmod_init(); - } else { - pr_err("Could not init hwmod data - unknown SoC\n"); - } - /* Set the default postsetup state for all hwmods */ #ifdef CONFIG_PM_RUNTIME postsetup_state = _HWMOD_STATE_IDLE; @@ -392,57 +371,79 @@ void __init omap2_init_common_infrastructure(void) &postsetup_state); omap_pm_if_early_init(); - - if (cpu_is_omap2420()) - omap2420_clk_init(); - else if (cpu_is_omap2430()) - omap2430_clk_init(); - else if (cpu_is_omap34xx()) - omap3xxx_clk_init(); - else if (cpu_is_omap44xx()) - omap4xxx_clk_init(); - else - pr_err("Could not init clock framework - unknown SoC\n"); } void __init omap2420_init_early(void) { - omap2_init_common_infrastructure(); + omap_common_init_early(); + omap2xxx_voltagedomains_init(); + omap242x_powerdomains_init(); + omap242x_clockdomains_init(); + omap2420_hwmod_init(); + omap_hwmod_init_postsetup(); + omap2420_clk_init(); } void __init omap2430_init_early(void) { - omap2_init_common_infrastructure(); + omap_common_init_early(); + omap2xxx_voltagedomains_init(); + omap243x_powerdomains_init(); + omap243x_clockdomains_init(); + omap2430_hwmod_init(); + omap_hwmod_init_postsetup(); + omap2430_clk_init(); +} + +/* + * Currently only board-omap3beagle.c should call this because of the + * same machine_id for 34xx and 36xx beagle.. Will get fixed with DT. + */ +void __init omap3_init_early(void) +{ + omap_common_init_early(); + omap3xxx_voltagedomains_init(); + omap3xxx_powerdomains_init(); + omap3xxx_clockdomains_init(); + omap3xxx_hwmod_init(); + omap_hwmod_init_postsetup(); + omap3xxx_clk_init(); } void __init omap3430_init_early(void) { - omap2_init_common_infrastructure(); + omap3_init_early(); } void __init omap35xx_init_early(void) { - omap2_init_common_infrastructure(); + omap3_init_early(); } void __init omap3630_init_early(void) { - omap2_init_common_infrastructure(); + omap3_init_early(); } void __init am35xx_init_early(void) { - omap2_init_common_infrastructure(); + omap3_init_early(); } void __init ti816x_init_early(void) { - omap2_init_common_infrastructure(); + omap3_init_early(); } void __init omap4430_init_early(void) { - omap2_init_common_infrastructure(); + omap_common_init_early(); + omap44xx_voltagedomains_init(); + omap44xx_powerdomains_init(); + omap44xx_clockdomains_init(); + omap44xx_hwmod_init(); + omap_hwmod_init_postsetup(); + omap4xxx_clk_init(); } void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index abda2c7e499b..5eac3553f96d 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -50,6 +50,7 @@ void omap2430_init_early(void); void omap3430_init_early(void); void omap35xx_init_early(void); void omap3630_init_early(void); +void omap3_init_early(void); /* Do not use this one */ void am35xx_init_early(void); void ti816x_init_early(void); void omap4430_init_early(void); From fee926bb0d399b1eaaf38f9f694bbf2747c4b8a2 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 4 Oct 2011 16:21:42 -0700 Subject: [PATCH 28/31] ARM: OMAP: Remove calls to SRAM allocations for framebuffer This assumes fixed mappings which will not work once we move to use ioremap_exec(). It seems that these are currently not in use, or in use for some out of tree corner cases. If SRAM support for framebuffer is wanted, it should be done with ioremap in the driver. Note that further removal of the code can now be done, but that can be done seprately by the driver maintainers. Acked-by: Tomi Valkeinen Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/sram.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 363c91e44efb..3c8aa44f14da 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -29,10 +28,8 @@ #include #include #include -#include #include "sram.h" -#include "fb.h" /* XXX These "sideways" includes are a sign that something is wrong */ #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) @@ -112,8 +109,6 @@ static int is_sram_locked(void) */ static void __init omap_detect_sram(void) { - unsigned long reserved; - if (cpu_class_is_omap2()) { if (is_sram_locked()) { if (cpu_is_omap34xx()) { @@ -170,17 +165,6 @@ static void __init omap_detect_sram(void) omap_sram_size = 0x4000; } } - reserved = omapfb_reserve_sram(omap_sram_start, omap_sram_base, - omap_sram_size, - omap_sram_start + SRAM_BOOTLOADER_SZ, - omap_sram_size - SRAM_BOOTLOADER_SZ); - omap_sram_size -= reserved; - - reserved = omap_vram_reserve_sram(omap_sram_start, omap_sram_base, - omap_sram_size, - omap_sram_start + SRAM_BOOTLOADER_SZ, - omap_sram_size - SRAM_BOOTLOADER_SZ); - omap_sram_size -= reserved; omap_sram_ceil = omap_sram_base + omap_sram_size; } From a66cb3454f220f49f900646ebdc76cb943319eb7 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 4 Oct 2011 13:52:57 -0700 Subject: [PATCH 29/31] ARM: OMAP: Map SRAM later on with ioremap_exec() This allows us to remove omap hacks for map_io. Acked-by: Nicolas Pitre Reviewed-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/devices.c | 3 ++ arch/arm/mach-omap1/io.c | 2 - arch/arm/mach-omap2/io.c | 21 ++------ arch/arm/mach-omap2/io.h | 7 --- arch/arm/plat-omap/include/plat/common.h | 2 + arch/arm/plat-omap/sram.c | 69 +++++++----------------- 6 files changed, 28 insertions(+), 76 deletions(-) diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 36f26c3fa25e..38e1142ba71f 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -291,6 +292,8 @@ static int __init omap1_init_devices(void) if (!cpu_class_is_omap1()) return -ENODEV; + omap_sram_init(); + /* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index a16aab71922c..8140a4ed66e4 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -21,7 +21,6 @@ #include "clock.h" extern void omap_check_revision(void); -extern void omap_sram_init(void); /* * The machine specific code may provide the extra mapping besides the @@ -133,7 +132,6 @@ void omap1_init_early(void) */ omap1_clk_init(); omap1_mux_init(); - omap_sram_init(); } /* diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index e8123d010307..b42bbb8f252d 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -35,8 +35,8 @@ #include "clock2xxx.h" #include "clock3xxx.h" #include "clock44xx.h" -#include "io.h" +#include #include #include "voltage.h" #include "powerdomain.h" @@ -240,22 +240,11 @@ static struct map_desc omap44xx_io_desc[] __initdata = { }; #endif -static void __init _omap2_map_common_io(void) -{ - /* Normally devicemaps_init() would flush caches and tlb after - * mdesc->map_io(), but we must also do it here because of the CPU - * revision check below. - */ - local_flush_tlb_all(); - flush_cache_all(); -} - #ifdef CONFIG_SOC_OMAP2420 void __init omap242x_map_common_io(void) { iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc)); - _omap2_map_common_io(); } #endif @@ -264,7 +253,6 @@ void __init omap243x_map_common_io(void) { iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc)); - _omap2_map_common_io(); } #endif @@ -272,7 +260,6 @@ void __init omap243x_map_common_io(void) void __init omap34xx_map_common_io(void) { iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc)); - _omap2_map_common_io(); } #endif @@ -280,7 +267,6 @@ void __init omap34xx_map_common_io(void) void __init omapti816x_map_common_io(void) { iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc)); - _omap2_map_common_io(); } #endif @@ -288,7 +274,6 @@ void __init omapti816x_map_common_io(void) void __init omap44xx_map_common_io(void) { iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc)); - _omap2_map_common_io(); } #endif @@ -337,7 +322,6 @@ void __iomem *omap_irq_base; static void __init omap_common_init_early(void) { omap2_check_revision(); - omap_sram_init(); } static void __init omap_hwmod_init_postsetup(void) @@ -449,11 +433,12 @@ void __init omap4430_init_early(void) void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0, struct omap_sdrc_params *sdrc_cs1) { + omap_sram_init(); + if (cpu_is_omap24xx() || omap3_has_sdrc()) { omap2_sdrc_init(sdrc_cs0, sdrc_cs1); _omap2_init_reprogram_sdrc(); } - } /* diff --git a/arch/arm/mach-omap2/io.h b/arch/arm/mach-omap2/io.h index fd230c6cded5..e69de29bb2d1 100644 --- a/arch/arm/mach-omap2/io.h +++ b/arch/arm/mach-omap2/io.h @@ -1,7 +0,0 @@ - -#ifndef __MACH_OMAP2_IO_H__ -#define __MACH_OMAP2_IO_H__ - -extern int __init omap_sram_init(void); - -#endif /* __MACH_OMAP2_IO_H__ */ diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index 5eac3553f96d..ed85720c59c7 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -55,6 +55,8 @@ void am35xx_init_early(void); void ti816x_init_early(void); void omap4430_init_early(void); +void omap_sram_init(void); + /* * IO bases for various OMAP processors * Except the tap base, rest all the io bases diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 3c8aa44f14da..8b28664d1c62 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -38,16 +38,9 @@ #endif #define OMAP1_SRAM_PA 0x20000000 -#define OMAP1_SRAM_VA VMALLOC_END #define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) -#define OMAP2_SRAM_VA 0xfe400000 -#define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800) -#define OMAP3_SRAM_VA 0xfe400000 #define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000) -#define OMAP3_SRAM_PUB_VA (OMAP3_SRAM_VA + 0x8000) -#define OMAP4_SRAM_VA 0xfe400000 #define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000) -#define OMAP4_SRAM_PUB_VA (OMAP4_SRAM_VA + 0x4000) #if defined(CONFIG_ARCH_OMAP2PLUS) #define SRAM_BOOTLOADER_SZ 0x00 @@ -70,9 +63,9 @@ #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) static unsigned long omap_sram_start; -static unsigned long omap_sram_base; +static void __iomem *omap_sram_base; static unsigned long omap_sram_size; -static unsigned long omap_sram_ceil; +static void __iomem *omap_sram_ceil; /* * Depending on the target RAMFS firewall setup, the public usable amount of @@ -112,7 +105,6 @@ static void __init omap_detect_sram(void) if (cpu_class_is_omap2()) { if (is_sram_locked()) { if (cpu_is_omap34xx()) { - omap_sram_base = OMAP3_SRAM_PUB_VA; omap_sram_start = OMAP3_SRAM_PUB_PA; if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) || (omap_type() == OMAP2_DEVICE_TYPE_SEC)) { @@ -121,25 +113,20 @@ static void __init omap_detect_sram(void) omap_sram_size = 0x8000; /* 32K */ } } else if (cpu_is_omap44xx()) { - omap_sram_base = OMAP4_SRAM_PUB_VA; omap_sram_start = OMAP4_SRAM_PUB_PA; omap_sram_size = 0xa000; /* 40K */ } else { - omap_sram_base = OMAP2_SRAM_PUB_VA; omap_sram_start = OMAP2_SRAM_PUB_PA; omap_sram_size = 0x800; /* 2K */ } } else { if (cpu_is_omap34xx()) { - omap_sram_base = OMAP3_SRAM_VA; omap_sram_start = OMAP3_SRAM_PA; omap_sram_size = 0x10000; /* 64K */ } else if (cpu_is_omap44xx()) { - omap_sram_base = OMAP4_SRAM_VA; omap_sram_start = OMAP4_SRAM_PA; omap_sram_size = 0xe000; /* 56K */ } else { - omap_sram_base = OMAP2_SRAM_VA; omap_sram_start = OMAP2_SRAM_PA; if (cpu_is_omap242x()) omap_sram_size = 0xa0000; /* 640K */ @@ -148,7 +135,6 @@ static void __init omap_detect_sram(void) } } } else { - omap_sram_base = OMAP1_SRAM_VA; omap_sram_start = OMAP1_SRAM_PA; if (cpu_is_omap7xx()) @@ -165,24 +151,14 @@ static void __init omap_detect_sram(void) omap_sram_size = 0x4000; } } - - omap_sram_ceil = omap_sram_base + omap_sram_size; } -static struct map_desc omap_sram_io_desc[] __initdata = { - { /* .length gets filled in at runtime */ - .virtual = OMAP1_SRAM_VA, - .pfn = __phys_to_pfn(OMAP1_SRAM_PA), - .type = MT_MEMORY - } -}; - /* * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early. */ static void __init omap_map_sram(void) { - unsigned long base; + int cached = 1; if (omap_sram_size == 0) return; @@ -195,28 +171,18 @@ static void __init omap_map_sram(void) * the ARM may attempt to write cache lines back to SDRAM * which will cause the system to hang. */ - omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; + cached = 0; } - omap_sram_io_desc[0].virtual = omap_sram_base; - base = omap_sram_start; - base = ROUND_DOWN(base, PAGE_SIZE); - omap_sram_io_desc[0].pfn = __phys_to_pfn(base); - omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE); - iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); + omap_sram_start = ROUND_DOWN(omap_sram_start, PAGE_SIZE); + omap_sram_base = __arm_ioremap_exec(omap_sram_start, omap_sram_size, + cached); + if (!omap_sram_base) { + pr_err("SRAM: Could not map\n"); + return; + } - pr_info("SRAM: Mapped pa 0x%08llx to va 0x%08lx size: 0x%lx\n", - (long long) __pfn_to_phys(omap_sram_io_desc[0].pfn), - omap_sram_io_desc[0].virtual, - omap_sram_io_desc[0].length); - - /* - * Normally devicemaps_init() would flush caches and tlb after - * mdesc->map_io(), but since we're called from map_io(), we - * must do it here. - */ - local_flush_tlb_all(); - flush_cache_all(); + omap_sram_ceil = omap_sram_base + omap_sram_size; /* * Looks like we need to preserve some bootloader code at the @@ -235,13 +201,18 @@ static void __init omap_map_sram(void) */ void *omap_sram_push_address(unsigned long size) { - if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { + unsigned long available, new_ceil = (unsigned long)omap_sram_ceil; + + available = omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ); + + if (size > available) { pr_err("Not enough space in SRAM\n"); return NULL; } - omap_sram_ceil -= size; - omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, FNCPY_ALIGN); + new_ceil -= size; + new_ceil = ROUND_DOWN(new_ceil, FNCPY_ALIGN); + omap_sram_ceil = IOMEM(new_ceil); return (void *)omap_sram_ceil; } From 4c3cf90117f1f4906d5975aeccc5ffd414807fd2 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 4 Oct 2011 18:17:41 -0700 Subject: [PATCH 30/31] ARM: OMAP: Move set_globals initialization to happen in init_early Otherwise we can't do generic map_io as we currently rely on static mappings that work only because of arch_ioremap. Acked-by: Nicolas Pitre Reviewed-by: Santosh Shilimkar Tested-by: Santosh Shilimkar Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-ti8168evm.c | 1 - arch/arm/mach-omap2/common.c | 50 +++++++++++------------- arch/arm/mach-omap2/control.c | 14 ++----- arch/arm/mach-omap2/io.c | 14 ++++++- arch/arm/mach-omap2/omap-smp.c | 7 +++- arch/arm/mach-omap2/prcm.c | 19 +++------ arch/arm/mach-omap2/sdrc.c | 13 ++---- arch/arm/plat-omap/include/plat/common.h | 14 +++---- 8 files changed, 62 insertions(+), 70 deletions(-) diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c index 981ca00d6e29..b0a16d2f2388 100644 --- a/arch/arm/mach-omap2/board-ti8168evm.c +++ b/arch/arm/mach-omap2/board-ti8168evm.c @@ -37,7 +37,6 @@ static void __init ti8168_evm_init(void) static void __init ti8168_evm_map_io(void) { - omap2_set_globals_ti816x(); omapti816x_map_common_io(); } diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index de61f15c48e2..110e5b9db145 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -45,11 +45,11 @@ static void __init __omap2_set_globals(struct omap_globals *omap2_globals) static struct omap_globals omap242x_globals = { .class = OMAP242X_CLASS, .tap = OMAP2_L4_IO_ADDRESS(0x48014000), - .sdrc = OMAP2420_SDRC_BASE, - .sms = OMAP2420_SMS_BASE, - .ctrl = OMAP242X_CTRL_BASE, - .prm = OMAP2420_PRM_BASE, - .cm = OMAP2420_CM_BASE, + .sdrc = OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE), + .sms = OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE), + .ctrl = OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE), + .prm = OMAP2_L4_IO_ADDRESS(OMAP2420_PRM_BASE), + .cm = OMAP2_L4_IO_ADDRESS(OMAP2420_CM_BASE), }; void __init omap2_set_globals_242x(void) @@ -59,7 +59,6 @@ void __init omap2_set_globals_242x(void) void __init omap242x_map_io(void) { - omap2_set_globals_242x(); omap242x_map_common_io(); } #endif @@ -69,11 +68,11 @@ void __init omap242x_map_io(void) static struct omap_globals omap243x_globals = { .class = OMAP243X_CLASS, .tap = OMAP2_L4_IO_ADDRESS(0x4900a000), - .sdrc = OMAP243X_SDRC_BASE, - .sms = OMAP243X_SMS_BASE, - .ctrl = OMAP243X_CTRL_BASE, - .prm = OMAP2430_PRM_BASE, - .cm = OMAP2430_CM_BASE, + .sdrc = OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE), + .sms = OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE), + .ctrl = OMAP2_L4_IO_ADDRESS(OMAP243X_CTRL_BASE), + .prm = OMAP2_L4_IO_ADDRESS(OMAP2430_PRM_BASE), + .cm = OMAP2_L4_IO_ADDRESS(OMAP2430_CM_BASE), }; void __init omap2_set_globals_243x(void) @@ -83,7 +82,6 @@ void __init omap2_set_globals_243x(void) void __init omap243x_map_io(void) { - omap2_set_globals_243x(); omap243x_map_common_io(); } #endif @@ -93,11 +91,11 @@ void __init omap243x_map_io(void) static struct omap_globals omap3_globals = { .class = OMAP343X_CLASS, .tap = OMAP2_L4_IO_ADDRESS(0x4830A000), - .sdrc = OMAP343X_SDRC_BASE, - .sms = OMAP343X_SMS_BASE, - .ctrl = OMAP343X_CTRL_BASE, - .prm = OMAP3430_PRM_BASE, - .cm = OMAP3430_CM_BASE, + .sdrc = OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE), + .sms = OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE), + .ctrl = OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE), + .prm = OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE), + .cm = OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), }; void __init omap2_set_globals_3xxx(void) @@ -107,7 +105,6 @@ void __init omap2_set_globals_3xxx(void) void __init omap3_map_io(void) { - omap2_set_globals_3xxx(); omap34xx_map_common_io(); } @@ -122,9 +119,9 @@ void __init omap3_map_io(void) static struct omap_globals ti816x_globals = { .class = OMAP343X_CLASS, .tap = OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE), - .ctrl = TI816X_CTRL_BASE, - .prm = TI816X_PRCM_BASE, - .cm = TI816X_PRCM_BASE, + .ctrl = OMAP2_L4_IO_ADDRESS(TI816X_CTRL_BASE), + .prm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), + .cm = OMAP2_L4_IO_ADDRESS(TI816X_PRCM_BASE), }; void __init omap2_set_globals_ti816x(void) @@ -137,11 +134,11 @@ void __init omap2_set_globals_ti816x(void) static struct omap_globals omap4_globals = { .class = OMAP443X_CLASS, .tap = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE), - .ctrl = OMAP443X_SCM_BASE, - .ctrl_pad = OMAP443X_CTRL_BASE, - .prm = OMAP4430_PRM_BASE, - .cm = OMAP4430_CM_BASE, - .cm2 = OMAP4430_CM2_BASE, + .ctrl = OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE), + .ctrl_pad = OMAP2_L4_IO_ADDRESS(OMAP443X_CTRL_BASE), + .prm = OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE), + .cm = OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE), + .cm2 = OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE), }; void __init omap2_set_globals_443x(void) @@ -153,7 +150,6 @@ void __init omap2_set_globals_443x(void) void __init omap4_map_io(void) { - omap2_set_globals_443x(); omap44xx_map_common_io(); } #endif diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index aab884fecc55..e34d27f8c49c 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -149,17 +149,11 @@ static struct omap3_control_regs control_context; void __init omap2_set_globals_control(struct omap_globals *omap2_globals) { - /* Static mapping, never released */ - if (omap2_globals->ctrl) { - omap2_ctrl_base = ioremap(omap2_globals->ctrl, SZ_4K); - WARN_ON(!omap2_ctrl_base); - } + if (omap2_globals->ctrl) + omap2_ctrl_base = omap2_globals->ctrl; - /* Static mapping, never released */ - if (omap2_globals->ctrl_pad) { - omap4_ctrl_pad_base = ioremap(omap2_globals->ctrl_pad, SZ_4K); - WARN_ON(!omap4_ctrl_pad_base); - } + if (omap2_globals->ctrl_pad) + omap4_ctrl_pad_base = omap2_globals->ctrl_pad; } void __iomem *omap_ctrl_base_get(void) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index b42bbb8f252d..d5caac3698dd 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -44,6 +44,7 @@ #include "clockdomain.h" #include #include +#include /* * The machine specific code may provide the extra mapping besides the @@ -359,6 +360,7 @@ static void __init omap_hwmod_init_postsetup(void) void __init omap2420_init_early(void) { + omap2_set_globals_242x(); omap_common_init_early(); omap2xxx_voltagedomains_init(); omap242x_powerdomains_init(); @@ -370,6 +372,7 @@ void __init omap2420_init_early(void) void __init omap2430_init_early(void) { + omap2_set_globals_243x(); omap_common_init_early(); omap2xxx_voltagedomains_init(); omap243x_powerdomains_init(); @@ -385,6 +388,7 @@ void __init omap2430_init_early(void) */ void __init omap3_init_early(void) { + omap2_set_globals_3xxx(); omap_common_init_early(); omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); @@ -416,11 +420,19 @@ void __init am35xx_init_early(void) void __init ti816x_init_early(void) { - omap3_init_early(); + omap2_set_globals_ti816x(); + omap_common_init_early(); + omap3xxx_voltagedomains_init(); + omap3xxx_powerdomains_init(); + omap3xxx_clockdomains_init(); + omap3xxx_hwmod_init(); + omap_hwmod_init_postsetup(); + omap3xxx_clk_init(); } void __init omap4430_init_early(void) { + omap2_set_globals_443x(); omap_common_init_early(); omap44xx_voltagedomains_init(); omap44xx_powerdomains_init(); diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index ce65e9329c7b..11e25a4c4bd5 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -102,8 +102,11 @@ void __init smp_init_cpus(void) { unsigned int i, ncores; - /* Never released */ - scu_base = ioremap(OMAP44XX_SCU_BASE, SZ_256); + /* + * Currently we can't call ioremap here because + * SoC detection won't work until after init_early. + */ + scu_base = OMAP2_L4_IO_ADDRESS(OMAP44XX_SCU_BASE); BUG_ON(!scu_base); ncores = scu_get_core_count(scu_base); diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index 2e40a5cf0163..8db5f035eb0a 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -151,17 +151,10 @@ int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest, void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals) { - /* Static mapping, never released */ - if (omap2_globals->prm) { - prm_base = ioremap(omap2_globals->prm, SZ_8K); - WARN_ON(!prm_base); - } - if (omap2_globals->cm) { - cm_base = ioremap(omap2_globals->cm, SZ_8K); - WARN_ON(!cm_base); - } - if (omap2_globals->cm2) { - cm2_base = ioremap(omap2_globals->cm2, SZ_8K); - WARN_ON(!cm2_base); - } + if (omap2_globals->prm) + prm_base = omap2_globals->prm; + if (omap2_globals->cm) + cm_base = omap2_globals->cm; + if (omap2_globals->cm2) + cm2_base = omap2_globals->cm2; } diff --git a/arch/arm/mach-omap2/sdrc.c b/arch/arm/mach-omap2/sdrc.c index da6f3a63b5d5..8f2782874771 100644 --- a/arch/arm/mach-omap2/sdrc.c +++ b/arch/arm/mach-omap2/sdrc.c @@ -117,15 +117,10 @@ int omap2_sdrc_get_params(unsigned long r, void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals) { - /* Static mapping, never released */ - if (omap2_globals->sdrc) { - omap2_sdrc_base = ioremap(omap2_globals->sdrc, SZ_64K); - WARN_ON(!omap2_sdrc_base); - } - if (omap2_globals->sms) { - omap2_sms_base = ioremap(omap2_globals->sms, SZ_64K); - WARN_ON(!omap2_sms_base); - } + if (omap2_globals->sdrc) + omap2_sdrc_base = omap2_globals->sdrc; + if (omap2_globals->sms) + omap2_sms_base = omap2_globals->sms; } /** diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index ed85720c59c7..c50df4814f6f 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -65,13 +65,13 @@ void omap_sram_init(void); struct omap_globals { u32 class; /* OMAP class to detect */ void __iomem *tap; /* Control module ID code */ - unsigned long sdrc; /* SDRAM Controller */ - unsigned long sms; /* SDRAM Memory Scheduler */ - unsigned long ctrl; /* System Control Module */ - unsigned long ctrl_pad; /* PAD Control Module */ - unsigned long prm; /* Power and Reset Management */ - unsigned long cm; /* Clock Management */ - unsigned long cm2; + void __iomem *sdrc; /* SDRAM Controller */ + void __iomem *sms; /* SDRAM Memory Scheduler */ + void __iomem *ctrl; /* System Control Module */ + void __iomem *ctrl_pad; /* PAD Control Module */ + void __iomem *prm; /* Power and Reset Management */ + void __iomem *cm; /* Clock Management */ + void __iomem *cm2; }; void omap2_set_globals_242x(void); From 8aca3ab5865f8cfbde841b6daf9442cc2279ced3 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 5 Oct 2011 17:22:39 -0700 Subject: [PATCH 31/31] ARM: OMAP: Warn if omap_ioremap is called before SoC detection We don't have cpu_is_omapxxxx SoC detection initialized until SoC detection is initialized from init_early. Note that with the common map_io we should no longer need cpu_is_omapxxxx for ioremap. Acked-by: Nicolas Pitre Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/io.c | 1 + arch/arm/mach-omap2/io.c | 1 + arch/arm/plat-omap/include/plat/io.h | 2 ++ arch/arm/plat-omap/io.c | 10 ++++++++++ 4 files changed, 14 insertions(+) diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index 8140a4ed66e4..fd9eb0984121 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -121,6 +121,7 @@ void __init omap16xx_map_io(void) void omap1_init_early(void) { omap_check_revision(); + omap_ioremap_init(); /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort * on a Posted Write in the TIPB Bridge". diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index d5caac3698dd..aa96538f3fee 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -323,6 +323,7 @@ void __iomem *omap_irq_base; static void __init omap_common_init_early(void) { omap2_check_revision(); + omap_ioremap_init(); } static void __init omap_hwmod_init_postsetup(void) diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h index c0c785073141..5ffbea60be45 100644 --- a/arch/arm/plat-omap/include/plat/io.h +++ b/arch/arm/plat-omap/include/plat/io.h @@ -247,6 +247,8 @@ * NOTE: Please use ioremap + __raw_read/write where possible instead of these */ +void omap_ioremap_init(void); + extern u8 omap_readb(u32 pa); extern u16 omap_readw(u32 pa); extern u32 omap_readl(u32 pa); diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c index f1ecfa9fc61d..1bbcbde76400 100644 --- a/arch/arm/plat-omap/io.c +++ b/arch/arm/plat-omap/io.c @@ -23,11 +23,16 @@ #define BETWEEN(p,st,sz) ((p) >= (st) && (p) < ((st) + (sz))) #define XLATE(p,pst,vst) ((void __iomem *)((p) - (pst) + (vst))) +static int initialized; + /* * Intercept ioremap() requests for addresses in our fixed mapping regions. */ void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type) { + + WARN(!initialized, "Do not use ioremap before init_early\n"); + #ifdef CONFIG_ARCH_OMAP1 if (cpu_class_is_omap1()) { if (BETWEEN(p, OMAP1_IO_PHYS, OMAP1_IO_SIZE)) @@ -139,3 +144,8 @@ void omap_iounmap(volatile void __iomem *addr) __iounmap(addr); } EXPORT_SYMBOL(omap_iounmap); + +void __init omap_ioremap_init(void) +{ + initialized++; +}