From 63aa945b1013c34b145dcf218d4ea323cbd93f86 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 1 Jun 2015 19:22:10 -0600 Subject: memory: omap-gpmc: Add Kconfig option for debug We support decoding the bootloader values if DEBUG is defined. But we also need to change the struct omap_hwmod flags to have HWMOD_INIT_NO_RESET to avoid the GPMC being reset during the boot. Otherwise just the default timings will be displayed instead of the bootloader configured timings. This also allows us to clean up the various GPMC related hwmod flags. For debugging, we only need HWMOD_INIT_NO_RESET, and HWMOD_INIT_NO_IDLE is not needed. Cc: Brian Hutchinson Cc: Paul Walmsley Cc: Roger Quadros Signed-off-by: Tony Lindgren Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.h | 6 ++++++ arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 12 ++---------- arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c | 3 ++- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 12 ++---------- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 11 ++--------- arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 4 ++-- arch/arm/mach-omap2/omap_hwmod_81xx_data.c | 2 ++ 7 files changed, 18 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 9611c91d9b82..b5d27ec81610 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -109,6 +109,12 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3; #define DEBUG_OMAPUART_FLAGS (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET) +#ifdef CONFIG_OMAP_GPMC_DEBUG +#define DEBUG_OMAP_GPMC_HWMOD_FLAGS HWMOD_INIT_NO_RESET +#else +#define DEBUG_OMAP_GPMC_HWMOD_FLAGS 0 +#endif + #if defined(CONFIG_DEBUG_OMAP2UART1) #undef DEBUG_OMAP2UART1_FLAGS #define DEBUG_OMAP2UART1_FLAGS DEBUG_OMAPUART_FLAGS diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index 8821b9d6bae4..6dcfd03ced8f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -762,16 +762,8 @@ struct omap_hwmod omap2xxx_gpmc_hwmod = { .name = "gpmc", .class = &omap2xxx_gpmc_hwmod_class, .main_clk = "gpmc_fck", - /* - * XXX HWMOD_INIT_NO_RESET should not be needed for this IP - * block. It is not being added due to any known bugs with - * resetting the GPMC IP block, but rather because any timings - * set by the bootloader are not being correctly programmed by - * the kernel from the board file or DT data. - * HWMOD_INIT_NO_RESET should be removed ASAP. - */ - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | - HWMOD_NO_IDLEST), + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ + .flags = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS, .prcm = { .omap2 = { .prcm_reg_id = 3, diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c index cabc5695b504..ae0cb673a3d1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c @@ -668,7 +668,8 @@ struct omap_hwmod am33xx_gpmc_hwmod = { .name = "gpmc", .class = &am33xx_gpmc_hwmod_class, .clkdm_name = "l3s_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ + .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, .main_clk = "l3s_gclk", .prcm = { .omap4 = { diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 4e8e93c398db..0ca4d3fb7df6 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -2169,16 +2169,8 @@ static struct omap_hwmod omap3xxx_gpmc_hwmod = { .clkdm_name = "core_l3_clkdm", .mpu_irqs = omap3xxx_gpmc_irqs, .main_clk = "gpmc_fck", - /* - * XXX HWMOD_INIT_NO_RESET should not be needed for this IP - * block. It is not being added due to any known bugs with - * resetting the GPMC IP block, but rather because any timings - * set by the bootloader are not being correctly programmed by - * the kernel from the board file or DT data. - * HWMOD_INIT_NO_RESET should be removed ASAP. - */ - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | - HWMOD_NO_IDLEST), + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ + .flags = HWMOD_NO_IDLEST | DEBUG_OMAP_GPMC_HWMOD_FLAGS, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index f5e68a782025..43eebf2c59e2 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1188,15 +1188,8 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = { .name = "gpmc", .class = &omap44xx_gpmc_hwmod_class, .clkdm_name = "l3_2_clkdm", - /* - * XXX HWMOD_INIT_NO_RESET should not be needed for this IP - * block. It is not being added due to any known bugs with - * resetting the GPMC IP block, but rather because any timings - * set by the bootloader are not being correctly programmed by - * the kernel from the board file or DT data. - * HWMOD_INIT_NO_RESET should be removed ASAP. - */ - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ + .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET, diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 0e64c2fac0b5..a0411f32e8b1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -819,8 +819,8 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = { .name = "gpmc", .class = &dra7xx_gpmc_hwmod_class, .clkdm_name = "l3main1_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET | - HWMOD_SWSUP_SIDLE), + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ + .flags = HWMOD_SWSUP_SIDLE | DEBUG_OMAP_GPMC_HWMOD_FLAGS, .main_clk = "l3_iclk_div", .prcm = { .omap4 = { diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index cab1eb61ac96..c92413769144 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -478,6 +478,8 @@ static struct omap_hwmod dm81xx_gpmc_hwmod = { .clkdm_name = "alwon_l3s_clkdm", .class = &dm81xx_gpmc_hwmod_class, .main_clk = "sysclk6_ck", + /* Skip reset for CONFIG_OMAP_GPMC_DEBUG for bootloader timings */ + .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, .prcm = { .omap4 = { .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL, -- cgit v1.2.3 From fabbe6df130a46d5b5e7484b2273d69c4be3012a Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Mon, 1 Jun 2015 19:22:11 -0600 Subject: ARM: OMAP: AM43xx hwmod: Add data for am43xx emif hwmod Without a hwmod for am43xx emif use counting for emif clockdomain does not happen correctly so it may be shut off by pm code unintentionally. Signed-off-by: Dave Gerlach [paul@pwsan.com: updated to apply] Signed-off-by: Paul Walmsley --- .../mach-omap2/omap_hwmod_33xx_43xx_common_data.h | 1 + .../mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c | 13 +++++++++++++ arch/arm/mach-omap2/omap_hwmod_33xx_data.c | 13 ------------- arch/arm/mach-omap2/omap_hwmod_43xx_data.c | 22 ++++++++++++++++++++++ arch/arm/mach-omap2/prcm43xx.h | 2 ++ 5 files changed, 38 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h index 130332c0534d..7f737965f543 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h @@ -145,6 +145,7 @@ extern struct omap_hwmod am33xx_uart5_hwmod; extern struct omap_hwmod am33xx_uart6_hwmod; extern struct omap_hwmod am33xx_wd_timer1_hwmod; +extern struct omap_hwmod_class am33xx_emif_hwmod_class; extern struct omap_hwmod_class am33xx_l4_hwmod_class; extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class; extern struct omap_hwmod_class am33xx_control_hwmod_class; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c index ae0cb673a3d1..907a452b78ea 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c @@ -202,6 +202,19 @@ struct omap_hwmod am33xx_prcm_hwmod = { .clkdm_name = "l4_wkup_clkdm", }; +/* + * 'emif' class + * instance(s): emif + */ +static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = { + .rev_offs = 0x0000, +}; + +struct omap_hwmod_class am33xx_emif_hwmod_class = { + .name = "emif", + .sysc = &am33xx_emif_sysc, +}; + /* * 'aes0' class */ diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 0cf7b563dcd1..cc0791d9125b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -34,19 +34,6 @@ * IP blocks */ -/* - * 'emif' class - * instance(s): emif - */ -static struct omap_hwmod_class_sysconfig am33xx_emif_sysc = { - .rev_offs = 0x0000, -}; - -static struct omap_hwmod_class am33xx_emif_hwmod_class = { - .name = "emif", - .sysc = &am33xx_emif_sysc, -}; - /* emif */ static struct omap_hwmod am33xx_emif_hwmod = { .name = "emif", diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index 17e8004fc20f..215d5efa0dba 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -24,6 +24,20 @@ /* IP blocks */ +static struct omap_hwmod am43xx_emif_hwmod = { + .name = "emif", + .class = &am33xx_emif_hwmod_class, + .clkdm_name = "emif_clkdm", + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "dpll_ddr_m2_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + static struct omap_hwmod am43xx_l4_hs_hwmod = { .name = "l4_hs", .class = &am33xx_l4_hwmod_class, @@ -583,6 +597,13 @@ static struct omap_hwmod am43xx_vpfe1_hwmod = { }; /* Interfaces */ +static struct omap_hwmod_ocp_if am43xx_l3_main__emif = { + .master = &am33xx_l3_main_hwmod, + .slave = &am43xx_emif_hwmod, + .clk = "dpll_core_m4_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_ocp_if am43xx_l3_main__l4_hs = { .master = &am33xx_l3_main_hwmod, .slave = &am43xx_l4_hs_hwmod, @@ -918,6 +939,7 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l3_main__l3_instr, &am33xx_l3_main__gfx, &am33xx_l3_s__l3_main, + &am43xx_l3_main__emif, &am33xx_pruss__l3_main, &am43xx_wkup_m3__l4_wkup, &am33xx_gfx__l3_main, diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h index d0261996db6d..7eebc27fa892 100644 --- a/arch/arm/mach-omap2/prcm43xx.h +++ b/arch/arm/mach-omap2/prcm43xx.h @@ -146,4 +146,6 @@ #define AM43XX_CM_PER_HDQ1W_CLKCTRL_OFFSET 0x04a0 #define AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET 0x0068 #define AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET 0x0070 +#define AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET 0x0720 + #endif -- cgit v1.2.3 From 6da233589f26ebd891d507a5a134ab43267006f2 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 26 Feb 2015 14:49:51 +0100 Subject: ARM: OMAP2+: Return correct error values from device and hwmod MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this patch function pm_runtime_get_sync() returns 0 even when some omap subfunction fails. This patch properly propagate error codes from omap functions back to caller. This patch fix problem, when loading omap-aes driver in qemu cause kernel oops. Signed-off-by: Pali Rohár [paul@pwsan.com: fix a checkpatch warning] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_device.c | 30 +++++++++++++++++------------- arch/arm/mach-omap2/omap_hwmod.c | 10 ++++++---- 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 166b18f515a2..4a7303cf563e 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -224,13 +224,13 @@ static int _omap_device_notifier_call(struct notifier_block *nb, */ static int _omap_device_enable_hwmods(struct omap_device *od) { + int ret = 0; int i; for (i = 0; i < od->hwmods_cnt; i++) - omap_hwmod_enable(od->hwmods[i]); + ret |= omap_hwmod_enable(od->hwmods[i]); - /* XXX pass along return value here? */ - return 0; + return ret; } /** @@ -241,13 +241,13 @@ static int _omap_device_enable_hwmods(struct omap_device *od) */ static int _omap_device_idle_hwmods(struct omap_device *od) { + int ret = 0; int i; for (i = 0; i < od->hwmods_cnt; i++) - omap_hwmod_idle(od->hwmods[i]); + ret |= omap_hwmod_idle(od->hwmods[i]); - /* XXX pass along return value here? */ - return 0; + return ret; } /* Public functions for use by core code */ @@ -595,18 +595,20 @@ static int _od_runtime_suspend(struct device *dev) int ret; ret = pm_generic_runtime_suspend(dev); + if (ret) + return ret; - if (!ret) - omap_device_idle(pdev); - - return ret; + return omap_device_idle(pdev); } static int _od_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); + int ret; - omap_device_enable(pdev); + ret = omap_device_enable(pdev); + if (ret) + return ret; return pm_generic_runtime_resume(dev); } @@ -743,7 +745,8 @@ int omap_device_enable(struct platform_device *pdev) ret = _omap_device_enable_hwmods(od); - od->_state = OMAP_DEVICE_STATE_ENABLED; + if (ret == 0) + od->_state = OMAP_DEVICE_STATE_ENABLED; return ret; } @@ -773,7 +776,8 @@ int omap_device_idle(struct platform_device *pdev) ret = _omap_device_idle_hwmods(od); - od->_state = OMAP_DEVICE_STATE_IDLE; + if (ret == 0) + od->_state = OMAP_DEVICE_STATE_IDLE; return ret; } diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 752969ff9de0..d78c12e7cb5e 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3318,16 +3318,17 @@ int omap_hwmod_enable(struct omap_hwmod *oh) */ int omap_hwmod_idle(struct omap_hwmod *oh) { + int r; unsigned long flags; if (!oh) return -EINVAL; spin_lock_irqsave(&oh->_lock, flags); - _idle(oh); + r = _idle(oh); spin_unlock_irqrestore(&oh->_lock, flags); - return 0; + return r; } /** @@ -3340,16 +3341,17 @@ int omap_hwmod_idle(struct omap_hwmod *oh) */ int omap_hwmod_shutdown(struct omap_hwmod *oh) { + int r; unsigned long flags; if (!oh) return -EINVAL; spin_lock_irqsave(&oh->_lock, flags); - _shutdown(oh); + r = _shutdown(oh); spin_unlock_irqrestore(&oh->_lock, flags); - return 0; + return r; } /* -- cgit v1.2.3 From a55a744582e0dc106537ba5e508c340c39cfe454 Mon Sep 17 00:00:00 2001 From: Pali Rohár Date: Thu, 26 Feb 2015 14:49:52 +0100 Subject: ARM: OMAP3: Fix crypto support for HS devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register crypto hwmod links only if they are not disabled in DT. If DT information is missing, enable them only for GP devices. Before this patch crypto hwmod links were always disabled for all HS devices and it was not possible to use omap-aes and omap-sham linux drivers. Signed-off-by: Pali Rohár Acked-by: Pavel Machek [paul@pwsan.com: move the complex IP-block presence heuristics into their own function to simplify the code; fix some checkpatch warnings] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 107 +++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 0ca4d3fb7df6..dc55f8dedf2c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3736,29 +3736,54 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { /* GP-only hwmod links */ static struct omap_hwmod_ocp_if *omap34xx_gp_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l4_sec__timer12, - &omap3xxx_l4_core__sham, - &omap3xxx_l4_core__aes, NULL }; static struct omap_hwmod_ocp_if *omap36xx_gp_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l4_sec__timer12, - &omap3xxx_l4_core__sham, - &omap3xxx_l4_core__aes, NULL }; static struct omap_hwmod_ocp_if *am35xx_gp_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l4_sec__timer12, - /* - * Apparently the SHA/MD5 and AES accelerator IP blocks are - * only present on some AM35xx chips, and no one knows which - * ones. See - * http://www.spinics.net/lists/arm-kernel/msg215466.html So - * if you need these IP blocks on an AM35xx, try uncommenting - * the following lines. - */ + NULL +}; + +/* crypto hwmod links */ +static struct omap_hwmod_ocp_if *omap34xx_sham_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_core__sham, + NULL +}; + +static struct omap_hwmod_ocp_if *omap34xx_aes_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_core__aes, + NULL +}; + +static struct omap_hwmod_ocp_if *omap36xx_sham_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_core__sham, + NULL +}; + +static struct omap_hwmod_ocp_if *omap36xx_aes_hwmod_ocp_ifs[] __initdata = { + &omap3xxx_l4_core__aes, + NULL +}; + +/* + * Apparently the SHA/MD5 and AES accelerator IP blocks are + * only present on some AM35xx chips, and no one knows which + * ones. See + * http://www.spinics.net/lists/arm-kernel/msg215466.html So + * if you need these IP blocks on an AM35xx, try uncommenting + * the following lines. + */ +static struct omap_hwmod_ocp_if *am35xx_sham_hwmod_ocp_ifs[] __initdata = { /* &omap3xxx_l4_core__sham, */ + NULL +}; + +static struct omap_hwmod_ocp_if *am35xx_aes_hwmod_ocp_ifs[] __initdata = { /* &omap3xxx_l4_core__aes, */ NULL }; @@ -3860,10 +3885,41 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_hwmod_ocp_ifs[] __initdata = { NULL }; +/** + * omap3xxx_hwmod_is_hs_ip_block_usable - is a security IP block accessible? + * @bus: struct device_node * for the top-level OMAP DT data + * @dev_name: device name used in the DT file + * + * Determine whether a "secure" IP block @dev_name is usable by Linux. + * There doesn't appear to be a 100% reliable way to determine this, + * so we rely on heuristics. If @bus is null, meaning there's no DT + * data, then we only assume the IP block is accessible if the OMAP is + * fused as a 'general-purpose' SoC. If however DT data is present, + * test to see if the IP block is described in the DT data and set to + * 'status = "okay"'. If so then we assume the ODM has configured the + * OMAP firewalls to allow access to the IP block. + * + * Return: 0 if device named @dev_name is not likely to be accessible, + * or 1 if it is likely to be accessible. + */ +static int __init omap3xxx_hwmod_is_hs_ip_block_usable(struct device_node *bus, + const char *dev_name) +{ + if (!bus) + return (omap_type() == OMAP2_DEVICE_TYPE_GP) ? 1 : 0; + + if (of_device_is_available(of_find_node_by_name(bus, dev_name))) + return 1; + + return 0; +} + int __init omap3xxx_hwmod_init(void) { int r; - struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL; + struct omap_hwmod_ocp_if **h = NULL, **h_gp = NULL, **h_sham = NULL; + struct omap_hwmod_ocp_if **h_aes = NULL; + struct device_node *bus = NULL; unsigned int rev; omap_hwmod_init(); @@ -3885,13 +3941,19 @@ int __init omap3xxx_hwmod_init(void) rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) { h = omap34xx_hwmod_ocp_ifs; h_gp = omap34xx_gp_hwmod_ocp_ifs; + h_sham = omap34xx_sham_hwmod_ocp_ifs; + h_aes = omap34xx_aes_hwmod_ocp_ifs; } else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { h = am35xx_hwmod_ocp_ifs; h_gp = am35xx_gp_hwmod_ocp_ifs; + h_sham = am35xx_sham_hwmod_ocp_ifs; + h_aes = am35xx_aes_hwmod_ocp_ifs; } else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2) { h = omap36xx_hwmod_ocp_ifs; h_gp = omap36xx_gp_hwmod_ocp_ifs; + h_sham = omap36xx_sham_hwmod_ocp_ifs; + h_aes = omap36xx_aes_hwmod_ocp_ifs; } else { WARN(1, "OMAP3 hwmod family init: unknown chip type\n"); return -EINVAL; @@ -3908,6 +3970,25 @@ int __init omap3xxx_hwmod_init(void) return r; } + /* + * Register crypto hwmod links only if they are not disabled in DT. + * If DT information is missing, enable them only for GP devices. + */ + + if (of_have_populated_dt()) + bus = of_find_node_by_name(NULL, "ocp"); + + if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) { + r = omap_hwmod_register_links(h_sham); + if (r < 0) + return r; + } + + if (h_aes && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "aes")) { + r = omap_hwmod_register_links(h_aes); + if (r < 0) + return r; + } /* * Register hwmod links specific to certain ES levels of a -- cgit v1.2.3