Re: [PATCH 1/2] phy: ti-pipe3: Disable clocks on system suspend
Kishon, On 09/01/15 15:57, Kishon Vijay Abraham I wrote: Hi Roger, On Friday 19 December 2014 05:35 PM, Roger Quadros wrote: On system suspend, the runtime_suspend() driver hook doesn't get called and so the clocks are not disabled in the driver. This causes the L3INIT_960M_GFCLK and L3INIT_480M_GFCLK to remain active on the DRA7 platform while in system suspend. Add suspend/resume hooks to the driver. In case of pcie-phy, the runtime_suspend hook gets called after This contradicts with the first line of your commit message. Is pcie-phy driver is an exception? Yes in the pcie-phy case it behaves differently. I'll rewrite the message. cheers, -roger Thanks Kishon the suspend hook so we introduce a flag phy-enabled to keep track if our clocks are enabled or not to prevent multiple enable/disables. Move enabling/disabling clock code into helper functions. Reported-by: Nishant Menon n...@ti.com Signed-off-by: Roger Quadros rog...@ti.com -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/2] phy: ti-pipe3: Fix SATA across suspend/resume
On 09/01/15 15:59, Kishon Vijay Abraham I wrote: Hi Roger, On Thursday 08 January 2015 04:47 PM, Roger Quadros wrote: Failed test case: Boot without SATA drive connected. Suspend/resume the board and then connect SATA drive. It fails to enumerate. Due to Errata i783 SATA Lockup After SATA DPLL Unlock/Relock we can't allow SATA DPLL to be in the unlocked state. The SATA refclk (sata_ref_clk) is the source of the SATA_DPLL. Till now this clock was controlled by the AHCI SATA driver and was being shut off during system suspend (if the SATA drive was not already attached) causing the SATA DPLL to be unlocked and so causing errata i783. To prevent sata_ref_clk from being disabled, we move the control of this clock from the SATA AHCI driver to the SATA PHY driver and prevent it from being disabled. This also fixes the issue of SATA not working on OMAP5/DRA7 when AHCI platform driver is built as a module. I feel the dt patches and the PHY patches can go separately. Can you split and re-send? OK. will re-send. cheers, -roger -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v8 1/2] clk: Make clk API return per-user struct clk instances
Moves clock state to struct clk_core, but takes care to change as little API as possible. struct clk_hw still has a pointer to a struct clk, which is the implementation's per-user clk instance, for backwards compatibility. The struct clk that clk_get_parent() returns isn't owned by the caller, but by the clock implementation, so the former shouldn't call clk_put() on it. Because some boards in mach-omap2 still register clocks statically, their clock registration had to be updated to take into account that the clock information is stored in struct clk_core now. Signed-off-by: Tomeu Vizoso tomeu.viz...@collabora.com --- v7: * Add stub for __of_clk_get_by_name to fix builds without OF v6: * Guard against NULL pointer v4: * Remove unused function __clk_core_to_clk * Use core more often as the name for struct clk_core* variables * Make sure we don't lose information about the caller in of_clk_get_* v3: * Rebase on top of linux-next 20141009 v2: * Remove exported functions that aren't really used outside clk.c * Rename new internal functions to clk_core_ prefix * Remove redundant checks for error pointers in *_get_parent * Change __clk_create_clk to take a struct clk_hw instead * Match the original error behavior in clk_get_sys --- arch/arm/mach-omap2/cclock3xxx_data.c | 108 -- arch/arm/mach-omap2/clock.h | 11 +- arch/arm/mach-omap2/clock_common_data.c | 5 +- drivers/clk/clk.c | 644 drivers/clk/clk.h | 5 + drivers/clk/clkdev.c| 80 +++- include/linux/clk-private.h | 35 +- include/linux/clk-provider.h| 9 +- 8 files changed, 584 insertions(+), 313 deletions(-) diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c index 644ff32..4305105 100644 --- a/arch/arm/mach-omap2/cclock3xxx_data.c +++ b/arch/arm/mach-omap2/cclock3xxx_data.c @@ -82,7 +82,7 @@ DEFINE_CLK_MUX(osc_sys_ck, osc_sys_ck_parent_names, NULL, 0x0, OMAP3430_PRM_CLKSEL, OMAP3430_SYS_CLKIN_SEL_SHIFT, OMAP3430_SYS_CLKIN_SEL_WIDTH, 0x0, NULL); -DEFINE_CLK_DIVIDER(sys_ck, osc_sys_ck, osc_sys_ck, 0x0, +DEFINE_CLK_DIVIDER(sys_ck, osc_sys_ck, osc_sys_ck_core, 0x0, OMAP3430_PRM_CLKSRC_CTRL, OMAP_SYSCLKDIV_SHIFT, OMAP_SYSCLKDIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); @@ -132,7 +132,7 @@ static struct clk_hw_omap dpll3_ck_hw = { DEFINE_STRUCT_CLK(dpll3_ck, dpll3_ck_parent_names, dpll3_ck_ops); -DEFINE_CLK_DIVIDER(dpll3_m2_ck, dpll3_ck, dpll3_ck, 0x0, +DEFINE_CLK_DIVIDER(dpll3_m2_ck, dpll3_ck, dpll3_ck_core, 0x0, OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT, OMAP3430_CORE_DPLL_CLKOUT_DIV_WIDTH, @@ -149,12 +149,12 @@ static const struct clk_ops core_ck_ops = {}; DEFINE_STRUCT_CLK_HW_OMAP(core_ck, NULL); DEFINE_STRUCT_CLK(core_ck, core_ck_parent_names, core_ck_ops); -DEFINE_CLK_DIVIDER(l3_ick, core_ck, core_ck, 0x0, +DEFINE_CLK_DIVIDER(l3_ick, core_ck, core_ck_core, 0x0, OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), OMAP3430_CLKSEL_L3_SHIFT, OMAP3430_CLKSEL_L3_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); -DEFINE_CLK_DIVIDER(l4_ick, l3_ick, l3_ick, 0x0, +DEFINE_CLK_DIVIDER(l4_ick, l3_ick, l3_ick_core, 0x0, OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL), OMAP3430_CLKSEL_L4_SHIFT, OMAP3430_CLKSEL_L4_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); @@ -275,9 +275,9 @@ static struct clk_hw_omap dpll1_ck_hw = { DEFINE_STRUCT_CLK(dpll1_ck, dpll3_ck_parent_names, dpll1_ck_ops); -DEFINE_CLK_FIXED_FACTOR(dpll1_x2_ck, dpll1_ck, dpll1_ck, 0x0, 2, 1); +DEFINE_CLK_FIXED_FACTOR(dpll1_x2_ck, dpll1_ck, dpll1_ck_core, 0x0, 2, 1); -DEFINE_CLK_DIVIDER(dpll1_x2m2_ck, dpll1_x2_ck, dpll1_x2_ck, 0x0, +DEFINE_CLK_DIVIDER(dpll1_x2m2_ck, dpll1_x2_ck, dpll1_x2_ck_core, 0x0, OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL2_PLL), OMAP3430_MPU_DPLL_CLKOUT_DIV_SHIFT, OMAP3430_MPU_DPLL_CLKOUT_DIV_WIDTH, @@ -292,7 +292,7 @@ static const char *mpu_ck_parent_names[] = { DEFINE_STRUCT_CLK_HW_OMAP(mpu_ck, mpu_clkdm); DEFINE_STRUCT_CLK(mpu_ck, mpu_ck_parent_names, core_l4_ick_ops); -DEFINE_CLK_DIVIDER(arm_fck, mpu_ck, mpu_ck, 0x0, +DEFINE_CLK_DIVIDER(arm_fck, mpu_ck, mpu_ck_core, 0x0, OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), OMAP3430_ST_MPU_CLK_SHIFT, OMAP3430_ST_MPU_CLK_WIDTH, 0x0, NULL); @@ -424,7 +424,7 @@ static const struct clk_div_table dpll4_mx_ck_div_table[] = { { .div = 0 }, }; -DEFINE_CLK_DIVIDER(dpll4_m5_ck, dpll4_ck, dpll4_ck, 0x0, +DEFINE_CLK_DIVIDER(dpll4_m5_ck, dpll4_ck, dpll4_ck_core, 0x0, OMAP_CM_REGADDR(OMAP3430_CAM_MOD,
[PATCH RESEND v8 2/2] clk: Add floor and ceiling constraints to clock rates
Adds a way for clock consumers to set maximum and minimum rates. This can be used for thermal drivers to set ceiling rates, or by misc. drivers to set floor rates to assure a minimum performance level. Changes the signature of the determine_rate callback by adding the parameters floor_rate and ceiling_rate. Signed-off-by: Tomeu Vizoso tomeu.viz...@collabora.com --- v7: * Update a few more instances in new code v6: * Take the prepare lock before removing a per-user clk * Init per-user clks list before adding the first clk * Pass the constraints to determine_rate and let clk implementations deal with constraints * Add clk_set_rate_range v5: * Initialize clk.ceiling_constraint to ULONG_MAX * Warn about inconsistent constraints v4: * Copy function docs from header * Move WARN out of critical section * Refresh rate after removing a per-user clk * Rename clk_core.per_user_clks to clk_core.clks * Store requested rate and re-apply it when constraints are updated --- Documentation/clk.txt | 2 + arch/arm/mach-omap2/dpll3xxx.c | 2 + arch/arm/mach-omap2/dpll44xx.c | 2 + arch/mips/alchemy/common/clock.c| 8 ++ drivers/clk/at91/clk-programmable.c | 2 + drivers/clk/bcm/clk-kona.c | 2 + drivers/clk/clk-composite.c | 9 +- drivers/clk/clk.c | 160 +--- drivers/clk/hisilicon/clk-hi3620.c | 2 + drivers/clk/mmp/clk-mix.c | 2 + drivers/clk/qcom/clk-pll.c | 1 + drivers/clk/qcom/clk-rcg.c | 10 ++- drivers/clk/qcom/clk-rcg2.c | 6 ++ drivers/clk/sunxi/clk-factors.c | 2 + drivers/clk/sunxi/clk-sun6i-ar100.c | 2 + include/linux/clk-private.h | 6 ++ include/linux/clk-provider.h| 11 ++- include/linux/clk.h | 28 +++ include/linux/clk/ti.h | 4 + 19 files changed, 224 insertions(+), 37 deletions(-) diff --git a/Documentation/clk.txt b/Documentation/clk.txt index 4ff8462..8ebd665 100644 --- a/Documentation/clk.txt +++ b/Documentation/clk.txt @@ -73,6 +73,8 @@ the operations defined in clk.h: unsigned long *parent_rate); long(*determine_rate)(struct clk_hw *hw, unsigned long rate, + unsigned long floor_rate, + unsigned long ceiling_rate, unsigned long *best_parent_rate, struct clk_hw **best_parent_clk); int (*set_parent)(struct clk_hw *hw, u8 index); diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index c2da2a0..b25375c 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -473,6 +473,8 @@ void omap3_noncore_dpll_disable(struct clk_hw *hw) * in failure. */ long omap3_noncore_dpll_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long floor_rate, + unsigned long ceiling_rate, unsigned long *best_parent_rate, struct clk_hw **best_parent_clk) { diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c index 0e58e5a..579fa18 100644 --- a/arch/arm/mach-omap2/dpll44xx.c +++ b/arch/arm/mach-omap2/dpll44xx.c @@ -222,6 +222,8 @@ out: * in failure. */ long omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, unsigned long rate, + unsigned long floor_rate, + unsigned long ceiling_rate, unsigned long *best_parent_rate, struct clk_hw **best_parent_clk) { diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c index 48a9dfc..731bedd 100644 --- a/arch/mips/alchemy/common/clock.c +++ b/arch/mips/alchemy/common/clock.c @@ -373,6 +373,8 @@ static long alchemy_calc_div(unsigned long rate, unsigned long prate, } static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate, + unsigned long floor_rate, + unsigned long ceiling_rate, unsigned long *best_parent_rate, struct clk_hw **best_parent_clk, int scale, int maxdiv) @@ -546,6 +548,8 @@ static unsigned long alchemy_clk_fgv1_recalc(struct clk_hw *hw, } static long alchemy_clk_fgv1_detr(struct clk_hw *hw, unsigned long rate, + unsigned long floor_rate, +
Re: [PATCH v2 00/21] irqchip: gic: killing gic_arch_extn and co, slowly
On Wed, Jan 7, 2015 at 11:42 AM, Marc Zyngier marc.zyng...@arm.com wrote: The gic_arch_extn hack that a number of platform use has been nagging me for too long. It is only there for the benefit of a few platform, and yet it impacts all GIC users. Moreover, it gives people the wrong idea (let's use it to put some new custom hack in there...). But now that stacked irq domains have landed in -next, the time has come for gic_arch_extn to meet the Big Bit Bucket. [...] - This actively *breaks* existing setups. Once you boot a new kernel with an old DT, suspend/resume *will* be broken. Old kernels on a new DT won't even boot! You've been warned. This really outline the necessity of actually describing the HW in device trees... Just to be clear, you need some agreement from the maintainers of those platforms before doing this. It doesn't appear there is disagreement, but I don't see any explicit agreement either. This seems to model the interrupts as chained, but at least for some cases aren't these auxiliary controllers in parallel to the GIC? In other words, do the they require configuration for interrupts to work for the normal non-wakeup use? I'm not sure that the h/w is being modeled any more accurately if that is the case. However, we don't really have a way to describe an interrupt line is connected to 2 interrupt parents in DT, so I'm not sure what else you could do here. Rob -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] can: c_can: use regmap_update_bits() to modify RAMINIT register
On Mon, Jan 12, 2015 at 12:02:21PM +0200, Roger Quadros wrote: +Mark with correct id. Please fix your mail client to word wrap within paragraphs, it amkes your mail more legible. The problem here is we can't use regmap_update_bits() because we need to write a 1 to the DONE bit to clear it and _regmap_update_bits() doesn't allow us to do that because of commit d91e8db2c3bb regmap: Suppress noop writes in regmap_update_bits() Is reverting it going to cause other issues? If yes then can we have a flag to specify forced update? The usual thing to do here is an explicit write clearing the latch, either immediately after setting it or immediately before setting it. If the register is marked as volatile and the hardware doesn't read back the latched state that also does the trick. signature.asc Description: Digital signature
Re: ARM64: hibernation: How to use hibernation/suspend-to-disk on ARMv8?
On Sat, Jan 10, 2015 at 03:14:33PM +, George Bush wrote: Hi all I notice we have hibernation.c in arm/kernel, however, I don't find it in arm64. Does it mean arm64 do not support hibernation/suspend-to-disk function? Yes, not at the moment, but we have planned to implement it. I tried some path to search the reason, but found nothing, they all say arm64 has the backward compatibility. So I send this email to the community and hope to get the reason. Thanks! I ported the arm hibernation.c to arm64/kernel(with LP64), but failed in a strange way. When I do resume, the arch_restore_image() get a page_fault when it calls the copy_page(), like: Unable to handle kernel paging request at virtual address 0xffbc055c3fa8 I'm sure the copy_page()'s parameters is in the memory area, why and how I get the strange address 0xffbc055c3fa8? vmalloc: 0xff80 - 0xffbb vmemmap: 0xffbc0140 - 0xffbc04f88000 modules: 0xffbffc00 - 0xffc0 memory:0xffc0 - 0xffc0be80 Look forward to your reply, thanks! We need your patch, kernel version, config file, your board/SoC HW details before even assuming what is happening. Please provide them and I am happy to help you implement suspend-to-disk on arm64 properly. Thanks, Lorenzo -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] can: c_can: use regmap_update_bits() to modify RAMINIT register
+Mark, On 09/01/15 15:50, Tomi Valkeinen wrote: On 07/01/15 16:32, Roger Quadros wrote: use of regmap_read() and regmap_write() in c_can_hw_raminit_syscon() is not safe as the RAMINIT register can be shared between different drivers at least for TI SoCs. To make the modification atomic we switch to using regmap_update_bits(). Signed-off-by: Roger Quadros rog...@ti.com --- drivers/net/can/c_can/c_can_platform.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index f363972..364209a 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -110,6 +110,10 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable) */ ctrl = ~(1 raminit-bits.start); ctrl |= 1 raminit-bits.done; + +/* we can't use regmap_update_bits here as it will bypass the write + * if START is already 0 and DONE is already 1. + */ regmap_write(raminit-syscon, raminit-reg, ctrl); Can you first use update_bits to change either bit, so that this update will be done? Initial condition is START=0, DONE=1. Now setting and clearing START bit initiates the start process and will cause the DONE bit to be set after a while. So unfortunately this doesn't work for us. Mark, The problem here is we can't use regmap_update_bits() because we need to write a 1 to the DONE bit to clear it and _regmap_update_bits() doesn't allow us to do that because of commit d91e8db2c3bb regmap: Suppress noop writes in regmap_update_bits() Is reverting it going to cause other issues? If yes then can we have a flag to specify forced update? cheers, -roger [1] - http://lxr.free-electrons.com/source/drivers/base/regmap/regmap.c#L2332 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] can: c_can: use regmap_update_bits() to modify RAMINIT register
+Mark with correct id. On 12/01/15 11:57, Roger Quadros wrote: +Mark, On 09/01/15 15:50, Tomi Valkeinen wrote: On 07/01/15 16:32, Roger Quadros wrote: use of regmap_read() and regmap_write() in c_can_hw_raminit_syscon() is not safe as the RAMINIT register can be shared between different drivers at least for TI SoCs. To make the modification atomic we switch to using regmap_update_bits(). Signed-off-by: Roger Quadros rog...@ti.com --- drivers/net/can/c_can/c_can_platform.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index f363972..364209a 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c @@ -110,6 +110,10 @@ static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable) */ ctrl = ~(1 raminit-bits.start); ctrl |= 1 raminit-bits.done; + + /* we can't use regmap_update_bits here as it will bypass the write +* if START is already 0 and DONE is already 1. +*/ regmap_write(raminit-syscon, raminit-reg, ctrl); Can you first use update_bits to change either bit, so that this update will be done? Initial condition is START=0, DONE=1. Now setting and clearing START bit initiates the start process and will cause the DONE bit to be set after a while. So unfortunately this doesn't work for us. Mark, The problem here is we can't use regmap_update_bits() because we need to write a 1 to the DONE bit to clear it and _regmap_update_bits() doesn't allow us to do that because of commit d91e8db2c3bb regmap: Suppress noop writes in regmap_update_bits() Is reverting it going to cause other issues? If yes then can we have a flag to specify forced update? cheers, -roger [1] - http://lxr.free-electrons.com/source/drivers/base/regmap/regmap.c#L2332 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] can: c_can: use regmap_update_bits() to modify RAMINIT register
On Mon, Jan 12, 2015 at 02:37:21PM +0200, Roger Quadros wrote: On 12/01/15 14:05, Mark Brown wrote: The usual thing to do here is an explicit write clearing the latch, either immediately after setting it or immediately before setting it. If the register is marked as volatile and the hardware doesn't read back the latched state that also does the trick. How does this work if driver has access to only 1 bit that can only be written with 1 to clear a condition? Writing a 0 is no-op. The expectation is that for hardware like that writes of zero will be ignored so you can just do one (generally this is the point of such things - you write to explicitly clear the bits you want to clear so by extension other bits are ignored. It can read back 0 or 1 depending on the condition. If the hardware readback has nothing to do with what's read back then by definition this isn't something you should be updating with update_bits() - it's doing a read/modify/write cycle so if the read part doesn't correspond to the write part things will go wrong. I didn't understand the volatile trick :P. If the hardware always reads back zero then if the register isn't cached (which it sounds like this one shouldn't be) the comparison done by update_bits() will always show that the latch bit needs writing. signature.asc Description: Digital signature
Re: [PATCH] can: c_can: use regmap_update_bits() to modify RAMINIT register
On 12/01/15 14:05, Mark Brown wrote: On Mon, Jan 12, 2015 at 12:02:21PM +0200, Roger Quadros wrote: +Mark with correct id. Please fix your mail client to word wrap within paragraphs, it amkes your mail more legible. Fixed now. Thanks for pointing out. The problem here is we can't use regmap_update_bits() because we need to write a 1 to the DONE bit to clear it and _regmap_update_bits() doesn't allow us to do that because of commit d91e8db2c3bb regmap: Suppress noop writes in regmap_update_bits() Is reverting it going to cause other issues? If yes then can we have a flag to specify forced update? The usual thing to do here is an explicit write clearing the latch, either immediately after setting it or immediately before setting it. If the register is marked as volatile and the hardware doesn't read back the latched state that also does the trick. How does this work if driver has access to only 1 bit that can only be written with 1 to clear a condition? Writing a 0 is no-op. It can read back 0 or 1 depending on the condition. I didn't understand the volatile trick :P. cheers, -roger -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 00/21] irqchip: gic: killing gic_arch_extn and co, slowly
On 12/01/15 14:14, Rob Herring wrote: On Wed, Jan 7, 2015 at 11:42 AM, Marc Zyngier marc.zyng...@arm.com wrote: The gic_arch_extn hack that a number of platform use has been nagging me for too long. It is only there for the benefit of a few platform, and yet it impacts all GIC users. Moreover, it gives people the wrong idea (let's use it to put some new custom hack in there...). But now that stacked irq domains have landed in -next, the time has come for gic_arch_extn to meet the Big Bit Bucket. [...] - This actively *breaks* existing setups. Once you boot a new kernel with an old DT, suspend/resume *will* be broken. Old kernels on a new DT won't even boot! You've been warned. This really outline the necessity of actually describing the HW in device trees... Just to be clear, you need some agreement from the maintainers of those platforms before doing this. It doesn't appear there is disagreement, but I don't see any explicit agreement either. I'm not trying to go behind anyone's back, if that's your concern. I fully intend to obtain every maintainer's explicit acknowledgement before removing any feature from the kernel. The warning above is there to get the maintainers attention on the disrupting effect of this series. This seems to model the interrupts as chained, but at least for some cases aren't these auxiliary controllers in parallel to the GIC? In From looking at the various TRMs, they all look to be chained interrupt controllers (at least Tegra, OMAP and IMX6 show this). I have not been able to find a publicly available TRM for any of the Samsung platforms, so this one could be different (but I really doubt it somehow). other words, do the they require configuration for interrupts to work for the normal non-wakeup use? I'm not sure that the h/w is being modeled any more accurately if that is the case. However, we don't really have a way to describe an interrupt line is connected to 2 interrupt parents in DT, so I'm not sure what else you could do here. The main problem is that they are not general-purpose interrupt controllers. They all come first on the interrupt path, and somehow feed two signals into the GIC: the actual interrupt, and the bypass signal. None of that is representable in DT. I'm willing to take any idea though. Thanks, M. -- Jazz is not dead. It just smells funny... -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] mmc: omap_hsmmc: use mmc_of_parse to parse common mmc configuration.
This ensures that all standard options are available to hsmmc, In particular, I need cap-power-off-card. Signed-off-by: NeilBrown ne...@suse.de --- drivers/mmc/host/omap_hsmmc.c | 33 - 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 08c65e01b547..f84cfb01716d 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1929,13 +1929,6 @@ static struct omap_hsmmc_platform_data *of_get_hsmmc_pdata(struct device *dev) { struct omap_hsmmc_platform_data *pdata; struct device_node *np = dev-of_node; - u32 bus_width, max_freq; - int cd_gpio, wp_gpio; - - cd_gpio = of_get_named_gpio(np, cd-gpios, 0); - wp_gpio = of_get_named_gpio(np, wp-gpios, 0); - if (cd_gpio == -EPROBE_DEFER || wp_gpio == -EPROBE_DEFER) - return ERR_PTR(-EPROBE_DEFER); pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -1944,34 +1937,20 @@ static struct omap_hsmmc_platform_data *of_get_hsmmc_pdata(struct device *dev) if (of_find_property(np, ti,dual-volt, NULL)) pdata-controller_flags |= OMAP_HSMMC_SUPPORTS_DUAL_VOLT; - pdata-switch_pin = cd_gpio; - pdata-gpio_wp = wp_gpio; + pdata-switch_pin = -EINVAL; + pdata-gpio_wp = -EINVAL; if (of_find_property(np, ti,non-removable, NULL)) { pdata-nonremovable = true; pdata-no_regulator_off_init = true; } - of_property_read_u32(np, bus-width, bus_width); - if (bus_width == 4) - pdata-caps |= MMC_CAP_4_BIT_DATA; - else if (bus_width == 8) - pdata-caps |= MMC_CAP_8_BIT_DATA; if (of_find_property(np, ti,needs-special-reset, NULL)) pdata-features |= HSMMC_HAS_UPDATED_RESET; - if (!of_property_read_u32(np, max-frequency, max_freq)) - pdata-max_freq = max_freq; - if (of_find_property(np, ti,needs-special-hs-handling, NULL)) pdata-features |= HSMMC_HAS_HSPE_SUPPORT; - if (of_find_property(np, keep-power-in-suspend, NULL)) - pdata-pm_caps |= MMC_PM_KEEP_POWER; - - if (of_find_property(np, enable-sdio-wakeup, NULL)) - pdata-pm_caps |= MMC_PM_WAKE_SDIO_IRQ; - return pdata; } #else @@ -2029,6 +2008,10 @@ static int omap_hsmmc_probe(struct platform_device *pdev) goto err; } + ret = mmc_of_parse(mmc); + if (ret) + goto err1; + host= mmc_priv(mmc); host-mmc = mmc; host-pdata = pdata; @@ -2057,7 +2040,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) if (pdata-max_freq 0) mmc-f_max = pdata-max_freq; - else + else if (mmc-f_max == 0) mmc-f_max = OMAP_MMC_MAX_CLOCK; spin_lock_init(host-irq_lock); @@ -2111,7 +2094,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) if (mmc_pdata(host)-nonremovable) mmc-caps |= MMC_CAP_NONREMOVABLE; - mmc-pm_caps = mmc_pdata(host)-pm_caps; + mmc-pm_caps |= mmc_pdata(host)-pm_caps; omap_hsmmc_conf_bus_power(host); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] mmc: omap_hsmmc: use slot-gpio library for gpio support.
Using the common code removes some code duplication, and makes it easier to switch to using mmc_of_parse() which will remove more duplication. This uses the new mmc_gpio_request_cd_isr to provide a non-standard interrupt service routine for card-detect interrupts. Signed-off-by: NeilBrown ne...@suse.de --- drivers/mmc/host/omap_hsmmc.c | 67 - 1 file changed, 13 insertions(+), 54 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 537cba8f1de1..08c65e01b547 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -36,6 +36,7 @@ #include linux/mmc/host.h #include linux/mmc/core.h #include linux/mmc/mmc.h +#include linux/mmc/slot-gpio.h #include linux/io.h #include linux/irq.h #include linux/gpio.h @@ -251,28 +252,22 @@ static void omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host); static int omap_hsmmc_card_detect(struct device *dev) { struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_hsmmc_platform_data *mmc = host-pdata; - /* NOTE: assumes card detect signal is active-low */ - return !gpio_get_value_cansleep(mmc-switch_pin); + return mmc_gpio_get_cd(host-mmc); } static int omap_hsmmc_get_wp(struct device *dev) { struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_hsmmc_platform_data *mmc = host-pdata; - /* NOTE: assumes write protect signal is active-high */ - return gpio_get_value_cansleep(mmc-gpio_wp); + return mmc_gpio_get_ro(host-mmc); } static int omap_hsmmc_get_cover_state(struct device *dev) { struct omap_hsmmc_host *host = dev_get_drvdata(dev); - struct omap_hsmmc_platform_data *mmc = host-pdata; - /* NOTE: assumes card detect signal is active-low */ - return !gpio_get_value_cansleep(mmc-switch_pin); + return mmc_gpio_get_cd(host-mmc); } #ifdef CONFIG_REGULATOR @@ -439,7 +434,10 @@ static inline int omap_hsmmc_have_reg(void) #endif -static int omap_hsmmc_gpio_init(struct omap_hsmmc_host *host, +static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id); + +static int omap_hsmmc_gpio_init(struct mmc_host *mmc, + struct omap_hsmmc_host *host, struct omap_hsmmc_platform_data *pdata) { int ret; @@ -452,46 +450,24 @@ static int omap_hsmmc_gpio_init(struct omap_hsmmc_host *host, host-card_detect = omap_hsmmc_card_detect; host-card_detect_irq = gpio_to_irq(pdata-switch_pin); - ret = gpio_request(pdata-switch_pin, mmc_cd); + mmc_gpio_set_cd_isr(mmc, omap_hsmmc_detect); + ret = mmc_gpio_request_cd(mmc, pdata-switch_pin, 0); if (ret) return ret; - ret = gpio_direction_input(pdata-switch_pin); - if (ret) - goto err_free_sp; } else { pdata-switch_pin = -EINVAL; } if (gpio_is_valid(pdata-gpio_wp)) { host-get_ro = omap_hsmmc_get_wp; - ret = gpio_request(pdata-gpio_wp, mmc_wp); - if (ret) - goto err_free_cd; - ret = gpio_direction_input(pdata-gpio_wp); + ret = mmc_gpio_request_ro(mmc, pdata-gpio_wp); if (ret) - goto err_free_wp; + return ret; } else { pdata-gpio_wp = -EINVAL; } return 0; - -err_free_wp: - gpio_free(pdata-gpio_wp); -err_free_cd: - if (gpio_is_valid(pdata-switch_pin)) -err_free_sp: - gpio_free(pdata-switch_pin); - return ret; -} - -static void omap_hsmmc_gpio_free(struct omap_hsmmc_host *host, -struct omap_hsmmc_platform_data *pdata) -{ - if (gpio_is_valid(pdata-gpio_wp)) - gpio_free(pdata-gpio_wp); - if (gpio_is_valid(pdata-switch_pin)) - gpio_free(pdata-switch_pin); } /* @@ -2066,7 +2042,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) host-next_data.cookie = 1; host-pbias_enabled = 0; - ret = omap_hsmmc_gpio_init(host, pdata); + ret = omap_hsmmc_gpio_init(mmc, host, pdata); if (ret) goto err_gpio; @@ -2197,20 +2173,6 @@ static int omap_hsmmc_probe(struct platform_device *pdev) mmc-ocr_avail = mmc_pdata(host)-ocr_mask; - /* Request IRQ for card detect */ - if (host-card_detect_irq) { - ret = devm_request_threaded_irq(pdev-dev, - host-card_detect_irq, - NULL, omap_hsmmc_detect, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, -
[PATCH 1/3] mmc: core: Allow host driver to provide isr for card-detect interrupts.
One of the reasons omap_hsmmc doesn't use the slot-gpio library is that it has some non-standard functionality in the card-detect interrupt service routine. To make it possible for omap_hsmmc (and maybe others) to be converted to use slot-gpio, add 'mmc_gpio_request_cd_isr' which provide an alternate isr to be register by the slot-gpio code. Signed-off-by: NeilBrown ne...@suse.de --- drivers/mmc/core/slot-gpio.c | 18 +- include/linux/mmc/slot-gpio.h |2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c index 1a3edbd47719..27117ba47073 100644 --- a/drivers/mmc/core/slot-gpio.c +++ b/drivers/mmc/core/slot-gpio.c @@ -25,6 +25,7 @@ struct mmc_gpio { struct gpio_desc *cd_gpio; bool override_ro_active_level; bool override_cd_active_level; + irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); char *ro_label; char cd_label[0]; }; @@ -136,8 +137,10 @@ void mmc_gpiod_request_cd_irq(struct mmc_host *host) irq = -EINVAL; if (irq = 0) { + if (!ctx-cd_gpio_isr) + ctx-cd_gpio_isr = mmc_gpio_cd_irqt; ret = devm_request_threaded_irq(host-parent, irq, - NULL, mmc_gpio_cd_irqt, + NULL, ctx-cd_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, ctx-cd_label, host); if (ret 0) @@ -151,6 +154,19 @@ void mmc_gpiod_request_cd_irq(struct mmc_host *host) } EXPORT_SYMBOL(mmc_gpiod_request_cd_irq); +/* Register an alternate interrupt service routine for + * the card-detect GPIO. + */ +void mmc_gpio_set_cd_isr(struct mmc_host *host, +irqreturn_t (*isr)(int irq, void *dev_id)) +{ + struct mmc_gpio *ctx = host-slot.handler_priv; + + WARN_ON(ctx-cd_gpio_isr); + ctx-cd_gpio_isr = isr; +} +EXPORT_SYMBOL(mmc_gpio_set_cd_isr); + /** * mmc_gpio_request_cd - request a gpio for card-detection * @host: mmc host diff --git a/include/linux/mmc/slot-gpio.h b/include/linux/mmc/slot-gpio.h index 4a36d6954631..3945a8c9d3cb 100644 --- a/include/linux/mmc/slot-gpio.h +++ b/include/linux/mmc/slot-gpio.h @@ -26,6 +26,8 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, unsigned int idx, bool override_active_level, unsigned int debounce, bool *gpio_invert); +void mmc_gpio_set_cd_isr(struct mmc_host *host, +irqreturn_t (*isr)(int irq, void *dev_id)); void mmc_gpiod_request_cd_irq(struct mmc_host *host); #endif -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3] Convert omap_hsmmc to use common devicetree parsing code.
This is another resend with mmc_gpio_set_cd_isr() now returning void and being EXPORTed. I included WARN_ON(ctx-cd_gpio_isr); to guard against misuse. My goal is to get omap_hsmmc to use the common code for parsing of, particularly so that I can set cap-power-off-card, which omap_hsmmc doesn't explicitly report. Thanks, NeilBrown P.S. Sorry for delay - I've been travelling. --- NeilBrown (3): mmc: core: Allow host driver to provide isr for card-detect interrupts. mmc: omap_hsmmc: use slot-gpio library for gpio support. mmc: omap_hsmmc: use mmc_of_parse to parse common mmc configuration. drivers/mmc/core/slot-gpio.c | 18 +++ drivers/mmc/host/omap_hsmmc.c | 100 + include/linux/mmc/slot-gpio.h |2 + 3 files changed, 40 insertions(+), 80 deletions(-) -- Signature -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 14/21] ARM: imx6: convert GPC to stacked domains
Hi Marc, On 2015-01-12 19:26, Marc Zyngier wrote: IMX6 has been (ab)using the gic_arch_extn to provide wakeup from suspend, and it makes a lot of sense to convert this code to use stacked domains instead. This patch does just this, updating the DT files to actually reflect what the HW provides. BIG FAT WARNING: because the DTs were so far lying by not exposing the fact that the GPC block is actually the first interrupt controller in the chain, kernels with this patch applied wont have any suspend-resume facility when booted with old DTs, and old kernels with updated DTs won't even boot. Tested-by: Stefan Agner ste...@agner.ch Acked-by: Stefan Agner ste...@agner.ch Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/boot/dts/imx6qdl.dtsi | 7 ++- arch/arm/boot/dts/imx6sl.dtsi | 5 +- arch/arm/boot/dts/imx6sx.dtsi | 5 +- arch/arm/mach-imx/common.h | 1 - arch/arm/mach-imx/gpc.c | 127 arch/arm/mach-imx/mach-imx6q.c | 1 - arch/arm/mach-imx/mach-imx6sl.c | 1 - arch/arm/mach-imx/mach-imx6sx.c | 1 - 8 files changed, 117 insertions(+), 31 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 4fc03b7..aff9ded 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -53,6 +53,7 @@ interrupt-controller; reg = 0x00a01000 0x1000, 0x00a00100 0x100; + interrupt-parent = intc; }; clocks { @@ -82,7 +83,7 @@ #address-cells = 1; #size-cells = 1; compatible = simple-bus; - interrupt-parent = intc; + interrupt-parent = gpc; ranges; dma_apbh: dma-apbh@0011 { @@ -122,6 +123,7 @@ compatible = arm,cortex-a9-twd-timer; reg = 0x00a00600 0x20; interrupts = 1 13 0xf01; + interrupt-parent = intc; clocks = clks IMX6QDL_CLK_TWD; }; @@ -694,8 +696,11 @@ gpc: gpc@020dc000 { compatible = fsl,imx6q-gpc; reg = 0x020dc000 0x4000; + interrupt-controller; + #interrupt-cells = 3; interrupts = 0 89 IRQ_TYPE_LEVEL_HIGH, 0 90 IRQ_TYPE_LEVEL_HIGH; + interrupt-parent = intc; }; gpr: iomuxc-gpr@020e { diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 36ab8e0..35099b7 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -72,6 +72,7 @@ interrupt-controller; reg = 0x00a01000 0x1000, 0x00a00100 0x100; + interrupt-parent = intc; }; clocks { @@ -95,7 +96,7 @@ #address-cells = 1; #size-cells = 1; compatible = simple-bus; - interrupt-parent = intc; + interrupt-parent = gpc; ranges; ocram: sram@0090 { @@ -603,7 +604,9 @@ gpc: gpc@020dc000 { compatible = fsl,imx6sl-gpc, fsl,imx6q-gpc; reg = 0x020dc000 0x4000; + interrupt-controller; GPC is in three base device trees, and missing in all of them. So the first is fixed this one... interrupts = 0 89 IRQ_TYPE_LEVEL_HIGH; + interrupt-parent = intc; }; gpr: iomuxc-gpr@020e { diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index 7a24fee..c476e67 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -88,6 +88,7 @@ interrupt-controller; reg = 0x00a01000 0x1000, 0x00a00100 0x100; + interrupt-parent = intc; }; clocks { @@ -131,7 +132,7 @@ #address-cells = 1; #size-cells = 1; compatible = simple-bus; - interrupt-parent = intc; + interrupt-parent = gpc; ranges; pmu { @@ -700,7 +701,9 @@ gpc: gpc@020dc000 { compatible = fsl,imx6sx-gpc, fsl,imx6q-gpc; reg = 0x020dc000 0x4000; + interrupt-controller; ... and this one is still missing. Sorry I did not see that the first review. -- Stefan interrupts = GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH; +
Re: [PATCH 2/4] usb: dwc3: gadget: Stop TRB preparation after limit is reached
On 1/13/2015 12:04 AM, Felipe Balbi wrote: Hi, On Tue, Jan 06, 2015 at 11:44:23AM +0530, Amit Virdi wrote: I can certainly provide the dwc3 specific kernel bootup logs, full regdump and any loglevel you want me to, if that helps Yeah, if you can provide those, then that'll help me verifying. Full logs from boot to failure point with VERBOSE_DEBUG enabled (considering you're not running on anything recent). Okay. I'll provide full verbose logs, along with the register dump, when I'm back to the office next week, for the working and non-working case, but how - as attachment or as inline? Either way will do but I have a feeling mailing list attachment size will bite you, so maybe it's best to make a tarball of both logs and send that as attachment. Compressed text will be very small. Attached are the dwc3 verbose logs and register dump without and with the fixes in this patchset. Sorry for the long delay, it has been a bit hectic. It's okay! I can see from your logs that we end up with a Transfer Not Ready (Transfer Active) event and endpoint has BUSY flag set. I also see that you're queueing 31 requests and all of them will use 2 TRBs, so we clearly go over our TRB table. This fix is, indeed, necessary but we need to improve commit log a bit so it's extremely clear what the error is. Later, we can improve how we handle requests in this driver, but that is outside of the scope of your patchset. Please improve commit log and resend your series so it can be applied. Alright! I'll improve the commit messages and, also, cc stable list while resending the patches. As I see, you have already picked patches [3/4] and [4/4]. So, I'll resend only [1/4] and [2/4] cheers Thank you for your patience and kind understanding. -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND 1/2] usb: dwc3: gadget: Fix TRB preparation during SG
When scatter gather (SG) is used, multiple TRBs are prepared from one DWC3 request (dwc3_request). So while preparing TRBs, the 'last' flag should be set only when it is the last TRB being prepared from the last dwc3_request entry. The current implementation uses list_is_last to check if the dwc3_request is the last entry from the request_list. However, list_is_last returns false for the last entry too. This is because, while preparing the first TRB from a request, the function dwc3_prepare_one_trb modifies the request's next and prev pointers while moving the URB to req_queued. Hence, list_is_last always returns false no matter what. The correct way is not to access the modified pointers of dwc3_request but to use list_empty macro instead. Fixes: e5ba5ec833aa4a76980b512d6a6779643516b850 (usb: dwc3: gadget: fix scatter gather implementation Signed-off-by: Amit Virdi amit.vi...@st.com Cc: sta...@vger.kernel.org # v3.9+ --- drivers/usb/dwc3/gadget.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 4e2593993fae..cb8939134c32 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -879,8 +879,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) if (i == (request-num_mapped_sgs - 1) || sg_is_last(s)) { - if (list_is_last(req-list, - dep-request_list)) + if (list_empty(dep-request_list)) last_one = true; chain = false; } -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND 0/2] usb: dwc3: gadget: Bug fixes
This is a re-submission of patches [1/4] and [2/4] from: http://www.spinics.net/lists/linux-usb/msg118841.html Commit log of both these patches has been modified for aided clarity. These patches have been rebased on Balbi's testing/next. Patches [3/4] and [4/4] were accepted as they were. Amit Virdi (2): usb: dwc3: gadget: Fix TRB preparation during SG usb: dwc3: gadget: Stop TRB preparation after limit is reached drivers/usb/dwc3/gadget.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 14/21] ARM: imx6: convert GPC to stacked domains
On Mon, Jan 12, 2015 at 7:26 PM, Marc Zyngier marc.zyng...@arm.com wrote: IMX6 has been (ab)using the gic_arch_extn to provide wakeup from suspend, and it makes a lot of sense to convert this code to use stacked domains instead. This patch does just this, updating the DT files to actually reflect what the HW provides. BIG FAT WARNING: because the DTs were so far lying by not exposing the fact that the GPC block is actually the first interrupt controller in the chain, kernels with this patch applied wont have any suspend-resume facility when booted with old DTs, and old kernels with updated DTs won't even boot. Tested-by: Stefan Agner ste...@agner.ch Acked-by: Stefan Agner ste...@agner.ch Signed-off-by: Marc Zyngier marc.zyng...@arm.com (...) +static int imx_gpc_domain_alloc(struct irq_domain *domain, + unsigned int virq, Nutcase nitpick on this nice patch series: every time I see virq my OCD triggers, as I think the v in virq stand for virtual. These irqs are no more virtual than any other Linux irq numbers, hwirq is more to the point. I just refer to these as irq (sans v) in any code I write. Yours, Linus Walleij -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND 2/2] usb: dwc3: gadget: Stop TRB preparation after limit is reached
DWC3 gadget sets up a pool of 32 TRBs for each EP during initialization. This means, the max TRBs that can be submitted for an EP is fixed to 32. Since the request queue for an EP is a linked list, any number of requests can be queued to it by the gadget layer. However, the dwc3 driver must not submit TRBs more than the pool it has created for. This limit wasn't respected when SG was used resulting in submitting more than the max TRBs, eventually leading to non-transfer of the TRBs submitted over the max limit. Root cause: When SG is used, there are two loops iterating to prepare TRBs: - Outer loop over the request_list - Inner loop over the SG list The code was missing break to get out of the outer loop. Signed-off-by: Amit Virdi amit.vi...@st.com Cc: sta...@vger.kernel.org # v3.9+ --- drivers/usb/dwc3/gadget.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index cb8939134c32..6c5e344822b9 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -897,6 +897,9 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting) if (last_one) break; } + + if (last_one) + break; } else { dma = req-request.dma; length = req-request.length; -- 1.8.0 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] usb: dwc3: add a quirk for device disconnection issue in Synopsis dwc3 core
On Mon, Jan 12, 2015 at 06:29:43PM +0100, Paul Bolle wrote: On Mon, 2015-01-12 at 11:20 -0600, Felipe Balbi wrote: On Sun, Jan 11, 2015 at 11:19:55PM +0800, Sneeker Yeh wrote: in case i express unclearly i also put a pdf: https://drive.google.com/file/d/0B18MmcvvKjNNbDF6eEdHSzZCazA/view This issue is defined by a two-way race at disconnect, between 1) class driver interrupt endpoint resheduling attempts if the ISR gave an ep error event due to device detach (it would try 3 times) 2) Disconnect interrupt on PORTSC_CSC, which is cleared by hub thread asynchronously 3) The hardware IP was configured in silicon with - DWC_USB3_SUSPEND_ON_DISCONNECT_EN=1 (this is an IP configuration yeah, aparently this is another configuration which is not exposed on HWPARAMS registers. Paul, can you confirm for us ? I couldn't find it on Databook on any of the HWPARAMS registers. I guess you meant to ask Pawel, because I know nothing at all about all that! No, it was Paul Zimmerman :-) -- balbi signature.asc Description: Digital signature
Re: [PATCH 3/3] usb: dwc3: add a quirk for device disconnection issue in Synopsis dwc3 core
Hi, On Sun, Jan 11, 2015 at 11:19:55PM +0800, Sneeker Yeh wrote: enable the quirk only for you. Isn't there a better way of enabling the quirk based off of revision detection couple with a look on GHWPARAMS* registers ? What's tricking me is this claim that only config-free PHYs would be affected, why ? i'm still struggling now to try to get more information about this. some security policy inside Fujitsu make me unable to access full information of this errata today. Someday after i get enough information, i shall take your suggestion here that seems better to incur quirk dynamically via GHWPARAMS, and then send it here again. ok, hopefully you'll find a way ;-) I got some update information here finally~ in case i express unclearly i also put a pdf: https://drive.google.com/file/d/0B18MmcvvKjNNbDF6eEdHSzZCazA/view This issue is defined by a two-way race at disconnect, between 1) class driver interrupt endpoint resheduling attempts if the ISR gave an ep error event due to device detach (it would try 3 times) 2) Disconnect interrupt on PORTSC_CSC, which is cleared by hub thread asynchronously 3) The hardware IP was configured in silicon with - DWC_USB3_SUSPEND_ON_DISCONNECT_EN=1 (this is an IP configuration yeah, aparently this is another configuration which is not exposed on HWPARAMS registers. Paul, can you confirm for us ? I couldn't find it on Databook on any of the HWPARAMS registers. port whose state cannot be checked from software) - Synopsys IP version is 3.00a heh, so pretty much everybody :-) The IP will auto-suspend itself on device detach with some phy-specific interval after CSC is cleared by 2) If 2) and 3) complete before 1), the interrupts it expects will not be generated by the autosuspended IP, leading to a deadlock. Even later disconnection procedure would detect that corresponding urb is still in-progress and issue a ep stop command, auto-suspended IP still won't respond to that command. this defect would result in this when device detached: --- [ 99.603544] usb 4-1: USB disconnect, device number 2 [ 104.615254] xhci-hcd xhci-hcd.0.auto: xHCI host not responding to stop endpoint command. [ 104.623362] xhci-hcd xhci-hcd.0.auto: Assuming host is dying, halting host. [ 104.653261] xhci-hcd xhci-hcd.0.auto: Host not halted after 16000 microseconds. [ 104.660584] xhci-hcd xhci-hcd.0.auto: Non-responsive xHCI host is not halting. [ 104.667817] xhci-hcd xhci-hcd.0.auto: Completing active URBs anyway. [ 104.674198] xhci-hcd xhci-hcd.0.auto: HC died; cleaning up As a result, when device detached, we desired to postpone PORTCSC clear behind disable slot. it's found that all executed ep command related to disconnetion, are executed before disable slot. Now this is all great information and they should all be part of your commit log and probably a big comment should be added to code as well. Thanks for going after all these details, now let's figure out a way to pass dwc3 revision to xhci, or maybe we pass just a flag for the quirk, something like: if (dwc-revision 3.00a dwc-has_suspend_on_disconnect) xhci_pdata.delay_portcsc_clear = true; or something similar to that. cheers -- balbi signature.asc Description: Digital signature
Re: [PATCH 3/3] usb: dwc3: add a quirk for device disconnection issue in Synopsis dwc3 core
On Mon, 2015-01-12 at 11:20 -0600, Felipe Balbi wrote: On Sun, Jan 11, 2015 at 11:19:55PM +0800, Sneeker Yeh wrote: in case i express unclearly i also put a pdf: https://drive.google.com/file/d/0B18MmcvvKjNNbDF6eEdHSzZCazA/view This issue is defined by a two-way race at disconnect, between 1) class driver interrupt endpoint resheduling attempts if the ISR gave an ep error event due to device detach (it would try 3 times) 2) Disconnect interrupt on PORTSC_CSC, which is cleared by hub thread asynchronously 3) The hardware IP was configured in silicon with - DWC_USB3_SUSPEND_ON_DISCONNECT_EN=1 (this is an IP configuration yeah, aparently this is another configuration which is not exposed on HWPARAMS registers. Paul, can you confirm for us ? I couldn't find it on Databook on any of the HWPARAMS registers. I guess you meant to ask Pawel, because I know nothing at all about all that! Thanks, Paul Bolle -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/5] mfd: tps65218: make INT[12] and STATUS registers volatile
Hi, On Thu, Jan 08, 2015 at 10:25:12AM -0600, Felipe Balbi wrote: On Tue, Jan 06, 2015 at 11:37:34AM -0600, Felipe Balbi wrote: On Fri, Dec 26, 2014 at 01:28:20PM -0600, Felipe Balbi wrote: STATUS register can be modified by the HW, so we should bypass cache because of that. In the case of INT[12] registers, they are the ones that actually clear the IRQ source at the time they are read. If we rely on the cache for them, we will never be able to clear the interrupt, which will cause our IRQ line to be disabled due to IRQ throttling. Fixes: 44b4dc6 mfd: tps65218: Add driver for the TPS65218 PMIC Cc: sta...@vger.kernel.org # v3.15+ Cc: Keerthy j-keer...@ti.com Cc: Lee Jones lee.jo...@linaro.org Signed-off-by: Felipe Balbi ba...@ti.com ping another ping. Without this and the following patch TPS65218 power button driver which was already applied by Dmitry, won't work. Anybody ? -rc4 is out and tps65218 is still broken because nobody has acted on these two patches. All other patches which are meant for 3.20 merge window are applied and because of these pending, those patches won't work. --- drivers/mfd/tps65218.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index 0d256cb..2243f75 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c @@ -125,10 +125,21 @@ int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg, } EXPORT_SYMBOL_GPL(tps65218_clear_bits); +static const struct regmap_range tps65218_yes_ranges[] = { + regmap_reg_range(TPS65218_REG_INT1, TPS65218_REG_INT2), + regmap_reg_range(TPS65218_REG_STATUS, TPS65218_REG_STATUS), +}; + +static const struct regmap_access_table tps65218_volatile_table = { + .yes_ranges = tps65218_yes_ranges, + .n_yes_ranges = ARRAY_SIZE(tps65218_yes_ranges), +}; + static struct regmap_config tps65218_regmap_config = { .reg_bits = 8, .val_bits = 8, .cache_type = REGCACHE_RBTREE, + .volatile_table = tps65218_volatile_table, }; static const struct regmap_irq tps65218_irqs[] = { -- 2.2.0 -- balbi -- balbi -- balbi signature.asc Description: Digital signature
[PATCH v3 09/21] DT: update ti,irq-crossbar binding
Make it look like a real interrupt controller. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- .../devicetree/bindings/arm/omap/crossbar.txt | 18 +- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/omap/crossbar.txt b/Documentation/devicetree/bindings/arm/omap/crossbar.txt index 4139db3..a9b28d7 100644 --- a/Documentation/devicetree/bindings/arm/omap/crossbar.txt +++ b/Documentation/devicetree/bindings/arm/omap/crossbar.txt @@ -9,7 +9,9 @@ inputs. Required properties: - compatible : Should be ti,irq-crossbar - reg: Base address and the size of the crossbar registers. -- ti,max-irqs: Total number of irqs available at the interrupt controller. +- interrupt-controller: indicates that this block is an interrupt controller. +- interrupt-parent: the interrupt controller this block is connected to. +- ti,max-irqs: Total number of irqs available at the parent interrupt controller. - ti,max-crossbar-sources: Maximum number of crossbar sources that can be routed. - ti,reg-size: Size of a individual register in bytes. Every individual register is assumed to be of same size. Valid sizes are 1, 2, 4. @@ -27,13 +29,13 @@ Optional properties: when the interrupt controller irq is unused (when not provided, default is 0) Examples: - crossbar_mpu: @4a02 { + crossbar_mpu: crossbar@4a002a48 { compatible = ti,irq-crossbar; reg = 0x4a002a48 0x130; ti,max-irqs = 160; ti,max-crossbar-sources = 400; ti,reg-size = 2; - ti,irqs-reserved = 0 1 2 3 5 6 131 132 139 140; + ti,irqs-reserved = 0 1 2 3 5 6 131 132; ti,irqs-skip = 10 133 139 140; }; @@ -44,10 +46,6 @@ Documentation/devicetree/bindings/arm/gic.txt for further details. An interrupt consumer on an SoC using crossbar will use: interrupts = GIC_SPI request_number interrupt_level -When the request number is between 0 to that described by -ti,max-crossbar-sources, it is assumed to be a crossbar mapping. If the -request_number is greater than ti,max-crossbar-sources, then it is mapped as a -quirky hardware mapping direct to GIC. Example: device_x@0x4a023000 { @@ -55,9 +53,3 @@ Example: interrupts = GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH; ... }; - - device_y@0x4a033000 { - /* Direct mapped GIC SPI 1 used */ - interrupts = GIC_SPI DIRECT_IRQ(1) IRQ_TYPE_LEVEL_HIGH; - ... - }; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 06/21] ARM: tegra: remove old LIC support
Now that all DTs have been updated, entierely drop support for the non-DT code. This is likely to break platforms that do not update their DT, so print a warning at boot time. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/mach-tegra/iomap.h | 15 arch/arm/mach-tegra/irq.c | 201 +--- arch/arm/mach-tegra/irq.h | 6 -- 3 files changed, 2 insertions(+), 220 deletions(-) diff --git a/arch/arm/mach-tegra/iomap.h b/arch/arm/mach-tegra/iomap.h index ee79808..81dc950 100644 --- a/arch/arm/mach-tegra/iomap.h +++ b/arch/arm/mach-tegra/iomap.h @@ -31,21 +31,6 @@ #define TEGRA_ARM_INT_DIST_BASE0x50041000 #define TEGRA_ARM_INT_DIST_SIZESZ_4K -#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000 -#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64 - -#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100 -#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64 - -#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200 -#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64 - -#define TEGRA_QUATERNARY_ICTLR_BASE0x60004300 -#define TEGRA_QUATERNARY_ICTLR_SIZESZ_64 - -#define TEGRA_QUINARY_ICTLR_BASE 0x60004400 -#define TEGRA_QUINARY_ICTLR_SIZE SZ_64 - #define TEGRA_TMR1_BASE0x60005000 #define TEGRA_TMR1_SIZESZ_8 diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 1593c4c..3b9098d 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -30,43 +30,9 @@ #include board.h #include iomap.h -#define ICTLR_CPU_IEP_VFIQ 0x08 -#define ICTLR_CPU_IEP_FIR 0x14 -#define ICTLR_CPU_IEP_FIR_SET 0x18 -#define ICTLR_CPU_IEP_FIR_CLR 0x1c - -#define ICTLR_CPU_IER 0x20 -#define ICTLR_CPU_IER_SET 0x24 -#define ICTLR_CPU_IER_CLR 0x28 -#define ICTLR_CPU_IEP_CLASS0x2C - -#define ICTLR_COP_IER 0x30 -#define ICTLR_COP_IER_SET 0x34 -#define ICTLR_COP_IER_CLR 0x38 -#define ICTLR_COP_IEP_CLASS0x3c - -#define FIRST_LEGACY_IRQ 32 -#define TEGRA_MAX_NUM_ICTLRS 5 - #define SGI_MASK 0x -static int num_ictlrs; - -static void __iomem *ictlr_reg_base[] = { - IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE), - IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE), -}; - #ifdef CONFIG_PM_SLEEP -static u32 cop_ier[TEGRA_MAX_NUM_ICTLRS]; -static u32 cop_iep[TEGRA_MAX_NUM_ICTLRS]; -static u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS]; -static u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS]; - -static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS]; static void __iomem *tegra_gic_cpu_base; #endif @@ -83,140 +49,7 @@ bool tegra_pending_sgi(void) return false; } -static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg) -{ - void __iomem *base; - u32 mask; - - BUG_ON(irq FIRST_LEGACY_IRQ || - irq = FIRST_LEGACY_IRQ + num_ictlrs * 32); - - base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32]; - mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); - - __raw_writel(mask, base + reg); -} - -static void tegra_mask(struct irq_data *d) -{ - if (d-hwirq FIRST_LEGACY_IRQ) - return; - - tegra_irq_write_mask(d-hwirq, ICTLR_CPU_IER_CLR); -} - -static void tegra_unmask(struct irq_data *d) -{ - if (d-hwirq FIRST_LEGACY_IRQ) - return; - - tegra_irq_write_mask(d-hwirq, ICTLR_CPU_IER_SET); -} - -static void tegra_ack(struct irq_data *d) -{ - if (d-hwirq FIRST_LEGACY_IRQ) - return; - - tegra_irq_write_mask(d-hwirq, ICTLR_CPU_IEP_FIR_CLR); -} - -static void tegra_eoi(struct irq_data *d) -{ - if (d-hwirq FIRST_LEGACY_IRQ) - return; - - tegra_irq_write_mask(d-hwirq, ICTLR_CPU_IEP_FIR_CLR); -} - -static int tegra_retrigger(struct irq_data *d) -{ - if (d-hwirq FIRST_LEGACY_IRQ) - return 0; - - tegra_irq_write_mask(d-hwirq, ICTLR_CPU_IEP_FIR_SET); - - return 1; -} - #ifdef CONFIG_PM_SLEEP -static int tegra_set_wake(struct irq_data *d, unsigned int enable) -{ - u32 irq = d-hwirq; - u32 index, mask; - - if (irq FIRST_LEGACY_IRQ || - irq = FIRST_LEGACY_IRQ + num_ictlrs * 32) - return -EINVAL; - - index = ((irq - FIRST_LEGACY_IRQ) / 32); - mask = BIT((irq - FIRST_LEGACY_IRQ) % 32); - if (enable) - ictlr_wake_mask[index] |= mask; - else - ictlr_wake_mask[index] = ~mask; - - return 0; -} - -static int tegra_legacy_irq_suspend(void) -{ - unsigned long flags; - int i; - - local_irq_save(flags); - for (i = 0; i num_ictlrs; i++) { - void __iomem *ictlr = ictlr_reg_base[i]; - /* Save interrupt state */ - cpu_ier[i] = readl_relaxed(ictlr + ICTLR_CPU_IER); - cpu_iep[i] =
[PATCH v3 14/21] ARM: imx6: convert GPC to stacked domains
IMX6 has been (ab)using the gic_arch_extn to provide wakeup from suspend, and it makes a lot of sense to convert this code to use stacked domains instead. This patch does just this, updating the DT files to actually reflect what the HW provides. BIG FAT WARNING: because the DTs were so far lying by not exposing the fact that the GPC block is actually the first interrupt controller in the chain, kernels with this patch applied wont have any suspend-resume facility when booted with old DTs, and old kernels with updated DTs won't even boot. Tested-by: Stefan Agner ste...@agner.ch Acked-by: Stefan Agner ste...@agner.ch Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/boot/dts/imx6qdl.dtsi | 7 ++- arch/arm/boot/dts/imx6sl.dtsi | 5 +- arch/arm/boot/dts/imx6sx.dtsi | 5 +- arch/arm/mach-imx/common.h | 1 - arch/arm/mach-imx/gpc.c | 127 arch/arm/mach-imx/mach-imx6q.c | 1 - arch/arm/mach-imx/mach-imx6sl.c | 1 - arch/arm/mach-imx/mach-imx6sx.c | 1 - 8 files changed, 117 insertions(+), 31 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 4fc03b7..aff9ded 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -53,6 +53,7 @@ interrupt-controller; reg = 0x00a01000 0x1000, 0x00a00100 0x100; + interrupt-parent = intc; }; clocks { @@ -82,7 +83,7 @@ #address-cells = 1; #size-cells = 1; compatible = simple-bus; - interrupt-parent = intc; + interrupt-parent = gpc; ranges; dma_apbh: dma-apbh@0011 { @@ -122,6 +123,7 @@ compatible = arm,cortex-a9-twd-timer; reg = 0x00a00600 0x20; interrupts = 1 13 0xf01; + interrupt-parent = intc; clocks = clks IMX6QDL_CLK_TWD; }; @@ -694,8 +696,11 @@ gpc: gpc@020dc000 { compatible = fsl,imx6q-gpc; reg = 0x020dc000 0x4000; + interrupt-controller; + #interrupt-cells = 3; interrupts = 0 89 IRQ_TYPE_LEVEL_HIGH, 0 90 IRQ_TYPE_LEVEL_HIGH; + interrupt-parent = intc; }; gpr: iomuxc-gpr@020e { diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 36ab8e0..35099b7 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -72,6 +72,7 @@ interrupt-controller; reg = 0x00a01000 0x1000, 0x00a00100 0x100; + interrupt-parent = intc; }; clocks { @@ -95,7 +96,7 @@ #address-cells = 1; #size-cells = 1; compatible = simple-bus; - interrupt-parent = intc; + interrupt-parent = gpc; ranges; ocram: sram@0090 { @@ -603,7 +604,9 @@ gpc: gpc@020dc000 { compatible = fsl,imx6sl-gpc, fsl,imx6q-gpc; reg = 0x020dc000 0x4000; + interrupt-controller; interrupts = 0 89 IRQ_TYPE_LEVEL_HIGH; + interrupt-parent = intc; }; gpr: iomuxc-gpr@020e { diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index 7a24fee..c476e67 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -88,6 +88,7 @@ interrupt-controller; reg = 0x00a01000 0x1000, 0x00a00100 0x100; + interrupt-parent = intc; }; clocks { @@ -131,7 +132,7 @@ #address-cells = 1; #size-cells = 1; compatible = simple-bus; - interrupt-parent = intc; + interrupt-parent = gpc; ranges; pmu { @@ -700,7 +701,9 @@ gpc: gpc@020dc000 { compatible = fsl,imx6sx-gpc, fsl,imx6q-gpc; reg = 0x020dc000 0x4000; + interrupt-controller; interrupts = GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH; + interrupt-parent = intc; }; iomuxc: iomuxc@020e { diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index cfcdb62..7052302 100644 ---
[PATCH v3 05/21] DT: tegra: add binding for the legacy interrupt controller
Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- .../interrupt-controller/nvidia,tegra-ictlr.txt| 43 ++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra-ictlr.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra-ictlr.txt b/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra-ictlr.txt new file mode 100644 index 000..1099fe0 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/nvidia,tegra-ictlr.txt @@ -0,0 +1,43 @@ +NVIDIA Legacy Interrupt Controller + +All Tegra SoCs contain a legacy interrupt controller that routes +interrupts to the GIC, and also serves as a wakeup source. It is also +referred to as ictlr, hence the name of the binding. + +The HW block exposes a number of interrupt controllers, each +implementing a set of 32 interrupts. + +Required properties: + +- compatible : should be: nvidia,tegrachip-ictlr. The LIC on + subsequent SoCs remained backwards-compatible with Tegra30, so on + Tegra generations later than Tegra30 the compatible value should + include nvidia,tegra30-ictlr. +- reg : Specifies base physical address and size of the registers. + Each controller must be described separately (Tegra20 has 4 of them, + whereas Tegra30 and later have 5 +- interrupt-controller : Identifies the node as an interrupt controller. +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value must be 3. +- interrupt-parent : a phandle to the GIC these interrupts are routed + to. + +Notes: + +- Because this HW ultimately routes interrupts to the GIC, the + interrupt specifier must be that of the GIC. +- Only SPIs can use the ictlr as an interrupt parent. SGIs and PPIs + are explicitly forbidden. + +Example: + + ictlr: interrupt-controller@60004000 { + compatible = nvidia,tegra20-ictlr, nvidia,tegra-ictlr; + reg = 0x60004000 64, + 0x60004100 64, + 0x60004200 64, + 0x60004300 64; + interrupt-controller; + #interrupt-cells = 3; + interrupt-parent = intc; + }; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 18/21] ARM: shmobile: remove use of gic_arch_extn.irq_set_wake
shmobile only uses gic_arch_extn.irq_set_wake to prevent the GIC from returning -ENXIO when receiving a wake-up configuration request. It is a lot simpler to tell the irq layer that we don't need any configuration by using the IRQCHIP_SKIP_SET_WAKE, thanks to the new gic_set_irqchip_flags function. Acked-by: Simon Horman horms+rene...@verge.net.au Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/mach-shmobile/intc-sh73a0.c | 7 +-- arch/arm/mach-shmobile/setup-r8a7779.c | 7 +-- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index 9e36180..fd63ae6 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c @@ -252,11 +252,6 @@ static irqreturn_t sh73a0_intcs_demux(int irq, void *dev_id) return IRQ_HANDLED; } -static int sh73a0_set_wake(struct irq_data *data, unsigned int on) -{ - return 0; /* always allow wakeup */ -} - #define PINTER0_PHYS 0xe69000a0 #define PINTER1_PHYS 0xe69000a4 #define PINTER0_VIRT IOMEM(0xe69000a0) @@ -318,8 +313,8 @@ void __init sh73a0_init_irq(void) void __iomem *gic_cpu_base = IOMEM(0xf100); void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); + gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE); gic_init(0, 29, gic_dist_base, gic_cpu_base); - gic_arch_extn.irq_set_wake = sh73a0_set_wake; register_intc_controller(intcs_desc); register_intc_controller(intc_pint0_desc); diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 6156d17..989de2d 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -713,14 +713,9 @@ void __init r8a7779_init_late(void) } #ifdef CONFIG_USE_OF -static int r8a7779_set_wake(struct irq_data *data, unsigned int on) -{ - return 0; /* always allow wakeup */ -} - void __init r8a7779_init_irq_dt(void) { - gic_arch_extn.irq_set_wake = r8a7779_set_wake; + gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE); irqchip_init(); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 10/21] irqchip: GIC: get rid of routable domain
The only user of the so called routable domain functionality now being fixed, let's clean up the GIC. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- drivers/irqchip/irq-gic.c | 59 - include/linux/irqchip/arm-gic.h | 6 - 2 files changed, 5 insertions(+), 60 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index d617ee5..9c30a76 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -795,15 +795,12 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_domain_set_info(d, irq, hw, gic_chip, d-host_data, handle_fasteoi_irq, NULL, NULL); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - - gic_routable_irq_domain_ops-map(d, irq, hw); } return 0; } static void gic_irq_domain_unmap(struct irq_domain *d, unsigned int irq) { - gic_routable_irq_domain_ops-unmap(d, irq); } static int gic_irq_domain_xlate(struct irq_domain *d, @@ -822,16 +819,8 @@ static int gic_irq_domain_xlate(struct irq_domain *d, *out_hwirq = intspec[1] + 16; /* For SPIs, we need to add 16 more to get the GIC irq ID number */ - if (!intspec[0]) { - ret = gic_routable_irq_domain_ops-xlate(d, controller, -intspec, -intsize, -out_hwirq, -out_type); - - if (IS_ERR_VALUE(ret)) - return ret; - } + if (!intspec[0]) + *out_hwirq += 16; *out_type = intspec[2] IRQ_TYPE_SENSE_MASK; @@ -888,37 +877,6 @@ static const struct irq_domain_ops gic_irq_domain_ops = { .xlate = gic_irq_domain_xlate, }; -/* Default functions for routable irq domain */ -static int gic_routable_irq_domain_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hw) -{ - return 0; -} - -static void gic_routable_irq_domain_unmap(struct irq_domain *d, - unsigned int irq) -{ -} - -static int gic_routable_irq_domain_xlate(struct irq_domain *d, - struct device_node *controller, - const u32 *intspec, unsigned int intsize, - unsigned long *out_hwirq, - unsigned int *out_type) -{ - *out_hwirq += 16; - return 0; -} - -static const struct irq_domain_ops gic_default_routable_irq_domain_ops = { - .map = gic_routable_irq_domain_map, - .unmap = gic_routable_irq_domain_unmap, - .xlate = gic_routable_irq_domain_xlate, -}; - -const struct irq_domain_ops *gic_routable_irq_domain_ops = - gic_default_routable_irq_domain_ops; - void __init gic_init_bases(unsigned int gic_nr, int irq_start, void __iomem *dist_base, void __iomem *cpu_base, u32 percpu_offset, struct device_node *node) @@ -926,7 +884,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, irq_hw_number_t hwirq_base; struct gic_chip_data *gic; int gic_irqs, irq_base, i; - int nr_routable_irqs; BUG_ON(gic_nr = MAX_GIC_NR); @@ -982,15 +939,9 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic-gic_irqs = gic_irqs; if (node) { /* DT case */ - const struct irq_domain_ops *ops = gic_irq_domain_hierarchy_ops; - - if (!of_property_read_u32(node, arm,routable-irqs, - nr_routable_irqs)) { - ops = gic_irq_domain_ops; - gic_irqs = nr_routable_irqs; - } - - gic-domain = irq_domain_add_linear(node, gic_irqs, ops, gic); + gic-domain = irq_domain_add_linear(node, gic_irqs, + gic_irq_domain_hierarchy_ops, + gic); } else {/* Non-DT case */ /* * For primary GICs, skip over SGIs. diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 71d706d..3978c5b 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -115,11 +115,5 @@ int gic_get_cpu_id(unsigned int cpu); void gic_migrate_target(unsigned int new_cpu_id); unsigned long gic_get_sgir_physaddr(void); -extern const struct irq_domain_ops *gic_routable_irq_domain_ops; -static inline void __init register_routable_domain_ops - (const struct irq_domain_ops *ops) -{ - gic_routable_irq_domain_ops = ops; -}
[PATCH v3 13/21] ARM: omap: convert wakeupgen to stacked domains
OMAP4/5 has been (ab)using the gic_arch_extn to provide wakeup from suspend, and it makes a lot of sense to convert this code to use stacked domains instead. This patch does just this, updating the DT files to actually reflect what the HW provides. BIG FAT WARNING: because the DTs were so far lying by not exposing the WUGEN HW block, kernels with this patch applied won't have any suspend-resume facility when booted with old DTs, and old kernels with updated DTs won't even boot. On a platform with this patch applied, the system looks like this: root@bacon-fat:~# cat /proc/interrupts CPU0 CPU1 16: 0 0 WUGEN 37 gp_timer 19: 233799 155916 GIC 27 arch_timer 23: 0 0 WUGEN 9 l3-dbg-irq 24: 1 0 WUGEN 10 l3-app-irq 27:282 0 WUGEN 13 omap-dma-engine 44: 0 0 4ae1.gpio 13 DMA 294: 0 0 WUGEN 20 gpmc 297:506 0 WUGEN 56 4807.i2c 298: 0 0 WUGEN 57 48072000.i2c 299: 0 0 WUGEN 61 4806.i2c 300: 0 0 WUGEN 62 4807a000.i2c 301: 8 0 WUGEN 60 4807c000.i2c 308: 2439 0 WUGEN 74 OMAP UART2 312:362 0 WUGEN 83 mmc2 313:502 0 WUGEN 86 mmc0 314: 13 0 WUGEN 94 mmc1 350: 0 0 PRCM pinctrl, pinctrl 406: 35155709 0 GIC 109 ehci_hcd:usb1 407: 0 0 WUGEN 7 palmas 409: 0 0 WUGEN 119 twl6040 410: 0 0 twl6040 5 twl6040_irq_ready 411: 0 0 twl6040 0 twl6040_irq_th IPI0: 0 1 CPU wakeup interrupts IPI1: 0 0 Timer broadcast interrupts IPI2: 95334 902334 Rescheduling interrupts IPI3: 0 0 Function call interrupts IPI4:479648 Single function call interrupts IPI5: 0 0 CPU stop interrupts IPI6: 0 0 IRQ work interrupts IPI7: 0 0 completion interrupts Err: 0 Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/boot/dts/am4372.dtsi | 11 ++- arch/arm/boot/dts/am437x-gp-evm.dts | 1 - arch/arm/boot/dts/am437x-sk-evm.dts | 1 - arch/arm/boot/dts/am43x-epos-evm.dts | 1 - arch/arm/boot/dts/dra7.dtsi | 12 ++- arch/arm/boot/dts/dra72x.dtsi | 2 +- arch/arm/boot/dts/dra74x.dtsi | 2 +- arch/arm/boot/dts/omap4-duovero.dtsi | 2 - arch/arm/boot/dts/omap4-panda-common.dtsi | 8 +- arch/arm/boot/dts/omap4-sdp.dts | 8 +- arch/arm/boot/dts/omap4-var-som-om44.dtsi | 2 - arch/arm/boot/dts/omap4.dtsi | 18 - arch/arm/boot/dts/omap5-cm-t54.dts| 1 - arch/arm/boot/dts/omap5-uevm.dts | 2 - arch/arm/boot/dts/omap5.dtsi | 26 --- arch/arm/mach-omap2/omap-wakeupgen.c | 125 +++--- arch/arm/mach-omap2/omap-wakeupgen.h | 1 - arch/arm/mach-omap2/omap4-common.c| 1 - 18 files changed, 154 insertions(+), 70 deletions(-) diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index b62a1cd..9d672a7 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -15,7 +15,7 @@ / { compatible = ti,am4372, ti,am43; - interrupt-parent = gic; + interrupt-parent = wakeupgen; aliases { @@ -48,6 +48,15 @@ #interrupt-cells = 3; reg = 0x48241000 0x1000, 0x48240100 0x0100; + interrupt-parent = gic; + }; + + wakeupgen: interrupt-controller@48281000 { + compatible = ti,omap4-wugen-mpu; + interrupt-controller; + #interrupt-cells = 3; + reg = 0x48281000 0x1000; + interrupt-parent = gic; }; l2-cache-controller@48242000 { diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index 7eaae4c..69f2313 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts @@ -280,7 +280,6 @@ reg = 0x24; compatible = ti,tps65218; interrupts = GIC_SPI 7 IRQ_TYPE_NONE; /* NMIn */ - interrupt-parent = gic; interrupt-controller; #interrupt-cells = 2; diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts index 53bbfc9..029bade 100644 --- a/arch/arm/boot/dts/am437x-sk-evm.dts +++ b/arch/arm/boot/dts/am437x-sk-evm.dts @@ -334,7 +334,6 @@ tps@24 { compatible = ti,tps65218; reg = 0x24; - interrupt-parent = gic; interrupts = GIC_SPI 7
[PATCH v3 16/21] DT: exynos: update PMU binding
Document the fact that some Exynos PMUs are capable of acting as an interrupt controller. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- Documentation/devicetree/bindings/arm/samsung/pmu.txt | 13 + 1 file changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt index 1e1979b..d698e74 100644 --- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt +++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt @@ -28,10 +28,23 @@ Properties: - clocks : list of phandles and specifiers to all input clocks listed in clock-names property. +Optional properties: + +Some PMUs are capable of behaving as an interrupt controller (mostly +to wake up a suspended PMU). In which case, they can have the +following properties: + +- interrupt-controller: indicate that said PMU is an interrupt controller + +- interrupt-parent: a phandle indicating which interrupt controller + this PMU signals interrupts to. + Example : pmu_system_controller: system-controller@1004 { compatible = samsung,exynos5250-pmu, syscon; reg = 0x1004 0x5000; + interrupt-controller; + interrupt-parent = gic; #clock-cells = 1; clock-names = clkout0, clkout1, clkout2, clkout3, clkout4, clkout8, clkout9; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 19/21] ARM: ux500: switch from gic_arch_extn to gic_set_irqchip_flags
Instead of directly touching gic_arch_extn, which is about to be removed, use gic_set_irqchip_flags instead. Acked-by: Linus Walleij linus.wall...@linaro.org Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/mach-ux500/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index dbb2970..6ced0f6 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -52,7 +52,7 @@ void ux500_restart(enum reboot_mode mode, const char *cmd) */ void __init ux500_init_irq(void) { - gic_arch_extn.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; + gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND); irqchip_init(); /* -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 07/21] genirq: Add irqchip_set_wake_parent
This proves to be useful with stacked domains, when the current domain doesn't implement wake-up, but expect the parent to do so. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- include/linux/irq.h | 1 + kernel/irq/chip.c | 16 2 files changed, 17 insertions(+) diff --git a/include/linux/irq.h b/include/linux/irq.h index d09ec7a..3057c48 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -460,6 +460,7 @@ extern void irq_chip_eoi_parent(struct irq_data *data); extern int irq_chip_set_affinity_parent(struct irq_data *data, const struct cpumask *dest, bool force); +extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on); #endif /* Handling of unhandled and spurious interrupts: */ diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 6f1c7a5..eb9a4ea 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -948,6 +948,22 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data) return -ENOSYS; } + +/** + * irq_chip_set_wake_parent - Set/reset wake-up on the parent interrupt + * @data: Pointer to interrupt specific data + * @on:Whether to set or reset the wake-up capability of this irq + * + * Conditional, as the underlying parent chip might not implement it. + */ +int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on) +{ + data = data-parent_data; + if (data-chip-irq_set_wake) + return data-chip-irq_set_wake(data, on); + + return -ENOSYS; +} #endif /** -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 02/21] irqchip: tegra: add DT-based support for legacy interrupt controller
Tegra's LIC (Legacy Interrupt Controller) has been so far only supported as a weird extension of the GIC, which is not exactly pretty. The stacked IRQ domain framework fits this pretty well, and allows the LIC code to be turned into a standalone irqchip. In the process, make the driver DT aware, something that was sorely missing from the mach-tegra implementation. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- drivers/irqchip/Makefile| 1 + drivers/irqchip/irq-tegra.c | 368 2 files changed, 369 insertions(+) create mode 100644 drivers/irqchip/irq-tegra.c diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 9516a32..59f34be 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_ARCH_HIP04)+= irq-hip04.o obj-$(CONFIG_ARCH_MMP) += irq-mmp.o obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o obj-$(CONFIG_ARCH_MXS) += irq-mxs.o +obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o obj-$(CONFIG_METAG)+= irq-metag-ext.o diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c new file mode 100644 index 000..e1ac65e --- /dev/null +++ b/drivers/irqchip/irq-tegra.c @@ -0,0 +1,368 @@ +/* + * Driver code for Tegra's Legacy Interrupt Controller + * + * Author: Marc Zyngier marc.zyng...@arm.com + * + * Heavily based on the original arch/arm/mach-tegra/irq.c code: + * Copyright (C) 2011 Google, Inc. + * + * Author: + * Colin Cross ccr...@android.com + * + * Copyright (C) 2010,2013, NVIDIA Corporation + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + * + */ + +#include linux/io.h +#include linux/irq.h +#include linux/irqdomain.h +#include linux/of_address.h +#include linux/slab.h +#include linux/syscore_ops.h + +#include dt-bindings/interrupt-controller/arm-gic.h + +#include irqchip.h + +#define ICTLR_CPU_IEP_VFIQ 0x08 +#define ICTLR_CPU_IEP_FIR 0x14 +#define ICTLR_CPU_IEP_FIR_SET 0x18 +#define ICTLR_CPU_IEP_FIR_CLR 0x1c + +#define ICTLR_CPU_IER 0x20 +#define ICTLR_CPU_IER_SET 0x24 +#define ICTLR_CPU_IER_CLR 0x28 +#define ICTLR_CPU_IEP_CLASS0x2C + +#define ICTLR_COP_IER 0x30 +#define ICTLR_COP_IER_SET 0x34 +#define ICTLR_COP_IER_CLR 0x38 +#define ICTLR_COP_IEP_CLASS0x3c + +#define TEGRA_MAX_NUM_ICTLRS 5 + +static unsigned int num_ictlrs; + +struct tegra_ictlr_soc { + unsigned int num_ictlrs; +}; + +static const struct tegra_ictlr_soc tegra20_ictlr_soc = { + .num_ictlrs = 4, +}; + +static const struct tegra_ictlr_soc tegra30_ictlr_soc = { + .num_ictlrs = 5, +}; + +static const struct of_device_id ictlr_matches[] = { + { .compatible = nvidia,tegra30-ictlr, .data = tegra30_ictlr_soc }, + { .compatible = nvidia,tegra20-ictlr, .data = tegra20_ictlr_soc }, + { } +}; + +struct tegra_ictlr_info { + void __iomem *base[TEGRA_MAX_NUM_ICTLRS]; +#ifdef CONFIG_PM_SLEEP + u32 cop_ier[TEGRA_MAX_NUM_ICTLRS]; + u32 cop_iep[TEGRA_MAX_NUM_ICTLRS]; + u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS]; + u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS]; + + u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS]; +#endif +}; + +static struct tegra_ictlr_info *lic; + +static inline void tegra_ictlr_write_mask(struct irq_data *d, unsigned long reg) +{ + void __iomem *base = d-chip_data; + u32 mask; + + mask = BIT(d-hwirq % 32); + writel_relaxed(mask, base + reg); +} + +static void tegra_mask(struct irq_data *d) +{ + tegra_ictlr_write_mask(d, ICTLR_CPU_IER_CLR); + irq_chip_mask_parent(d); +} + +static void tegra_unmask(struct irq_data *d) +{ + tegra_ictlr_write_mask(d, ICTLR_CPU_IER_SET); + irq_chip_unmask_parent(d); +} + +static void tegra_eoi(struct irq_data *d) +{ + tegra_ictlr_write_mask(d, ICTLR_CPU_IEP_FIR_CLR); + irq_chip_eoi_parent(d); +} + +static int tegra_retrigger(struct irq_data *d) +{ + tegra_ictlr_write_mask(d, ICTLR_CPU_IEP_FIR_SET); + return irq_chip_retrigger_hierarchy(d); +} + +#ifdef CONFIG_PM_SLEEP +static int tegra_set_wake(struct irq_data *d, unsigned int enable) +{ + u32 irq = d-hwirq; + u32 index, mask; + + index = (irq / 32); + mask = BIT(irq % 32); + if (enable) + lic-ictlr_wake_mask[index] |= mask; + else + lic-ictlr_wake_mask[index] = ~mask; + +
[PATCH v3 00/21] irqchip: gic: killing gic_arch_extn and co, slowly
The gic_arch_extn hack that a number of platform use has been nagging me for too long. It is only there for the benefit of a few platform, and yet it impacts all GIC users. Moreover, it gives people the wrong idea (let's use it to put some new custom hack in there...). But now that stacked irq domains have been merged into 3.19, the time has come for gic_arch_extn to meet the Big Bit Bucket. This patch series takes several steps towards the elimination of gic_arch_extn: - moves Tegra's legacy interrupt controller support to drivers/irqchip, implementing a stacked domain on top of the standard GIC. - OMAP, imx6 and exynos are also converted to stacked domains, but their implementation is left in place (the code is far too intricately mixed with other details of the platform for me to even try to move it). Some OMAP variants get a special treatment as we also kill the crossbar horror (more on that below). - shmobile, ux500 and zynq are only slightly modified. - The GIC itself is cleaned up, and some other bits and bobs are adjusted for a good measure. About the TI crossbar: - The allocation of interrupts in this domain is fairly similar to what we do for MSI (see the GICv2m driver), and stacked domains have proved to be a fitting solution. - The current description in DT is currently entierely inaccurate, and as we're already breaking it for the WUGEN block, we might as well do it again for the crossbar. - The way crossbar, WUGEN and GIC interract is quite complex (this is effectively a stack of three interrupt controllers with interesting exceptions and braindead routing), and stacked domains are the right abstraction for that. - Other platforms (Freescale Vybrid) are starting to come up with the same type of things, and it'd be good to avoid them following the same broken model. - It removes a few lines from the code base so it can't completely be a bad idea! So this patch series does exactly that: make the crossbar a stacked interrupt controller that only takes care of setting up the routing, fix the DTs to represent the actual HW, and remove a bit of the craziness from the GIC code. It is worth realizing that: - I haven't been able to test this as much as I would have wanted to (it's only been tested on tegra2 and omap5). - I've created DT bindings when needed, updated existing ones, but I haven't created a binding for platforms that already used an undocumented one (imx6, I'm looking at you). - I've relaxed quite a bit of the locking in the GIC code. I believe this is safe, but someone else should give it a long hard look. - This actively *breaks* existing setups. Once you boot a new kernel with an old DT, suspend/resume *will* be broken. Old kernels on a new DT won't even boot! You've been warned. This really outline the necessity of actually describing the HW in device trees... As for the patches, they are on top of 3.19-rc3. I've pushed the code to: git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/die-gic-arch-extn-die-die-die I'm still targetting 3.20 for this, but obviously things are getting quite tight. I'd very much like to hear from the maintainers about their views concerning this series. Thanks, M. From v2 [2]: - Addressed numerous comments from Thierry - Merged bug fixes from Nishanth - Merged bug fix from Stefan From v1 [1]: - Rebased on 3.19-rc3 - Added crossbar conversion to stacked domains - Merged bug fixes from Nishanth Marc Zyngier (21): ARM: tegra: irq: nuke leftovers from non-DT support irqchip: tegra: add DT-based support for legacy interrupt controller ARM: tegra: skip gic_arch_extn setup if DT has a LIC node ARM: tegra: update DTs to expose legacy interrupt controller DT: tegra: add binding for the legacy interrupt controller ARM: tegra: remove old LIC support genirq: Add irqchip_set_wake_parent irqchip: crossbar: convert dra7 crossbar to stacked domains DT: update ti,irq-crossbar binding irqchip: GIC: get rid of routable domain DT: arm,gic: kill arm,routable-irqs DT: omap4/5: add binding for the wake-up generator ARM: omap: convert wakeupgen to stacked domains ARM: imx6: convert GPC to stacked domains ARM: exynos4/5: convert pmu wakeup to stacked domains DT: exynos: update PMU binding irqchip: gic: add an entry point to set up irqchip flags ARM: shmobile: remove use of gic_arch_extn.irq_set_wake ARM: ux500: switch from gic_arch_extn to gic_set_irqchip_flags ARM: zynq: switch from gic_arch_extn to gic_set_irqchip_flags irqchip: gic: Drop support for gic_arch_extn Documentation/devicetree/bindings/arm/gic.txt | 6 - .../devicetree/bindings/arm/omap/crossbar.txt | 18 +- .../devicetree/bindings/arm/samsung/pmu.txt| 13 + .../interrupt-controller/nvidia,tegra-ictlr.txt| 43 +++ .../interrupt-controller/ti,omap4-wugen-mpu| 33 ++ arch/arm/boot/dts/am4372.dtsi | 11 +-
[PATCH v3 08/21] irqchip: crossbar: convert dra7 crossbar to stacked domains
Support for the TI crossbar used on the DRA7 family of chips is implemented as an ugly hack on the side of the GIC. Converting it to stacked domains makes it slightly more palatable, as it results in a cleanup. Unfortunately, as the DT bindings failed to acknowledge the fact that this is actually yet another interrupt controller (the third, actually), we have yet another breakage. Oh well. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/boot/dts/am57xx-beagle-x15.dts | 3 +- arch/arm/boot/dts/dra7-evm.dts | 2 +- arch/arm/boot/dts/dra7.dtsi | 35 +++--- arch/arm/boot/dts/dra72-evm.dts | 1 - arch/arm/boot/dts/dra72x.dtsi | 3 +- arch/arm/boot/dts/dra74x.dtsi | 5 +- arch/arm/mach-omap2/omap4-common.c | 4 - drivers/irqchip/irq-crossbar.c | 207 ++-- include/linux/irqchip/irq-crossbar.h| 11 -- 9 files changed, 146 insertions(+), 125 deletions(-) delete mode 100644 include/linux/irqchip/irq-crossbar.h diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index 49edbda..c2241c2 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -335,7 +335,6 @@ mcp_rtc: rtc@6f { compatible = microchip,mcp7941x; reg = 0x6f; - interrupt-parent = gic; interrupts = GIC_SPI 2 IRQ_TYPE_LEVEL_LOW; /* IRQ_SYS_1N */ pinctrl-names = default; @@ -358,7 +357,7 @@ uart3 { status = okay; - interrupts-extended = gic GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH, + interrupts-extended = crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH, dra7_pmx_core 0x248; pinctrl-names = default; diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index 10b725c..048cfeb 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -423,7 +423,7 @@ status = okay; pinctrl-names = default; pinctrl-0 = uart1_pins; - interrupts-extended = gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH, + interrupts-extended = crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH, dra7_pmx_core 0x3e0; }; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 22771bc..6f90673 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -13,14 +13,13 @@ #include skeleton.dtsi #define MAX_SOURCES 400 -#define DIRECT_IRQ(irq) (MAX_SOURCES + irq) / { #address-cells = 1; #size-cells = 1; compatible = ti,dra7xx; - interrupt-parent = gic; + interrupt-parent = crossbar_mpu; aliases { i2c0 = i2c1; @@ -50,18 +49,19 @@ GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW), GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW), GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW); + interrupt-parent = gic; }; gic: interrupt-controller@48211000 { compatible = arm,cortex-a15-gic; interrupt-controller; #interrupt-cells = 3; - arm,routable-irqs = 192; reg = 0x48211000 0x1000, 0x48212000 0x1000, 0x48214000 0x2000, 0x48216000 0x2000; interrupts = GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH); + interrupt-parent = gic; }; /* @@ -91,8 +91,8 @@ ti,hwmods = l3_main_1, l3_main_2; reg = 0x4400 0x100, 0x4500 0x1000; - interrupts = GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH, -GIC_SPI DIRECT_IRQ(10) IRQ_TYPE_LEVEL_HIGH; + interrupts-extended = crossbar_mpu GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH, + gic GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH; prm: prm@4ae06000 { compatible = ti,dra7-prm; @@ -344,7 +344,7 @@ uart1: serial@4806a000 { compatible = ti,omap4-uart; reg = 0x4806a000 0x100; - interrupts-extended = gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH; + interrupts-extended = crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH; ti,hwmods = uart1; clock-frequency = 4800; status = disabled; @@ -355,7 +355,7 @@ uart2: serial@4806c000 { compatible = ti,omap4-uart; reg = 0x4806c000 0x100; - interrupts-extended = gic GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH; + interrupts = GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH;
[PATCH v3 04/21] ARM: tegra: update DTs to expose legacy interrupt controller
Describe the legacy interrupt controller in every tegra DTSI files, and make it the parent of most interrupts. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/boot/dts/tegra114.dtsi | 16 +++- arch/arm/boot/dts/tegra124.dtsi | 16 +++- arch/arm/boot/dts/tegra20.dtsi | 15 ++- arch/arm/boot/dts/tegra30.dtsi | 16 +++- 4 files changed, 59 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/tegra114.dtsi b/arch/arm/boot/dts/tegra114.dtsi index 4296b53..f58a3d9 100644 --- a/arch/arm/boot/dts/tegra114.dtsi +++ b/arch/arm/boot/dts/tegra114.dtsi @@ -8,7 +8,7 @@ / { compatible = nvidia,tegra114; - interrupt-parent = gic; + interrupt-parent = lic; host1x@5000 { compatible = nvidia,tegra114-host1x, simple-bus; @@ -134,6 +134,19 @@ 0x50046000 0x2000; interrupts = GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH); + interrupt-parent = gic; + }; + + lic: interrupt-controller@60004000 { + compatible = nvidia,tegra114-ictlr, nvidia,tegra30-ictlr; + reg = 0x60004000 0x100, + 0x60004100 0x50, + 0x60004200 0x50, + 0x60004300 0x50, + 0x60004400 0x50; + interrupt-controller; + #interrupt-cells = 3; + interrupt-parent = gic; }; timer@60005000 { @@ -766,5 +779,6 @@ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW), GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW); + interrupt-parent = gic; }; }; diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index 4be06c6..db85695 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -10,7 +10,7 @@ / { compatible = nvidia,tegra124; - interrupt-parent = gic; + interrupt-parent = lic; #address-cells = 2; #size-cells = 2; @@ -173,6 +173,7 @@ 0x0 0x50046000 0x0 0x2000; interrupts = GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH); + interrupt-parent = gic; }; gpu@0,5700 { @@ -190,6 +191,18 @@ status = disabled; }; + lic: interrupt-controller@60004000 { + compatible = nvidia,tegra124-ictlr, nvidia,tegra30-ictlr; + reg = 0x0 0x60004000 0x0 0x100, + 0x0 0x60004100 0x0 0x100, + 0x0 0x60004200 0x0 0x100, + 0x0 0x60004300 0x0 0x100, + 0x0 0x60004400 0x0 0x100; + interrupt-controller; + #interrupt-cells = 3; + interrupt-parent = gic; + }; + timer@0,60005000 { compatible = nvidia,tegra124-timer, nvidia,tegra20-timer; reg = 0x0 0x60005000 0x0 0x400; @@ -955,5 +968,6 @@ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW), GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW); + interrupt-parent = gic; }; }; diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi index 8acf5d8..362bb21 100644 --- a/arch/arm/boot/dts/tegra20.dtsi +++ b/arch/arm/boot/dts/tegra20.dtsi @@ -7,7 +7,7 @@ / { compatible = nvidia,tegra20; - interrupt-parent = intc; + interrupt-parent = lic; host1x@5000 { compatible = nvidia,tegra20-host1x, simple-bus; @@ -142,6 +142,7 @@ timer@50004600 { compatible = arm,cortex-a9-twd-timer; + interrupt-parent = intc; reg = 0x50040600 0x20; interrupts = GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH); @@ -154,6 +155,7 @@ 0x50040100 0x0100; interrupt-controller; #interrupt-cells = 3; + interrupt-parent = intc; }; cache-controller@50043000 { @@ -165,6 +167,17 @@ cache-level = 2; }; + lic: interrupt-controller@60004000 { + compatible = nvidia,tegra20-ictlr; + reg = 0x60004000 0x100, + 0x60004100 0x50, + 0x60004200 0x50, + 0x60004300 0x50; + interrupt-controller; + #interrupt-cells = 3; + interrupt-parent = intc; + }; + timer@60005000 { compatible = nvidia,tegra20-timer; reg = 0x60005000 0x60; diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index 99475f6..6bea674 100644
[PATCH v3 15/21] ARM: exynos4/5: convert pmu wakeup to stacked domains
Exynos has been (ab)using the gic_arch_extn to provide wakeup from suspend, and it makes a lot of sense to convert this code to use stacked domains instead. This patch does just this, updating the DT files to actually reflect what the HW provides. BIG FAT WARNING: because the DTs were so far lying by not exposing the fact that the PMU block is actually the first interrupt controller in the chain for RTC, kernels with this patch applied wont have any suspend-resume facility when booted with old DTs, and old kernels with updated DTs may not even boot. Also, I stronly suspect that there is more than two wake-up interrupts on these platforms, but I leave it to the maintainers to fix their mess. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/boot/dts/exynos4.dtsi| 3 + arch/arm/boot/dts/exynos5250.dtsi | 3 + arch/arm/boot/dts/exynos5420.dtsi | 3 + arch/arm/mach-exynos/exynos.c | 14 ++--- arch/arm/mach-exynos/suspend.c| 122 ++ 5 files changed, 126 insertions(+), 19 deletions(-) diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index b8168f1..adc189f 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -141,6 +141,8 @@ pmu_system_controller: system-controller@1002 { compatible = samsung,exynos4210-pmu, syscon; reg = 0x1002 0x4000; + interrupt-controller; + interrupt-parent = gic; }; dsi_0: dsi@11C8 { @@ -253,6 +255,7 @@ rtc@1007 { compatible = samsung,s3c6410-rtc; reg = 0x1007 0x100; + interrupt-parent = pmu_system_controller; interrupts = 0 44 0, 0 45 0; clocks = clock CLK_RTC; clock-names = rtc; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 0a229fc..c31007c 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -194,6 +194,8 @@ clock-names = clkout16; clocks = clock CLK_FIN_PLL; #clock-cells = 1; + interrupt-controller; + interrupt-parent = gic; }; sysreg_system_controller: syscon@1005 { @@ -230,6 +232,7 @@ rtc: rtc@101E { clocks = clock CLK_RTC; clock-names = rtc; + interrupt-parent = pmu_system_controller; status = disabled; }; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 517e50f..1946c76c 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -309,6 +309,7 @@ rtc: rtc@101E { clocks = clock CLK_RTC; clock-names = rtc; + interrupt-parent = pmu_system_controller; status = disabled; }; @@ -748,6 +749,8 @@ clock-names = clkout16; clocks = clock CLK_FIN_PLL; #clock-cells = 1; + interrupt-controller; + interrupt-parent = gic; }; sysreg_system_controller: syscon@1005 { diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index c13d083..e417fdc 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -175,16 +175,15 @@ static void __init exynos_init_io(void) exynos_map_io(); } +/* + * Apparently, these SoCs are not able to wake-up from suspend using + * the PMU. Too bad. Should they suddenly become capable of such a + * feat, the matches below should be moved to suspend.c. + */ static const struct of_device_id exynos_dt_pmu_match[] = { { .compatible = samsung,exynos3250-pmu }, - { .compatible = samsung,exynos4210-pmu }, - { .compatible = samsung,exynos4212-pmu }, - { .compatible = samsung,exynos4412-pmu }, - { .compatible = samsung,exynos4415-pmu }, - { .compatible = samsung,exynos5250-pmu }, { .compatible = samsung,exynos5260-pmu }, { .compatible = samsung,exynos5410-pmu }, - { .compatible = samsung,exynos5420-pmu }, { /*sentinel*/ }, }; @@ -195,9 +194,6 @@ static void exynos_map_pmu(void) np = of_find_matching_node(NULL, exynos_dt_pmu_match); if (np) pmu_base_addr = of_iomap(np, 0); - - if (!pmu_base_addr) - panic(failed to find exynos pmu register\n); } static void __init exynos_init_irq(void) diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index f8e7dcd..b325ecd 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -18,7 +18,9 @@ #include linux/syscore_ops.h #include linux/cpu_pm.h #include linux/io.h -#include linux/irqchip/arm-gic.h +#include linux/irq.h +#include linux/irqdomain.h +#include linux/of_address.h
[PATCH v3 12/21] DT: omap4/5: add binding for the wake-up generator
Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- .../interrupt-controller/ti,omap4-wugen-mpu| 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu b/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu new file mode 100644 index 000..43effa0 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,omap4-wugen-mpu @@ -0,0 +1,33 @@ +TI OMAP4 Wake-up Generator + +All TI OMAP4/5 (and their derivatives) an interrupt controller that +routes interrupts to the GIC, and also serves as a wakeup source. It +is also referred to as WUGEN-MPU, hence the name of the binding. + +Reguired properties: + +- compatible : should contain at least ti,omap4-wugen-mpu or + ti,omap5-wugen-mpu +- reg : Specifies base physical address and size of the registers. +- interrupt-controller : Identifies the node as an interrupt controller. +- #interrupt-cells : Specifies the number of cells needed to encode an + interrupt source. The value must be 3. +- interrupt-parent : a phandle to the GIC these interrupts are routed + to. + +Notes: + +- Because this HW ultimately routes interrupts to the GIC, the + interrupt specifier must be that of the GIC. +- Only SPIs can use the WUGEN as an interrupt parent. SGIs and PPIs + are explicitly forbiden. + +Example: + + wakeupgen: interrupt-controller@48281000 { + compatible = ti,omap5-wugen-mpu, ti,omap4-wugen-mpu; + interrupt-controller; + #interrupt-cells = 3; + reg = 0x48281000 0x1000; + interrupt-parent = gic; + }; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 01/21] ARM: tegra: irq: nuke leftovers from non-DT support
The GIC is now always initialized from DT on tegra, and there is no point in keeping non-DT init code. Acked-by: Thierry Reding tred...@nvidia.com Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/mach-tegra/irq.c | 8 1 file changed, 8 deletions(-) diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index ab95f53..7f87a50 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -283,13 +283,5 @@ void __init tegra_init_irq(void) gic_arch_extn.irq_set_wake = tegra_set_wake; gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND; - /* -* Check if there is a devicetree present, since the GIC will be -* initialized elsewhere under DT. -*/ - if (!of_have_populated_dt()) - gic_init(0, 29, distbase, - IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100)); - tegra114_gic_cpu_pm_registration(); } -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 03/21] ARM: tegra: skip gic_arch_extn setup if DT has a LIC node
If we detect that our DT has a LIC node, don't setup gic_arch_extn, and skip tegra_legacy_irq_syscore_init as well. This is only a temporary measure until that code is removed for good. Acked-by: Thierry Reding tred...@nvidia.com Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/mach-tegra/irq.c | 12 arch/arm/mach-tegra/tegra.c | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c index 7f87a50..1593c4c 100644 --- a/arch/arm/mach-tegra/irq.c +++ b/arch/arm/mach-tegra/irq.c @@ -255,11 +255,22 @@ static void tegra114_gic_cpu_pm_registration(void) static void tegra114_gic_cpu_pm_registration(void) { } #endif +static const struct of_device_id tegra_ictlr_match[] __initconst = { + { .compatible = nvidia,tegra20-ictlr }, + { .compatible = nvidia,tegra30-ictlr }, + { } +}; + void __init tegra_init_irq(void) { int i; void __iomem *distbase; + if (of_find_matching_node(NULL, tegra_ictlr_match)) + goto skip_extn_setup; + + tegra_legacy_irq_syscore_init(); + distbase = IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE); num_ictlrs = readl_relaxed(distbase + GIC_DIST_CTR) 0x1f; @@ -283,5 +294,6 @@ void __init tegra_init_irq(void) gic_arch_extn.irq_set_wake = tegra_set_wake; gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND; +skip_extn_setup: tegra114_gic_cpu_pm_registration(); } diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c index ef016af..c33fba7 100644 --- a/arch/arm/mach-tegra/tegra.c +++ b/arch/arm/mach-tegra/tegra.c @@ -82,7 +82,6 @@ static void __init tegra_dt_init_irq(void) { tegra_init_irq(); irqchip_init(); - tegra_legacy_irq_syscore_init(); } static void __init tegra_dt_init(void) -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 11/21] DT: arm,gic: kill arm,routable-irqs
Nobody will regret it. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- Documentation/devicetree/bindings/arm/gic.txt | 6 -- 1 file changed, 6 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/gic.txt b/Documentation/devicetree/bindings/arm/gic.txt index 8112d0c..631cb71 100644 --- a/Documentation/devicetree/bindings/arm/gic.txt +++ b/Documentation/devicetree/bindings/arm/gic.txt @@ -52,11 +52,6 @@ Optional regions, used when the GIC doesn't have banked registers. The offset is cpu-offset * cpu-nr. -- arm,routable-irqs : Total number of gic irq inputs which are not directly - connected from the peripherals, but are routed dynamically - by a crossbar/multiplexer preceding the GIC. The GIC irq - input line is assigned dynamically when the corresponding - peripheral's crossbar line is mapped. Example: intc: interrupt-controller@fff11000 { @@ -64,7 +59,6 @@ Example: #interrupt-cells = 3; #address-cells = 1; interrupt-controller; - arm,routable-irqs = 160; reg = 0xfff11000 0x1000, 0xfff10100 0x100; }; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 21/21] irqchip: gic: Drop support for gic_arch_extn
Now that the users of gic_arch_extn have been fixed, drop the feature for good. This leads to the removal of some now useless locking. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- drivers/irqchip/irq-gic.c | 54 - include/linux/irqchip/arm-gic.h | 2 -- 2 files changed, 56 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 23fe3be..78d4dee 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -80,19 +80,6 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock); #define NR_GIC_CPU_IF 8 static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly; -/* - * Supported arch specific GIC irq extension. - * Default make them NULL. - */ -struct irq_chip gic_arch_extn = { - .irq_eoi= NULL, - .irq_mask = NULL, - .irq_unmask = NULL, - .irq_retrigger = NULL, - .irq_set_type = NULL, - .irq_set_wake = NULL, -}; - #ifndef MAX_GIC_NR #define MAX_GIC_NR 1 #endif @@ -155,32 +142,18 @@ static void gic_mask_irq(struct irq_data *d) { u32 mask = 1 (gic_irq(d) % 32); - raw_spin_lock(irq_controller_lock); writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); - if (gic_arch_extn.irq_mask) - gic_arch_extn.irq_mask(d); - raw_spin_unlock(irq_controller_lock); } static void gic_unmask_irq(struct irq_data *d) { u32 mask = 1 (gic_irq(d) % 32); - raw_spin_lock(irq_controller_lock); - if (gic_arch_extn.irq_unmask) - gic_arch_extn.irq_unmask(d); writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4); - raw_spin_unlock(irq_controller_lock); } static void gic_eoi_irq(struct irq_data *d) { - if (gic_arch_extn.irq_eoi) { - raw_spin_lock(irq_controller_lock); - gic_arch_extn.irq_eoi(d); - raw_spin_unlock(irq_controller_lock); - } - writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI); } @@ -196,23 +169,13 @@ static int gic_set_type(struct irq_data *d, unsigned int type) if (type != IRQ_TYPE_LEVEL_HIGH type != IRQ_TYPE_EDGE_RISING) return -EINVAL; - raw_spin_lock(irq_controller_lock); - - if (gic_arch_extn.irq_set_type) - gic_arch_extn.irq_set_type(d, type); - gic_configure_irq(gicirq, type, base, NULL); - raw_spin_unlock(irq_controller_lock); - return 0; } static int gic_retrigger(struct irq_data *d) { - if (gic_arch_extn.irq_retrigger) - return gic_arch_extn.irq_retrigger(d); - /* the genirq layer expects 0 if we can't retrigger in hardware */ return 0; } @@ -244,21 +207,6 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, } #endif -#ifdef CONFIG_PM -static int gic_set_wake(struct irq_data *d, unsigned int on) -{ - int ret = -ENXIO; - - if (gic_arch_extn.irq_set_wake) - ret = gic_arch_extn.irq_set_wake(d, on); - - return ret; -} - -#else -#define gic_set_wake NULL -#endif - static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) { u32 irqstat, irqnr; @@ -321,7 +269,6 @@ static struct irq_chip gic_chip = { #ifdef CONFIG_SMP .irq_set_affinity = gic_set_affinity, #endif - .irq_set_wake = gic_set_wake, }; void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) @@ -985,7 +932,6 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, set_handle_irq(gic_handle_irq); } - gic_chip.flags |= gic_arch_extn.flags; gic_dist_init(gic); gic_cpu_init(gic); gic_pm_init(gic); diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 36ec4ae..9de976b 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -95,8 +95,6 @@ struct device_node; -extern struct irq_chip gic_arch_extn; - void gic_set_irqchip_flags(unsigned long flags); void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, u32 offset, struct device_node *); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 17/21] irqchip: gic: add an entry point to set up irqchip flags
A common use of gic_arch_extn is to set up additional flags to the GIC irqchip. It looks like a benign enough hack that doesn't really require the users of that feature to be converted to stacked domains. Add a gic_set_irqchip_flags() function that platform code can call instead of using the dreaded gic_arch_extn. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- drivers/irqchip/irq-gic.c | 5 + include/linux/irqchip/arm-gic.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 9c30a76..23fe3be 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -877,6 +877,11 @@ static const struct irq_domain_ops gic_irq_domain_ops = { .xlate = gic_irq_domain_xlate, }; +void gic_set_irqchip_flags(unsigned long flags) +{ + gic_chip.flags |= flags; +} + void __init gic_init_bases(unsigned int gic_nr, int irq_start, void __iomem *dist_base, void __iomem *cpu_base, u32 percpu_offset, struct device_node *node) diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 3978c5b..36ec4ae 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -97,6 +97,7 @@ struct device_node; extern struct irq_chip gic_arch_extn; +void gic_set_irqchip_flags(unsigned long flags); void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, u32 offset, struct device_node *); void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 20/21] ARM: zynq: switch from gic_arch_extn to gic_set_irqchip_flags
Instead of directly touching gic_arch_extn, which is about to be removed, use gic_set_irqchip_flags instead. Signed-off-by: Marc Zyngier marc.zyng...@arm.com --- arch/arm/mach-zynq/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 26f92c2..82734d5 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -188,7 +188,7 @@ static void __init zynq_map_io(void) static void __init zynq_irq_init(void) { - gic_arch_extn.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; + gic_set_irqchip_flags(IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND); irqchip_init(); } -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] usb: dwc3: gadget: Stop TRB preparation after limit is reached
Hi, On Tue, Jan 06, 2015 at 11:44:23AM +0530, Amit Virdi wrote: I can certainly provide the dwc3 specific kernel bootup logs, full regdump and any loglevel you want me to, if that helps Yeah, if you can provide those, then that'll help me verifying. Full logs from boot to failure point with VERBOSE_DEBUG enabled (considering you're not running on anything recent). Okay. I'll provide full verbose logs, along with the register dump, when I'm back to the office next week, for the working and non-working case, but how - as attachment or as inline? Either way will do but I have a feeling mailing list attachment size will bite you, so maybe it's best to make a tarball of both logs and send that as attachment. Compressed text will be very small. Attached are the dwc3 verbose logs and register dump without and with the fixes in this patchset. Sorry for the long delay, it has been a bit hectic. I can see from your logs that we end up with a Transfer Not Ready (Transfer Active) event and endpoint has BUSY flag set. I also see that you're queueing 31 requests and all of them will use 2 TRBs, so we clearly go over our TRB table. This fix is, indeed, necessary but we need to improve commit log a bit so it's extremely clear what the error is. Later, we can improve how we handle requests in this driver, but that is outside of the scope of your patchset. Please improve commit log and resend your series so it can be applied. cheers -- balbi signature.asc Description: Digital signature