Re: [PATCH 2/2] rtc: omap: Add external clock enabling support
On 13/08/2015 at 12:37:48 +0530, Keerthy wrote : Configure the clock source to either internal clock or external clock based on the availability of the clocks. External clock is preferred as it can be ticking during suspend. Signed-off-by: Keerthy j-keer...@ti.com --- drivers/rtc/rtc-omap.c | 44 1 file changed, 44 insertions(+) diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 8b6355f..479f730 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -25,6 +25,7 @@ #include linux/of_device.h #include linux/pm_runtime.h #include linux/io.h +#include linux/clk.h /* * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock @@ -107,6 +108,7 @@ /* OMAP_RTC_OSC_REG bit fields: */ #define OMAP_RTC_OSC_32KCLK_EN BIT(6) +#define OMAP_RTC_OSC_SEL_32KCLK_SRC BIT(3) /* OMAP_RTC_IRQWAKEEN bit fields: */ #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1) @@ -136,6 +138,7 @@ struct omap_rtc { int irq_timer; u8 interrupts_reg; bool is_pmic_controller; + bool has_ext_clk; const struct omap_rtc_device_type *type; }; @@ -525,6 +528,7 @@ static int omap_rtc_probe(struct platform_device *pdev) { struct omap_rtc *rtc; struct resource *res; + struct clk *ext_clk, *int_clk; u8 reg, mask, new_ctrl; const struct platform_device_id *id_entry; const struct of_device_id *of_id; @@ -553,6 +557,17 @@ static int omap_rtc_probe(struct platform_device *pdev) if (rtc-irq_alarm = 0) return -ENOENT; + ext_clk = devm_clk_get(pdev-dev, ext-clk); + if (!IS_ERR(ext_clk)) { + rtc-has_ext_clk = true; + clk_prepare(ext_clk); I'd say this has to be prepare_enable because you are not enabling those clocks anywhere + } else { + int_clk = devm_clk_get(pdev-dev, int-clk); + + if (!IS_ERR(int_clk)) + clk_prepare(int_clk); + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rtc-base = devm_ioremap_resource(pdev-dev, res); if (IS_ERR(rtc-base)) @@ -627,6 +642,17 @@ static int omap_rtc_probe(struct platform_device *pdev) if (reg != new_ctrl) rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); + /* + * If we have the external clock then + * Switch to external clock so we can keep ticking + * acorss suspend + */ + if (rtc-has_ext_clk) { + reg = rtc_read(rtc, OMAP_RTC_OSC_REG); + rtc_write(rtc, OMAP_RTC_OSC_REG, reg | + OMAP_RTC_OSC_SEL_32KCLK_SRC); + } + rtc-type-lock(rtc); device_init_wakeup(pdev-dev, true); @@ -672,6 +698,8 @@ err: static int __exit omap_rtc_remove(struct platform_device *pdev) { struct omap_rtc *rtc = platform_get_drvdata(pdev); + struct clk *ext_clk, *int_clk; + u8 reg; if (pm_power_off == omap_rtc_power_off omap_rtc_power_off_rtc == rtc) { @@ -681,10 +709,26 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) device_init_wakeup(pdev-dev, 0); + ext_clk = devm_clk_get(pdev-dev, ext-clk); + if (!IS_ERR(ext_clk)) { + clk_unprepare(ext_clk); + } else { + int_clk = devm_clk_get(pdev-dev, int-clk); + + if (!IS_ERR(int_clk)) + clk_unprepare(int_clk); + } + You can probably add ext_clk and int_clk to struct omap_rtc and avoid those devm_clk_get. rtc-type-unlock(rtc); /* leave rtc running, but disable irqs */ rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); + if (rtc-has_ext_clk) { Then you could also avoid has_ext_clk and simply test rtc-ext_clk. + reg = rtc_read(rtc, OMAP_RTC_OSC_REG); + reg = ~OMAP_RTC_OSC_SEL_32KCLK_SRC; + rtc_write(rtc, OMAP_RTC_OSC_REG, reg); + } + rtc-type-lock(rtc); /* Disable the clock/module */ -- 1.9.1 -- Alexandre Belloni, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.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/6] rtc: omap: Add external clock enabling support
On 13/08/2015 at 20:17:23 +, Paul Walmsley wrote : I'd say that I don't really care. I'd say the best would be to make a decision based on clock-accuracy but maybe that is an information you don't have yet. Anyway, this could be added at a later date. Either the clock mux logic is glitchless, in which case the RTC is likely to lose at least 31 microseconds per switch; or it's not glitchless, in which case it's unsafe to switch the RTC clock source while the clock isn't gated. Keerthy, before submitting this patch for merging, I'd suggest consulting your hardware folks to figure out which case it is. Don't take me wrong, your point is perfectly valid. I was just saying that I didn't care what was done in the driver. Obviously, this has to match what is best from a hardware point of view. But since we agreed on the DT bindings, I'd say that we can still adjust the driver later. -- Alexandre Belloni, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.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 2/2] rtc: omap: Add external clock enabling support
On Friday 14 August 2015 02:03 PM, Alexandre Belloni wrote: On 13/08/2015 at 12:37:48 +0530, Keerthy wrote : Configure the clock source to either internal clock or external clock based on the availability of the clocks. External clock is preferred as it can be ticking during suspend. Signed-off-by: Keerthy j-keer...@ti.com --- drivers/rtc/rtc-omap.c | 44 1 file changed, 44 insertions(+) diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 8b6355f..479f730 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -25,6 +25,7 @@ #include linux/of_device.h #include linux/pm_runtime.h #include linux/io.h +#include linux/clk.h /* * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock @@ -107,6 +108,7 @@ /* OMAP_RTC_OSC_REG bit fields: */ #define OMAP_RTC_OSC_32KCLK_ENBIT(6) +#define OMAP_RTC_OSC_SEL_32KCLK_SRCBIT(3) /* OMAP_RTC_IRQWAKEEN bit fields: */ #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN BIT(1) @@ -136,6 +138,7 @@ struct omap_rtc { int irq_timer; u8 interrupts_reg; bool is_pmic_controller; + bool has_ext_clk; const struct omap_rtc_device_type *type; }; @@ -525,6 +528,7 @@ static int omap_rtc_probe(struct platform_device *pdev) { struct omap_rtc *rtc; struct resource *res; + struct clk *ext_clk, *int_clk; u8 reg, mask, new_ctrl; const struct platform_device_id *id_entry; const struct of_device_id *of_id; @@ -553,6 +557,17 @@ static int omap_rtc_probe(struct platform_device *pdev) if (rtc-irq_alarm = 0) return -ENOENT; + ext_clk = devm_clk_get(pdev-dev, ext-clk); + if (!IS_ERR(ext_clk)) { + rtc-has_ext_clk = true; + clk_prepare(ext_clk); I'd say this has to be prepare_enable because you are not enabling those clocks anywhere + } else { + int_clk = devm_clk_get(pdev-dev, int-clk); + + if (!IS_ERR(int_clk)) + clk_prepare(int_clk); + } + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rtc-base = devm_ioremap_resource(pdev-dev, res); if (IS_ERR(rtc-base)) @@ -627,6 +642,17 @@ static int omap_rtc_probe(struct platform_device *pdev) if (reg != new_ctrl) rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); + /* +* If we have the external clock then +* Switch to external clock so we can keep ticking +* acorss suspend +*/ + if (rtc-has_ext_clk) { + reg = rtc_read(rtc, OMAP_RTC_OSC_REG); + rtc_write(rtc, OMAP_RTC_OSC_REG, reg | + OMAP_RTC_OSC_SEL_32KCLK_SRC); + } + rtc-type-lock(rtc); device_init_wakeup(pdev-dev, true); @@ -672,6 +698,8 @@ err: static int __exit omap_rtc_remove(struct platform_device *pdev) { struct omap_rtc *rtc = platform_get_drvdata(pdev); + struct clk *ext_clk, *int_clk; + u8 reg; if (pm_power_off == omap_rtc_power_off omap_rtc_power_off_rtc == rtc) { @@ -681,10 +709,26 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) device_init_wakeup(pdev-dev, 0); + ext_clk = devm_clk_get(pdev-dev, ext-clk); + if (!IS_ERR(ext_clk)) { + clk_unprepare(ext_clk); + } else { + int_clk = devm_clk_get(pdev-dev, int-clk); + + if (!IS_ERR(int_clk)) + clk_unprepare(int_clk); + } + You can probably add ext_clk and int_clk to struct omap_rtc and avoid those devm_clk_get. Since both int_clk and ext_clk are mutual exclusive, you can have only one variable. Thanks, Vaibhav -- 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] gpiolib: irqchip: use different lockdep class for each gpio irqchip
On 13/08/15 17:58, Grygorii Strashko wrote: Since IRQ chip helpers were introduced drivers lose ability to register separate lockdep classes for each registered GPIO IRQ chip and the gpiolib now is using shared lockdep class for all GPIO IRQ chips (gpiochip_irq_lock_class). As result, lockdep will produce warning when there are min two stacked GPIO chips and all of them are interrupt controllers. HW configuration which generates lockdep warning (TI dra7-evm): [SOC GPIO bankA.gpioX] - irq - [pcf875x.gpioY] - irq - DevZ.enable_irq_wake(pcf_gpioY_irq); The issue was reported in [1] and discussed [2]. = [ INFO: possible recursive locking detected ] 4.2.0-rc6-00013-g5d050ed-dirty #55 Not tainted - sh/63 is trying to acquire lock: (class){..}, at: [c009b91c] __irq_get_desc_lock+0x50/0x94 but task is already holding lock: (class){..}, at: [c009b91c] __irq_get_desc_lock+0x50/0x94 other info that might help us debug this: Possible unsafe locking scenario: CPU0 lock(class); lock(class); *** DEADLOCK *** May be due to missing lock nesting notation 7 locks held by sh/63: #0: (sb_writers#4){.+.+.+}, at: [c016bbb8] vfs_write+0x13c/0x164 #1: (of-mutex){+.+.+.}, at: [c01debf4] kernfs_fop_write+0x4c/0x1a0 #2: (s_active#36){.+.+.+}, at: [c01debfc] kernfs_fop_write+0x54/0x1a0 #3: (pm_mutex){+.+.+.}, at: [c009758c] pm_suspend+0xec/0x4c4 #4: (dev-mutex){..}, at: [c03f77f8] __device_suspend+0xd4/0x398 #5: (gpio-lock){+.+.+.}, at: [c009b940] __irq_get_desc_lock+0x74/0x94 #6: (class){..}, at: [c009b91c] __irq_get_desc_lock+0x50/0x94 stack backtrace: CPU: 0 PID: 63 Comm: sh Not tainted 4.2.0-rc6-00013-g5d050ed-dirty #55 Hardware name: Generic DRA74X (Flattened Device Tree) [c0016e24] (unwind_backtrace) from [c0013338] (show_stack+0x10/0x14) [c0013338] (show_stack) from [c05f6b24] (dump_stack+0x84/0x9c) [c05f6b24] (dump_stack) from [c00903f4] (__lock_acquire+0x19c0/0x1e20) [c00903f4] (__lock_acquire) from [c0091098] (lock_acquire+0xa8/0x128) [c0091098] (lock_acquire) from [c05fd61c] (_raw_spin_lock_irqsave+0x38/0x4c) [c05fd61c] (_raw_spin_lock_irqsave) from [c009b91c] (__irq_get_desc_lock+0x50/0x94) [c009b91c] (__irq_get_desc_lock) from [c009c4f4] (irq_set_irq_wake+0x20/0xfc) [c009c4f4] (irq_set_irq_wake) from [c0393ac4] (pcf857x_irq_set_wake+0x24/0x54) [c0393ac4] (pcf857x_irq_set_wake) from [c009c560] (irq_set_irq_wake+0x8c/0xfc) [c009c560] (irq_set_irq_wake) from [c04a02ac] (gpio_keys_suspend+0x70/0xd4) [c04a02ac] (gpio_keys_suspend) from [c03f6a00] (dpm_run_callback+0x50/0x124) [c03f6a00] (dpm_run_callback) from [c03f7830] (__device_suspend+0x10c/0x398) [c03f7830] (__device_suspend) from [c03f90f0] (dpm_suspend+0x134/0x2f4) [c03f90f0] (dpm_suspend) from [c0096e20] (suspend_devices_and_enter+0xa8/0x728) [c0096e20] (suspend_devices_and_enter) from [c00977cc] (pm_suspend+0x32c/0x4c4) [c00977cc] (pm_suspend) from [c0096060] (state_store+0x64/0xb8) [c0096060] (state_store) from [c01dec64] (kernfs_fop_write+0xbc/0x1a0) [c01dec64] (kernfs_fop_write) from [c016b280] (__vfs_write+0x20/0xd8) [c016b280] (__vfs_write) from [c016bb0c] (vfs_write+0x90/0x164) [c016bb0c] (vfs_write) from [c016c330] (SyS_write+0x44/0x9c) [c016c330] (SyS_write) from [c000f500] (ret_fast_syscall+0x0/0x54) Lets fix it by using separate lockdep class for each registered GPIO IRQ Chip. This is done by wrapping gpiochip_irqchip_add call into macros. The implementation of this patch inspired by solution done by Nicolas Boichat for regmap [3] [1] http://www.spinics.net/lists/linux-gpio/msg05844.html [2] http://www.spinics.net/lists/linux-gpio/msg06021.html [3] http://www.spinics.net/lists/arm-kernel/msg429834.html Cc: Geert Uytterhoeven ge...@linux-m68k.org Cc: Roger Quadros rog...@ti.com Reported-by: Roger Quadros rog...@ti.com Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com Nice !! :) Tested-by: Roger Quadros rog...@ti.com cheers, -roger --- drivers/gpio/gpiolib.c | 27 ++- include/linux/gpio/driver.h | 27 ++- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index bf4bd1d..75dddc1 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -456,12 +456,6 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, } EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip); -/* - * This lock class tells lockdep that GPIO irqs are in a different - * category than their parents, so it won't report false recursion. - */ -static struct lock_class_key gpiochip_irq_lock_class; - /** * gpiochip_irq_map() - maps an IRQ into a GPIO irqchip * @d: the irqdomain used by this irqchip @@ -478,7 +472,11 @@ static int gpiochip_irq_map(struct
[PATCH RFC v3 7/7] ARM: dts: am335x-boneblack: Add HDMI audio support
Add HDMI audio support. Adds mcasp0_pins, clk_mcasp0_fixed, clk_mcasp0, mcasp0, sound node, and updates the tda19988 node to follow the new binding. Signed-off-by: Jyri Sarha jsa...@ti.com --- arch/arm/boot/dts/am335x-boneblack.dts | 90 -- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts index eadbba3..7d3e899 100644 --- a/arch/arm/boot/dts/am335x-boneblack.dts +++ b/arch/arm/boot/dts/am335x-boneblack.dts @@ -64,6 +64,16 @@ 0x1b0 0x03 /* xdma_event_intr0, OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT */ ; }; + + mcasp0_pins: mcasp0_pins { + pinctrl-single,pins = + 0x1ac (PIN_INPUT_PULLUP | MUX_MODE0)/* mcasp0_ahclkx.mcasp0_ahclkx */ + 0x19c (PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2 */ + 0x194 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ + 0x190 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ + 0x06c (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a11.GPIO1_27 */ + ; + }; }; lcdc { @@ -76,17 +86,89 @@ }; i2c0 { - tda19988 { + tda19988: tda19988 { compatible = nxp,tda998x; reg = 0x70; + + #sound-dai-cells = 0; + pinctrl-names = default, off; pinctrl-0 = nxp_hdmi_bonelt_pins; pinctrl-1 = nxp_hdmi_bonelt_off_pins; - port { - hdmi_0: endpoint@0 { - remote-endpoint = lcdc_0; + ports { + #address-cells = 1; + #size-cells = 0; + port@0 { + port-type = rgb; + reg = 0x230145; + hdmi_0: endpoint@0 { + remote-endpoint = lcdc_0; + }; }; + port@1 { + port-type = i2s; + reg = 0x03; + tda19988_i2s: endpoint { + remote-endpoint = mcasp0_i2s; + }; + }; + }; + }; +}; + +rtc { + system-power-controller; +}; + +mcasp0{ + #sound-dai-cells = 0; + pinctrl-names = default; + pinctrl-0 = mcasp0_pins; + status = okay; + op-mode = 0; /* MCASP_IIS_MODE */ + tdm-slots = 2; + serial-dir = /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 1 0 + ; + tx-num-evt = 1; + rx-num-evt = 1; + + port { + mcasp0_i2s: endpoint { + remote-endpoint = tda19988_i2s; + }; + }; +}; + +/ { + clk_mcasp0_fixed: clk_mcasp0_fixed { + #clock-cells = 0; + compatible = fixed-clock; + clock-frequency = 24576000; + }; + + clk_mcasp0: clk_mcasp0 { + #clock-cells = 0; + compatible = gpio-gate-clock; + clocks = clk_mcasp0_fixed; + enable-gpios = gpio1 27 0; /* BeagleBone Black Clk enable on GPIO1_27 */ + }; + + sound { + compatible = simple-audio-card; + simple-audio-card,name = TI BeagleBone Black; + simple-audio-card,format = i2s; + simple-audio-card,bitclock-master = dailink0_master; + simple-audio-card,frame-master = dailink0_master; + + dailink0_master: simple-audio-card,cpu { + sound-dai = mcasp0; + clocks = clk_mcasp0; + }; + + simple-audio-card,codec { + sound-dai = tda19988; }; }; }; -- 1.9.1 -- 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 RFC v3 4/7] drm/i2c: tda998x: Add support of a DT graph of ports
From: Jean-Francois Moine moin...@free.fr Two kinds of ports may be declared in a DT graph of ports: video and audio. This patch accepts the port value from a video port as an alternative to the video-ports property. It also accepts audio ports in the case the transmitter is not used as a slave encoder. The new file include/sound/tda998x.h prepares to the definition of a tda998x CODEC. Signed-off-by: Jean-Francois Moine moin...@free.fr Signed-off-by: Jyri Sarha jsa...@ti.com --- .../devicetree/bindings/drm/i2c/tda998x.txt| 51 drivers/gpu/drm/i2c/tda998x_drv.c | 90 +++--- include/sound/tda998x.h| 8 ++ 3 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 include/sound/tda998x.h diff --git a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt index e9e4bce..35f6a80 100644 --- a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt +++ b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt @@ -16,6 +16,35 @@ Optional properties: - video-ports: 24 bits value which defines how the video controller output is wired to the TDA998x input - default: 0x230145 + This property is not used when ports are defined. + +Optional nodes: + + - port: up to three ports. + The ports are defined according to [1]. + +Video port. + There may be only one video port. + This one must contain the following property: + + - port-type: must be rgb + + and may contain the optional property: + + - reg: 24 bits value which defines how the video controller + output is wired to the TDA998x input (video pins) + When absent, the default value is 0x230145. + +Audio ports. + There may be one or two audio ports. + These ones must contain the following properties: + + - port-type: must be i2s or spdif + + - reg: 8 bits value which defines how the audio controller + output is wired to the TDA998x input (audio pins) + +[1] Documentation/devicetree/bindings/graph.txt Example: @@ -26,4 +55,26 @@ Example: interrupts = 27 2;/* falling edge */ pinctrl-0 = pmx_camera; pinctrl-names = default; + + port@230145 { + port-type = rgb; + reg = 0x230145; + hdmi_0: endpoint { + remote-endpoint = lcd0_0; + }; + }; + port@3 {/* AP1 = I2S */ + port-type = i2s; + reg = 0x03; + tda998x_i2s: endpoint { + remote-endpoint = audio1_i2s; + }; + }; + port@4 { /* AP2 = S/PDIF */ + port-type = spdif; + reg = 0x04; + tda998x_spdif: endpoint { + remote-endpoint = audio1_spdif1; + }; + }; }; diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 424228b..0952eac 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -27,6 +27,7 @@ #include drm/drm_edid.h #include drm/drm_of.h #include drm/i2c/tda998x.h +#include sound/tda998x.h #define DBG(fmt, ...) DRM_DEBUG(fmt\n, ##__VA_ARGS__) @@ -47,6 +48,8 @@ struct tda998x_priv { wait_queue_head_t wq_edid; volatile int wq_edid_wait; struct drm_encoder *encoder; + + struct tda998x_audio audio; }; #define to_tda998x_priv(x) ((struct tda998x_priv *)to_encoder_slave(x)-slave_priv) @@ -774,6 +777,8 @@ static void tda998x_encoder_set_config(struct tda998x_priv *priv, (p-mirr_f ? VIP_CNTRL_2_MIRR_F : 0); priv-params = *p; + priv-audio.port_types[0] = p-audio_format; + priv-audio.ports[0] = p-audio_cfg; } static void tda998x_encoder_dpms(struct tda998x_priv *priv, int mode) @@ -1230,9 +1235,57 @@ static struct drm_encoder_slave_funcs tda998x_encoder_slave_funcs = { /* I2C driver functions */ +static int tda998x_parse_ports(struct tda998x_priv *priv, + struct device_node *np) +{ + struct device_node *of_port; + const char *port_type; + int ret, audio_index, reg, afmt; + + audio_index = 0; + for_each_child_of_node(np, of_port) { + if (!of_port-name +|| of_node_cmp(of_port-name, port) != 0) + continue; + ret = of_property_read_string(of_port, port-type, + port_type); + if (ret 0) + continue; + ret = of_property_read_u32(of_port,
[PATCH RFC v3 0/7] Implement generic ASoC HDMI codec and use it in tda998x
This is my third RFC patch series on the subject. This time also the tda998x driver patches are a serious attempt to come up with an initial implementation for HDMI audio ASoC support. Russell's drm/edid: add function to help find SADs is here just to produce a working patch-set on top of mainline. It should be getting in trough drm-next at some point. The binding for tda998x is taken from Jean Francois' patch series[1] on the same subject. The implementation of the of-node parsing has some minor changes from my self. Here is what I think at least could or should still be done, but non of that stuff does not sounds critical right now. Missing from tda998x driver side - hdmi_codec_ops audio_startup() implementation for audio abort support - multi channel audio support (I would need specs and preferably some HW to test for this). Missing from ASoC side generic implementation: - channel_allocation handling is completely left for the video side driver, see if ASoC side could help in any way - snd_soc_jack functionality to handle hdmi cable plug/unplug events [1] http://mailman.alsa-project.org/pipermail/alsa-devel/2015-July/095596.html Best regards, Jyri Jean-Francois Moine (1): drm/i2c: tda998x: Add support of a DT graph of ports Jyri Sarha (5): ASoC: hdmi: Remove obsolete dummy HDMI codec ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality ARM: dts: am335x-boneblack: Add HDMI audio support Russell King - ARM Linux (1): drm/edid: add function to help find SADs, DO NOT MERGE .../devicetree/bindings/drm/i2c/tda998x.txt| 51 +++ arch/arm/boot/dts/am335x-boneblack.dts | 90 +++- drivers/gpu/drm/i2c/Kconfig| 1 + drivers/gpu/drm/i2c/tda998x_drv.c | 336 +-- include/drm/drm_edid.h | 19 + include/sound/hdmi-codec.h | 99 + sound/soc/codecs/Kconfig | 3 +- sound/soc/codecs/Makefile | 4 +- sound/soc/codecs/hdmi-codec.c | 467 + sound/soc/codecs/hdmi.c| 109 - 10 files changed, 1026 insertions(+), 153 deletions(-) create mode 100644 include/sound/hdmi-codec.h create mode 100644 sound/soc/codecs/hdmi-codec.c delete mode 100644 sound/soc/codecs/hdmi.c -- 1.9.1 -- 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 RFC v3 6/7] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality
Register ASoC HDMI codec for audio functionality. This is an initial ASoC audio implementation for tda998x driver and it does not use all the features provided by hdmi-codec. HDMI audio info-frame and audio stream header is generated by the ASoC HDMI codec. The codec also applies constraints for available sample-rates. Implementation of audio_startup for hdmi_codec_ops would enable tda998x driver to abort ongoing playback if the HDMI cable is unplugged or re-plugged to a device without audio capability. Signed-off-by: Jyri Sarha jsa...@ti.com --- drivers/gpu/drm/i2c/Kconfig | 1 + drivers/gpu/drm/i2c/tda998x_drv.c | 241 +- 2 files changed, 214 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i2c/Kconfig b/drivers/gpu/drm/i2c/Kconfig index 22c7ed6..088f278 100644 --- a/drivers/gpu/drm/i2c/Kconfig +++ b/drivers/gpu/drm/i2c/Kconfig @@ -28,6 +28,7 @@ config DRM_I2C_SIL164 config DRM_I2C_NXP_TDA998X tristate NXP Semiconductors TDA998X HDMI encoder default m if DRM_TILCDC + select SND_SOC_HDMI_CODEC if SND_SOC help Support for NXP Semiconductors TDA998X HDMI encoders. diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 4dc2dc0..8444e18 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -20,6 +20,7 @@ #include linux/module.h #include linux/irq.h #include sound/asoundef.h +#include sound/hdmi-codec.h #include drm/drmP.h #include drm/drm_crtc_helper.h @@ -49,6 +50,8 @@ struct tda998x_priv { u8 vip_cntrl_2; struct tda998x_encoder_params params; + struct platform_device *audio_pdev; + wait_queue_head_t wq_edid; volatile int wq_edid_wait; struct drm_encoder *encoder; @@ -435,7 +438,7 @@ out: } static void -reg_write_range(struct tda998x_priv *priv, uint16_t reg, uint8_t *p, int cnt) +reg_write_range(struct tda998x_priv *priv, uint16_t reg, const u8 *p, int cnt) { struct i2c_client *client = priv-hdmi; uint8_t buf[cnt+1]; @@ -619,7 +622,7 @@ tda998x_write_if(struct tda998x_priv *priv, uint8_t bit, uint16_t addr, } static void -tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) +tda998x_write_raw_aif(struct tda998x_priv *priv, u8 *audio_frame) { u8 buf[PB(HDMI_AUDIO_INFOFRAME_SIZE) + 1]; @@ -627,10 +630,10 @@ tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) buf[HB(0)] = HDMI_INFOFRAME_TYPE_AUDIO; buf[HB(1)] = 0x01; buf[HB(2)] = HDMI_AUDIO_INFOFRAME_SIZE; - buf[PB(1)] = p-audio_frame[1] 0x07; /* CC */ - buf[PB(2)] = p-audio_frame[2] 0x1c; /* SF */ - buf[PB(4)] = p-audio_frame[4]; - buf[PB(5)] = p-audio_frame[5] 0xf8; /* DM_INH + LSV */ + buf[PB(1)] = audio_frame[1] 0x07; /* CC */ + buf[PB(2)] = audio_frame[2] 0x1c; /* SF */ + buf[PB(4)] = audio_frame[4]; + buf[PB(5)] = audio_frame[5] 0xf8; /* DM_INH + LSV */ buf[PB(0)] = tda998x_cksum(buf, sizeof(buf)); @@ -638,6 +641,24 @@ tda998x_write_aif(struct tda998x_priv *priv, struct tda998x_encoder_params *p) sizeof(buf)); } +static int tda998x_write_aif(struct tda998x_priv *priv, +struct hdmi_audio_infoframe *cea) +{ + uint8_t buf[HDMI_INFOFRAME_SIZE(AUDIO)]; + int len; + + len = hdmi_audio_infoframe_pack(cea, buf, sizeof(buf)); + if (len 0) { + dev_err(priv-hdmi-dev, + Failed to pack audio infoframe: %d\n, len); + return len; + } + + /* Write the audio information packet */ + tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, len); + return 0; +} + static void tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode) { @@ -670,19 +691,24 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) } } -static void +static int tda998x_configure_audio(struct tda998x_priv *priv, - struct drm_display_mode *mode, struct tda998x_encoder_params *p) + int mode_clock, + int ena_ap, + int dai_format, + int sample_width, + int sample_rate, + const u8 *status) { uint8_t buf[6], clksel_aip, clksel_fs, cts_n, adiv; uint32_t n; /* Enable audio ports */ - reg_write(priv, REG_ENA_AP, p-audio_cfg); - reg_write(priv, REG_ENA_ACLK, p-audio_clk_cfg); + reg_write(priv, REG_ENA_AP, ena_ap); + reg_write(priv, REG_ENA_ACLK, dai_format == AFMT_SPDIF ? 0 : 1); /* Set audio input source */ - switch (p-audio_format) { + switch (dai_format) { case AFMT_SPDIF: reg_write(priv, REG_MUX_AP, MUX_AP_SELECT_SPDIF); clksel_aip =
[PATCH RFC v3 5/7] drm/i2c: tda998x: Remove include/sound/tda998x.h and fix graph parsing
Move struct tda998x_audio definition to tda998x_drv.c and remove include/sound/tda998x.h. There is no external use for struct tda998x_audio. Fix graph parsing to allow ports to be inside a separate ports-node as specified in Documentation/devicetree/bindings/graph.txt. Signed-off-by: Jyri Sarha jsa...@ti.com --- drivers/gpu/drm/i2c/tda998x_drv.c | 59 +-- include/sound/tda998x.h | 8 -- 2 files changed, 32 insertions(+), 35 deletions(-) delete mode 100644 include/sound/tda998x.h diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 0952eac..4dc2dc0 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -27,10 +27,14 @@ #include drm/drm_edid.h #include drm/drm_of.h #include drm/i2c/tda998x.h -#include sound/tda998x.h #define DBG(fmt, ...) DRM_DEBUG(fmt\n, ##__VA_ARGS__) +struct tda998x_audio { + u8 ports[2];/* AP value */ + u8 port_types[2]; /* AFMT_xxx */ +}; + struct tda998x_priv { struct i2c_client *cec; struct i2c_client *hdmi; @@ -1240,9 +1244,10 @@ static int tda998x_parse_ports(struct tda998x_priv *priv, { struct device_node *of_port; const char *port_type; - int ret, audio_index, reg, afmt; + int ret, audio_index, reg, afmt, rgb_initialized; audio_index = 0; + rgb_initialized = 0; for_each_child_of_node(np, of_port) { if (!of_port-name || of_node_cmp(of_port-name, port) != 0) @@ -1252,11 +1257,17 @@ static int tda998x_parse_ports(struct tda998x_priv *priv, if (ret 0) continue; ret = of_property_read_u32(of_port, reg, reg); + if (ret 0) { + dev_err(priv-hdmi-dev, missing reg for %s\n, + port_type); + return ret; + } if (strcmp(port_type, rgb) == 0) { if (!ret) { /* video reg is optional */ priv-vip_cntrl_0 = reg 16; priv-vip_cntrl_1 = reg 8; priv-vip_cntrl_2 = reg; + rgb_initialized = 1; } continue; } @@ -1266,11 +1277,6 @@ static int tda998x_parse_ports(struct tda998x_priv *priv, afmt = AFMT_SPDIF; else continue; - if (ret 0) { - dev_err(priv-hdmi-dev, missing reg for %s\n, - port_type); - return ret; - } if (audio_index = ARRAY_SIZE(priv-audio.ports)) { dev_err(priv-hdmi-dev, too many audio ports\n); break; @@ -1279,13 +1285,13 @@ static int tda998x_parse_ports(struct tda998x_priv *priv, priv-audio.port_types[audio_index] = afmt; audio_index++; } - return 0; + return rgb_initialized; } static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) { struct device_node *np = client-dev.of_node; - struct device_node *of_port; + struct device_node *ports; u32 video; int rev_lo, rev_hi, ret; unsigned short cec_addr; @@ -1392,24 +1398,15 @@ static int tda998x_create(struct i2c_client *client, struct tda998x_priv *priv) /* get the device tree parameters */ if (np) { - of_port = of_get_child_by_name(np, port); - if (of_port) { /* graph of ports */ - of_node_put(of_port); - ret = tda998x_parse_ports(priv, np); - if (ret 0) - goto fail; - - /* initialize the default audio configuration */ - if (priv-audio.ports[0]) { - priv-params.audio_cfg = priv-audio.ports[0]; - priv-params.audio_format = - priv-audio.port_types[0]; - priv-params.audio_clk_cfg = - priv-params.audio_format == - AFMT_SPDIF ? 0 : 1; - } - } else { - + ports = of_get_child_by_name(np, ports); + if (!ports) + ports = of_node_get(np); + /* graph of ports */ + ret = tda998x_parse_ports(priv, ports); + of_node_put(ports); + if (ret 0) + goto fail; + if (ret == 0) { /* optional video properties
[PATCH RFC v3 2/7] ASoC: hdmi: Remove obsolete dummy HDMI codec
The hdmi stub codec has not been used since refactoring of OMAP HDMI audio support. Signed-off-by: Jyri Sarha jsa...@ti.com --- sound/soc/codecs/Kconfig | 4 -- sound/soc/codecs/Makefile | 2 - sound/soc/codecs/hdmi.c | 109 -- 3 files changed, 115 deletions(-) delete mode 100644 sound/soc/codecs/hdmi.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index efaafce..fc8e729 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -76,7 +76,6 @@ config SND_SOC_ALL_CODECS select SND_SOC_MAX9877 if I2C select SND_SOC_MC13783 if MFD_MC13XXX select SND_SOC_ML26124 if I2C - select SND_SOC_HDMI_CODEC select SND_SOC_PCM1681 if I2C select SND_SOC_PCM1792A if SPI_MASTER select SND_SOC_PCM3008 @@ -432,9 +431,6 @@ config SND_SOC_BT_SCO config SND_SOC_DMIC tristate -config SND_SOC_HDMI_CODEC - tristate HDMI stub CODEC - config SND_SOC_ES8328 tristate Everest Semi ES8328 CODEC diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index cf160d9..01b4601 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -69,7 +69,6 @@ snd-soc-max98925-objs := max98925.o snd-soc-max9850-objs := max9850.o snd-soc-mc13783-objs := mc13783.o snd-soc-ml26124-objs := ml26124.o -snd-soc-hdmi-codec-objs := hdmi.o snd-soc-pcm1681-objs := pcm1681.o snd-soc-pcm1792a-codec-objs := pcm1792a.o snd-soc-pcm3008-objs := pcm3008.o @@ -256,7 +255,6 @@ obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o -obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o obj-$(CONFIG_SND_SOC_PCM1792A) += snd-soc-pcm1792a-codec.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c deleted file mode 100644 index bd42ad3..000 --- a/sound/soc/codecs/hdmi.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * ALSA SoC codec driver for HDMI audio codecs. - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ - * Author: Ricardo Neri ricardo.n...@ti.com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ -#include linux/module.h -#include sound/soc.h -#include linux/of.h -#include linux/of_device.h - -#define DRV_NAME hdmi-audio-codec - -static const struct snd_soc_dapm_widget hdmi_widgets[] = { - SND_SOC_DAPM_INPUT(RX), - SND_SOC_DAPM_OUTPUT(TX), -}; - -static const struct snd_soc_dapm_route hdmi_routes[] = { - { Capture, NULL, RX }, - { TX, NULL, Playback }, -}; - -static struct snd_soc_dai_driver hdmi_codec_dai = { - .name = hdmi-hifi, - .playback = { - .stream_name = Playback, - .channels_min = 2, - .channels_max = 8, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, - .sig_bits = 24, - }, - .capture = { - .stream_name = Capture, - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | - SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, - }, - -}; - -#ifdef CONFIG_OF -static const struct of_device_id hdmi_audio_codec_ids[] = { - { .compatible = linux,hdmi-audio, }, - { } -}; -MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids); -#endif - -static struct snd_soc_codec_driver hdmi_codec = { - .dapm_widgets = hdmi_widgets, - .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), - .dapm_routes = hdmi_routes, - .num_dapm_routes = ARRAY_SIZE(hdmi_routes), - .ignore_pmdown_time
[RFT PATCH] arm: omap1_defconfig: convert to use libata PATA drivers
IDE subsystem has been deprecated since 2009 and the majority (if not all) of Linux distributions have switched to use libata for ATA support exclusively. However there are still some users (mostly old or/and embedded non-x86 systems) that have not converted from using IDE subsystem to libata PATA drivers. This doesn't seem to be good thing in the long-term for Linux as while there is less and less PATA systems left in use: * testing efforts are divided between two subsystems * having duplicate drivers for same hardware confuses users This patch converts omap1_defconfig to use libata PATA drivers. Cc: Tony Lindgren t...@atomide.com Cc: linux-omap@vger.kernel.org Signed-off-by: Bartlomiej Zolnierkiewicz b.zolnier...@samsung.com --- Build tested only. If you have affected hardware please test. Thank you. arch/arm/configs/omap1_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index 0c8a787..6ffc984 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig @@ -96,14 +96,14 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_IDE=m -CONFIG_BLK_DEV_IDECS=m CONFIG_SCSI=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y CONFIG_CHR_DEV_SG=y +CONFIG_ATA=m +CONFIG_PATA_PCMCIA=m CONFIG_NETDEVICES=y CONFIG_TUN=y CONFIG_PHYLIB=y -- 1.9.1 -- 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: Nokia N900 - audio TPA6130A2 problems
Hi! Maybe some power management problem? Something is not always initialized correctly? I remember that there is some problem (maybe in NoLo - Nokia bootloader) that sometimes chainloaded U-Boot (booted via NoLo) is not able to initialize mmc chip (all read operation fails). In U-Boot I added some code to enable some parts in twl4030 regulator and after that mmc is working always... Could I get some details? Thay code should be moved to kernel, I'd really like mmc to work, no matter how machine was booted. Best regards, Pavel -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html -- 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: Nokia N900 - audio TPA6130A2 problems
On Friday 14 August 2015 22:46:49 Pavel Machek wrote: Hi! Maybe some power management problem? Something is not always initialized correctly? I remember that there is some problem (maybe in NoLo - Nokia bootloader) that sometimes chainloaded U-Boot (booted via NoLo) is not able to initialize mmc chip (all read operation fails). In U-Boot I added some code to enable some parts in twl4030 regulator and after that mmc is working always... Could I get some details? Thay code should be moved to kernel, I'd really like mmc to work, no matter how machine was booted. Best regards, Pavel I think I was inspirited by kernel code when I added that functionality into u-boot... But I do not remember which kernel version... If you are interested and what to play with that, just look at few lines of twl4030 code in uboot rx51.c (until restore I2C access state): http://git.denx.de/?p=u-boot.git;a=blob;f=board/nokia/rx51/rx51.c;h=3d019b01428b5392fb5d0b8c7428a6d1d2ba31af;hb=HEAD#l388 All are just i2c calls to twl4030 chipset. -- Pali Rohár pali.ro...@gmail.com signature.asc Description: This is a digitally signed message part.
Re: [PATCH RFC v2 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders
On Tue, May 26, 2015 at 09:59:07PM +0300, Jyri Sarha wrote: + + mutex_lock(hcp-current_stream_lock); + if (hcp-current_stream hcp-current_stream-runtime + snd_pcm_running(hcp-current_stream)) { + dev_info(dev, HDMI audio playback aborted\n); Does this really need to be dev_info()? + if (hcp-hcd.ops-get_eld) { + hcp-eld = hcp-hcd.ops-get_eld(hcp-hcd.dev); + + /* Call snd_pcm_hw_constraint_eld here */ + } ... + dev_dbg(dai-dev, %s()\n, __func__); + + mutex_lock(hcp-current_stream_lock); + BUG_ON(hcp-current_stream != substream); + hcp-current_stream = NULL; + mutex_unlock(hcp-current_stream_lock); + + hcp-hcd.ops-audio_shutdown(hcp-hcd.dev); Shouldn't the callback be in or before the lock? Otherwise we could potentially race with starting a new stream. signature.asc Description: Digital signature
Re: [PATCH RFC v3 2/7] ASoC: hdmi: Remove obsolete dummy HDMI codec
On Fri, Aug 14, 2015 at 12:30:40PM +0300, Jyri Sarha wrote: The hdmi stub codec has not been used since refactoring of OMAP HDMI audio support. grep tells me that the OMAP HDMI4 and HDMI5 drivers are still registering this device in -next... signature.asc Description: Digital signature
Re: [PATCH RFC v3 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders
On Fri, Aug 14, 2015 at 12:30:41PM +0300, Jyri Sarha wrote: +struct hdmi_codec_ops { + /* For runtime clock configuration from ASoC machine driver. + * A direct forward from set_sysclk in struct snd_soc_dai_ops. + * Optional */ + int (*set_clk)(struct device *dev, int clk_id, int freq); I'd be much happier if we were using the clock API as the external interface here, it's where we want to be internally too and it's going to be easier to not introduce any external dependencies on the ASoC internal stuff. + /* Called when ASoC starts an audio stream setup. The call + * provides an audio abort callback for stoping an ongoing + * stream if the HDMI audio becomes unavailable. + * Optional */ + int (*audio_startup)(struct device *dev, + void (*abort_cb)(struct device *dev)); I'm a bit confused about what is going to use abort_cb() and why they wouldn't just call shutdown instead? +/* HDMI codec initalization data */ +struct hdmi_codec_pdata { + struct device *dev; /* The HDMI encoder registering the codec */ Shouldn't this just be dev-parent? +enum { + DAI_ID_I2C = 0, + DAI_ID_SPDIF, +}; I2C? :P signature.asc Description: Digital signature
Re: [PATCH 1/2] regulator: pbias: use untranslated address to program pbias regulator
On Mon, Jul 27, 2015 at 04:54:09PM +0530, Kishon Vijay Abraham I wrote: vsel_reg and enable_reg of the pbias regulator descriptor should actually have the offset from syscon. However after the pbias device tree node I'm having a hard time understanding this statement, sorry. What makes you say that they shouild actually have the offset from syscon? What is the problem that this is supposed to fix? is moved as a child node of syscon, vsel_reg and enable_reg has the absolute address because of the address translation that happens while creating device from device tree node. So avoid using platform_get_resource and use of_get_address in order to get only the offset (untranslated address) and populate these in vsel_reg and enable_reg. This sounds like we're going in the wrong direction, we're moving from a more generic API to a firmware specific one. Why is this a good fix? signature.asc Description: Digital signature
[PATCH v2] tty: serial: 8250_omap: do not use RX DMA if pause is not supported
The 8250-omap driver requires the DMA-engine driver to support the pause command in order to properly turn off programmed RX transfer before the driver stars manually reading from the FIFO. The lacking support of the requirement has been discovered recently. In order to stay safe here we disable RX-DMA completly on probe. The rx_dma_broken assignment on probe could be removed once we working pause function in omap-dma. Cc: sta...@vger.kernel.org Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de --- v1…v2: - disable RX-DMA right on boot drivers/tty/serial/8250/8250_omap.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index d9a37191a1ae..2ac63c8bd946 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -112,6 +112,7 @@ struct omap8250_priv { struct work_struct qos_work; struct uart_8250_dma omap8250_dma; spinlock_t rx_dma_lock; + bool rx_dma_broken; }; static u32 uart_read(struct uart_8250_port *up, u32 reg) @@ -773,6 +774,7 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p) struct omap8250_priv*priv = p-port.private_data; struct uart_8250_dma*dma = p-dma; unsigned long flags; + int ret; spin_lock_irqsave(priv-rx_dma_lock, flags); @@ -781,7 +783,9 @@ static void omap_8250_rx_dma_flush(struct uart_8250_port *p) return; } - dmaengine_pause(dma-rxchan); + ret = dmaengine_pause(dma-rxchan); + if (WARN_ON_ONCE(ret)) + priv-rx_dma_broken = true; spin_unlock_irqrestore(priv-rx_dma_lock, flags); @@ -825,6 +829,9 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) break; } + if (priv-rx_dma_broken) + return -EINVAL; + spin_lock_irqsave(priv-rx_dma_lock, flags); if (dma-rx_running) @@ -1219,6 +1226,11 @@ static int omap8250_probe(struct platform_device *pdev) if (of_machine_is_compatible(ti,am33xx)) priv-habit |= OMAP_DMA_TX_KICK; + /* +* pause is currently not supported atleast on omap-sdma +* and edma on most earlier kernels. +*/ + priv-rx_dma_broken = true; } } #endif -- 2.5.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 2/3] serial: 8250_omap: check how many bytes were injected
The function tty_insert_flip_string() returns an int and as such it might fail. So the result is that I kindly asked to insert 48 bytes and the function only insterted 32. I have no idea what to do with the remaining 16 so I think dropping them is the only option. I also increase the buf_overrun counter so userpace has a clue that we lost bytes. Cc: Greg Kroah-Hartman gre...@linuxfoundation.org Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de --- drivers/tty/serial/8250/8250_omap.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 2ac63c8bd946..933f7ef2c004 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -738,6 +738,7 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) struct dma_tx_state state; int count; unsigned long flags; + int ret; dma_sync_single_for_cpu(dma-rxchan-device-dev, dma-rx_addr, dma-rx_size, DMA_FROM_DEVICE); @@ -753,8 +754,10 @@ static void __dma_rx_do_complete(struct uart_8250_port *p, bool error) count = dma-rx_size - state.residue; - tty_insert_flip_string(tty_port, dma-rx_buf, count); - p-port.icount.rx += count; + ret = tty_insert_flip_string(tty_port, dma-rx_buf, count); + + p-port.icount.rx += ret; + p-port.icount.buf_overrun += count - ret; unlock: spin_unlock_irqrestore(priv-rx_dma_lock, flags); -- 2.5.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 1/3] serial: 8250: move rx_running out of the bitfield
From: John Ogness john.ogn...@linutronix.de That bitfield is modified by read + or + write operation. If someone sets any of the other two bits it might render the lock useless. While at it, remove other bitfields as well to avoid more such errors. Cc: Greg Kroah-Hartman gre...@linuxfoundation.org Signed-off-by: John Ogness john.ogn...@linutronix.de Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de --- drivers/tty/serial/8250/8250.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index c43f74c53cd9..a407757dcecc 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -42,9 +42,9 @@ struct uart_8250_dma { size_t rx_size; size_t tx_size; - unsigned char tx_running:1; - unsigned char tx_err: 1; - unsigned char rx_running:1; + unsigned char tx_running; + unsigned char tx_err; + unsigned char rx_running; }; struct old_serial_port { -- 2.5.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
[RFC 3/3] serial: 8250_omap: try to avoid IER_RDI with DMA
It has been observed on DRA7-evm that the UART triggers the interrupt and reading IIR says IIR_NO_INT. It seems that we receive data via RX-DMA but the interrupt is triggered anyway. I have hardly observed it on AM335x and not in *that* quantity. On DRA7-evm with continuous transfers at 3MBaud and CPU running at 1.5Ghz it is possible that the IRQ-core will close the UART interrupt after some time with nobody cared. I've seen that by not enabling IER_RDI those spurious interrupts are not triggered. Also it seems that DMA and RDI cause the timeout interrupt which does not allow RX-DMA to be scheduled even if the FIFO reached the programmed RX threshold. However without RDI we don't get a notification if we have less than RX threshold bytes in the FIFO. This is where we have the rx_dma_wd timer. After programming the RX-DMA transfer wait HZ / 4 or 250ms for it to complete. If it does not complete in that time span we cancel the DMA transfer and enable RDI. RDI will trigger an UART interrupt in case we have bytes in the FIFO. Once we read bytes manually from the FIFO we enable RX-DMA again (without RDI) with the same 250ms timeout. One downside with this approach is that latency sensitive protocols that transfer less than 48 bytes will have to wait 250ms to complete. Is there maybe a user interface where one could set small or bulk transfers? Signed-off-by: Sebastian Andrzej Siewior bige...@linutronix.de --- drivers/tty/serial/8250/8250_omap.c | 33 - 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 383f143b6b36..68d03553617b 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -113,6 +113,7 @@ struct omap8250_priv { struct uart_8250_dma omap8250_dma; spinlock_t rx_dma_lock; bool rx_dma_broken; + struct timer_list rx_dma_wd; }; static u32 uart_read(struct uart_8250_port *up, u32 reg) @@ -599,6 +600,7 @@ static irqreturn_t omap8250_irq(int irq, void *dev_id) return IRQ_RETVAL(ret); } +static void omap8250_rx_dma_wd(unsigned long data); static int omap_8250_startup(struct uart_port *port) { struct uart_8250_port *up = up_to_u8250p(port); @@ -627,6 +629,10 @@ static int omap_8250_startup(struct uart_port *port) dev_warn_ratelimited(port-dev, failed to request DMA\n); up-dma = NULL; + } else { + init_timer(priv-rx_dma_wd); + priv-rx_dma_wd.function = omap8250_rx_dma_wd; + priv-rx_dma_wd.data = (unsigned long) up; } } @@ -635,7 +641,9 @@ static int omap_8250_startup(struct uart_port *port) if (ret 0) goto err; - up-ier = UART_IER_RLSI | UART_IER_RDI; + up-ier = UART_IER_RLSI; + if (!up-dma-rxchan) + up-ier |= UART_IER_RDI; serial_out(up, UART_IER, up-ier); #ifdef CONFIG_PM @@ -670,6 +678,8 @@ static void omap_8250_shutdown(struct uart_port *port) if (up-dma) up-dma-rx_dma(up, UART_IIR_RX_TIMEOUT); + del_timer_sync(priv-rx_dma_wd); + pm_runtime_get_sync(port-dev); serial_out(up, UART_OMAP_WER, 0); @@ -846,6 +856,9 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) if (dma-rx_running) goto out; + if (p-ier UART_IER_RDI) + goto out; + desc = dmaengine_prep_slave_single(dma-rxchan, dma-rx_addr, dma-rx_size, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); @@ -864,6 +877,7 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir) dma-rx_size, DMA_FROM_DEVICE); dma_async_issue_pending(dma-rxchan); + mod_timer(priv-rx_dma_wd, jiffies + HZ / 4); out: spin_unlock_irqrestore(priv-rx_dma_lock, flags); return err; @@ -1044,6 +1058,9 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) dma_err = omap_8250_rx_dma(up, iir); if (dma_err) { status = serial8250_rx_chars(up, status); + + up-ier = ~UART_IER_RDI; + serial_port_out(port, UART_IER, up-ier); omap_8250_rx_dma(up, 0); } } @@ -1069,6 +1086,20 @@ static int omap_8250_dma_handle_irq(struct uart_port *port) return 1; } +static void omap8250_rx_dma_wd(unsigned long data) +{ + struct uart_8250_port *up = (void *) data; + struct uart_port*port = up-port; + unsigned long flags; + + spin_lock_irqsave(port-lock, flags); + + omap_8250_rx_dma_flush(up); + up-ier |= UART_IER_RDI; +
Re: [PATCH v2 2/6] genirq: fix irqchip_set_wake_parent if IRQCHIP_SKIP_SET_WAKE
On 14/08/15 11:18, Grygorii Strashko wrote: On 08/13/2015 03:58 PM, Grygorii Strashko wrote: On 08/13/2015 01:31 PM, Grygorii Strashko wrote: On 08/13/2015 01:01 PM, Marc Zyngier wrote: On 12/08/15 18:45, Grygorii Strashko wrote: The irqchip_set_wake_parent should not fail if IRQ chip specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup configuration can't be propagated properly through IRQ domains hierarchy. In case of TI OMAP DRA7 the issue reproduced with following configuration: ARM GIC-OMAP wakeupgen-TI CBAR-GPIO-GPIO pcf857x-gpio_key gpio_key is wakeup source Failure is reproduced during suspend/resume to RAM: suspend: - gpio_keys_suspend enable_irq_wake + pcf857x_irq_set_wake + omap_gpio_wake_enable + TI CBAR irq_chip_set_wake_parent + OMAP wakeupgen has no .irq_set_wake() Most importantly, wakeupgen has IRQCHIP_SKIP_SET_WAKE set. and -ENOSYS will be returned resume: - gpio_keys_resume + disable_irq_wake + irq_set_irq_wake + WARN(1, Unbalanced IRQ %d wake disable\n, irq); Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent') Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com --- kernel/irq/chip.c | 4 1 file changed, 4 insertions(+) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 6de638b..bdb1b9d 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info) int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on) { data = data-parent_data; + +if (irq_data_get_irq_chip(data)-flags IRQCHIP_SKIP_SET_WAKE) +return 0; + if (data-chip-irq_set_wake) return data-chip-irq_set_wake(data, on); We have a more general issue with chip flags, and how they combine within a stack of irqchips. Indeed. Problem looks similar to IRQCHIP_MASK_ON_SUSPEND flag usage. What if you remove the irq_chip_set_wake_parent from the crossbar driver, and instead set IRQCHIP_SKIP_SET_WAKE? I've thought about this and it should work for me. One question - what if crossbar will be not the last one in IRQ domains hierarchy? I can confirm, if I revert this patch, add IRQCHIP_SKIP_SET_WAKE to the crossbar and remove irq_chip_set_wake_parent wakeups still works. What do you prefer me to do: add additional patch for the crossbar, drop/keep this patch? OK. There are two possibilities to fix set_wake functionality for TI OMAPs where below HW configurations are used: OMAP4/5: GIC - OMAP wakeupgen DRA7: GIC - OMAP wakeupgen - TI CBAR 1) ensure that IRQCHIP_SKIP_SET_WAKE flag is set only for GIC and use irq_chip_set_wake_parent() in both wakeupgen and crossbar [this patch is required] 2) ensure that IRQCHIP_SKIP_SET_WAKE flag is set and drop .irq_set_wake()/irq_chip_set_wake_parent() for all IRQ chips in IRQ domains hierarchy. [this patch can be dropped] I'm going to select approach 2 and re-send. Yeah, I'd like to go for the minimal approach for now, and work out what exactly are the propagation semantics (I had something at some point, need to find what I did with those patches...). 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
Re: [PATCH 2/2] rtc: omap: Add external clock enabling support
On Thu, Aug 13, 2015 at 12:37:48PM +0530, Keerthy wrote: Configure the clock source to either internal clock or external clock based on the availability of the clocks. External clock is preferred as it can be ticking during suspend. Signed-off-by: Keerthy j-keer...@ti.com @@ -627,6 +642,17 @@ static int omap_rtc_probe(struct platform_device *pdev) if (reg != new_ctrl) rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); + /* + * If we have the external clock then + * Switch to external clock so we can keep ticking + * acorss suspend + */ You should fix up the comment (e.g. stray capitalisation and typo) as well. Perhaps reword as /* * If we have an external clock then switch to it so we can keep * ticking across suspend. */ Johan -- 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 2/6] genirq: introduce irq_chip_set_type_parent() helper
It's expected to use this helper when the current domain doesn't implement .irq_set_type(), but expect the parent to do so. Cc: Sudeep Holla sudeep.ho...@arm.com Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com --- include/linux/irq.h | 1 + kernel/irq/chip.c | 17 + 2 files changed, 18 insertions(+) diff --git a/include/linux/irq.h b/include/linux/irq.h index 92188b0..51744bc 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -484,6 +484,7 @@ extern int irq_chip_set_affinity_parent(struct irq_data *data, extern int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on); extern int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info); +extern int irq_chip_set_type_parent(struct irq_data *data, unsigned int type); #endif /* Handling of unhandled and spurious interrupts: */ diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 6de638b..ae21682 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -985,6 +985,23 @@ int irq_chip_set_affinity_parent(struct irq_data *data, } /** + * irq_chip_set_type_parent - Set IRQ type on the parent interrupt + * @data: Pointer to interrupt specific data + * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h + * + * Conditional, as the underlying parent chip might not implement it. + */ +int irq_chip_set_type_parent(struct irq_data *data, unsigned int type) +{ + data = data-parent_data; + + if (data-chip-irq_set_type) + return data-chip-irq_set_type(data, type); + + return -ENOSYS; +} + +/** * irq_chip_retrigger_hierarchy - Retrigger an interrupt in hardware * @data: Pointer to interrupt specific data * -- 2.5.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 v3 3/6] irqchip: crossbar: fix arm gic irq type configuration
It's observed that ARM GIC IRQ triggering type is not configured properly when IRQ is routed through IRQ domain hierarchy and system started using DT. As result, system will start using default ARM GIC configuration, ignore DT IRQ triggering configuration, and value of desc-irq_data.state_use_accessors = 0. In case of TI OMAP DRA7 the following IRQ hierarchy is defined: ARM GIC - OMAP wakeupgen - TI CBAR Failed call chain: irq_create_of_mapping irq_set_irq_type __irq_set_trigger if (!chip || !chip-irq_set_type) { return 0; - return here } Crossbar has no .irq_set_type() defined and, so, IRQ triggering configuration will not be propagated to parent IRQ domain. Hence, fix it by using irq_chip_set_type_parent() for propagation IRQ triggering type to parent IRQ domains. Cc: Sudeep Holla sudeep.ho...@arm.com Fixes: 783d31863fb8 ('irqchip: crossbar: Convert dra7 crossbar...') Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com --- drivers/irqchip/irq-crossbar.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 692fe2b..3ba58e7 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -69,6 +69,7 @@ static struct irq_chip crossbar_chip = { .irq_unmask = irq_chip_unmask_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_wake = irq_chip_set_wake_parent, + .irq_set_type = irq_chip_set_type_parent, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, #endif -- 2.5.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 v3 0/6] genirq: irqdomain_hierarchy: fixes
Hi All, I've had able to identify and reproduce four issues related to switching on using IRQ domain hierarchy on TI OMAP DRA7 (dra7-evm). Most of them were discovered during testing of Suspend to RAM and IRQ wakeup functionality. In my opinion, most of these issue could also affect on other ARM SoC if they are using IRQ domain hierarchy. In case of TI OMAP DRA7 the following IRQ hierarchy is defined: ARM GIC - OMAP wakeupgen - TI CBAR Issue 1 - patch 1: IRQ re-triggering is not working if IRQ domain hierarchy used in combination with ARM GIC and irq_chip_retrigger_hierarchy() is used by child IRQ domain. Issue 2 - patches 2-4: ARM GIC IRQ triggering type is not configured properly when IRQ is routed through IRQ domain hierarchy and system started using DT. As result, system will start using default ARM GIC configuration, ignore DT IRQ triggering configuration, and value of desc-irq_data.state_use_accessors = 0. / # cat /proc/interrupts -- before 230: 0 0 CBAR 30 Edge- 48051000.gpio 263: 0 0 CBAR 116 Edge- 48053000.gpio 296:246 0 CBAR 67 Edge- OMAP UART0 311:341 0 CBAR 51 Edge- 4807.i2c 312: 3 0 CBAR 52 Edge- 48072000.i2c 313: 0 0 CBAR 56 Edge- 4806.i2c 314:255 0 CBAR 78 Edge- mmc0 315: 40 0 CBAR 81 Edge- mmc1 316: 13 0 CBAR 91 Edge- mmc2 320: 0 0 CBAR 49 Edge- 4a14.sata 324: 0 0 CBAR 1 Edge- 48078000.elm 325: 0 0 CBAR 15 Edge- gpmc 333: 0 0 CBAR 335 Edge- 48484000.ethernet 334: 0 0 CBAR 336 Edge- 48484000.ethernet 415: 0 0 pcf857x 2 Edge- btnUser1 416: 0 0 pcf857x 3 Edge- btnUser2 445: 0 0 pinctrl 992 Edge-0001 4806a000.seria / # cat /proc/interrupts -- after 230: 0 0 CBAR 30 Level -2004 48051000.gpio 263: 0 0 CBAR 116 Level -2004 48053000.gpio 296:567 0 CBAR 67 Level -2004 OMAP UART0 311:363 0 CBAR 51 Level -2004 4807.i2c 312: 3 0 CBAR 52 Level -2004 48072000.i2c 313: 0 0 CBAR 56 Level -2004 4806.i2c 314:197 0 CBAR 78 Level -2004 mmc0 315: 40 0 CBAR 81 Level -2004 mmc1 316: 13 0 CBAR 91 Level -2004 mmc2 320: 0 0 CBAR 49 Level -2004 4a14.sata 324: 0 0 CBAR 1 Level -2004 48078000.elm 325: 0 0 CBAR 15 Level -2004 gpmc 333: 0 0 CBAR 335 Level -2004 48484000.ethernet 334: 0 0 CBAR 336 Level -2004 48484000.ethernet 415: 0 0 pcf857x 2 Edge- btnUser1 416: 4 2 pcf857x 3 Edge- btnUser2 445: 0 0 pinctrl 992 Edge-0001 4806a000.serial - are current values of desc-irq_data.state_use_accessors Issue 3 - patch 5: ARM GIC IRQs are not masked during suspend even if they are not wakeup source. This issue related to IRQCHIP MASK ON SUSPEND flag usage and, honestly, it's not clear how this flag has to be processed in case of IRQ domain hierarchy - previously there was one IRQ chip per IRQ desc and if it has IRQCHIP MASK ON SUSPEND flag set we had to mask IRQ. But now there are up to three (DRA7) IRQ chip per IRQ desc, and all of them could have different IRQCHIP MASK ON SUSPEND flag's configuration. Here, to fix an issue, I've just added IRQCHIP MASK ON SUSPEND flag to TI Crossbar which is the last IRQ domain in hierarchy. Issue 4 - patch 6: On TI dra7-evm, when irq_set_irq_type() is called for IRQ which belongs to IRQ domain hierarchy the .irq_set_wake() callback will be executed for TI Crossbar IRQ chip. The TI Crossbar doesn't provides any facility to configure the wakeup sources, but it implements .irq_set_wake() callback as: .irq_set_wake = irq_chip_set_wake_parent As result, the irq_chip_set_wake_parent() will try to execute .irq_set_wake() callback for parent IRQ domain, which is TI OMAP wakeupgen, but TI OMAP wakeupgen has IRQCHIP_SKIP_SET_WAKE flag set and do not implement .irq_set_wake() callback. Thus, irq_chip_set_wake_parent() will fail with -ENOSYS, but it shouldn't. IRQ domain hierarchy code was merged in 4.1, so it seems these patches are material for stable 4.1+. Tested on: TI OMAP DRA7, dra7-evm Series based on:
Re: [PATCH] gpiolib: irqchip: use different lockdep class for each gpio irqchip
On Thu, Aug 13, 2015 at 4:58 PM, Grygorii Strashko grygorii.stras...@ti.com wrote: Since IRQ chip helpers were introduced drivers lose ability to register separate lockdep classes for each registered GPIO IRQ chip and the gpiolib now is using shared lockdep class for all GPIO IRQ chips (gpiochip_irq_lock_class). As result, lockdep will produce warning when there are min two stacked GPIO chips and all of them are interrupt controllers. HW configuration which generates lockdep warning (TI dra7-evm): (...) Cc: Geert Uytterhoeven ge...@linux-m68k.org Cc: Roger Quadros rog...@ti.com Reported-by: Roger Quadros rog...@ti.com Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com Ah, I see... * implies that if the chip supports IRQs, these IRQs need to be threaded * as the chip access may sleep when e.g. reading out the IRQ status * registers. + * @exported: flags if the gpiochip is exported for use from sysfs. Private. * @irq_not_threaded: flag must be set if @can_sleep is set but the * IRQs don't need to be threaded * @@ -126,6 +128,7 @@ struct gpio_chip { irq_flow_handler_t irq_handler; unsigned intirq_default_type; int irq_parent; + struct lock_class_key *lock_key; There is something weird with the kerneldoc. It is documenting something else but not documenting the new member. Anyway, so here: +int _gpiochip_irqchip_add(struct gpio_chip *gpiochip, + struct irq_chip *irqchip, + unsigned int first_irq, + irq_flow_handler_t handler, + unsigned int type, + struct lock_class_key *lock_key); + +#ifdef CONFIG_LOCKDEP +#define gpiochip_irqchip_add(...) \ +( \ + ({ \ + static struct lock_class_key _key; \ + _gpiochip_irqchip_add(__VA_ARGS__, _key); \ + }) \ +) +#else +#define gpiochip_irqchip_add(...) \ + _gpiochip_irqchip_add(__VA_ARGS__, NULL) +#endif Every chip will get their own lock class on the heap. But I think it is a bit kludgy. Is it not possible to have the lock key in struct gpio_chip be a real member instead of a pointer and get a per-chip lock that way? (...) struct lock_class_key lock_key; instead of: struct lock_class_key *lock_key; - problem solved, without kludgy header defines? 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
Re: [PATCH] gpiolib: irqchip: use different lockdep class for each gpio irqchip
On 08/14/2015 02:34 PM, Linus Walleij wrote: [...] Every chip will get their own lock class on the heap. But I think it is a bit kludgy. Is it not possible to have the lock key in struct gpio_chip be a real member instead of a pointer and get a per-chip lock that way? (...) struct lock_class_key lock_key; instead of: struct lock_class_key *lock_key; - problem solved, without kludgy header defines? Lock keys need to be in persistent memory since they have a unlimited life time. Once registered it is expected to exist until the system is reset. We recently fixed the same issue of nested locks in regmap. For reference the discussion with had a look at different ways to solve this can be found here[1] and the final patch series that went in here[2]. - Lars [1] https://lkml.org/lkml/2015/6/25/144 [2] https://lkml.org/lkml/2015/7/8/43 -- 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 4/6] ARM: OMAP: wakeupgen: fix arm gic irq type configuration
It's observed that ARM GIC IRQ triggering type is not configured properly when IRQ is routed through IRQ domain hierarchy and system started using DT. As result, system will start using default ARM GIC configuration, ignore DT IRQ triggering configuration, and value of desc-irq_data.state_use_accessors = 0. In case of TI OMAP DRA7 the following IRQ hierarchy is defined: ARM GIC - OMAP wakeupgen - TI CBAR Failed call chain: irq_create_of_mapping irq_set_irq_type __irq_set_trigger if (!chip || !chip-irq_set_type) { return 0; - return here } OMAP wakeupgen has no .irq_set_type() defined and, so, IRQ triggering configuration will not be propagated to parent IRQ domain. Hence, fix it by using irq_chip_set_type_parent() for propagation IRQ triggering type to parent IRQ domains. Cc: Sudeep Holla sudeep.ho...@arm.com Fixes: 7136d457f365 ('ARM: omap: convert wakeupgen to stacked domains') Acked-by: Tony Lindgren t...@atomide.com Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com --- arch/arm/mach-omap2/omap-wakeupgen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 8e52621..e1d2e99 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -392,6 +392,7 @@ static struct irq_chip wakeupgen_chip = { .irq_mask = wakeupgen_mask, .irq_unmask = wakeupgen_unmask, .irq_retrigger = irq_chip_retrigger_hierarchy, + .irq_set_type = irq_chip_set_type_parent, .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, -- 2.5.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 v3 1/6] genirq: fix irq_chip_retrigger_hierarchy
Now irq_chip_retrigger_hierarchy() returns -ENOSYS if it was not able to find at least one .irq_retrigger() callback implemented in IRQ domain hierarchy. As result, IRQ re-triggering is not working now on ARM (TI OMAP) where ARM GIC is not implemented this callback. The .irq_retrigger() is optional (see check_irq_resend()) and there are no reasons to fail if it was not found, hence lets return 0 in this case. In case of TI OMAP DRA7 the following IRQ hierarchy is defined: ARM GIC - OMAP wakeupgen - TI CBAR Failure is reproduced during resume from suspend to RAM: - wakeup by IRQx - suspend_enter + arch_suspend_enable_irqs + handle_fasteoi_irq + irq_may_run + irq_pm_check_wakeup + irq_disable(IRQx) + dpm_resume_noirq() + resume_device_irqs + resume_irqs + resume_irq + __enable_irq == IRQx is not re-triggered Cc: Sudeep Holla sudeep.ho...@arm.com Cc: Jiang Liu jiang@linux.intel.com Fixes: 85f08c17de26 ('genirq: Introduce helper functions...') Reviewed-by: Marc Zyngier marc.zyng...@arm.com Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com --- kernel/irq/chip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 27f4332..6de638b 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -997,7 +997,7 @@ int irq_chip_retrigger_hierarchy(struct irq_data *data) if (data-chip data-chip-irq_retrigger) return data-chip-irq_retrigger(data); - return -ENOSYS; + return 0; } /** -- 2.5.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 v3 6/6] irqchip: crossbar: fix set_wake functionality
The TI crossbar doesn't provides any facility to configure the wakeup sources, but it implements .irq_set_wake() callback: .irq_set_wake = irq_chip_set_wake_parent As result, the irq_chip_set_wake_parent() will try to execute .irq_set_wake() callback for parent IRQ domain, which is TI OMAP wakeupgen, but TI OMAP wakeupgen has IRQCHIP_SKIP_SET_WAKE flag set and do not implement .irq_set_wake() callback. Thus, irq_chip_set_wake_parent() will fail with -ENOSYS. In case of TI OMAP DRA7 the issue reproduced with following configuration: ARM GIC-OMAP wakeupgen-TI CBAR-GPIO-GPIO pcf857x-gpio_key gpio_key is wakeup source Failure is reproduced during suspend/resume to RAM: suspend: - gpio_keys_suspend + enable_irq_wake + pcf857x_irq_set_wake + omap_gpio_wake_enable + TI CBAR irq_chip_set_wake_parent + OMAP wakeupgen has no .irq_set_wake() and -ENOSYS will be returned resume: - gpio_keys_resume + disable_irq_wake + irq_set_irq_wake + WARN(1, Unbalanced IRQ %d wake disable\n, irq); Hence, fix it by adding IRQCHIP_SKIP_SET_WAKE flag to TI Crossbar and drop .irq_set_wake() at the same time. Cc: Sudeep Holla sudeep.ho...@arm.com Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com --- drivers/irqchip/irq-crossbar.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index f5a72cc..c12bb93 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -68,9 +68,9 @@ static struct irq_chip crossbar_chip = { .irq_mask = irq_chip_mask_parent, .irq_unmask = irq_chip_unmask_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, - .irq_set_wake = irq_chip_set_wake_parent, .irq_set_type = irq_chip_set_type_parent, - .flags = IRQCHIP_MASK_ON_SUSPEND, + .flags = IRQCHIP_MASK_ON_SUSPEND | + IRQCHIP_SKIP_SET_WAKE, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, #endif -- 2.5.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 v3 5/6] irqchip: crossbar: fix irq masking at suspend
All ARM GIC IRQs have to masked during suspend if they are not wakeup source - this is expected behavior.Now this is not happen, since switching to use IRQ domain hierarchy, because suspend_device_irq() only checks flags in the last IRQ chip in hierarchy for IRQCHIP_MASK_ON_SUSPEND bit set. And in the case of TI OMAP DRA7 the last IRQ chip is TI Crossbar which do not have this flag set. In case of TI OMAP DRA7 the following IRQ hierarchy is defined: ARM GIC - OMAP wakeupgen - TI CBAR ARM GIC - IRQCHIP_MASK_ON_SUSPEND=n OMAP wakeupgen - IRQCHIP_MASK_ON_SUSPEND=y TI CBAR - IRQCHIP_MASK_ON_SUSPEND=n Hence, fix by adding IRQCHIP_MASK_ON_SUSPEND for TI Crossbar IRQ chip. Cc: Sudeep Holla sudeep.ho...@arm.com Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com --- drivers/irqchip/irq-crossbar.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 3ba58e7..f5a72cc 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -70,6 +70,7 @@ static struct irq_chip crossbar_chip = { .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_wake = irq_chip_set_wake_parent, .irq_set_type = irq_chip_set_type_parent, + .flags = IRQCHIP_MASK_ON_SUSPEND, #ifdef CONFIG_SMP .irq_set_affinity = irq_chip_set_affinity_parent, #endif -- 2.5.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
[RFC 6/7] ARM: OMAP2+: PRCM: add support for registering prcm domains from DT
Power and clock domains can now be registered from DT based layout. Some data is retained in the kernel for initialization purposes. The platforms that require DT based domain support, shall have their DT and the clock/powerdomainxyz_data.c files updated. The template clock/powerdomain data should be stripped to minimal amount and use a clkdm_setup / pwrdm_setup struct that consumes less memory. This patch is just directly using the existing data for the template purposes. The domains are also now registered via the generic power domain framework, and can be used by other generic parts of the kernel also. Signed-off-by: Tero Kristo t-kri...@ti.com --- arch/arm/mach-omap2/Kconfig |1 + arch/arm/mach-omap2/Makefile |3 +- arch/arm/mach-omap2/clockdomain.h | 10 +- arch/arm/mach-omap2/pm-domains.c | 228 + arch/arm/mach-omap2/powerdomain.h |9 +- 5 files changed, 243 insertions(+), 8 deletions(-) create mode 100644 arch/arm/mach-omap2/pm-domains.c diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 6468f15..b4a0ce1 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -24,6 +24,7 @@ config ARCH_OMAP4 select ARCH_OMAP2PLUS select ARCH_NEEDS_CPU_IDLE_COUPLED if SMP select ARM_CPU_SUSPEND if PM + select PM_GENERIC_DOMAINS if PM select ARM_ERRATA_720789 select ARM_GIC select HAVE_ARM_SCU if SMP diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index d424920..1ac9fa7 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -140,7 +140,8 @@ obj-$(CONFIG_SOC_OMAP5)+= voltagedomains54xx_data.o obj-$(CONFIG_SOC_DRA7XX) += $(voltagedomain-common) # OMAP powerdomain framework -powerdomain-common += powerdomain.o powerdomain-common.o +powerdomain-common += powerdomain.o powerdomain-common.o \ + pm-domains.o obj-$(CONFIG_ARCH_OMAP2) += $(powerdomain-common) obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_data.o obj-$(CONFIG_ARCH_OMAP2) += powerdomains2xxx_3xxx_data.o diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 77bab5f..d316c4e 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -123,7 +123,7 @@ struct omap_hwmod; * definitions (OMAP4 only) */ struct clockdomain { - const char *name; + char *name; union { const char *name; struct powerdomain *ptr; @@ -132,9 +132,9 @@ struct clockdomain { const u8 flags; u8 _flags; const u8 dep_bit; - const u8 prcm_partition; - const u16 cm_inst; - const u16 clkdm_offs; + u8 prcm_partition; + u16 cm_inst; + u16 clkdm_offs; struct clkdm_dep *wkdep_srcs; struct clkdm_dep *sleepdep_srcs; int usecount; @@ -235,4 +235,6 @@ extern struct clkdm_dep gfx_24xx_wkdeps[]; extern struct clkdm_dep dsp_24xx_wkdeps[]; extern struct clockdomain wkup_common_clkdm; +int of_omap_clockdomain_init(const struct of_device_id *match); + #endif diff --git a/arch/arm/mach-omap2/pm-domains.c b/arch/arm/mach-omap2/pm-domains.c new file mode 100644 index 000..b373b21 --- /dev/null +++ b/arch/arm/mach-omap2/pm-domains.c @@ -0,0 +1,228 @@ +/* + * DT based powerdomain support for OMAP2+ SoCs + * + * Copyright (C) 2015 Texas Instruments, Inc. + * Tero Kristo t-kri...@ti.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/errno.h +#include linux/kernel.h +#include linux/bug.h +#include linux/of.h +#include linux/of_address.h +#include linux/pm_domain.h + +#include powerdomain.h +#include clockdomain.h +#include prcm-common.h + +#define OMAP_PD_TYPE_PWRDM 0x1 +#define OMAP_PD_TYPE_CLKDM 0x2 + +struct omap_pm_domain { + void *domain; + int type; + struct generic_pm_domain pd; +}; + +#define to_omap_pm_domain(genpd) container_of(genpd, struct omap_pm_domain, pd) + +static int _get_offset(struct device_node *node, u16 *val) +{ + u32 tmp; + + if (of_property_read_u32(node, reg, tmp)) { + pr_err(%s: %s does not provide reg addr!\n, __func__, + node-name); + return -EINVAL; + } + + *val = (u16)tmp; + + return 0; +} + +static int omap_genpd_power_off(struct generic_pm_domain *gen_pd) +{ + return 0; +} + +static int omap_genpd_power_on(struct generic_pm_domain *gen_pd) +{ + return 0; +} + +int __init of_omap_powerdomain_init(const struct of_device_id *match_table) +{ + struct device_node *np; + const struct of_device_id *match; +
[RFC 7/7] ARM: OMAP4: PRCM: convert to DT based pwrdm/clkdm data
Clock and powerdomain data can now be moved partially to DT. Some init data is still left to the existing data files, to act as templates for the DT based data. Signed-off-by: Tero Kristo t-kri...@ti.com --- arch/arm/mach-omap2/clockdomains44xx_data.c | 327 +++ arch/arm/mach-omap2/powerdomains44xx_data.c | 124 +++--- 2 files changed, 60 insertions(+), 391 deletions(-) diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index 95192a0..823f546 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -21,6 +21,7 @@ #include linux/kernel.h #include linux/io.h +#include linux/of.h #include clockdomain.h #include cm1_44xx.h @@ -31,413 +32,145 @@ #include prcm44xx.h #include prcm_mpu44xx.h -/* Static Dependencies for OMAP4 Clock Domains */ - -static struct clkdm_dep d2d_wkup_sleep_deps[] = { - { .clkdm_name = abe_clkdm }, - { .clkdm_name = ivahd_clkdm }, - { .clkdm_name = l3_1_clkdm }, - { .clkdm_name = l3_2_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { .clkdm_name = l3_init_clkdm }, - { .clkdm_name = l4_cfg_clkdm }, - { .clkdm_name = l4_per_clkdm }, - { NULL }, -}; - -static struct clkdm_dep ducati_wkup_sleep_deps[] = { - { .clkdm_name = abe_clkdm }, - { .clkdm_name = ivahd_clkdm }, - { .clkdm_name = l3_1_clkdm }, - { .clkdm_name = l3_2_clkdm }, - { .clkdm_name = l3_dss_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { .clkdm_name = l3_gfx_clkdm }, - { .clkdm_name = l3_init_clkdm }, - { .clkdm_name = l4_cfg_clkdm }, - { .clkdm_name = l4_per_clkdm }, - { .clkdm_name = l4_secure_clkdm }, - { .clkdm_name = l4_wkup_clkdm }, - { .clkdm_name = tesla_clkdm }, - { NULL }, -}; - -static struct clkdm_dep iss_wkup_sleep_deps[] = { - { .clkdm_name = ivahd_clkdm }, - { .clkdm_name = l3_1_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { NULL }, -}; - -static struct clkdm_dep ivahd_wkup_sleep_deps[] = { - { .clkdm_name = l3_1_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { NULL }, -}; - -static struct clkdm_dep l3_dma_wkup_sleep_deps[] = { - { .clkdm_name = abe_clkdm }, - { .clkdm_name = ducati_clkdm }, - { .clkdm_name = ivahd_clkdm }, - { .clkdm_name = l3_1_clkdm }, - { .clkdm_name = l3_dss_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { .clkdm_name = l3_init_clkdm }, - { .clkdm_name = l4_cfg_clkdm }, - { .clkdm_name = l4_per_clkdm }, - { .clkdm_name = l4_secure_clkdm }, - { .clkdm_name = l4_wkup_clkdm }, - { NULL }, -}; - -static struct clkdm_dep l3_dss_wkup_sleep_deps[] = { - { .clkdm_name = ivahd_clkdm }, - { .clkdm_name = l3_2_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { NULL }, -}; - -static struct clkdm_dep l3_gfx_wkup_sleep_deps[] = { - { .clkdm_name = ivahd_clkdm }, - { .clkdm_name = l3_1_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { NULL }, -}; - -static struct clkdm_dep l3_init_wkup_sleep_deps[] = { - { .clkdm_name = abe_clkdm }, - { .clkdm_name = ivahd_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { .clkdm_name = l4_cfg_clkdm }, - { .clkdm_name = l4_per_clkdm }, - { .clkdm_name = l4_secure_clkdm }, - { .clkdm_name = l4_wkup_clkdm }, - { NULL }, -}; - -static struct clkdm_dep l4_secure_wkup_sleep_deps[] = { - { .clkdm_name = l3_1_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { .clkdm_name = l4_per_clkdm }, - { NULL }, -}; - -static struct clkdm_dep mpu_wkup_sleep_deps[] = { - { .clkdm_name = abe_clkdm }, - { .clkdm_name = ducati_clkdm }, - { .clkdm_name = ivahd_clkdm }, - { .clkdm_name = l3_1_clkdm }, - { .clkdm_name = l3_2_clkdm }, - { .clkdm_name = l3_dss_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { .clkdm_name = l3_gfx_clkdm }, - { .clkdm_name = l3_init_clkdm }, - { .clkdm_name = l4_cfg_clkdm }, - { .clkdm_name = l4_per_clkdm }, - { .clkdm_name = l4_secure_clkdm }, - { .clkdm_name = l4_wkup_clkdm }, - { .clkdm_name = tesla_clkdm }, - { NULL }, -}; - -static struct clkdm_dep tesla_wkup_sleep_deps[] = { - { .clkdm_name = abe_clkdm }, - { .clkdm_name = ivahd_clkdm }, - { .clkdm_name = l3_1_clkdm }, - { .clkdm_name = l3_2_clkdm }, - { .clkdm_name = l3_emif_clkdm }, - { .clkdm_name = l3_init_clkdm }, - { .clkdm_name = l4_cfg_clkdm }, - { .clkdm_name = l4_per_clkdm }, - { .clkdm_name = l4_wkup_clkdm }, - { NULL }, -}; - static struct clockdomain l4_cefuse_44xx_clkdm = { - .name = l4_cefuse_clkdm, - .pwrdm= { .name = cefuse_pwrdm }, - .prcm_partition = OMAP4430_CM2_PARTITION, - .cm_inst =
[RFC 2/7] ARM: OMAP4+: PRCM: add support for registering PRCM partition against DT node
The PRCM core code contains a notion of PRCM partition and instances, and all PRCM driver register accesses are done through the partitions. The APIs provided in this patch make it possible for PRCM child nodes to map their register spaces against proper PRCM partition, and access the correct partition ID through the common PRCM APIs. Signed-off-by: Tero Kristo t-kri...@ti.com --- arch/arm/mach-omap2/cm_common.c | 12 + arch/arm/mach-omap2/prcm-common.h |5 arch/arm/mach-omap2/prm_common.c | 53 + 3 files changed, 70 insertions(+) diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c index 23e8bce..541ecaa 100644 --- a/arch/arm/mach-omap2/cm_common.c +++ b/arch/arm/mach-omap2/cm_common.c @@ -23,6 +23,8 @@ #include cm33xx.h #include cm44xx.h #include clock.h +#include prcm43xx.h +#include prcm44xx.h /* * cm_ll_data: function pointers to SoC-specific implementations of @@ -225,11 +227,13 @@ int cm_unregister(struct cm_ll_data *cld) static struct omap_prcm_init_data cm_data __initdata = { .index = TI_CLKM_CM, .init = omap4_cm_init, + .part = OMAP4430_CM1_PARTITION, }; static struct omap_prcm_init_data cm2_data __initdata = { .index = TI_CLKM_CM2, .init = omap4_cm_init, + .part = OMAP4430_CM2_PARTITION, }; #endif @@ -268,6 +272,7 @@ static struct omap_prcm_init_data am4_prcm_data __initdata = { .index = TI_CLKM_CM, .flags = CM_NO_CLOCKS | CM_SINGLE_INSTANCE, .init = omap4_cm_init, + .part = AM43XX_CM_PARTITION, }; #endif @@ -316,6 +321,7 @@ int __init omap2_cm_base_init(void) const struct of_device_id *match; struct omap_prcm_init_data *data; void __iomem *mem; + int ret; for_each_matching_node_and_match(np, omap_cm_dt_match_table, match) { data = (struct omap_prcm_init_data *)match-data; @@ -337,6 +343,12 @@ int __init omap2_cm_base_init(void) if (data-init (data-flags CM_SINGLE_INSTANCE || (cm_base cm2_base))) data-init(data); + + if (data-part) { + ret = omap_prcm_map_partition(np, data-part); + if (ret) + return ret; + } } return 0; diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 6ae0b3a..037754d 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -527,6 +527,7 @@ struct omap_prcm_irq_setup { * @device_inst_offset: device instance offset within the module address space * @init: low level PRCM init function for this module * @np: device node for this PRCM module + * @part: PRCM partition ID, applicable for OMAP4+ only */ struct omap_prcm_init_data { int index; @@ -536,6 +537,7 @@ struct omap_prcm_init_data { s32 device_inst_offset; int (*init)(const struct omap_prcm_init_data *data); struct device_node *np; + u8 part; }; extern void omap_prcm_irq_cleanup(void); @@ -545,6 +547,9 @@ extern int omap_prcm_event_to_irq(const char *event); extern void omap_prcm_irq_prepare(void); extern void omap_prcm_irq_complete(void); +int omap_prcm_map_partition(struct device_node *np, u8 part); +int omap_prcm_get_partition(struct device_node *np); + # endif #endif diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 7add799..a3f0aef 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -37,6 +37,7 @@ #include prm54xx.h #include prm7xx.h #include prcm43xx.h +#include prcm44xx.h #include common.h #include clock.h #include cm.h @@ -77,6 +78,8 @@ u16 prm_features; static struct prm_ll_data null_prm_ll_data; static struct prm_ll_data *prm_ll_data = null_prm_ll_data; +static struct device_node *prcm_base_nodes[OMAP4_MAX_PRCM_PARTITIONS]; + /* Private functions */ /* @@ -670,6 +673,7 @@ static struct omap_prcm_init_data omap4_prm_data __initdata = { .init = omap44xx_prm_init, .device_inst_offset = OMAP4430_PRM_DEVICE_INST, .flags = PRM_HAS_IO_WAKEUP | PRM_HAS_VOLTAGE | PRM_IRQ_DEFAULT, + .part = OMAP4430_PRM_PARTITION, }; #endif @@ -679,6 +683,7 @@ static struct omap_prcm_init_data omap5_prm_data __initdata = { .init = omap44xx_prm_init, .device_inst_offset = OMAP54XX_PRM_DEVICE_INST, .flags = PRM_HAS_IO_WAKEUP | PRM_HAS_VOLTAGE, + .part = OMAP54XX_PRM_PARTITION, }; #endif @@ -688,6 +693,7 @@ static struct omap_prcm_init_data dra7_prm_data __initdata = { .init = omap44xx_prm_init, .device_inst_offset = DRA7XX_PRM_DEVICE_INST, .flags = PRM_HAS_IO_WAKEUP, + .part = DRA7XX_PRM_PARTITION, }; #endif @@ -696,12 +702,14 @@ static struct omap_prcm_init_data am4_prm_data __initdata = {
[RFC 3/7] ARM: OMAP4+: PRCM: parse PRCM MPU base address from DT
All the OMAP4+ boards are DT based only, so the prcm_mpu base address can be parsed from DT. Signed-off-by: Tero Kristo t-kri...@ti.com --- arch/arm/mach-omap2/io.c |4 arch/arm/mach-omap2/prm_common.c | 18 ++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index a253aaf..fc207ff 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -48,7 +48,6 @@ #include cm44xx.h #include prm.h #include cm.h -#include prcm_mpu44xx.h #include prminst44xx.h #include prm2xxx.h #include prm3xxx.h @@ -628,7 +627,6 @@ void __init omap4430_init_early(void) { omap2_set_globals_tap(OMAP443X_CLASS, OMAP2_L4_IO_ADDRESS(OMAP443X_SCM_BASE)); - omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE)); omap2_control_base_init(); omap4xxx_check_revision(); omap4xxx_check_features(); @@ -656,7 +654,6 @@ void __init omap5_init_early(void) { omap2_set_globals_tap(OMAP54XX_CLASS, OMAP2_L4_IO_ADDRESS(OMAP54XX_SCM_BASE)); - omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE)); omap2_control_base_init(); omap4_pm_init_early(); omap2_prcm_base_init(); @@ -681,7 +678,6 @@ void __init omap5_init_late(void) void __init dra7xx_init_early(void) { omap2_set_globals_tap(-1, OMAP2_L4_IO_ADDRESS(DRA7XX_TAP_BASE)); - omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE)); omap2_control_base_init(); omap4_pm_init_early(); omap2_prcm_base_init(); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index a3f0aef..ea2fb54 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -38,6 +38,7 @@ #include prm7xx.h #include prcm43xx.h #include prcm44xx.h +#include prcm_mpu44xx.h #include common.h #include clock.h #include cm.h @@ -697,6 +698,13 @@ static struct omap_prcm_init_data dra7_prm_data __initdata = { }; #endif +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ + defined(CONFIG_SOC_DRA7XX) +static struct omap_prcm_init_data omap4_prcm_mpu_data __initdata = { + .part = OMAP4430_PRCM_MPU_PARTITION, +}; +#endif + #ifdef CONFIG_SOC_AM43XX static struct omap_prcm_init_data am4_prm_data __initdata = { .index = TI_CLKM_PRM, @@ -741,6 +749,10 @@ static const struct of_device_id omap_prcm_dt_match_table[] __initconst = { #ifdef CONFIG_SOC_DRA7XX { .compatible = ti,dra7-prm, .data = dra7_prm_data }, #endif +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \ + defined(CONFIG_SOC_DRA7XX) + { .compatible = ti,omap4-prcm-mpu, .data = omap4_prcm_mpu_data }, +#endif { } }; @@ -769,6 +781,9 @@ int __init omap2_prm_base_init(void) if (data-index == TI_CLKM_PRM) prm_base = mem + data-offset; + if (data-part == OMAP4430_PRCM_MPU_PARTITION) + omap2_set_globals_prcm_mpu(mem); + data-mem = mem; data-np = np; @@ -813,6 +828,9 @@ int __init omap_prcm_init(void) for_each_matching_node_and_match(np, omap_prcm_dt_match_table, match) { data = match-data; + if (data-part == OMAP4430_PRCM_MPU_PARTITION) + continue; + ret = omap2_clk_provider_init(np, data-index, NULL, data-mem); if (ret) return ret; -- 1.7.9.5 -- 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
[RFC 4/7] ARM: OMAP2+: PRCM: move PRCM data init later in boot sequence
This avoids the need to use memblock_virt_alloc in the code. Done in preparation of adding generic PM domains to OMAP platform codebase; generic PM domain registration doesn't work during early_init. Signed-off-by: Tero Kristo t-kri...@ti.com --- arch/arm/mach-omap2/io.c | 180 -- arch/arm/mach-omap2/omap_hwmod.c |5 +- drivers/clk/ti/clk.c |3 +- 3 files changed, 118 insertions(+), 70 deletions(-) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index fc207ff..282fd96 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -62,6 +62,12 @@ static int (*omap_clk_soc_init)(void); /* + * prcm_data_init: points to a function that does the SoC-specific + * PRCM data (pwrdm/clkdm/hwmod) initializations + */ +static void (*prcm_data_init)(void); + +/* * The machine specific code may provide the extra mapping besides the * default mapping provided here. */ @@ -375,19 +381,24 @@ static void __init __maybe_unused omap_common_late_init(void) } #ifdef CONFIG_SOC_OMAP2420 -void __init omap2420_init_early(void) +static void __init omap2420_prcm_data_init(void) { - omap2_set_globals_tap(OMAP242X_CLASS, OMAP2_L4_IO_ADDRESS(0x48014000)); - omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE), - OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE)); - omap2_control_base_init(); - omap2xxx_check_revision(); omap2_prcm_base_init(); omap2xxx_voltagedomains_init(); omap242x_powerdomains_init(); omap242x_clockdomains_init(); omap2420_hwmod_init(); omap_hwmod_init_postsetup(); +} + +void __init omap2420_init_early(void) +{ + omap2_set_globals_tap(OMAP242X_CLASS, OMAP2_L4_IO_ADDRESS(0x48014000)); + omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP2420_SDRC_BASE), + OMAP2_L3_IO_ADDRESS(OMAP2420_SMS_BASE)); + omap2_control_base_init(); + omap2xxx_check_revision(); + prcm_data_init = omap2420_prcm_data_init; omap_clk_soc_init = omap2420_dt_clk_init; rate_table = omap2420_rate_table; } @@ -401,19 +412,24 @@ void __init omap2420_init_late(void) #endif #ifdef CONFIG_SOC_OMAP2430 -void __init omap2430_init_early(void) +static void __init omap2430_prcm_data_init(void) { - omap2_set_globals_tap(OMAP243X_CLASS, OMAP2_L4_IO_ADDRESS(0x4900a000)); - omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE), - OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE)); - omap2_control_base_init(); - omap2xxx_check_revision(); omap2_prcm_base_init(); omap2xxx_voltagedomains_init(); omap243x_powerdomains_init(); omap243x_clockdomains_init(); omap2430_hwmod_init(); omap_hwmod_init_postsetup(); +} + +void __init omap2430_init_early(void) +{ + omap2_set_globals_tap(OMAP243X_CLASS, OMAP2_L4_IO_ADDRESS(0x4900a000)); + omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP243X_SDRC_BASE), + OMAP2_L3_IO_ADDRESS(OMAP243X_SMS_BASE)); + omap2_control_base_init(); + omap2xxx_check_revision(); + prcm_data_init = omap2430_prcm_data_init; omap_clk_soc_init = omap2430_dt_clk_init; rate_table = omap2430_rate_table; } @@ -431,22 +447,8 @@ void __init omap2430_init_late(void) * same machine_id for 34xx and 36xx beagle.. Will get fixed with DT. */ #ifdef CONFIG_ARCH_OMAP3 -void __init omap3_init_early(void) +static void __init omap3_prcm_data_init(void) { - omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000)); - omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE), - OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE)); - /* XXX: remove these once OMAP3 is DT only */ - if (!of_have_populated_dt()) { - omap2_set_globals_control( - OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE)); - omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE)); - omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), -NULL); - } - omap2_control_base_init(); - omap3xxx_check_revision(); - omap3xxx_check_features(); omap2_prcm_base_init(); /* XXX: remove these once OMAP3 is DT only */ if (!of_have_populated_dt()) { @@ -471,6 +473,25 @@ void __init omap3_init_early(void) } } +void __init omap3_init_early(void) +{ + omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000)); + omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE), + OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE)); + /* XXX: remove these once OMAP3 is DT only */ + if (!of_have_populated_dt()) { + omap2_set_globals_control( +
[RFC 1/7] ARM: dts: OMAP4+: add prcm_mpu node
PRCM has a local instance directly under the MPU domain, for controlling local MPU powerdomains and clockdomains. Add a DT node for this for omap4, omap5 and dra7. Signed-off-by: Tero Kristo t-kri...@ti.com --- arch/arm/boot/dts/dra7.dtsi |8 arch/arm/boot/dts/omap4.dtsi |8 arch/arm/boot/dts/omap5.dtsi |8 3 files changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 5332b57..73ef19317 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -64,6 +64,14 @@ interrupt-parent = gic; }; + prcm_mpu: prcm_mpu@48243000 { + compatible = ti,omap4-prcm-mpu, simple-bus; + reg = 0x48243000 0xb00; + #address-cells = 1; + #size-cells = 1; + ranges = 0 0x48243000 0xb00; + }; + wakeupgen: interrupt-controller@48281000 { compatible = ti,omap5-wugen-mpu, ti,omap4-wugen-mpu; interrupt-controller; diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index f884d6a..e569e28 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -66,6 +66,14 @@ cache-level = 2; }; + prcm_mpu: prcm_mpu@48243000 { + compatible = ti,omap4-prcm-mpu, simple-bus; + reg = 0x48243000 0x900; + #address-cells = 1; + #size-cells = 1; + ranges = 0 0x48243000 0x900; + }; + local-timer@48240600 { compatible = arm,cortex-a9-twd-timer; clocks = mpu_periphclk; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index efe5f73..b0a123f 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -99,6 +99,14 @@ interrupt-parent = gic; }; + prcm_mpu: prcm_mpu@48243000 { + compatible = ti,omap4-prcm-mpu, simple-bus; + reg = 0x48243000 0xb00; + #address-cells = 1; + #size-cells = 1; + ranges = 0 0x48243000 0xb00; + }; + wakeupgen: interrupt-controller@48281000 { compatible = ti,omap5-wugen-mpu, ti,omap4-wugen-mpu; interrupt-controller; -- 1.7.9.5 -- 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
[RFC 0/7] ARM: OMAP2+: support for DT based pwrdm/clkdm data
Hi, This series provides DT based support for clock/powerdomain data. Some parts of the data is retained under the existing *_data.c files to act as templates. Also, minimal support for generic power domains is added, but without power_off / power_on support at this point (should be relatively trivial to add on top.) The pm-domains.c file has lots of debugging info present at the moment just for testing purposes, the pr_infos shall be gone from the actual code if this should go forward. Patches 1-4 contains some generic tweaks to the PRCM core handling, and should be good to go in their current form already. As a sample in this set, only omap4 clkdm/pwrdm data is converted. Conversion for the rest should be relatively easy to script (I have a script that converts OMAP5/DRA7/AM43xx already, needs some tweaking for the rest of the SoCs.) Basically the question with this set is, whether the DT node layout / compatible string arrangement looks sane or not. Some of the compatibles can be squashed together especially at clkdm data side, seeing the remaining stub data portions are rather minimal. They could also just be retained just in case we need to tweak something later I also pushed a test branch here: tree: https://github.com/t-kristo/linux-pm.git branch: 4.1-rc2-prcm-domains-dt (contains the clock changes on bottom) Overall diffstat for the set below: arch/arm/boot/dts/dra7.dtsi |8 + arch/arm/boot/dts/omap4.dtsi| 40 +++- arch/arm/boot/dts/omap44xx-clocks.dtsi | 298 +++- arch/arm/boot/dts/omap5.dtsi|8 + arch/arm/mach-omap2/Kconfig |1 + arch/arm/mach-omap2/Makefile|3 +- arch/arm/mach-omap2/clockdomain.h | 10 +- arch/arm/mach-omap2/clockdomains44xx_data.c | 327 +++ arch/arm/mach-omap2/cm_common.c | 12 + arch/arm/mach-omap2/io.c| 184 +-- arch/arm/mach-omap2/omap_hwmod.c|5 +- arch/arm/mach-omap2/pm-domains.c| 228 +++ arch/arm/mach-omap2/powerdomain.h |9 +- arch/arm/mach-omap2/powerdomains44xx_data.c | 124 +++--- arch/arm/mach-omap2/prcm-common.h |5 + arch/arm/mach-omap2/prm_common.c| 71 ++ drivers/clk/ti/clk.c|3 +- 17 files changed, 854 insertions(+), 482 deletions(-) bloat-o-meter (with the CONFIG_PM_GENERIC_DOMAINS in place pre/post): add/remove: 22/15 grow/shrink: 26/19 up/down: 10698/-2304 (8394) function old new delta omap_clkdm_match_table -4704 +4704 omap_pwrdm_match_table -3136 +3136 of_omap_clockdomain_init - 912+912 of_omap_powerdomain_init - 408+408 The new compatible strings are consuming any saved space (and plenty more.) With clkdm templates, we can save this (on OMAP4): add/remove: 0/0 grow/shrink: 1/23 up/down: 4/-874 (-870) Pwrdm templates maybe a bit less, as there are less users. -Tero -- 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
[RFC 5/7] ARM: dts: omap4: add clockdomain / powerdomain data
Clockdomain / powerdomain nodes with corresponding register addresses and PRCM hierarchy is added to the DT. This data can be parsed to create the clock/powerdomain data required by the kernel. Signed-off-by: Tero Kristo t-kri...@ti.com --- arch/arm/boot/dts/omap4.dtsi | 32 +++- arch/arm/boot/dts/omap44xx-clocks.dtsi | 298 +++- 2 files changed, 321 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index e569e28..62bfd07 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -72,6 +72,12 @@ #address-cells = 1; #size-cells = 1; ranges = 0 0x48243000 0x900; + + prcm_mpu_pm_domains: pm_domains { + #address-cells = 1; + #size-cells = 1; + ranges; + }; }; local-timer@48240600 { @@ -141,26 +147,38 @@ cm1: cm1@4000 { compatible = ti,omap4-cm1; reg = 0x4000 0x2000; + #address-cells = 1; + #size-cells = 1; + ranges = 0 0x4000 0x2000; cm1_clocks: clocks { #address-cells = 1; #size-cells = 0; }; - cm1_clockdomains: clockdomains { + cm1_pm_domains: pm_domains { + #address-cells = 1; + #size-cells = 1; + ranges; }; }; cm2: cm2@8000 { compatible = ti,omap4-cm2; reg = 0x8000 0x3000; + #address-cells = 1; + #size-cells = 1; + ranges = 0 0x8000 0x3000; cm2_clocks: clocks { #address-cells = 1; #size-cells = 0; }; - cm2_clockdomains: clockdomains { + cm2_pm_domains: pm_domains { + #address-cells = 1; + #size-cells = 1; + ranges; }; }; @@ -233,13 +251,19 @@ compatible = ti,omap4-prm; reg = 0x6000 0x3000; interrupts = GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH; + #address-cells = 1; + #size-cells = 1; + ranges = 0 0x6000 0x3000; prm_clocks: clocks { #address-cells = 1; #size-cells = 0; }; - prm_clockdomains: clockdomains { + prm_pm_domains: pm_domains { + #address-cells = 1; + #size-cells = 1; + ranges; }; }; @@ -252,7 +276,7 @@ #size-cells = 0; }; - scrm_clockdomains: clockdomains { + scrm_pm_domains: pm_domains { }; }; diff --git a/arch/arm/boot/dts/omap44xx-clocks.dtsi b/arch/arm/boot/dts/omap44xx-clocks.dtsi index f2c48f0..370694b 100644 --- a/arch/arm/boot/dts/omap44xx-clocks.dtsi +++ b/arch/arm/boot/dts/omap44xx-clocks.dtsi @@ -744,11 +744,105 @@ }; }; -prm_clockdomains { - emu_sys_clkdm: emu_sys_clkdm { - compatible = ti,clockdomain; +prm_pm_domains { + core_pwrdm: core_pwrdm@700 { + compatible = ti,omap4-core-pwrdm; + reg = 0x700 0x1c; + #power-domain-cells = 0; + }; + + cefuse_pwrdm: cefuse_pwrdm@1600 { + compatible = ti,omap4-cefuse-pwrdm; + reg = 0x1600 0x1c; + #power-domain-cells = 0; + }; + + l4per_pwrdm: l4per_pwrdm@1400 { + compatible = ti,omap4-l4per-pwrdm; +
[PATCH RFC v3 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders
The hdmi-codec is a platform device driver to be registered from drivers of external HDMI encoders with I2S and/or spdif interface. The driver in turn registers an ASoC codec for the HDMI encoder's audio functionality. The structures and definitions in the API header are mostly redundant copies of similar structures in ASoC headers. This is on purpose to avoid direct dependencies to ASoC structures in video side driver. Signed-off-by: Jyri Sarha jsa...@ti.com --- include/sound/hdmi-codec.h| 99 + sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/hdmi-codec.c | 467 ++ 4 files changed, 573 insertions(+) create mode 100644 include/sound/hdmi-codec.h create mode 100644 sound/soc/codecs/hdmi-codec.c diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h new file mode 100644 index 000..b8a90f7 --- /dev/null +++ b/include/sound/hdmi-codec.h @@ -0,0 +1,99 @@ +/* + * hdmi-codec.h - HDMI Codec driver API + * + * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com + * + * Author: Jyri Sarha jsa...@ti.com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * 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. + */ + +#ifndef __HDMI_CODEC_H__ +#define __HDMI_CODEC_H__ + +#include linux/hdmi.h +#include drm/drm_edid.h +#include sound/asoundef.h +#include uapi/sound/asound.h + +/* + * Protocol between ASoC cpu-dai and HDMI-encoder + */ +struct hdmi_codec_daifmt { + enum { + HDMI_I2S, + HDMI_RIGHT_J, + HDMI_LEFT_J, + HDMI_DSP_A, + HDMI_DSP_B, + HDMI_AC97, + HDMI_SPDIF, + } fmt; + int bit_clk_inv:1; + int frame_clk_inv:1; + int bit_clk_master:1; + int frame_clk_master:1; +}; + +/* + * HDMI audio parameters + */ +struct hdmi_codec_params { + struct hdmi_audio_infoframe cea; + struct snd_aes_iec958 iec; + int sample_rate; + int sample_width; + int channels; +}; + +struct hdmi_codec_ops { + /* For runtime clock configuration from ASoC machine driver. +* A direct forward from set_sysclk in struct snd_soc_dai_ops. +* Optional */ + int (*set_clk)(struct device *dev, int clk_id, int freq); + + /* Called when ASoC starts an audio stream setup. The call +* provides an audio abort callback for stoping an ongoing +* stream if the HDMI audio becomes unavailable. +* Optional */ + int (*audio_startup)(struct device *dev, +void (*abort_cb)(struct device *dev)); + + /* Configures HDMI-encoder for audio stream. +* Mandatory */ + int (*hw_params)(struct device *dev, +struct hdmi_codec_daifmt *fmt, +struct hdmi_codec_params *hparms); + + /* Shuts down the audio stream. +* Mandatory */ + void (*audio_shutdown)(struct device *dev); + + /* Mute/unmute HDMI audio stream. +* Optional */ + int (*digital_mute)(struct device *dev, bool enable); + + /* Provides EDID-Like-Data from connected HDMI device. +* Optional */ + int (*get_eld)(struct device *dev, uint8_t *buf, size_t len); +}; + +/* HDMI codec initalization data */ +struct hdmi_codec_pdata { + struct device *dev; /* The HDMI encoder registering the codec */ + const struct hdmi_codec_ops *ops; + uint i2s:1; + uint spdif:1; + int max_i2s_channels; +}; + +#define HDMI_CODEC_DRV_NAME hdmi-audio-codec + +#endif /* __HDMI_CODEC_H__ */ diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index fc8e729..a5cc574 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -76,6 +76,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_MAX9877 if I2C select SND_SOC_MC13783 if MFD_MC13XXX select SND_SOC_ML26124 if I2C + select SND_SOC_HDMI_CODEC select SND_SOC_PCM1681 if I2C select SND_SOC_PCM1792A if SPI_MASTER select SND_SOC_PCM3008 @@ -431,6 +432,10 @@ config SND_SOC_BT_SCO config SND_SOC_DMIC tristate +config SND_SOC_HDMI_CODEC + tristate + select SND_PCM_ELD + config SND_SOC_ES8328 tristate Everest Semi ES8328 CODEC diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 01b4601..0245e67 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -69,6 +69,7 @@ snd-soc-max98925-objs := max98925.o snd-soc-max9850-objs := max9850.o snd-soc-mc13783-objs := mc13783.o snd-soc-ml26124-objs
[PATCH RFC v3 1/7] drm/edid: add function to help find SADs, DO NOT MERGE
From: Russell King - ARM Linux li...@arm.linux.org.uk Add a function to find the start of the SADs in the ELD. This complements the helper to retrieve the SAD count. Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk This should already be coming in from drm-next. Signed-off-by: Jyri Sarha jsa...@ti.com --- include/drm/drm_edid.h | 19 +++ 1 file changed, 19 insertions(+) diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 7990501..53c53c4 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -348,6 +348,25 @@ static inline int drm_eld_mnl(const uint8_t *eld) } /** + * drm_eld_sad - Get ELD SAD structures. + * @eld: pointer to an eld memory structure with sad_count set + */ +static inline const uint8_t *drm_eld_sad(const uint8_t *eld) +{ + unsigned int ver, mnl; + + ver = (eld[DRM_ELD_VER] DRM_ELD_VER_MASK) DRM_ELD_VER_SHIFT; + if (ver != 2 ver != 31) + return NULL; + + mnl = drm_eld_mnl(eld); + if (mnl 16) + return NULL; + + return eld + DRM_ELD_CEA_SAD(mnl, 0); +} + +/** * drm_eld_sad_count - Get ELD SAD count. * @eld: pointer to an eld memory structure with sad_count set */ -- 1.9.1 -- 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 07/11] usb: otg: add OTG core
Hi Peter, On 13/07/15 13:20, Roger Quadros wrote: On 13/07/15 05:14, Peter Chen wrote: On Wed, Jul 08, 2015 at 01:19:33PM +0300, Roger Quadros wrote: The OTG core instantiates the OTG Finite State Machine per OTG controller and manages starting/stopping the host and gadget controllers based on the bus state. It provides APIs for the following tasks - Registering an OTG capable controller - Registering Host and Gadget controllers to OTG core - Providing inputs to and kicking the OTG state machine Signed-off-by: Roger Quadros rog...@ti.com --- MAINTAINERS | 4 +- drivers/usb/Kconfig | 2 +- drivers/usb/Makefile | 1 + drivers/usb/common/Makefile | 3 +- drivers/usb/common/usb-otg.c | 768 +++ drivers/usb/common/usb-otg.h | 71 drivers/usb/core/Kconfig | 11 +- include/linux/usb/otg.h | 91 - 8 files changed, 930 insertions(+), 21 deletions(-) create mode 100644 drivers/usb/common/usb-otg.c create mode 100644 drivers/usb/common/usb-otg.h diff --git a/MAINTAINERS b/MAINTAINERS index 8133cef..b21278e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10640,12 +10640,14 @@ S:Maintained F: Documentation/usb/ohci.txt F: drivers/usb/host/ohci* -USB OTG FSM (Finite State Machine) +USB OTG/DRD core and FSM (Finite State Machine) M: Peter Chen peter.c...@freescale.com +M: Roger Quadros rog...@ti.com T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git L: linux-...@vger.kernel.org S: Maintained F: drivers/usb/common/usb-otg-fsm.c +F: drivers/usb/common/usb-otg.c USB OVER IP DRIVER M: Valentina Manea valentina.mane...@gmail.com diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 8ed451d..5b625e2 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -32,7 +32,7 @@ if USB_SUPPORT config USB_COMMON tristate default y - depends on USB || USB_GADGET + depends on USB || USB_GADGET || USB_OTG USB_OTG can depends on USB || UB_GADGET? I didn't understand. The above is for USB_COMMON. config USB_ARCH_HAS_HCD def_bool y diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index d8926c6..769d13b 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -60,5 +60,6 @@ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ obj-$(CONFIG_USB_GADGET) += gadget/ obj-$(CONFIG_USB_COMMON) += common/ +obj-$(CONFIG_USB_OTG) += common/ The comment like above. What should it look like? Can you please clarify what you meant at the above two comments? Thanks. 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 RFC v3 3/7] ASoC: hdmi-codec: Add hdmi-codec for external HDMI-encoders
On Fri, Aug 14, 2015 at 12:30:41PM +0300, Jyri Sarha wrote: +static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); + struct hdmi_codec_params hp = { + .cea = { 0 }, Unnecessary initialisation - because you are initialising this structure, all unnamed fields will be zeroed. + .iec = { + .status = { + IEC958_AES0_CON_NOT_COPYRIGHT, + IEC958_AES1_CON_GENERAL, + IEC958_AES2_CON_SOURCE_UNSPEC, + IEC958_AES3_CON_CLOCK_VARIABLE, + }, ... + hdmi_audio_infoframe_init(hp.cea); + hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_PCM; Something tells me here that you haven't read the HDMI specification. HDMI says that the coding type will be zero (refer to stream header). The same goes for much of the CEA audio infoframe. Please see the Audio InfoFrame details in the HDMI specification. + hp.cea.channels = params_channels(params); + + switch (params_width(params)) { + case 16: + hp.iec.status[4] |= IEC958_AES4_CON_WORDLEN_20_16; + hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_16; + break; + case 18: + hp.iec.status[4] |= IEC958_AES4_CON_WORDLEN_22_18; + hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_20; + break; + case 20: + hp.iec.status[4] |= IEC958_AES4_CON_WORDLEN_24_20; + hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_20; + break; + case 24: + case 32: + hp.iec.status[4] |= IEC958_AES4_CON_MAX_WORDLEN_24 | + IEC958_AES4_CON_WORDLEN_24_20; Why not use the generic code to generate the AES channel status bits? See sound/core/pcm_iec958.c. -- FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up according to speedtest.net. -- 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 RFC v3 6/7] drm/i2c: tda998x: Register ASoC HDMI codec for audio functionality
On Fri, Aug 14, 2015 at 12:30:44PM +0300, Jyri Sarha wrote: +static int tda998x_write_aif(struct tda998x_priv *priv, + struct hdmi_audio_infoframe *cea) +{ + uint8_t buf[HDMI_INFOFRAME_SIZE(AUDIO)]; + int len; + + len = hdmi_audio_infoframe_pack(cea, buf, sizeof(buf)); + if (len 0) { + dev_err(priv-hdmi-dev, + Failed to pack audio infoframe: %d\n, len); + return len; + } + + /* Write the audio information packet */ + tda998x_write_if(priv, DIP_IF_FLAGS_IF4, REG_IF4_HB0, buf, len); + return 0; +} + I have such a function already queued up, but I can't push it out at the moment because of too many conflicts across all my DRM work. I'm waiting for after 4.3-rc1 before publishing anything from or accepting anything else into DRM branches. static void tda998x_write_avi(struct tda998x_priv *priv, struct drm_display_mode *mode) { @@ -670,19 +691,24 @@ static void tda998x_audio_mute(struct tda998x_priv *priv, bool on) } } -static void +static int tda998x_configure_audio(struct tda998x_priv *priv, - struct drm_display_mode *mode, struct tda998x_encoder_params *p) + int mode_clock, + int ena_ap, + int dai_format, + int sample_width, + int sample_rate, + const u8 *status) I don't think this is an improvement. +static int tda998x_audio_get_eld(struct device *dev, uint8_t *buf, size_t len) +{ + struct tda998x_priv *priv = dev_get_drvdata(dev); + struct drm_mode_config *config = priv-encoder-dev-mode_config; + struct drm_connector *connector; + int ret = -ENODEV; + + mutex_lock(config.mutex); + list_for_each_entry(connector, config-connector_list, head) { + if (priv-encoder == connector-encoder) { + memcpy(buf, connector-eld, +min(sizeof(connector-eld), len)); + ret = 0; + } + } + mutex_unlock(config.mutex); Obviously untested. Should be config-mutex. But in any case, when I kill the DRM slave encoder code in here, this becomes unnecessary. -- FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up according to speedtest.net. -- 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 07/11] usb: otg: add OTG core
On Fri, Aug 14, 2015 at 12:42:38PM +0300, Roger Quadros wrote: Hi Peter, On 13/07/15 13:20, Roger Quadros wrote: On 13/07/15 05:14, Peter Chen wrote: On Wed, Jul 08, 2015 at 01:19:33PM +0300, Roger Quadros wrote: The OTG core instantiates the OTG Finite State Machine per OTG controller and manages starting/stopping the host and gadget controllers based on the bus state. It provides APIs for the following tasks - Registering an OTG capable controller - Registering Host and Gadget controllers to OTG core - Providing inputs to and kicking the OTG state machine Signed-off-by: Roger Quadros rog...@ti.com --- MAINTAINERS | 4 +- drivers/usb/Kconfig | 2 +- drivers/usb/Makefile | 1 + drivers/usb/common/Makefile | 3 +- drivers/usb/common/usb-otg.c | 768 +++ drivers/usb/common/usb-otg.h | 71 drivers/usb/core/Kconfig | 11 +- include/linux/usb/otg.h | 91 - 8 files changed, 930 insertions(+), 21 deletions(-) create mode 100644 drivers/usb/common/usb-otg.c create mode 100644 drivers/usb/common/usb-otg.h diff --git a/MAINTAINERS b/MAINTAINERS index 8133cef..b21278e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10640,12 +10640,14 @@ S: Maintained F: Documentation/usb/ohci.txt F: drivers/usb/host/ohci* -USB OTG FSM (Finite State Machine) +USB OTG/DRD core and FSM (Finite State Machine) M: Peter Chen peter.c...@freescale.com +M: Roger Quadros rog...@ti.com T: git git://git.kernel.org/pub/scm/linux/kernel/git/peter.chen/usb.git L: linux-...@vger.kernel.org S: Maintained F: drivers/usb/common/usb-otg-fsm.c +F: drivers/usb/common/usb-otg.c USB OVER IP DRIVER M: Valentina Manea valentina.mane...@gmail.com diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 8ed451d..5b625e2 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -32,7 +32,7 @@ if USB_SUPPORT config USB_COMMON tristate default y - depends on USB || USB_GADGET + depends on USB || USB_GADGET || USB_OTG USB_OTG can depends on USB || UB_GADGET? I didn't understand. The above is for USB_COMMON. config USB_ARCH_HAS_HCD def_bool y diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index d8926c6..769d13b 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -60,5 +60,6 @@ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ obj-$(CONFIG_USB_GADGET) += gadget/ obj-$(CONFIG_USB_COMMON) += common/ +obj-$(CONFIG_USB_OTG)+= common/ The comment like above. What should it look like? Can you please clarify what you meant at the above two comments? Thanks. Forget them, I had thought the USB_OTG could be module. -- Best Regards, Peter Chen -- 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/6] genirq: fix irqchip_set_wake_parent if IRQCHIP_SKIP_SET_WAKE
On 08/13/2015 03:58 PM, Grygorii Strashko wrote: On 08/13/2015 01:31 PM, Grygorii Strashko wrote: On 08/13/2015 01:01 PM, Marc Zyngier wrote: On 12/08/15 18:45, Grygorii Strashko wrote: The irqchip_set_wake_parent should not fail if IRQ chip specifies IRQCHIP_SKIP_SET_WAKE. Otherwise, IRQ wakeup configuration can't be propagated properly through IRQ domains hierarchy. In case of TI OMAP DRA7 the issue reproduced with following configuration: ARM GIC-OMAP wakeupgen-TI CBAR-GPIO-GPIO pcf857x-gpio_key gpio_key is wakeup source Failure is reproduced during suspend/resume to RAM: suspend: - gpio_keys_suspend enable_irq_wake + pcf857x_irq_set_wake + omap_gpio_wake_enable + TI CBAR irq_chip_set_wake_parent + OMAP wakeupgen has no .irq_set_wake() Most importantly, wakeupgen has IRQCHIP_SKIP_SET_WAKE set. and -ENOSYS will be returned resume: - gpio_keys_resume + disable_irq_wake + irq_set_irq_wake + WARN(1, Unbalanced IRQ %d wake disable\n, irq); Fixes: 08b55e2a9208 ('genirq: Add irqchip_set_wake_parent') Signed-off-by: Grygorii Strashko grygorii.stras...@ti.com --- kernel/irq/chip.c | 4 1 file changed, 4 insertions(+) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 6de638b..bdb1b9d 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -1024,6 +1024,10 @@ int irq_chip_set_vcpu_affinity_parent(struct irq_data *data, void *vcpu_info) int irq_chip_set_wake_parent(struct irq_data *data, unsigned int on) { data = data-parent_data; + +if (irq_data_get_irq_chip(data)-flags IRQCHIP_SKIP_SET_WAKE) +return 0; + if (data-chip-irq_set_wake) return data-chip-irq_set_wake(data, on); We have a more general issue with chip flags, and how they combine within a stack of irqchips. Indeed. Problem looks similar to IRQCHIP_MASK_ON_SUSPEND flag usage. What if you remove the irq_chip_set_wake_parent from the crossbar driver, and instead set IRQCHIP_SKIP_SET_WAKE? I've thought about this and it should work for me. One question - what if crossbar will be not the last one in IRQ domains hierarchy? I can confirm, if I revert this patch, add IRQCHIP_SKIP_SET_WAKE to the crossbar and remove irq_chip_set_wake_parent wakeups still works. What do you prefer me to do: add additional patch for the crossbar, drop/keep this patch? OK. There are two possibilities to fix set_wake functionality for TI OMAPs where below HW configurations are used: OMAP4/5: GIC - OMAP wakeupgen DRA7: GIC - OMAP wakeupgen - TI CBAR 1) ensure that IRQCHIP_SKIP_SET_WAKE flag is set only for GIC and use irq_chip_set_wake_parent() in both wakeupgen and crossbar [this patch is required] 2) ensure that IRQCHIP_SKIP_SET_WAKE flag is set and drop .irq_set_wake()/irq_chip_set_wake_parent() for all IRQ chips in IRQ domains hierarchy. [this patch can be dropped] I'm going to select approach 2 and re-send. -- regards, -grygorii -- 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] gpiolib: irqchip: use different lockdep class for each gpio irqchip
On 08/14/2015 03:40 PM, Lars-Peter Clausen wrote: On 08/14/2015 02:34 PM, Linus Walleij wrote: [...] Every chip will get their own lock class on the heap. But I think it is a bit kludgy. Is it not possible to have the lock key in struct gpio_chip be a real member instead of a pointer and get a per-chip lock that way? (...) struct lock_class_key lock_key; instead of: struct lock_class_key *lock_key; - problem solved, without kludgy header defines? Lock keys need to be in persistent memory since they have a unlimited life time. Once registered it is expected to exist until the system is reset. We recently fixed the same issue of nested locks in regmap. For reference the discussion with had a look at different ways to solve this can be found here[1] and the final patch series that went in here[2]. - Lars [1] https://lkml.org/lkml/2015/6/25/144 [2] https://lkml.org/lkml/2015/7/8/43 I've actually followed [2], but without deep digging in Lock keys anatomy :) (as mentioned in commit message) -- regards, -grygorii -- 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