ti-sysc driver changes to support more devices
Subsystems (9)
Tony Lindgren
maintainercover ti-sysc driver changes to support more devices
Hi all,
This series contains improvments for ti-sysc driver to allow booting with more devices configured in device tree instead of the legacy platform data. Looks like some device drivers also need updating for suspend and resume, I'll be posting patches separately for those.
Regards,
Tony
Tony Lindgren (16):
ARM: OMAP2+: Drop unused pm-noop
ARM: OMAP2+: Allow using ti-sysc for system timers
ARM: OMAP2+: Use signed value for sysc register offsets
ARM: OMAP2+: Only probe SDMA via ti-sysc if configured in dts
ARM: OMAP2+: Initialize SoC PM later
ARM: OMAP2+: Make display related init into device_initcall
bus: ti-sysc: Handle simple-bus for nested children
bus: ti-sysc: Make child clock alias handling more generic
bus: ti-sysc: Add handling for clkctrl opt clocks
bus: ti-sysc: Tag some modules resource providers for noirq suspend
bus: ti-sysc: Improve suspend and resume handling
bus: ti-sysc: Add initial support for external resets
bus: ti-sysc: Detect omap4 type timers for quirk
bus: ti-sysc: Detect UARTs for SYSC_QUIRK_LEGACY_IDLE quirk on omap4
bus: ti-sysc: Tag sdio and wdt with legacy mode for suspend
bus: ti-sysc: Show module information for suspend if DEBUG is enabled
.../devicetree/bindings/bus/ti-sysc.txt | 6 +- arch/arm/mach-omap2/Makefile | 1 - arch/arm/mach-omap2/board-generic.c | 2 - arch/arm/mach-omap2/common.h | 18 +- arch/arm/mach-omap2/display.c | 10 +- arch/arm/mach-omap2/hsmmc.c | 1 - arch/arm/mach-omap2/i2c.c | 1 - arch/arm/mach-omap2/io.c | 70 +--- arch/arm/mach-omap2/omap-pm-noop.c | 176 -------- arch/arm/mach-omap2/omap-pm.h | 161 -------- arch/arm/mach-omap2/omap_device.c | 22 +- arch/arm/mach-omap2/omap_hwmod.c | 21 +- arch/arm/mach-omap2/omap_hwmod.h | 6 +- .../omap_hwmod_33xx_43xx_ipblock_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 4 + arch/arm/mach-omap2/omap_hwmod_43xx_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 4 + arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 3 + arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 6 + arch/arm/mach-omap2/omap_hwmod_81xx_data.c | 1 + arch/arm/mach-omap2/pdata-quirks.c | 15 - arch/arm/mach-omap2/pm-debug.c | 5 - arch/arm/mach-omap2/pm.c | 21 +- arch/arm/mach-omap2/pm33xx-core.c | 4 +- arch/arm/mach-omap2/timer.c | 68 ++- arch/arm/plat-omap/Kconfig | 10 - drivers/bus/ti-sysc.c | 388 ++++++++++++++++-- drivers/media/rc/ir-rx51.c | 17 +- include/linux/platform_data/media/ir-rx51.h | 9 - include/linux/platform_data/ti-sysc.h | 1 + 30 files changed, 494 insertions(+), 559 deletions(-) delete mode 100644 arch/arm/mach-omap2/omap-pm-noop.c delete mode 100644 arch/arm/mach-omap2/omap-pm.h delete mode 100644 include/linux/platform_data/media/ir-rx51.h
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 1/16 ARM: OMAP2+: Drop unused pm-noop
Looks like these functions don't do anything in the mainline kernel so we can just drop it.
Note that we must now also remove ir-rx51 pdata as it relies on the dummy platform data that does not do anything. And ir-rx51 is calling a pdata callback that doesn't do anything without checking if it exists first.
For configuring device specific minimal latencies, the interface to use is pm_qos_add_request(). For an example, see what was done in commit 9834ffd1ecc3 ("ASoC: omap-mcbsp: Add PM QoS support for McBSP to prevent glitches"). I've added some comments to ir-rx51 so people using it can add pm_qos support and test it.
--- arch/arm/mach-omap2/Makefile | 1 - arch/arm/mach-omap2/display.c | 7 - arch/arm/mach-omap2/hsmmc.c | 1 - arch/arm/mach-omap2/i2c.c | 1 - arch/arm/mach-omap2/io.c | 3 - arch/arm/mach-omap2/omap-pm-noop.c | 176 -------------------- arch/arm/mach-omap2/omap-pm.h | 161 ------------------ arch/arm/mach-omap2/pdata-quirks.c | 15 -- arch/arm/mach-omap2/pm-debug.c | 5 - arch/arm/mach-omap2/pm.c | 10 +- arch/arm/mach-omap2/timer.c | 1 - arch/arm/plat-omap/Kconfig | 10 -- drivers/media/rc/ir-rx51.c | 17 +- include/linux/platform_data/media/ir-rx51.h | 9 - 14 files changed, 4 insertions(+), 413 deletions(-) delete mode 100644 arch/arm/mach-omap2/omap-pm-noop.c delete mode 100644 arch/arm/mach-omap2/omap-pm.h delete mode 100644 include/linux/platform_data/media/ir-rx51.h
arch/arm/mach-omap2/Makefile +0 -1
@@ -78,7 +78,6 @@ endif omap-4-5-pm-common = omap-mpuss-lowpower.o obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common) obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-pm-common) -obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
arch/arm/mach-omap2/display.c +0 -7
@@ -32,7 +32,6 @@#include <linux/platform_data/omapdss.h> #include "omap_hwmod.h" #include "omap_device.h" -#include "omap-pm.h" #include "common.h" #include "soc.h"
@@ -126,11 +125,6 @@ static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)omap4_dsi_mux_pads (dsi_id,0 ); } -static int omap_dss_set_min_bus_tput (struct device *dev,unsigned long tput) -{ -return omap_pm_set_min_bus_tput (dev,OCP_INITIATOR_AGENT , tput); -} -static enum omapdss_version __init omap_display_get_version (void ) {if (cpu_is_omap24xx ())
@@ -169,7 +163,6 @@ static int __init omapdss_init_fbdev(void)static struct omap_dss_board_info board_data = { .dsi_enable_pads = omap_dsi_enable_pads, .dsi_disable_pads = omap_dsi_disable_pads, - .set_min_bus_tput = omap_dss_set_min_bus_tput, };struct device_node *node;int r;
arch/arm/mach-omap2/hsmmc.c +0 -1
@@ -18,7 +18,6 @@#include "soc.h" #include "omap_device.h" -#include "omap-pm.h" #include "hsmmc.h" #include "control.h"
arch/arm/mach-omap2/i2c.c +0 -1
@@ -22,7 +22,6 @@#include "soc.h" #include "omap_hwmod.h" #include "omap_device.h" -#include "omap-pm.h" #include "prm.h" #include "common.h"
arch/arm/mach-omap2/io.c +0 -3
@@ -37,7 +37,6 @@#include "clock.h" #include "clock2xxx.h" #include "clock3xxx.h" -#include "omap-pm.h" #include "sdrc.h" #include "control.h" #include "serial.h"
@@ -421,8 +420,6 @@ static void __init __maybe_unused omap_hwmod_init_postsetup(void) postsetup_state = _HWMOD_STATE_ENABLED;#endif omap_hwmod_for_each (_set_hwmod_postsetup_state, &postsetup_state); - -omap_pm_if_early_init (); }static void __init __maybe_unused omap_common_late_init (void )
arch/arm/mach-omap2/omap-pm-noop.c deleted +0 -176
176 lines not on this page · raw message
arch/arm/mach-omap2/omap-pm.h deleted +0 -161
161 lines not on this page · raw message
arch/arm/mach-omap2/pdata-quirks.c +0 -15
@@ -26,14 +26,12 @@#include <linux/platform_data/iommu-omap.h> #include <linux/platform_data/ti-sysc.h> #include <linux/platform_data/wkup_m3.h> -#include <linux/platform_data/media/ir-rx51.h> #include <linux/platform_data/asoc-ti-mcbsp.h> #include "common.h" #include "common-board-devices.h" #include "control.h" #include "omap_device.h" -#include "omap-pm.h" #include "omap-secure.h" #include "soc.h" #include "hsmmc.h"
@@ -514,18 +512,6 @@ void omap_auxdata_legacy_init(struct device *dev) dev->platform_data = &twl_gpio_auxdata; } -static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = { - .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat, -}; - -static struct platform_device __maybe_unused rx51_ir_device = { - .name ="ir_rx51" , - .id =-1 , - .dev = { - .platform_data = &rx51_ir_data, - }, -}; -#if IS_ENABLED (CONFIG_SND_OMAP_SOC_MCBSP )static struct omap_mcbsp_platform_data mcbsp_pdata;static void __init omap3_mcbsp_init (void )
@@ -569,7 +555,6 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = { "480c9000.smartreflex", &omap_sr_pdata[OMAP_SR_MPU]),OF_DEV_AUXDATA ("ti,omap3-hsmmc" ,0x4809c000 ,"4809c000.mmc" , &mmc_pdata[0 ]),OF_DEV_AUXDATA ("ti,omap3-hsmmc" ,0x480b4000 ,"480b4000.mmc" , &mmc_pdata[1 ]), -OF_DEV_AUXDATA ("nokia,n900-ir" ,0 ,"n900-ir" , &rx51_ir_data),/* Only on am3517 */ OF_DEV_AUXDATA ("ti,davinci_mdio" ,0x5c030000 ,"davinci_mdio.0" ,NULL ), OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
arch/arm/mach-omap2/pm-debug.c +0 -5
@@ -31,7 +31,6 @@#include "clock.h" #include "powerdomain.h" #include "clockdomain.h" -#include "omap-pm.h" #include "soc.h" #include "cm2xxx_3xxx.h"
@@ -240,10 +239,6 @@ static int option_set(void *data, u64 val) *option = val;if (option == &enable_off_mode) { -if (val) -omap_pm_enable_off_mode (); -else -omap_pm_disable_off_mode ();if (cpu_is_omap34xx ())omap3_pm_off_mode_enable (val); }
arch/arm/mach-omap2/pm.c +1 -9
@@ -16,11 +16,11 @@#include <linux/pm_opp.h> #include <linux/export.h> #include <linux/suspend.h> +#include <linux/clk.h> #include <linux/cpu.h> #include <asm/system_misc.h> -#include "omap-pm.h" #include "omap_device.h" #include "common.h"
@@ -230,14 +230,6 @@ static void __init omap4_init_voltages(void)omap2_set_init_voltage ("iva" ,"dpll_iva_m5x2_ck" ,"iva" ); } -static int __init omap2_common_pm_init (void ) -{ -omap_pm_if_init (); - -return 0 ; -} -omap_postcore_initcall (omap2_common_pm_init); -int __init omap2_common_pm_late_init (void ) {/* Init the voltage layer */
arch/arm/mach-omap2/timer.c +0 -1
@@ -50,7 +50,6 @@#include "omap_device.h" #include <plat/counter-32k.h> #include <clocksource/timer-ti-dm.h> -#include "omap-pm.h" #include "soc.h" #include "common.h"
arch/arm/plat-omap/Kconfig +0 -10
@@ -115,16 +115,6 @@ config OMAP_SERIAL_WAKE to data on the serial RX line. This allows you to wake the system from serial console. -choice - prompt "OMAP PM layer selection" - depends on ARCH_OMAP - default OMAP_PM_NOOP - -config OMAP_PM_NOOP - bool "No-op/debug PM layer" - -endchoice - endmenu endif
drivers/media/rc/ir-rx51.c +3 -14
@@ -22,7 +22,6 @@#include <linux/hrtimer.h> #include <media/rc-core.h> -#include <linux/platform_data/media/ir-rx51.h> #define WBUF_LEN 256
@@ -31,7 +30,6 @@ struct ir_rx51 {struct pwm_device *pwm;struct hrtimer timer;struct device *dev; -struct ir_rx51_platform_data *pdata;wait_queue_head_t wqueue;unsigned int freq;/* carrier frequency */
@@ -130,10 +128,9 @@ static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer, ir_rx51->wbuf[count] =-1 ;/* Insert termination mark */ /* -* Adjust latency requirements so the device doesn't go in too -* deep sleep states +* REVISIT: Adjust latency requirements so the device doesn't go in too +* deep sleep states with pm_qos_add_request(). */ - ir_rx51->pdata->set_max_mpu_wakeup_lat (ir_rx51->dev,50 );ir_rx51_on (ir_rx51); ir_rx51->wbuf_index =1 ;
@@ -146,8 +143,7 @@ static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer,*/ wait_event_interruptible (ir_rx51->wqueue, ir_rx51->wbuf_index <0 ); -/* We can sleep again */ - ir_rx51->pdata->set_max_mpu_wakeup_lat (ir_rx51->dev,-1 ); +/* REVISIT: Remove pm_qos constraint, we can sleep again */ return count; }
@@ -244,13 +240,6 @@ static int ir_rx51_probe(struct platform_device *dev)struct pwm_device *pwm;struct rc_dev *rcdev; - ir_rx51.pdata = dev->dev.platform_data; - -if (!ir_rx51.pdata) { -dev_err (&dev->dev,"Platform Data is missing\n" ); -return -ENXIO ; - } - pwm =pwm_get (&dev->dev,NULL );if (IS_ERR (pwm)) {int err =PTR_ERR (pwm);
include/linux/platform_data/media/ir-rx51.h deleted +0 -9
@@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _IR_RX51_H -#define _IR_RX51_H - -struct ir_rx51_platform_data { -int (*set_max_mpu_wakeup_lat)(struct device *dev,long t); -}; - -#endif
Signature · 1 line
2.17.0
Re: [PATCH 01/16] ARM: OMAP2+: Drop unused pm-noop
Em Mon, 23 Apr 2018 10:45:34 -0700
Tony Lindgren <[email protected]> escreveu:
Quoted 13 lines
Looks like these functions don't do anything in the mainline kernel so we can just drop it.
Note that we must now also remove ir-rx51 pdata as it relies on the dummy platform data that does not do anything. And ir-rx51 is calling a pdata callback that doesn't do anything without checking if it exists first.
For configuring device specific minimal latencies, the interface to use is
pm_qos_add_request(). For an example, see what was done in commit9834ffd1ecc3("ASoC: omap-mcbsp: Add PM QoS support for McBSP to prevent glitches"). I've added some comments to ir-rx51 so people using it can addpm_qossupport and test it.
Quoted 4 lines
Cc Ivaylo Dimitrov <[email protected]>Cc Kevin Hilman <[email protected]>Cc Laurent Pinchart <[email protected]>Cc Mauro Carvalho Chehab <[email protected]>
Quoted 643 lines
Cc Tomi Valkeinen <[email protected]>Signed-off-by Tony Lindgren <[email protected]>--- arch/arm/mach-omap2/Makefile | 1 - arch/arm/mach-omap2/display.c | 7 - arch/arm/mach-omap2/hsmmc.c | 1 - arch/arm/mach-omap2/i2c.c | 1 - arch/arm/mach-omap2/io.c | 3 - arch/arm/mach-omap2/omap-pm-noop.c | 176 -------------------- arch/arm/mach-omap2/omap-pm.h | 161 ------------------ arch/arm/mach-omap2/pdata-quirks.c | 15 -- arch/arm/mach-omap2/pm-debug.c | 5 - arch/arm/mach-omap2/pm.c | 10 +- arch/arm/mach-omap2/timer.c | 1 - arch/arm/plat-omap/Kconfig | 10 -- drivers/media/rc/ir-rx51.c | 17 +- include/linux/platform_data/media/ir-rx51.h | 9 - 14 files changed, 4 insertions(+), 413 deletions(-) delete mode 100644 arch/arm/mach-omap2/omap-pm-noop.c delete mode 100644 arch/arm/mach-omap2/omap-pm.h delete mode 100644 include/linux/platform_data/media/ir-rx51.harch/arm/mach-omap2/Makefile +0
-1@@ -78,7 +78,6 @@ endif omap-4-5-pm-common = omap-mpuss-lowpower.o obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common) obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-pm-common) -obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.oarch/arm/mach-omap2/display.c +0
-7@@ -32,7 +32,6 @@#include <linux/platform_data/omapdss.h> #include "omap_hwmod.h" #include "omap_device.h" -#include "omap-pm.h" #include "common.h" #include "soc.h" @@ -126,11 +125,6 @@ static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)omap4_dsi_mux_pads (dsi_id,0 ); } -static int omap_dss_set_min_bus_tput (struct device *dev,unsigned long tput) -{ -return omap_pm_set_min_bus_tput (dev,OCP_INITIATOR_AGENT , tput); -} -static enum omapdss_version __init omap_display_get_version (void ) {if (cpu_is_omap24xx ())@@ -169,7 +163,6 @@ static int __init omapdss_init_fbdev(void)static struct omap_dss_board_info board_data = { .dsi_enable_pads = omap_dsi_enable_pads, .dsi_disable_pads = omap_dsi_disable_pads, - .set_min_bus_tput = omap_dss_set_min_bus_tput, };struct device_node *node;int r;arch/arm/mach-omap2/hsmmc.c +0
-1@@ -18,7 +18,6 @@#include "soc.h" #include "omap_device.h" -#include "omap-pm.h" #include "hsmmc.h" #include "control.h" arch/arm/mach-omap2/i2c.c +0
-1@@ -22,7 +22,6 @@#include "soc.h" #include "omap_hwmod.h" #include "omap_device.h" -#include "omap-pm.h" #include "prm.h" #include "common.h" arch/arm/mach-omap2/io.c +0
-3@@ -37,7 +37,6 @@#include "clock.h" #include "clock2xxx.h" #include "clock3xxx.h" -#include "omap-pm.h" #include "sdrc.h" #include "control.h" #include "serial.h" @@ -421,8 +420,6 @@ static void __init __maybe_unused omap_hwmod_init_postsetup(void) postsetup_state = _HWMOD_STATE_ENABLED;#endif omap_hwmod_for_each (_set_hwmod_postsetup_state, &postsetup_state); - -omap_pm_if_early_init (); }static void __init __maybe_unused omap_common_late_init (void )arch/arm/mach-omap2/omap-pm-noop.c deleted +0
-176@@ -1,176 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* -* omap-pm-noop.c - OMAP power management interface - dummy version -* -* This code implements the OMAP power management interface to -* drivers, CPUIdle, CPUFreq, and DSP Bridge. It is strictly for -* debug/demonstration use, as it does nothing but printk() whenever a -* function is called (when DEBUG is defined, below) -* -* Copyright (C) 2008-2009 Texas Instruments, Inc. -* Copyright (C) 2008-2009 Nokia Corporation -* Paul Walmsley -* -* Interface developed by (in alphabetical order): -* Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan -* Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff -*/ - -#undef DEBUG - -#include <linux/init.h> -#include <linux/cpufreq.h> -#include <linux/device.h> -#include <linux/platform_device.h> - -#include "omap_device.h" -#include "omap-pm.h" - -static bool off_mode_enabled; -static int dummy_context_loss_counter; - -/* -* Device-driver-originated constraints (via board-*.c files) -*/ - -int omap_pm_set_max_mpu_wakeup_lat (struct device *dev,long t) -{ -if (!dev || t <-1 ) { -WARN (1 ,"OMAP PM: %s: invalid parameter(s)" , __func__); -return -EINVAL ; - } - -if (t ==-1 ) -pr_debug ("OMAP PM: remove max MPU wakeup latency constraint: dev %s\n" , -dev_name (dev)); -else -pr_debug ("OMAP PM: add max MPU wakeup latency constraint: dev %s, t = %ld usec\n" , -dev_name (dev), t); - -/* -* For current Linux, this needs to map the MPU to a -* powerdomain, then go through the list of current max lat -* constraints on the MPU and find the smallest. If -* the latency constraint has changed, the code should -* recompute the state to enter for the next powerdomain -* state. -* -* TI CDP code can call constraint_set here. -*/ - -return 0 ; -} - -int omap_pm_set_min_bus_tput (struct device *dev,u8 agent_id,unsigned long r) -{ -if (!dev || (agent_id !=OCP_INITIATOR_AGENT && - agent_id !=OCP_TARGET_AGENT )) { -WARN (1 ,"OMAP PM: %s: invalid parameter(s)" , __func__); -return -EINVAL ; - } - -if (r ==0 ) -pr_debug ("OMAP PM: remove min bus tput constraint: dev %s for agent_id %d\n" , -dev_name (dev), agent_id); -else -pr_debug ("OMAP PM: add min bus tput constraint: dev %s for agent_id %d: rate %ld KiB\n" , -dev_name (dev), agent_id, r); - -/* -* This code should model the interconnect and compute the -* required clock frequency, convert that to a VDD2 OPP ID, then -* set the VDD2 OPP appropriately. -* -* TI CDP code can call constraint_set here on the VDD2 OPP. -*/ - -return 0 ; -} - -/* -* DSP Bridge-specific constraints -*/ - - -/** -* omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled -* -* Intended for use only by OMAP PM core code to notify this layer -* that off mode has been enabled. -*/ -void omap_pm_enable_off_mode (void ) -{ - off_mode_enabled = true; -} - -/** -* omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled -* -* Intended for use only by OMAP PM core code to notify this layer -* that off mode has been disabled. -*/ -void omap_pm_disable_off_mode (void ) -{ - off_mode_enabled = false; -} - -/* -* Device context loss tracking -*/ - -#ifdef CONFIG_ARCH_OMAP2PLUS - -int omap_pm_get_dev_context_loss_count (struct device *dev) -{ -struct platform_device *pdev =to_platform_device (dev); -int count; - -if (WARN_ON (!dev)) -return -ENODEV ; - -if (dev->pm_domain == &omap_device_pm_domain) { - count =omap_device_get_context_loss_count (pdev); - }else { -WARN_ONCE (off_mode_enabled,"omap_pm: using dummy context loss counter; device %s should be converted to omap_device" , -dev_name (dev)); - - count = dummy_context_loss_counter; - -if (off_mode_enabled) { - count++; -/* -* Context loss count has to be a non-negative value. -* Clear the sign bit to get a value range from 0 to -* INT_MAX. -*/ - count &=INT_MAX ; - dummy_context_loss_counter = count; - } - } - -pr_debug ("OMAP PM: context loss count for dev %s = %d\n" , -dev_name (dev), count); - -return count; -} - -#else - -int omap_pm_get_dev_context_loss_count (struct device *dev) -{ -return dummy_context_loss_counter; -} - -#endif - -/* Should be called before clk framework init */ -int __init omap_pm_if_early_init (void ) -{ -return 0 ; -} - -/* Must be called after clock framework is initialized */ -int __init omap_pm_if_init (void ) -{ -return 0 ; -}arch/arm/mach-omap2/omap-pm.h deleted +0
-161@@ -1,161 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* -* omap-pm.h - OMAP power management interface -* -* Copyright (C) 2008-2010 Texas Instruments, Inc. -* Copyright (C) 2008-2010 Nokia Corporation -* Paul Walmsley -* -* Interface developed by (in alphabetical order): Karthik Dasu, Jouni -* H?gander, Tony Lindgren, Rajendra Nayak, Sakari Poussa, -* Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, -* Richard Woodruff -*/ - -#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H -#define ASM_ARM_ARCH_OMAP_OMAP_PM_H - -#include <linux/device.h> -#include <linux/cpufreq.h> -#include <linux/clk.h> -#include <linux/pm_opp.h> - -/* -* agent_id values for use with omap_pm_set_min_bus_tput(): -* -* OCP_INITIATOR_AGENT is only valid for devices that can act as -* initiators -- it represents the device's L3 interconnect -* connection. OCP_TARGET_AGENT represents the device's L4 -* interconnect connection. -*/ -#define OCP_TARGET_AGENT 1 -#define OCP_INITIATOR_AGENT 2 - -/** -* omap_pm_if_early_init - OMAP PM init code called before clock fw init -* @mpu_opp_table: array ptr to struct omap_opp for MPU -* @dsp_opp_table: array ptr to struct omap_opp for DSP -* @l3_opp_table : array ptr to struct omap_opp for CORE -* -* Initialize anything that must be configured before the clock -* framework starts. The "_if_" is to avoid name collisions with the -* PM idle-loop code. -*/ -int __init omap_pm_if_early_init (void ); - -/** -* omap_pm_if_init - OMAP PM init code called after clock fw init -* -* The main initialization code. OPP tables are passed in here. The -* "_if_" is to avoid name collisions with the PM idle-loop code. -*/ -int __init omap_pm_if_init (void ); - -/* -* Device-driver-originated constraints (via board-*.c files, platform_data) -*/ - - -/** -* omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency -* @dev: struct device * requesting the constraint -* @t: maximum MPU wakeup latency in microseconds -* -* Request that the maximum interrupt latency for the MPU to be no -* greater than @t microseconds. "Interrupt latency" in this case is -* defined as the elapsed time from the occurrence of a hardware or -* timer interrupt to the time when the device driver's interrupt -* service routine has been entered by the MPU. -* -* It is intended that underlying PM code will use this information to -* determine what power state to put the MPU powerdomain into, and -* possibly the CORE powerdomain as well, since interrupt handling -* code currently runs from SDRAM. Advanced PM or board*.c code may -* also configure interrupt controller priorities, OCP bus priorities, -* CPU speed(s), etc. -* -* This function will not affect device wakeup latency, e.g., time -* elapsed from when a device driver enables a hardware device with -* clk_enable(), to when the device is ready for register access or -* other use. To control this device wakeup latency, use -* omap_pm_set_max_dev_wakeup_lat() -* -* Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the -* previous t value. To remove the latency target for the MPU, call -* with t = -1. -* -* XXX This constraint will be deprecated soon in favor of the more -* general omap_pm_set_max_dev_wakeup_lat() -* -* Returns -EINVAL for an invalid argument, -ERANGE if the constraint -* is not satisfiable, or 0 upon success. -*/ -int omap_pm_set_max_mpu_wakeup_lat (struct device *dev,long t); - - -/** -* omap_pm_set_min_bus_tput - set minimum bus throughput needed by device -* @dev: struct device * requesting the constraint -* @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT) -* @r: minimum throughput (in KiB/s) -* -* Request that the minimum data throughput on the OCP interconnect -* attached to device @dev interconnect agent @tbus_id be no less -* than @r KiB/s. -* -* It is expected that the OMAP PM or bus code will use this -* information to set the interconnect clock to run at the lowest -* possible speed that satisfies all current system users. The PM or -* bus code will adjust the estimate based on its model of the bus, so -* device driver authors should attempt to specify an accurate -* quantity for their device use case, and let the PM or bus code -* overestimate the numbers as necessary to handle request/response -* latency, other competing users on the system, etc. On OMAP2/3, if -* a driver requests a minimum L4 interconnect speed constraint, the -* code will also need to add an minimum L3 interconnect speed -* constraint, -* -* Multiple calls to omap_pm_set_min_bus_tput() will replace the -* previous rate value for this device. To remove the interconnect -* throughput restriction for this device, call with r = 0. -* -* Returns -EINVAL for an invalid argument, -ERANGE if the constraint -* is not satisfiable, or 0 upon success. -*/ -int omap_pm_set_min_bus_tput (struct device *dev,u8 agent_id,unsigned long r); - - -/* -* CPUFreq-originated constraint -* -* In the future, this should be handled by custom OPP clocktype -* functions. -*/ - - -/* -* Device context loss tracking -*/ - -/** -* omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx -* @dev: struct device * -* -* This function returns the number of times that the device @dev has -* lost its internal context. This generally occurs on a powerdomain -* transition to OFF. Drivers use this as an optimization to avoid restoring -* context if the device hasn't lost it. To use, drivers should initially -* call this in their context save functions and store the result. Early in -* the driver's context restore function, the driver should call this function -* again, and compare the result to the stored counter. If they differ, the -* driver must restore device context. If the number of context losses -* exceeds the maximum positive integer, the function will wrap to 0 and -* continue counting. Returns the number of context losses for this device, -* or negative value upon error. -*/ -int omap_pm_get_dev_context_loss_count (struct device *dev); - -void omap_pm_enable_off_mode (void ); -void omap_pm_disable_off_mode (void ); - -#endif arch/arm/mach-omap2/pdata-quirks.c +0
-15@@ -26,14 +26,12 @@#include <linux/platform_data/iommu-omap.h> #include <linux/platform_data/ti-sysc.h> #include <linux/platform_data/wkup_m3.h> -#include <linux/platform_data/media/ir-rx51.h> #include <linux/platform_data/asoc-ti-mcbsp.h> #include "common.h" #include "common-board-devices.h" #include "control.h" #include "omap_device.h" -#include "omap-pm.h" #include "omap-secure.h" #include "soc.h" #include "hsmmc.h" @@ -514,18 +512,6 @@ void omap_auxdata_legacy_init(struct device *dev) dev->platform_data = &twl_gpio_auxdata; } -static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = { - .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat, -}; - -static struct platform_device __maybe_unused rx51_ir_device = { - .name ="ir_rx51" , - .id =-1 , - .dev = { - .platform_data = &rx51_ir_data, - }, -}; -#if IS_ENABLED (CONFIG_SND_OMAP_SOC_MCBSP )static struct omap_mcbsp_platform_data mcbsp_pdata;static void __init omap3_mcbsp_init (void )@@ -569,7 +555,6 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = { "480c9000.smartreflex", &omap_sr_pdata[OMAP_SR_MPU]),OF_DEV_AUXDATA ("ti,omap3-hsmmc" ,0x4809c000 ,"4809c000.mmc" , &mmc_pdata[0 ]),OF_DEV_AUXDATA ("ti,omap3-hsmmc" ,0x480b4000 ,"480b4000.mmc" , &mmc_pdata[1 ]), -OF_DEV_AUXDATA ("nokia,n900-ir" ,0 ,"n900-ir" , &rx51_ir_data),/* Only on am3517 */ OF_DEV_AUXDATA ("ti,davinci_mdio" ,0x5c030000 ,"davinci_mdio.0" ,NULL ), OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",arch/arm/mach-omap2/pm-debug.c +0
-5@@ -31,7 +31,6 @@#include "clock.h" #include "powerdomain.h" #include "clockdomain.h" -#include "omap-pm.h" #include "soc.h" #include "cm2xxx_3xxx.h" @@ -240,10 +239,6 @@ static int option_set(void *data, u64 val) *option = val;if (option == &enable_off_mode) { -if (val) -omap_pm_enable_off_mode (); -else -omap_pm_disable_off_mode ();if (cpu_is_omap34xx ())omap3_pm_off_mode_enable (val); }arch/arm/mach-omap2/pm.c +1
-9@@ -16,11 +16,11 @@#include <linux/pm_opp.h> #include <linux/export.h> #include <linux/suspend.h> +#include <linux/clk.h> #include <linux/cpu.h> #include <asm/system_misc.h> -#include "omap-pm.h" #include "omap_device.h" #include "common.h" @@ -230,14 +230,6 @@ static void __init omap4_init_voltages(void)omap2_set_init_voltage ("iva" ,"dpll_iva_m5x2_ck" ,"iva" ); } -static int __init omap2_common_pm_init (void ) -{ -omap_pm_if_init (); - -return 0 ; -} -omap_postcore_initcall (omap2_common_pm_init); -int __init omap2_common_pm_late_init (void ) {/* Init the voltage layer */ arch/arm/mach-omap2/timer.c +0
-1@@ -50,7 +50,6 @@#include "omap_device.h" #include <plat/counter-32k.h> #include <clocksource/timer-ti-dm.h> -#include "omap-pm.h" #include "soc.h" #include "common.h" arch/arm/plat-omap/Kconfig +0
-10@@ -115,16 +115,6 @@ config OMAP_SERIAL_WAKE to data on the serial RX line. This allows you to wake the system from serial console. -choice - prompt "OMAP PM layer selection" - depends on ARCH_OMAP - default OMAP_PM_NOOP - -config OMAP_PM_NOOP - bool "No-op/debug PM layer" - -endchoice - endmenu endifdrivers/media/rc/ir-rx51.c +3
-14@@ -22,7 +22,6 @@#include <linux/hrtimer.h> #include <media/rc-core.h> -#include <linux/platform_data/media/ir-rx51.h> #define WBUF_LEN 256@@ -31,7 +30,6 @@ struct ir_rx51 {struct pwm_device *pwm;struct hrtimer timer;struct device *dev; -struct ir_rx51_platform_data *pdata;wait_queue_head_t wqueue;unsigned int freq;/* carrier frequency */ @@ -130,10 +128,9 @@ static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer, ir_rx51->wbuf[count] =-1 ;/* Insert termination mark */ /* -* Adjust latency requirements so the device doesn't go in too -* deep sleep states +* REVISIT: Adjust latency requirements so the device doesn't go in too +* deep sleep states with pm_qos_add_request(). */ - ir_rx51->pdata->set_max_mpu_wakeup_lat (ir_rx51->dev,50 );ir_rx51_on (ir_rx51); ir_rx51->wbuf_index =1 ;@@ -146,8 +143,7 @@ static int ir_rx51_tx(struct rc_dev *dev, unsigned int *buffer,*/ wait_event_interruptible (ir_rx51->wqueue, ir_rx51->wbuf_index <0 ); -/* We can sleep again */ - ir_rx51->pdata->set_max_mpu_wakeup_lat (ir_rx51->dev,-1 ); +/* REVISIT: Remove pm_qos constraint, we can sleep again */ return count; }@@ -244,13 +240,6 @@ static int ir_rx51_probe(struct platform_device *dev)struct pwm_device *pwm;struct rc_dev *rcdev; - ir_rx51.pdata = dev->dev.platform_data; - -if (!ir_rx51.pdata) { -dev_err (&dev->dev,"Platform Data is missing\n" ); -return -ENXIO ; - } - pwm =pwm_get (&dev->dev,NULL );if (IS_ERR (pwm)) {int err =PTR_ERR (pwm);include/linux/platform_data/media/ir-rx51.h deleted +0
-0
include/linux/platform_data/media/ir-rx51.h line 9
Quoted 9 lines
include/linux/platform_data/media/ir-rx51.h deleted +0
-9@@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _IR_RX51_H -#define _IR_RX51_H - -struct ir_rx51_platform_data { -int (*set_max_mpu_wakeup_lat)(struct device *dev,long t); -}; - -#endif
Thanks,
Mauro
Tony Lindgren
maintainerPATCH 2/16 ARM: OMAP2+: Allow using ti-sysc for system timers
In reply to Tony LindgrenIf a system timer is configured with an interrconnect target module in the dts, the ti,hwmods and module fck are at the interconnect target level. Then there's a separate fck for the timer child device.
If the child device has a separate functional clock, we need to configure it directly. For example, timer clk clkctrl clock bit 0 is the module clock for the interconnect target, and bit 24 being the functional clock for the timer IP.
For system timers, we already mark them as disabled. Now must also mark the interconnect target module as disabled to prevent ti-sysc to manage it instead of the system timer.
--- arch/arm/mach-omap2/timer.c | 67 ++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 15 deletions(-)
arch/arm/mach-omap2/timer.c +52 -15
@@ -167,6 +167,43 @@ static const struct of_device_id omap_timer_match[] __initconst = { { } }; +static int omap_timer_add_disabled_property (struct device_node *np) +{ +struct property *prop; + + prop =kzalloc (sizeof (*prop),GFP_KERNEL ); +if (!prop) +return -ENOMEM ; + + prop->name ="status" ; + prop->value ="disabled" ; + prop->length =strlen (prop->value); + +return of_add_property (np, prop); +} + +static int omap_timer_update_dt (struct device_node *np) +{ +int error =0 ; + +if (!of_device_is_compatible (np,"ti,omap-counter32k" )) { + error =omap_timer_add_disabled_property (np); +if (error) +return error; + } + +/* No parent interconnect target module configured? */ +if (of_get_property (np,"ti,hwmods" ,NULL )) +return error; + +/* Tag parent interconnect target module disabled */ + error =omap_timer_add_disabled_property (np->parent); +if (error) +return error; + +return 0 ; +} +/** * omap_get_timer_dt - get a timer using device-tree * @match - device-tree match structure for matching a device type
@@ -182,6 +219,7 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id * const char *property) {struct device_node *np; +int error;for_each_matching_node (np, match) {if (!of_device_is_available (np))
@@ -196,17 +234,9 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id * of_get_property(np, "ti,timer-secure", NULL))) continue; -if (!of_device_is_compatible (np,"ti,omap-counter32k" )) { -struct property *prop; + error =omap_timer_update_dt (np); +WARN (error,"%s: Could not update dt: %i\n" , __func__, error); - prop =kzalloc (sizeof (*prop),GFP_KERNEL ); -if (!prop) -return NULL ; - prop->name ="status" ; - prop->value ="disabled" ; - prop->length =strlen (prop->value); -of_add_property (np, prop); - }return np; }
@@ -265,8 +295,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,return -ENODEV ;of_property_read_string_index (np,"ti,hwmods" ,0 , &oh_name); -if (!oh_name) -return -ENODEV ; +if (!oh_name) { +of_property_read_string_index (np->parent,"ti,hwmods" ,0 , + &oh_name); +if (!oh_name) +return -ENODEV ; + } timer->irq =irq_of_parse_and_map (np,0 );if (!timer->irq)
@@ -418,9 +452,12 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)if (!np)return -ENODEV ; -of_property_read_string_index (np,"ti,hwmods" ,0 , &oh_name); -if (!oh_name) -return -ENODEV ; +of_property_read_string_index (np->parent,"ti,hwmods" ,0 , &oh_name); +if (!oh_name) { +of_property_read_string_index (np,"ti,hwmods" ,0 , &oh_name); +if (!oh_name) +return -ENODEV ; + }/* * First check hwmod data is available for sync32k counter
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 3/16 ARM: OMAP2+: Use signed value for sysc register offsets
In reply to Tony LindgrenWe currently don't know if a revision register exists or not. Zero is often a valid offset for the revision register. As we are still checking device tree data against platform data, we will get bogus warnings with correct device tree data because of incomplete platform data.
Let's fix the issue by using signed offsets and tag the revision registers that don't exist with -ENODEV, and init the missing ones with the correct revision register offset.
--- arch/arm/mach-omap2/omap_hwmod.c | 21 ++++++++++--------- arch/arm/mach-omap2/omap_hwmod.h | 6 +++--- .../omap_hwmod_33xx_43xx_ipblock_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 4 ++++ arch/arm/mach-omap2/omap_hwmod_43xx_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 4 ++++ arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 3 +++ arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 6 ++++++ arch/arm/mach-omap2/omap_hwmod_81xx_data.c | 1 + 9 files changed, 34 insertions(+), 13 deletions(-)
arch/arm/mach-omap2/omap_hwmod.c +11 -10
@@ -481,7 +481,7 @@ static int _wait_softreset_complete(struct omap_hwmod *oh) sysc = oh->class->sysc; -if (sysc->sysc_flags &SYSS_HAS_RESET_STATUS ) +if (sysc->sysc_flags &SYSS_HAS_RESET_STATUS && sysc->syss_offs >0 )omap_test_timeout ((omap_hwmod_read (oh, sysc->syss_offs) &SYSS_RESETDONE_MASK ),MAX_MODULE_SOFTRESET_WAIT , c);
@@ -3171,19 +3171,19 @@ static int omap_hwmod_init_regbits(struct device *dev,*/ int omap_hwmod_init_reg_offs (struct device *dev,const struct ti_sysc_module_data *data, -u32 *rev_offs,u32 *sysc_offs,u32 *syss_offs) +s32 *rev_offs,s32 *sysc_offs,s32 *syss_offs) { - *rev_offs =0 ; + *rev_offs = -ENODEV ; *sysc_offs =0 ; *syss_offs =0 ; -if (data->offsets[SYSC_REVISION ] >0 ) +if (data->offsets[SYSC_REVISION ] >=0 ) *rev_offs = data->offsets[SYSC_REVISION ]; -if (data->offsets[SYSC_SYSCONFIG ] >0 ) +if (data->offsets[SYSC_SYSCONFIG ] >=0 ) *sysc_offs = data->offsets[SYSC_SYSCONFIG ]; -if (data->offsets[SYSC_SYSSTATUS ] >0 ) +if (data->offsets[SYSC_SYSSTATUS ] >=0 ) *syss_offs = data->offsets[SYSC_SYSSTATUS ];return 0 ;
@@ -3312,8 +3312,8 @@ static int omap_hwmod_check_module(struct device *dev,struct omap_hwmod *oh, const struct ti_sysc_module_data *data, struct sysc_regbits *sysc_fields, - u32 rev_offs, u32 sysc_offs, - u32 syss_offs, u32 sysc_flags, + s32 rev_offs, s32 sysc_offs, + s32 syss_offs, u32 sysc_flags, u32 idlemodes) { if (!oh->class->sysc)
@@ -3365,7 +3365,7 @@ static int omap_hwmod_check_module(struct device *dev,int omap_hwmod_allocate_module (struct device *dev,struct omap_hwmod *oh,const struct ti_sysc_module_data *data,struct sysc_regbits *sysc_fields, -u32 rev_offs,u32 sysc_offs,u32 syss_offs, +s32 rev_offs,s32 sysc_offs,s32 syss_offs,u32 sysc_flags,u32 idlemodes) {struct omap_hwmod_class_sysconfig *sysc;
@@ -3425,7 +3425,8 @@ int omap_hwmod_init_module(struct device *dev, {struct omap_hwmod *oh;struct sysc_regbits *sysc_fields; -u32 rev_offs, sysc_offs, syss_offs, sysc_flags, idlemodes; +s32 rev_offs, sysc_offs, syss_offs; +u32 sysc_flags, idlemodes;int error;if (!dev || !data)
arch/arm/mach-omap2/omap_hwmod.h +3 -3
@@ -317,9 +317,9 @@ struct omap_hwmod_ocp_if {* then this field has to be populated with the correct offset structure. */ struct omap_hwmod_class_sysconfig { -u32 rev_offs; -u32 sysc_offs; -u32 syss_offs; +s32 rev_offs; +s32 sysc_offs; +s32 syss_offs;u16 sysc_flags;struct sysc_regbits *sysc_fields;u8 srst_udelay;
arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +1 -0
@@ -629,6 +629,7 @@ struct omap_hwmod am33xx_gpmc_hwmod = {/* 'i2c' class */ static struct omap_hwmod_class_sysconfig am33xx_i2c_sysc = { + .rev_offs =0 , .sysc_offs =0x0010 , .syss_offs =0x0090 , .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +4 -0
@@ -885,6 +885,7 @@ static struct omap_hwmod omap3xxx_dma_system_hwmod = {*/ static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = { + .rev_offs = -ENODEV , .sysc_offs =0x008c , .sysc_flags = (SYSC_HAS_CLOCKACTIVITY |SYSC_HAS_ENAWAKEUP |SYSC_HAS_SIDLEMODE |SYSC_HAS_SOFTRESET ),
@@ -990,6 +991,7 @@ static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {/* 'mcbsp sidetone' class */ static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sidetone_sysc = { + .rev_offs = -ENODEV , .sysc_offs =0x0010 , .sysc_flags =SYSC_HAS_AUTOIDLE , .sysc_fields = &omap_hwmod_sysc_type1,
@@ -1018,6 +1020,7 @@ static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = {/* SR common */ static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = { + .rev_offs = -ENODEV , .sysc_offs =0x24 , .sysc_flags = (SYSC_HAS_CLOCKACTIVITY |SYSC_NO_CACHE ), .sysc_fields = &omap34xx_sr_sysc_fields,
@@ -1030,6 +1033,7 @@ static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = { };static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = { + .rev_offs = -ENODEV , .sysc_offs =0x38 , .idlemodes = (SIDLE_FORCE |SIDLE_NO |SIDLE_SMART ), .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
arch/arm/mach-omap2/omap_hwmod_43xx_data.c +1 -0
@@ -378,6 +378,7 @@ static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = { };static struct omap_hwmod_class_sysconfig am43xx_qspi_sysc = { + .rev_offs =0 , .sysc_offs =0x0010 , .sysc_flags =SYSC_HAS_SIDLEMODE , .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
arch/arm/mach-omap2/omap_hwmod_44xx_data.c +4 -0
@@ -1360,6 +1360,7 @@ static struct omap_hwmod omap44xx_hsi_hwmod = {*/ static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = { + .rev_offs =0 , .sysc_offs =0x0010 , .syss_offs =0x0090 , .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
@@ -1634,6 +1635,7 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = {/* The IP is not compliant to type1 / type2 scheme */ static struct omap_hwmod_class_sysconfig omap44xx_mcasp_sysc = { + .rev_offs =0 , .sysc_offs =0x0004 , .sysc_flags =SYSC_HAS_SIDLEMODE , .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
@@ -1667,6 +1669,7 @@ static struct omap_hwmod omap44xx_mcasp_hwmod = {*/ static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = { + .rev_offs = -ENODEV , .sysc_offs =0x008c , .sysc_flags = (SYSC_HAS_CLOCKACTIVITY |SYSC_HAS_ENAWAKEUP |SYSC_HAS_SIDLEMODE |SYSC_HAS_SOFTRESET ),
@@ -2353,6 +2356,7 @@ static struct omap_hwmod omap44xx_slimbus2_hwmod = {/* The IP is not compliant to type1 / type2 scheme */ static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = { + .rev_offs = -ENODEV , .sysc_offs =0x0038 , .sysc_flags = (SYSC_HAS_ENAWAKEUP |SYSC_HAS_SIDLEMODE ), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
arch/arm/mach-omap2/omap_hwmod_54xx_data.c +3 -0
@@ -804,6 +804,7 @@ static struct omap_hwmod omap54xx_gpio8_hwmod = {*/ static struct omap_hwmod_class_sysconfig omap54xx_i2c_sysc = { + .rev_offs =0 , .sysc_offs =0x0010 , .syss_offs =0x0090 , .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
@@ -974,6 +975,7 @@ static struct omap_hwmod omap54xx_mailbox_hwmod = {*/ static struct omap_hwmod_class_sysconfig omap54xx_mcbsp_sysc = { + .rev_offs = -ENODEV , .sysc_offs =0x008c , .sysc_flags = (SYSC_HAS_CLOCKACTIVITY |SYSC_HAS_ENAWAKEUP |SYSC_HAS_SIDLEMODE |SYSC_HAS_SOFTRESET ),
@@ -1997,6 +1999,7 @@ static struct omap_hwmod omap54xx_ocp2scp3_hwmod = {*/ static struct omap_hwmod_class_sysconfig omap54xx_sata_sysc = { + .rev_offs =0x00fc , .sysc_offs =0x0000 , .sysc_flags = (SYSC_HAS_MIDLEMODE |SYSC_HAS_SIDLEMODE ), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
arch/arm/mach-omap2/omap_hwmod_7xx_data.c +6 -0
@@ -1070,6 +1070,7 @@ static struct omap_hwmod dra7xx_hdq1w_hwmod = {*/ static struct omap_hwmod_class_sysconfig dra7xx_i2c_sysc = { + .rev_offs =0 , .sysc_offs =0x0010 , .syss_offs =0x0090 , .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
@@ -1440,6 +1441,7 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = {* */ static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = { + .rev_offs =0 , .sysc_offs =0x0004 , .sysc_flags =SYSC_HAS_SIDLEMODE , .idlemodes = (SIDLE_FORCE |SIDLE_NO |SIDLE_SMART ),
@@ -1898,6 +1900,7 @@ static struct omap_hwmod dra7xx_pciess2_hwmod = {*/ static struct omap_hwmod_class_sysconfig dra7xx_qspi_sysc = { + .rev_offs =0 , .sysc_offs =0x0010 , .sysc_flags =SYSC_HAS_SIDLEMODE , .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
@@ -1930,6 +1933,7 @@ static struct omap_hwmod dra7xx_qspi_hwmod = {* */ static struct omap_hwmod_class_sysconfig dra7xx_rtcss_sysc = { + .rev_offs =0x0074 , .sysc_offs =0x0078 , .sysc_flags =SYSC_HAS_SIDLEMODE , .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
@@ -1965,6 +1969,7 @@ static struct omap_hwmod dra7xx_rtcss_hwmod = {*/ static struct omap_hwmod_class_sysconfig dra7xx_sata_sysc = { + .rev_offs =0x00fc , .sysc_offs =0x0000 , .sysc_flags = (SYSC_HAS_MIDLEMODE |SYSC_HAS_SIDLEMODE ), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
@@ -2003,6 +2008,7 @@ static struct omap_hwmod dra7xx_sata_hwmod = {/* The IP is not compliant to type1 / type2 scheme */ static struct omap_hwmod_class_sysconfig dra7xx_smartreflex_sysc = { + .rev_offs = -ENODEV , .sysc_offs =0x0038 , .sysc_flags = (SYSC_HAS_ENAWAKEUP |SYSC_HAS_SIDLEMODE ), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
arch/arm/mach-omap2/omap_hwmod_81xx_data.c +1 -0
@@ -954,6 +954,7 @@ static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = { };static struct omap_hwmod_class_sysconfig dm81xx_sata_sysc = { + .rev_offs =0x00fc , .sysc_offs =0x1100 , .sysc_flags =SYSC_HAS_SIDLEMODE , .idlemodes =SIDLE_FORCE ,
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 4/16 ARM: OMAP2+: Only probe SDMA via ti-sysc if configured in dts
In reply to Tony LindgrenWe still have some SDMA probing using omap_device_build() for the arch/arm/plat-omap/dma.c part that the dmaengine driver then uses.
So we still need to ensure that omap_device_build() works even if we probe and manage the dmaengine driver via ti-sysc. And we don't want to call dev_pm_domain_set() as otherwise we'd also have omap_device try to manage the hardware in addition to ti-sysc.
--- arch/arm/mach-omap2/omap_device.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
arch/arm/mach-omap2/omap_device.c +15 -7
@@ -143,7 +143,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)struct resource res;const char *oh_name;int oh_cnt, i, ret =0 ; -bool device_active = false; +bool device_active = false, skip_pm_domain = false; oh_cnt =of_property_count_strings (node,"ti,hwmods" );if (oh_cnt <=0 ) {
@@ -151,8 +151,15 @@ static int omap_device_build_from_dt(struct platform_device *pdev)return -ENODEV ; } +/* SDMA still needs special handling for omap_device_build() */ + ret =of_property_read_string_index (node,"ti,hwmods" ,0 , &oh_name); +if (!ret && (!strncmp ("dma_system" , oh_name,10 ) || + !strncmp ("dma" , oh_name,3 ))) + skip_pm_domain = true; +/* Use ti-sysc driver instead of omap_device? */ -if (!omap_hwmod_parse_module_range (NULL , node, &res)) +if (!skip_pm_domain && + !omap_hwmod_parse_module_range (NULL , node, &res))return -ENODEV ; hwmods =kzalloc (sizeof (struct omap_hwmod *) * oh_cnt,GFP_KERNEL );
@@ -191,11 +198,12 @@ static int omap_device_build_from_dt(struct platform_device *pdev) r->name =dev_name (&pdev->dev); } -dev_pm_domain_set (&pdev->dev, &omap_device_pm_domain); - -if (device_active) { -omap_device_enable (pdev); -pm_runtime_set_active (&pdev->dev); +if (!skip_pm_domain) { +dev_pm_domain_set (&pdev->dev, &omap_device_pm_domain); +if (device_active) { +omap_device_enable (pdev); +pm_runtime_set_active (&pdev->dev); + } } odbfd_exit1:
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 5/16 ARM: OMAP2+: Initialize SoC PM later
In reply to Tony LindgrenThere's no need to probe devices until at module_init time and we currently have at least PM trying to use I2C for PMICs early on.
As only a part of the SoC init_early is SoC specific, we only need to call the SoC specific PM init function. And we can modify omap2_common_pm_late_init() so it becomes a late_initcall().
Note that this changes am335x to call omap2_clk_enable_autoidle_all() that seems to be missing currently.
--- arch/arm/mach-omap2/common.h | 16 ++++---- arch/arm/mach-omap2/io.c | 67 +++++-------------------------- arch/arm/mach-omap2/pm.c | 19 +++++++++ arch/arm/mach-omap2/pm33xx-core.c | 4 +- 4 files changed, 40 insertions(+), 66 deletions(-)
arch/arm/mach-omap2/common.h +9 -7
@@ -44,6 +44,9 @@#define OMAP_INTC_START NR_IRQS +extern int (*omap_pm_soc_init)(void ); +int omap_pm_nop_init (void ); +#if defined(CONFIG_PM ) && defined(CONFIG_ARCH_OMAP2 )int omap2_pm_init (void );#else
@@ -79,9 +82,12 @@ static inline int omap4_pm_init_early(void)#if defined(CONFIG_PM ) && (defined(CONFIG_SOC_AM33XX ) || \ defined(CONFIG_SOC_AM43XX )) -void amx3_common_pm_init (void ); +int amx3_common_pm_init (void );#else -static inline void amx3_common_pm_init (void ) { } +static inline int amx3_common_pm_init (void ) +{ +return 0 ; +}#endif extern void omap2_init_common_infrastructure (void );
@@ -122,14 +128,10 @@ void am43xx_init_early(void);void am43xx_init_late (void );void omap4430_init_early (void );void omap5_init_early (void ); -void omap3_init_late (void );/* Do not use this one */ +void omap3_init_late (void );void omap4430_init_late (void );void omap2420_init_late (void );void omap2430_init_late (void ); -void omap3430_init_late (void ); -void omap35xx_init_late (void ); -void omap3630_init_late (void ); -void am35xx_init_late (void );void ti81xx_init_late (void );void am33xx_init_late (void );void omap5_init_late (void );
arch/arm/mach-omap2/io.c +9 -58
125 lines not on this page · raw message
arch/arm/mach-omap2/pm.c +19 -0
@@ -230,8 +230,20 @@ static void __init omap4_init_voltages(void)omap2_set_init_voltage ("iva" ,"dpll_iva_m5x2_ck" ,"iva" ); } +int __maybe_unused omap_pm_nop_init (void ) +{ +return 0 ; +} + +int (*omap_pm_soc_init)(void ); +int __init omap2_common_pm_late_init (void ) { +int error; + +if (!omap_pm_soc_init) +return 0 ; +/* Init the voltage layer */ omap3_twl_init ();omap4_twl_init ();
@@ -244,5 +256,12 @@ int __init omap2_common_pm_late_init(void)/* Smartreflex device init */ omap_devinit_smartreflex (); + error =omap_pm_soc_init (); +if (error) +pr_warn ("%s: pm soc init failed: %i\n" , __func__, error); + +omap2_clk_enable_autoidle_all (); +return 0 ; } +omap_late_initcall (omap2_common_pm_late_init);
arch/arm/mach-omap2/pm33xx-core.c +3 -1
@@ -173,7 +173,7 @@ static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)return NULL ; } -void __init amx3_common_pm_init (void ) +int __init amx3_common_pm_init (void ) {struct am33xx_pm_platform_data *pdata;struct platform_device_info devinfo;
@@ -186,4 +186,6 @@ void __init amx3_common_pm_init(void) devinfo.size_data =sizeof (*pdata); devinfo.id =-1 ;platform_device_register_full (&devinfo); + +return 0 ; }
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 6/16 ARM: OMAP2+: Make display related init into device_initcall
In reply to Tony LindgrenWe can initialize almost everything at normal module_init time with ti-sysc except for clocks and timers. To prepare for that, let's make display init into device_initcall as otherwise we'll be calling of_platform_populate() before the parent has probed.
--- arch/arm/mach-omap2/board-generic.c | 2 -- arch/arm/mach-omap2/common.h | 2 -- arch/arm/mach-omap2/display.c | 3 ++- 3 files changed, 2 insertions(+), 5 deletions(-)
arch/arm/mach-omap2/board-generic.c +0 -2
@@ -31,8 +31,6 @@ static const struct of_device_id omap_dt_match_table[] __initconst = {static void __init __maybe_unused omap_generic_init (void ) {pdata_quirks_init (omap_dt_match_table); - -omapdss_init_of ();omap_soc_device_init (); }
arch/arm/mach-omap2/common.h +0 -2
@@ -352,7 +352,5 @@ extern int omap_dss_reset(struct omap_hwmod *);/* SoC specific clock initializer */ int omap_clk_init (void ); -int __init omapdss_init_of (void ); -#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
arch/arm/mach-omap2/display.c +2 -1
@@ -385,7 +385,7 @@ static struct device_node * __init omapdss_find_dss_of_node(void)return NULL ; } -int __init omapdss_init_of (void ) +static int __init omapdss_init_of (void ) {int r;struct device_node *node;
@@ -415,3 +415,4 @@ int __init omapdss_init_of(void)return omapdss_init_fbdev (); } +omap_device_initcall (omapdss_init_of);
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 7/16 bus: ti-sysc: Handle simple-bus for nested children
In reply to Tony LindgrenOtherwise child devices that some interconnect target module devices have won't probe using simple-bus.
--- drivers/bus/ti-sysc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/bus/ti-sysc.c +7 -2
@@ -1314,6 +1314,11 @@ static void ti_sysc_idle(struct work_struct *work)pm_runtime_put_sync (ddata->dev); } +static const struct of_device_id sysc_match_table[] = { + { .compatible ="simple-bus" , }, + {/* sentinel */ }, +}; +static int sysc_probe (struct platform_device *pdev) {struct ti_sysc_platform_data *pdata =dev_get_platdata (&pdev->dev);
@@ -1375,8 +1380,8 @@ static int sysc_probe(struct platform_device *pdev)sysc_show_registers (ddata); ddata->dev->type = &sysc_device_type; - error =of_platform_populate (ddata->dev->of_node, -NULL , pdata ? pdata->auxdata :NULL , + error =of_platform_populate (ddata->dev->of_node, sysc_match_table, + pdata ? pdata->auxdata :NULL , ddata->dev);if (error) goto err;
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 8/16 bus: ti-sysc: Make child clock alias handling more generic
In reply to Tony LindgrenIn order to prepare supporting clkctrl optional clocks, we need to make the current child clock handling more generic so we can use the clock role names for the optional clocks in the following patch.
--- drivers/bus/ti-sysc.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-)
drivers/bus/ti-sysc.c +23 -13
@@ -811,29 +811,38 @@ static int sysc_init_syss_mask(struct sysc *ddata) }/* -* Many child device drivers need to have fck available to get the clock -* rate for device internal configuration. +* Many child device drivers need to have fck and opt clocks available +* to get the clock rate for device internal configuration etc. */ -static int sysc_child_add_fck (struct sysc *ddata, -struct device *child) +static int sysc_child_add_named_clock (struct sysc *ddata, +struct device *child, +const char *name) { -struct clk *fck; +struct clk *clk;struct clk_lookup *l; -const char *name = clock_names[SYSC_FCK ]; +int error =0 ; -if (IS_ERR_OR_NULL (ddata->clocks[SYSC_FCK ])) +if (!name)return 0 ; - fck =clk_get (child, name); -if (!IS_ERR (fck)) { -clk_put (fck); + clk =clk_get (child, name); +if (!IS_ERR (clk)) { +clk_put (clk);return -EEXIST ; } - l =clkdev_create (ddata->clocks[SYSC_FCK ], name,dev_name (child)); + clk =clk_get (ddata->dev, name); +if (IS_ERR (clk)) +return -ENODEV ; + + l =clkdev_create (clk, name,dev_name (child)); +if (!l) + error = -ENOMEM ; -return l ?0 : -ENODEV ; +clk_put (clk); + +return error; }static struct device_type sysc_device_type = {
@@ -983,7 +992,8 @@ static int sysc_notifier_call(struct notifier_block *nb,switch (event) {case BUS_NOTIFY_ADD_DEVICE : - error =sysc_child_add_fck (ddata, dev); + error =sysc_child_add_named_clock (ddata, dev, + clock_names[SYSC_FCK ]);if (error && error != -EEXIST )dev_warn (ddata->dev,"could not add %s fck: %i\n" ,dev_name (dev), error);
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 9/16 bus: ti-sysc: Add handling for clkctrl opt clocks
In reply to Tony LindgrenThere can be up to eight optional device functional gate gate clocks for each clkctrl instance in clkctrl register bits 8 to 15. Some of them are only needed for module level reset while others may always be needed during use. Let's add support for those and update the binding doc accordingly.
Note that the optional clkctrl mux and divider clocks starting at bit 20 can be directly mapped to the child devices, and ti-sysc does not need to manage those.
And as GPIOs need the optional clocks for reset, we can now add it with SYSC_QUIRK_OPT_CLKS_IN_RESET.
--- .../devicetree/bindings/bus/ti-sysc.txt | 6 +- drivers/bus/ti-sysc.c | 140 ++++++++++++++---- 2 files changed, 120 insertions(+), 26 deletions(-)
Documentation/devicetree/bindings/bus/ti-sysc.txt +5 -1
@@ -79,7 +79,11 @@ Optional properties: mode as for example omap4 L4_CFG_CLKCTRL - clock-names should contain at least "fck", and optionally also "ick" - depending on the SoC and the interconnect target module + depending on the SoC and the interconnect target module, + some interconnect target modules also need additional + optional clocks that can be specified as listed in TRM + for the related CLKCTRL register bits 8 to 15 such as + "dbclk" or "clk32k" depending on their role - ti,hwmods optional TI interconnect module name to use legacy hwmod platform data
drivers/bus/ti-sysc.c +115 -25
217 lines not on this page · raw message
Signature · 1 line
2.17.0
Re: [PATCH 09/16] bus: ti-sysc: Add handling for clkctrl opt clocks
Quoted 13 lines · Tony Lindgren
There can be up to eight optional device functional gate gate clocks for each clkctrl instance in clkctrl register bits 8 to 15. Some of them are only needed for module level reset while others may always be needed during use. Let's add support for those and update the binding doc accordingly.
Note that the optional clkctrl mux and divider clocks starting at bit 20 can be directly mapped to the child devices, and ti-sysc does not need to manage those.
And as GPIOs need the optional clocks for reset, we can now add it with
SYSC_QUIRK_OPT_CLKS_IN_RESET.
Quoted 7 lines
Cc Mark Rutland <[email protected]>Cc Rob Herring <[email protected]>Cc Tero Kristo <[email protected]>Cc devicetree at vger.kernel.orgSigned-off-by Tony Lindgren <[email protected]>--- .../devicetree/bindings/bus/ti-sysc.txt | 6 +-
Quoted 2 lines
drivers/bus/ti-sysc.c | 140 ++++++++++++++---- 2 files changed, 120 insertions(+), 26 deletions(-)
Tony Lindgren
maintainerPATCH 10/16 bus: ti-sysc: Tag some modules resource providers for noirq suspend
In reply to Tony LindgrenModules that provide resources for other modules need to be suspended and resumed in the noirq calls. Tag the resource providing modules.
--- drivers/bus/ti-sysc.c | 77 +++++++++++++++++++++++++++ include/linux/platform_data/ti-sysc.h | 1 + 2 files changed, 78 insertions(+)
drivers/bus/ti-sysc.c +77 -0
@@ -665,6 +665,10 @@ static int sysc_suspend(struct device *dev) ddata =dev_get_drvdata (dev); +if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER | +SYSC_QUIRK_LEGACY_IDLE )) +return 0 ; +if (!ddata->enabled)return 0 ;
@@ -678,6 +682,58 @@ static int sysc_resume(struct device *dev)struct sysc *ddata; ddata =dev_get_drvdata (dev); + +if (ddata->cfg.quirks & (SYSC_QUIRK_RESOURCE_PROVIDER | +SYSC_QUIRK_LEGACY_IDLE )) +return 0 ; + +if (ddata->needs_resume) { +dev_dbg (ddata->dev,"%s %s\n" , __func__, + ddata->name ? ddata->name :"" ); + + ddata->needs_resume = false; + +return sysc_runtime_resume (dev); + } + +return 0 ; +} + +static int sysc_noirq_suspend (struct device *dev) +{ +struct sysc *ddata; + + ddata =dev_get_drvdata (dev); + +if (ddata->cfg.quirks &SYSC_QUIRK_LEGACY_IDLE ) +return 0 ; + +if (!(ddata->cfg.quirks &SYSC_QUIRK_RESOURCE_PROVIDER )) +return 0 ; + +if (!ddata->enabled) +return 0 ; + +dev_dbg (ddata->dev,"%s %s\n" , __func__, + ddata->name ? ddata->name :"" ); + + ddata->needs_resume = true; + +return sysc_runtime_suspend (dev); +} + +static int sysc_noirq_resume (struct device *dev) +{ +struct sysc *ddata; + + ddata =dev_get_drvdata (dev); + +if (ddata->cfg.quirks &SYSC_QUIRK_LEGACY_IDLE ) +return 0 ; + +if (!(ddata->cfg.quirks &SYSC_QUIRK_RESOURCE_PROVIDER )) +return 0 ; +if (ddata->needs_resume) { ddata->needs_resume = false;
@@ -690,6 +746,7 @@ static int sysc_resume(struct device *dev)static const struct dev_pm_ops sysc_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(sysc_suspend, sysc_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sysc_noirq_suspend, sysc_noirq_resume)SET_RUNTIME_PM_OPS (sysc_runtime_suspend, sysc_runtime_resume,NULL )
@@ -721,6 +778,26 @@ struct sysc_revision_quirk { }static const struct sysc_revision_quirk sysc_revision_quirks[] = { +/* These need to use noirq_suspend */ +SYSC_QUIRK ("control" ,0 ,0 ,0x10 ,-1 ,0x40000900 ,0xffffffff , +SYSC_QUIRK_RESOURCE_PROVIDER ), +SYSC_QUIRK ("i2c" ,0 ,0 ,0x10 ,0x90 ,0x5040000a ,0xffffffff , +SYSC_QUIRK_RESOURCE_PROVIDER ), +SYSC_QUIRK ("mcspi" ,0 ,0 ,0x10 ,-1 ,0x40300a0b ,0xffffffff , +SYSC_QUIRK_RESOURCE_PROVIDER ), +SYSC_QUIRK ("prcm" ,0 ,0 ,-1 ,-1 ,0x40000100 ,0xffffffff , +SYSC_QUIRK_RESOURCE_PROVIDER ), +SYSC_QUIRK ("ocp2scp" ,0 ,0 ,0x10 ,0x14 ,0x50060005 ,0xffffffff , +SYSC_QUIRK_RESOURCE_PROVIDER ), +SYSC_QUIRK ("padconf" ,0 ,0 ,0x10 ,-1 ,0x4fff0800 ,0xffffffff , +SYSC_QUIRK_RESOURCE_PROVIDER ), +SYSC_QUIRK ("scm" ,0 ,0 ,0x10 ,-1 ,0x40000900 ,0xffffffff , +SYSC_QUIRK_RESOURCE_PROVIDER ), +SYSC_QUIRK ("scrm" ,0 ,0 ,-1 ,-1 ,0x00000010 ,0xffffffff , +SYSC_QUIRK_RESOURCE_PROVIDER ), +SYSC_QUIRK ("sdma" ,0 ,0 ,0x2c ,0x28 ,0x00010900 ,0xffffffff , +SYSC_QUIRK_RESOURCE_PROVIDER ), +/* These drivers need to be fixed to not use pm_runtime_irq_safe() */ SYSC_QUIRK ("gpio" ,0 ,0 ,0x10 ,0x114 ,0x50600801 ,0xffffffff ,SYSC_QUIRK_LEGACY_IDLE |SYSC_QUIRK_OPT_CLKS_IN_RESET ),
include/linux/platform_data/ti-sysc.h +1 -0
@@ -45,6 +45,7 @@ struct sysc_regbits {s8 emufree_shift; }; +#define SYSC_QUIRK_RESOURCE_PROVIDER BIT(9)#define SYSC_QUIRK_LEGACY_IDLE BIT(8)#define SYSC_QUIRK_RESET_STATUS BIT(7)#define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6)
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 11/16 bus: ti-sysc: Improve suspend and resume handling
In reply to Tony LindgrenBased on testing with more devices I noticed that some devices don't suspend or resume properly. We need to PM runtime suspend and resume devices if we have ddata->needs_resume set.
Let's also improve the error handling and add few debug statements to make it easier to notice suspend and resume related issues if DEBUG is set.
--- drivers/bus/ti-sysc.c | 54 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-)
drivers/bus/ti-sysc.c +48 -6
@@ -662,6 +662,7 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)static int sysc_suspend (struct device *dev) {struct sysc *ddata; +int error; ddata =dev_get_drvdata (dev);
@@ -672,14 +673,27 @@ static int sysc_suspend(struct device *dev)if (!ddata->enabled)return 0 ; +dev_dbg (ddata->dev,"%s %s\n" , __func__, + ddata->name ? ddata->name :"" ); + + error =pm_runtime_put_sync_suspend (dev); +if (error <0 ) { +dev_warn (ddata->dev,"%s not idle %i %s\n" , + __func__, error, + ddata->name ? ddata->name :"" ); + +return 0 ; + } + ddata->needs_resume = true; -return sysc_runtime_suspend (dev); +return 0 ; }static int sysc_resume (struct device *dev) {struct sysc *ddata; +int error; ddata =dev_get_drvdata (dev);
@@ -691,9 +705,16 @@ static int sysc_resume(struct device *dev)dev_dbg (ddata->dev,"%s %s\n" , __func__, ddata->name ? ddata->name :"" ); - ddata->needs_resume = false; + error =pm_runtime_get_sync (dev); +if (error <0 ) { +dev_err (ddata->dev,"%s error %i %s\n" , + __func__, error, + ddata->name ? ddata->name :"" ); -return sysc_runtime_resume (dev); +return error; + } + + ddata->needs_resume = false; }return 0 ;
@@ -735,6 +756,9 @@ static int sysc_noirq_resume(struct device *dev)return 0 ;if (ddata->needs_resume) { +dev_dbg (ddata->dev,"%s %s\n" , __func__, + ddata->name ? ddata->name :"" ); + ddata->needs_resume = false;return sysc_runtime_resume (dev);
@@ -1069,18 +1093,33 @@ static int sysc_child_suspend_noirq(struct device *dev) ddata =sysc_child_to_parent (dev); +dev_dbg (ddata->dev,"%s %s\n" , __func__, + ddata->name ? ddata->name :"" ); + error =pm_generic_suspend_noirq (dev); -if (error) +if (error) { +dev_err (dev,"%s error at %i: %i\n" , + __func__, __LINE__, error); +return error; + }if (!pm_runtime_status_suspended (dev)) { error =pm_generic_runtime_suspend (dev); -if (error) +if (error) { +dev_err (dev,"%s error at %i: %i\n" , + __func__, __LINE__, error); +return error; + } error =sysc_runtime_suspend (ddata->dev); -if (error) +if (error) { +dev_err (dev,"%s error at %i: %i\n" , + __func__, __LINE__, error); +return error; + } ddata->child_needs_resume = true; }
@@ -1095,6 +1134,9 @@ static int sysc_child_resume_noirq(struct device *dev) ddata =sysc_child_to_parent (dev); +dev_dbg (ddata->dev,"%s %s\n" , __func__, + ddata->name ? ddata->name :"" ); +if (ddata->child_needs_resume) { ddata->child_needs_resume = false;
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 12/16 bus: ti-sysc: Add initial support for external resets
In reply to Tony LindgrenSome modules need to use external resets in the rstctrl bits. Typically only one of the rstctrl bits is for the interconnect target module while the others are for various child devices.
For ti-sysc driver, we just need the module rstctrl bit mapped. The rest of the rstctrl bits can be directly mapped to the child devices.
--- drivers/bus/ti-sysc.c | 48 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)
drivers/bus/ti-sysc.c +47 -1
@@ -19,6 +19,7 @@#include <linux/platform_device.h> #include <linux/pm_domain.h> #include <linux/pm_runtime.h> +#include <linux/reset.h> #include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/slab.h>
@@ -74,6 +75,7 @@ struct sysc {struct clk **clocks;const char **clock_roles;int nr_clocks; +struct reset_control *rsts;const char *legacy_mode;const struct sysc_capabilities *cap;struct sysc_config cfg;
@@ -213,6 +215,42 @@ static int sysc_get_clocks(struct sysc *ddata)return 0 ; } +/** +* sysc_init_resets - reset module on init +* @ddata: device driver data +* +* A module can have both OCP softreset control and external rstctrl. +* If more complicated rstctrl resets are needed, please handle these +* directly from the child device driver and map only the module reset +* for the parent interconnect target module device. +* +* Automatic reset of the module on init can be skipped with the +* "ti,no-reset-on-init" device tree property. +*/ +static int sysc_init_resets (struct sysc *ddata) +{ +int error; + + ddata->rsts = +devm_reset_control_array_get_optional_exclusive (ddata->dev); +if (IS_ERR (ddata->rsts)) +return PTR_ERR (ddata->rsts); + +if (ddata->cfg.quirks &SYSC_QUIRK_NO_RESET_ON_INIT ) + goto deassert; + + error =reset_control_assert (ddata->rsts); +if (error) +return error; + +deassert: + error =reset_control_deassert (ddata->rsts); +if (error) +return error; + +return 0 ; +} +/** * sysc_parse_and_check_child_range - parses module IO region from ranges * @ddata: device driver data
@@ -889,6 +927,7 @@ static int sysc_init_module(struct sysc *ddata)return 0 ; } + ddata->revision =sysc_read_revision (ddata);pm_runtime_put_sync (ddata->dev);
@@ -1583,8 +1622,11 @@ static int sysc_probe(struct platform_device *pdev)if (error) goto unprepare; -pm_runtime_enable (ddata->dev); + error =sysc_init_resets (ddata); +if (error) +return error; +pm_runtime_enable (ddata->dev); error =sysc_init_module (ddata);if (error) goto unprepare;
@@ -1615,6 +1657,9 @@ static int sysc_probe(struct platform_device *pdev)pm_runtime_put (&pdev->dev); } +if (!of_get_available_child_count (ddata->dev->of_node)) +reset_control_assert (ddata->rsts); +return 0 ; err:
@@ -1644,6 +1689,7 @@ static int sysc_remove(struct platform_device *pdev)pm_runtime_put_sync (&pdev->dev);pm_runtime_disable (&pdev->dev); +reset_control_assert (ddata->rsts); unprepare:sysc_unprepare (ddata);
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 13/16 bus: ti-sysc: Detect omap4 type timers for quirk
In reply to Tony LindgrenStarting with omap4 some timers have different sysc registers (type2) compared to the omap2 timers (type1). We need to detect these to enable the quirk for SYSC_QUIRK_LEGACY_IDLE, otherwise these won't be idling properly.
--- drivers/bus/ti-sysc.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/bus/ti-sysc.c +3 -0
@@ -875,6 +875,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK_LEGACY_IDLE),SYSC_QUIRK ("timer" ,0 ,0 ,0x10 ,0x14 ,0x00000015 ,0xffffffff ,SYSC_QUIRK_LEGACY_IDLE ), +/* Some timers on omap4 and later */ +SYSC_QUIRK ("timer" ,0 ,0 ,0x10 ,-1 ,0x4fff1301 ,0xffffffff , +SYSC_QUIRK_LEGACY_IDLE ),SYSC_QUIRK ("uart" ,0 ,0x50 ,0x54 ,0x58 ,0x00000052 ,0xffffffff , SYSC_QUIRK_LEGACY_IDLE), };
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 14/16 bus: ti-sysc: Detect UARTs for SYSC_QUIRK_LEGACY_IDLE quirk on omap4
In reply to Tony LindgrenStarting with omap4, UARTs have different revision register that we need to detect to enable SYSC_QUIRK_LEGACY_IDLE. Otherwise UARTs won't idle properly.
--- drivers/bus/ti-sysc.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/bus/ti-sysc.c +3 -0
@@ -880,6 +880,9 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK_LEGACY_IDLE),SYSC_QUIRK ("uart" ,0 ,0x50 ,0x54 ,0x58 ,0x00000052 ,0xffffffff ,SYSC_QUIRK_LEGACY_IDLE ), +/* Uarts on omap4 and later */ +SYSC_QUIRK ("uart" ,0 ,0x50 ,0x54 ,0x58 ,0x50411e03 ,0xffffffff , + SYSC_QUIRK_LEGACY_IDLE), };static void sysc_init_revision_quirks (struct sysc *ddata)
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 15/16 bus: ti-sysc: Tag sdio and wdt with legacy mode for suspend
In reply to Tony LindgrenLooks like these two device drivers don't yet behave properly for suspend unless configured with the legacy option.
--- drivers/bus/ti-sysc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/bus/ti-sysc.c +8 -0
@@ -883,6 +883,14 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {/* Uarts on omap4 and later */ SYSC_QUIRK ("uart" ,0 ,0x50 ,0x54 ,0x58 ,0x50411e03 ,0xffffffff ,SYSC_QUIRK_LEGACY_IDLE ), + +/* These devices don't yet suspend properly without legacy setting */ +SYSC_QUIRK ("sdio" ,0 ,0 ,0x10 ,-1 ,0x40202301 ,0xffffffff , +SYSC_QUIRK_LEGACY_IDLE ), +SYSC_QUIRK ("wdt" ,0 ,0 ,0x10 ,0x14 ,0x502a0500 ,0xffffffff , +SYSC_QUIRK_LEGACY_IDLE ), +SYSC_QUIRK ("wdt" ,0 ,0 ,0x10 ,0x14 ,0x502a0d00 ,0xffffffff , + SYSC_QUIRK_LEGACY_IDLE), };static void sysc_init_revision_quirks (struct sysc *ddata)
Signature · 1 line
2.17.0
Tony Lindgren
maintainerPATCH 16/16 bus: ti-sysc: Show module information for suspend if DEBUG is enabled
In reply to Tony LindgrenLet's show module info if DEBUG is enabled to make it easier to follow what happens on the suspend and resume path.
--- drivers/bus/ti-sysc.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
drivers/bus/ti-sysc.c +18 -0
@@ -891,6 +891,24 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK_LEGACY_IDLE),SYSC_QUIRK ("wdt" ,0 ,0 ,0x10 ,0x14 ,0x502a0d00 ,0xffffffff ,SYSC_QUIRK_LEGACY_IDLE ), + +#ifdef DEBUG +SYSC_QUIRK ("aess" ,0 ,0 ,0x10 ,-1 ,0x40000000 ,0xffffffff ,0 ), +SYSC_QUIRK ("gpu" ,0 ,0x1fc00 ,0x1fc10 ,-1 ,0 ,0 ,0 ), +SYSC_QUIRK ("hdq1w" ,0 ,0 ,0x14 ,0x18 ,0x00000006 ,0xffffffff ,0 ), +SYSC_QUIRK ("hsi" ,0 ,0 ,0x10 ,0x14 ,0x50043101 ,0xffffffff ,0 ), +SYSC_QUIRK ("iss" ,0 ,0 ,0x10 ,-1 ,0x40000101 ,0xffffffff ,0 ), +SYSC_QUIRK ("mcasp" ,0 ,0 ,0x4 ,-1 ,0x44306302 ,0xffffffff ,0 ), +SYSC_QUIRK ("mcbsp" ,0 ,-1 ,0x8c ,-1 ,0 ,0 ,0 ), +SYSC_QUIRK ("mailbox" ,0 ,0 ,0x10 ,-1 ,0x00000400 ,0xffffffff ,0 ), +SYSC_QUIRK ("slimbus" ,0 ,0 ,0x10 ,-1 ,0x40000902 ,0xffffffff ,0 ), +SYSC_QUIRK ("slimbus" ,0 ,0 ,0x10 ,-1 ,0x40002903 ,0xffffffff ,0 ), +SYSC_QUIRK ("spinlock" ,0 ,0 ,0x10 ,-1 ,0x50020000 ,0xffffffff ,0 ), +SYSC_QUIRK ("usbhstll" ,0 ,0 ,0x10 ,0x14 ,0x00000004 ,0xffffffff ,0 ), +SYSC_QUIRK ("usb_host_hs" ,0 ,0 ,0x10 ,0x14 ,0x50700100 ,0xffffffff ,0 ), +SYSC_QUIRK ("usb_otg_hs" ,0 ,0x400 ,0x404 ,0x408 ,0x00000050 , + 0xffffffff, 0), +#endif };static void sysc_init_revision_quirks (struct sysc *ddata)
Signature · 1 line
2.17.0