[PATCH v7 3/9] arm: omap: Move dmtimer.h out of plat-omap

2018-01-08 Thread Keerthy
The header file is currently under plat-omap directory
under arch/omap. Move this out to an accessible place.

No Code changes done to the header file.

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/mach-omap1/pm.c   | 2 +-
 arch/arm/mach-omap1/timer.c| 2 +-
 arch/arm/mach-omap2/omap_hwmod_2420_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_2430_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c  | 2 +-
 arch/arm/mach-omap2/omap_hwmod_81xx_data.c | 2 +-
 arch/arm/mach-omap2/pdata-quirks.c | 2 +-
 arch/arm/mach-omap2/timer.c| 2 +-
 arch/arm/plat-omap/dmtimer.c   | 2 +-
 {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h | 0
 14 files changed, 13 insertions(+), 13 deletions(-)
 rename {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h 
(100%)

diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index f1135bf..a07d47cf 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -55,7 +55,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include 
 
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
index 8fb1ec6..7c057ab 100644
--- a/arch/arm/mach-omap1/timer.c
+++ b/arch/arm/mach-omap1/timer.c
@@ -27,7 +27,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 #include "soc.h"
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 0afb014..0a8b95f 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -16,7 +16,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 013b26b..16e3d8c 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -18,7 +18,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 4b094cb..8a65f70 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -11,7 +11,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #include "omap_hwmod.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 1a2f224..b030137 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -25,7 +25,7 @@
 #include "l4_3xxx.h"
 #include 
 #include 
-#include 
+#include 
 
 #include "soc.h"
 #include "omap_hwmod.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index a1901c2..51c7d62 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -30,7 +30,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 988e7ea..530334e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index 4c2a05b..2452649 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
index 84f1182..94f3bb1 100644
--- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -18,7 +18,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 

[PATCH v7 4/9] arm: OMAP: Move dmtimer driver out of plat-omap to drivers under clocksource

2018-01-08 Thread Keerthy
Move the dmtimer driver out of plat-omap to clocksource.
So that non-omap devices also could use this.

No Code changes done to the driver file only renamed to timer-dm.c.
Also removed the config dependencies for OMAP_DM_TIMER.

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/plat-omap/Kconfig | 6 --
 arch/arm/plat-omap/Makefile| 1 -
 drivers/clocksource/Kconfig| 3 +++
 drivers/clocksource/Makefile   | 1 +
 arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c | 0
 5 files changed, 4 insertions(+), 7 deletions(-)
 rename arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c (100%)

diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 7276afe..afc1a1d 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -106,12 +106,6 @@ config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
help
  PPA routine service ID for setting L2 auxiliary control register.
 
-config OMAP_DM_TIMER
-   bool "Use dual-mode timer"
-   depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
-   help
-Select this option if you want to use OMAP Dual-Mode timers.
-
 config OMAP_SERIAL_WAKE
bool "Enable wake-up events for serial ports"
depends on ARCH_OMAP1 && OMAP_MUX
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 47e1867..7215ada 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -9,5 +9,4 @@ obj-y := sram.o dma.o counter_32k.o
 
 # omap_device support (OMAP2+ only at the moment)
 
-obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index c729a88..3f799b2 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -21,6 +21,9 @@ config CLKEVT_I8253
 config I8253_LOCK
bool
 
+config OMAP_DM_TIMER
+   bool
+
 config CLKBLD_I8253
def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 72711f1..27b5497 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EM_TIMER_STI)+= em_sti.o
 obj-$(CONFIG_CLKBLD_I8253) += i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)  += mmio.o
 obj-$(CONFIG_DIGICOLOR_TIMER)  += timer-digicolor.o
+obj-$(CONFIG_OMAP_DM_TIMER)+= timer-dm.o
 obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)  += dw_apb_timer_of.o
 obj-$(CONFIG_FTTMR010_TIMER)   += timer-fttmr010.o
diff --git a/arch/arm/plat-omap/dmtimer.c b/drivers/clocksource/timer-dm.c
similarity index 100%
rename from arch/arm/plat-omap/dmtimer.c
rename to drivers/clocksource/timer-dm.c
-- 
1.9.1



Re: NFSroot regression in next with handle inode->i_version

2018-01-10 Thread Keerthy


On Wednesday 10 January 2018 02:51 AM, Tony Lindgren wrote:
> * Jeff Layton <jlay...@redhat.com> [180109 21:14]:
>> On Tue, 2018-01-09 at 13:01 -0800, Tony Lindgren wrote:
>>> Commit 4b5bd6a8e7cf ("fs: handle inode->i_version more efficiently")
>>> causes NFSroot to not boot to login in Linux next on my ARM boxes.
> 
>> Krzysztof Kozlowski reported this late last week, and I just pushed an
>> updated branch earlier this morning that should fix this. It looks like
>> the current linux-next HEAD has the fixed patchset now too. Let me know
>> if that doesn't help you.
> 
> OK great, thanks for the update. I'll test again tomorrow and will
> whine again if I'm seeing issues :)

This fixes nfs boot for me on dra7-evm.

Regards,
Keerthy

> 
> Regards,
> 
> Tony
> --
> 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 v6 08/10] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops

2018-01-08 Thread Keerthy


On Monday 08 January 2018 02:14 PM, Claudiu Beznea wrote:
> 
> 
> On 02.01.2018 12:09, Keerthy wrote:
>> Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.
>>
>> Signed-off-by: Keerthy <j-keer...@ti.com>
>> Tested-by: Ladislav Michl <la...@linux-mips.org>
>> ---
>>  drivers/pwm/pwm-omap-dmtimer.c | 39 ++-
>>  1 file changed, 22 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
>> index 5ad42f3..3b27aff 100644
>> --- a/drivers/pwm/pwm-omap-dmtimer.c
>> +++ b/drivers/pwm/pwm-omap-dmtimer.c
>> @@ -23,6 +23,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
>>  struct pwm_chip chip;
>>  struct mutex mutex;
>>  pwm_omap_dmtimer *dm_timer;
>> -struct pwm_omap_dmtimer_pdata *pdata;
>> +struct omap_dm_timer_ops *pdata;
>>  struct platform_device *dm_timer_pdev;
>>  };
>>  
>> @@ -242,19 +243,33 @@ static int pwm_omap_dmtimer_probe(struct 
>> platform_device *pdev)
>>  {
>>  struct device_node *np = pdev->dev.of_node;
>>  struct device_node *timer;
>> +struct platform_device *timer_pdev;
>>  struct pwm_omap_dmtimer_chip *omap;
>> -struct pwm_omap_dmtimer_pdata *pdata;
>> +struct dmtimer_platform_data *timer_pdata;
>> +struct omap_dm_timer_ops *pdata;
>>  pwm_omap_dmtimer *dm_timer;
>>  u32 v;
>>  int status;
>>  
>> -pdata = dev_get_platdata(>dev);
>> -if (!pdata) {
>> -dev_err(>dev, "Missing dmtimer platform data\n");
>> +timer = of_parse_phandle(np, "ti,timers", 0);
> of_node_put() should be called when done with device_node pointer returned
> by of_parse_phandle() (you may want to check the return ERROR cases below
> regarding this statement):
>> +if (!timer)
>> +return -ENODEV;
>> +
>> +timer_pdev = of_find_device_by_node(timer);
>> +if (!timer_pdev) {
>> +dev_err(>dev, "Unable to find Timer pdev\n");
> here
>> +return -ENODEV;
>> +}
>> +
>> +timer_pdata = dev_get_platdata(_pdev->dev);
>> +if (!timer_pdata) {
>> +dev_err(>dev, "dmtimer pdata structure NULL\n");
> here
>>  return -EINVAL;
>>  }
>>  
>> -if (!pdata->request_by_node ||
>> +pdata = timer_pdata->timer_ops;
>> +
>> +if (!pdata || !pdata->request_by_node ||
>>  !pdata->free ||
>>  !pdata->enable ||
>>  !pdata->disable ||
>> @@ -270,10 +285,6 @@ static int pwm_omap_dmtimer_probe(struct 
>> platform_device *pdev)
>>  return -EINVAL;
>>  }
>>  
>> -timer = of_parse_phandle(np, "ti,timers", 0);
>> -if (!timer)
>> -return -ENODEV;
>> -
>>  if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
> here
>>  dev_err(>dev, "Missing ti,timer-pwm capability\n");
>>  return -ENODEV;
>> @@ -291,13 +302,7 @@ static int pwm_omap_dmtimer_probe(struct 
>> platform_device *pdev)
>>  
>>  omap->pdata = pdata;
>>  omap->dm_timer = dm_timer;
>> -
>> -omap->dm_timer_pdev = of_find_device_by_node(timer);
>> -if (!omap->dm_timer_pdev) {
>> -dev_err(>dev, "Unable to find timer pdev\n");
>> -omap->pdata->free(dm_timer);
>> -return -EINVAL;
>> -}
>> +omap->dm_timer_pdev = timer_pdev;
>>  
>>  /*
>>   * Ensure that the timer is stopped before we allow PWM core to call
>>
> And all the other return instructions from probe function not listed by git 
> diff

Thanks for reviewing. I will add the of_node_put call for all the error
paths.

> 


Re: [PATCH v6 08/10] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops

2018-01-08 Thread Keerthy



On 1/8/2018 8:17 PM, Claudiu Beznea wrote:



On 08.01.2018 16:44, Neil Armstrong wrote:

On 08/01/2018 15:33, Keerthy wrote:



On Monday 08 January 2018 02:14 PM, Claudiu Beznea wrote:



On 02.01.2018 12:09, Keerthy wrote:

Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.

Signed-off-by: Keerthy <j-keer...@ti.com>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
  drivers/pwm/pwm-omap-dmtimer.c | 39 ++-
  1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f3..3b27aff 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -23,6 +23,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
struct pwm_chip chip;
struct mutex mutex;
pwm_omap_dmtimer *dm_timer;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct omap_dm_timer_ops *pdata;
struct platform_device *dm_timer_pdev;
  };
  
@@ -242,19 +243,33 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)

  {
struct device_node *np = pdev->dev.of_node;
struct device_node *timer;
+   struct platform_device *timer_pdev;
struct pwm_omap_dmtimer_chip *omap;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct dmtimer_platform_data *timer_pdata;
+   struct omap_dm_timer_ops *pdata;
pwm_omap_dmtimer *dm_timer;
u32 v;
int status;
  
-	pdata = dev_get_platdata(>dev);

-   if (!pdata) {
-   dev_err(>dev, "Missing dmtimer platform data\n");
+   timer = of_parse_phandle(np, "ti,timers", 0);

of_node_put() should be called when done with device_node pointer returned
by of_parse_phandle() (you may want to check the return ERROR cases below
regarding this statement):

+   if (!timer)
+   return -ENODEV;
+
+   timer_pdev = of_find_device_by_node(timer);
+   if (!timer_pdev) {
+   dev_err(>dev, "Unable to find Timer pdev\n");

here

+   return -ENODEV;
+   }
+
+   timer_pdata = dev_get_platdata(_pdev->dev);
+   if (!timer_pdata) {
+   dev_err(>dev, "dmtimer pdata structure NULL\n");

here

return -EINVAL;
}
  
-	if (!pdata->request_by_node ||

+   pdata = timer_pdata->timer_ops;
+
+   if (!pdata || !pdata->request_by_node ||
!pdata->free ||
!pdata->enable ||
!pdata->disable ||
@@ -270,10 +285,6 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
return -EINVAL;
}
  
-	timer = of_parse_phandle(np, "ti,timers", 0);

-   if (!timer)
-   return -ENODEV;
-
if (!of_get_property(timer, "ti,timer-pwm", NULL)) {

here

dev_err(>dev, "Missing ti,timer-pwm capability\n");
return -ENODEV;
@@ -291,13 +302,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
  
  	omap->pdata = pdata;

omap->dm_timer = dm_timer;
-
-   omap->dm_timer_pdev = of_find_device_by_node(timer);
-   if (!omap->dm_timer_pdev) {
-   dev_err(>dev, "Unable to find timer pdev\n");
-   omap->pdata->free(dm_timer);
-   return -EINVAL;
-   }
+   omap->dm_timer_pdev = timer_pdev;
  
  	/*

 * Ensure that the timer is stopped before we allow PWM core to call


And all the other return instructions from probe function not listed by git diff


Thanks for reviewing. I will add the of_node_put call for all the error
paths.

After that you can add: Reviwed-by: Claudiu Beznea 
<claudiu.bez...@microchip.com>






___
linux-arm-kernel mailing list
linux-arm-ker...@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



Apart the missing of_node_put() :

Acked-by: Neil Armstrong <narmstr...@baylibre.com>


Thanks Neil and Claudiu.





Re: [PATCH, v3] arm: omap2: timer: fix a kmemleak caused in omap_get_timer_dt

2018-01-12 Thread Keerthy



On 1/13/2018 2:47 AM, Grygorii Strashko wrote:



On 01/12/2018 03:08 PM, Tony Lindgren wrote:

* Grygorii Strashko  [180112 20:36]:

Hi

On 01/10/2018 10:54 PM, Qi Hou wrote:

When more than one GP timers are used as kernel system timers and the
corresponding nodes in device-tree are marked with the same "disabled"
property, then the "attr" field of the property will be initialized
more than once as the property being added to sys file system via
__of_add_property_sysfs().

In __of_add_property_sysfs(), the "name" field of pp->attr.attr is set
directly to the return value of safe_name(), without taking care of
whether it's already a valid pointer to a memory block. If it is, its
old value will always be overwritten by the new one and the memory 
block

allocated before will a "ghost", then a kmemleak happened.

That the same "disabled" property being added to different nodes of 
device

tree would cause that kind of kmemleak overhead, at leat once.

To fix it, allocate the property dynamically, and delete static one.


Does it in sync with Keerthy's work [1]


First fixes, then new stuff! Keerthy's work will have to
wait for v4.17, we want that series sitting in Linux next
for several weeks.


Np. just want to be sure every party is aware about each other's work


Thanks Grygorii. I am not touching the mach-omap2 timer.c file as part 
of my migration series.


I applied the above patch and it seems my series applies cleanly after 
this patch. Compiled fine.






Re: [PATCH v7 3/9] arm: omap: Move dmtimer.h out of plat-omap

2018-02-13 Thread Keerthy


On Tuesday 13 February 2018 08:39 PM, Tony Lindgren wrote:
> * Suman Anna <s-a...@ti.com> [180213 02:07]:
>> On 01/09/2018 12:23 AM, J, KEERTHY wrote:
>>> The header file is currently under plat-omap directory
>>> under arch/omap. Move this out to an accessible place.
>>> @@ -18,7 +18,7 @@
>>>   #include 
>>>   #include 
>>>   #include 
>>> -#include 
>>> +#include 
>>
>> These headers are actually not needed in the first-place since we no
>> longer create any non-DT timer devices. I have submitted a series to
>> cleanup the presence of this header file, as part of a larger hwmod data
>> cleanup series.
> 
> OK great. Keerthy, care to take a look? Seems like it
> simplifies things a bit.

Sure Tony. I will look into this.

> 
> Regards,
> 
> Tony
> 


Re: [PATCH v7 3/9] arm: omap: Move dmtimer.h out of plat-omap

2018-02-13 Thread Keerthy


On Tuesday 13 February 2018 07:36 AM, Suman Anna wrote:
> Hi Keerthy,
> 
> On 01/09/2018 12:23 AM, J, KEERTHY wrote:
>> The header file is currently under plat-omap directory
>> under arch/omap. Move this out to an accessible place.
>>
>> No Code changes done to the header file.
>>
>> Signed-off-by: Keerthy <j-keer...@ti.com>
>> Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
>> Tested-by: Ladislav Michl <la...@linux-mips.org>
>> ---
>>   arch/arm/mach-omap1/pm.c   | 2 +-
>>   arch/arm/mach-omap1/timer.c| 2 +-
>>   arch/arm/mach-omap2/omap_hwmod_2420_data.c | 2 +-
>>   arch/arm/mach-omap2/omap_hwmod_2430_data.c | 2 +-
>>   arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 2 +-
>>   arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 +-
>>   arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 2 +-
>>   arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 2 +-
>>   arch/arm/mach-omap2/omap_hwmod_7xx_data.c  | 2 +-
>>   arch/arm/mach-omap2/omap_hwmod_81xx_data.c | 2 +-
>>   arch/arm/mach-omap2/pdata-quirks.c | 2 +-
>>   arch/arm/mach-omap2/timer.c| 2 +-
>>   arch/arm/plat-omap/dmtimer.c   | 2 +-
>>   {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h | 0
>>   14 files changed, 13 insertions(+), 13 deletions(-)
>>   rename {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h 
>> (100%)
>>
>> diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
>> index f1135bf..a07d47cf 100644
>> --- a/arch/arm/mach-omap1/pm.c
>> +++ b/arch/arm/mach-omap1/pm.c
>> @@ -55,7 +55,7 @@
>>   #include 
>>   #include 
>>   #include 
>> -#include 
>> +#include 
>>
>>   #include 
>>
>> diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
>> index 8fb1ec6..7c057ab 100644
>> --- a/arch/arm/mach-omap1/timer.c
>> +++ b/arch/arm/mach-omap1/timer.c
>> @@ -27,7 +27,7 @@
>>   #include 
>>   #include 
>>
>> -#include 
>> +#include 
>>
>>   #include "soc.h"
>>
>> diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c 
>> b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
>> index 0afb014..0a8b95f 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
>> @@ -16,7 +16,7 @@
>>   #include 
>>   #include 
>>   #include 
>> -#include 
>> +#include 
>>
>>   #include "omap_hwmod.h"
>>   #include "l3_2xxx.h"
>> diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c 
>> b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
>> index 013b26b..16e3d8c 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
>> @@ -18,7 +18,7 @@
>>   #include 
>>   #include 
>>   #include 
>> -#include 
>> +#include 
> 
> These headers are actually not needed in the first-place since we no
> longer create any non-DT timer devices. I have submitted a series to
> cleanup the presence of this header file, as part of a larger hwmod data
> cleanup series.

I will rebase my series on top of your clean up series. Thanks for clean
ups.

> 
>>
>>   #include "omap_hwmod.h"
>>   #include "l3_2xxx.h"
>> diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c 
>> b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
>> index 4b094cb..8a65f70 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
>> @@ -11,7 +11,7 @@
>>
>>   #include 
>>   #include 
>> -#include 
>> +#include 
>>   #include 
>>
>>   #include "omap_hwmod.h"
>> diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
>> b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
>> index 1a2f224..b030137 100644
>> --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
>> +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
>> @@ -25,7 +25,7 @@
>>   #include "l4_3xxx.h"
>>   #include 
>>   #include 
>> -#include 
>> +#include 
>>
>>   #include "soc.h"
>>   #include "omap_hwm

Re: [PATCH v7 4/9] arm: OMAP: Move dmtimer driver out of plat-omap to drivers under clocksource

2018-02-13 Thread Keerthy


On Tuesday 13 February 2018 07:54 AM, Suman Anna wrote:
> Hi Keerthy,
> 
> On 01/09/2018 12:23 AM, J, KEERTHY wrote:
>> Move the dmtimer driver out of plat-omap to clocksource.
>> So that non-omap devices also could use this.
> 
> What non-omap devices do you have in mind? I don't think this driver is
> ready for that yet. It still has a lot of OMAP dependencies. So you
> should defer this for later along with the rest of the cleanup and when
> the driver is ready for that.

I mean non-omap TI devices. Not totally generic one.

> 
>>
>> No Code changes done to the driver file only renamed to timer-dm.c.
>> Also removed the config dependencies for OMAP_DM_TIMER.
>>
>> Signed-off-by: Keerthy <j-keer...@ti.com>
>> Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
>> Tested-by: Ladislav Michl <la...@linux-mips.org>
>> ---
>>   arch/arm/plat-omap/Kconfig | 6 --
>>   arch/arm/plat-omap/Makefile| 1 -
>>   drivers/clocksource/Kconfig| 3 +++
>>   drivers/clocksource/Makefile   | 1 +
>>   arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c | 0
>>   5 files changed, 4 insertions(+), 7 deletions(-)
>>   rename arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c 
>> (100%)
>>
>> diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
>> index 7276afe..afc1a1d 100644
>> --- a/arch/arm/plat-omap/Kconfig
>> +++ b/arch/arm/plat-omap/Kconfig
>> @@ -106,12 +106,6 @@ config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
>>   help
>> PPA routine service ID for setting L2 auxiliary control register.
>>
>> -config OMAP_DM_TIMER
>> -   bool "Use dual-mode timer"
>> -   depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
>> -   help
>> -Select this option if you want to use OMAP Dual-Mode timers.
>> -
>>   config OMAP_SERIAL_WAKE
>>   bool "Enable wake-up events for serial ports"
>>   depends on ARCH_OMAP1 && OMAP_MUX
>> diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
>> index 47e1867..7215ada 100644
>> --- a/arch/arm/plat-omap/Makefile
>> +++ b/arch/arm/plat-omap/Makefile
>> @@ -9,5 +9,4 @@ obj-y := sram.o dma.o counter_32k.o
>>
>>   # omap_device support (OMAP2+ only at the moment)
>>
>> -obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
>>   obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
>> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
>> index c729a88..3f799b2 100644
>> --- a/drivers/clocksource/Kconfig
>> +++ b/drivers/clocksource/Kconfig
>> @@ -21,6 +21,9 @@ config CLKEVT_I8253
>>   config I8253_LOCK
>>   bool
>>
>> +config OMAP_DM_TIMER
>> +   bool
>> +
>>   config CLKBLD_I8253
>>   def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK
>>
>> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
>> index 72711f1..27b5497 100644
>> --- a/drivers/clocksource/Makefile
>> +++ b/drivers/clocksource/Makefile
>> @@ -16,6 +16,7 @@ obj-$(CONFIG_EM_TIMER_STI)+= em_sti.o
>>   obj-$(CONFIG_CLKBLD_I8253)  += i8253.o
>>   obj-$(CONFIG_CLKSRC_MMIO)   += mmio.o
>>   obj-$(CONFIG_DIGICOLOR_TIMER)   += timer-digicolor.o
>> +obj-$(CONFIG_OMAP_DM_TIMER)+= timer-dm.o
>>   obj-$(CONFIG_DW_APB_TIMER)  += dw_apb_timer.o
>>   obj-$(CONFIG_DW_APB_TIMER_OF)   += dw_apb_timer_of.o
>>   obj-$(CONFIG_FTTMR010_TIMER)+= timer-fttmr010.o
>> diff --git a/arch/arm/plat-omap/dmtimer.c b/drivers/clocksource/timer-dm.c
>> similarity index 100%
>> rename from arch/arm/plat-omap/dmtimer.c
>> rename to drivers/clocksource/timer-dm.c
> 
> Similar comments as in patch 3 about the file name at the top, and the
> question about adding omap to the file name.

I will go with timer-ti-dm.c following timer-ti-32k.c
Hope that is okay.

> 
> Also, I see that omap_dm_timer_get_fclk() is only defined for
> !CONFIG_ARCH_OMAP1, but currently the function is declared in the header
> file for both OMAP1 and OMAP2. You would want to inline that for OMAP1
> in the header file (we currently get away with it because no one uses it).

Sure.

> 
> regards
> Suman
> 
>> -- 
>> 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 v7 5/9] dmtimer: Add timer ops to the platform data structure

2018-02-13 Thread Keerthy


On Tuesday 13 February 2018 08:16 AM, Suman Anna wrote:
> On 01/09/2018 12:23 AM, J, KEERTHY wrote:
>> Add timer ops to the platform data structure
>>
>> Signed-off-by: Keerthy <j-keer...@ti.com>
>> Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
>> Tested-by: Ladislav Michl <la...@linux-mips.org>
>> ---
>>   include/linux/platform_data/dmtimer-omap.h | 38 
>> ++
>>   1 file changed, 38 insertions(+)
>>
>> diff --git a/include/linux/platform_data/dmtimer-omap.h 
>> b/include/linux/platform_data/dmtimer-omap.h
>> index a19b78d..a3e1794 100644
>> --- a/include/linux/platform_data/dmtimer-omap.h
>> +++ b/include/linux/platform_data/dmtimer-omap.h
>> @@ -20,12 +20,50 @@
>>   #ifndef __PLATFORM_DATA_DMTIMER_OMAP_H__
>>   #define __PLATFORM_DATA_DMTIMER_OMAP_H__
>>
>> +struct omap_dm_timer_ops {
>> +   struct omap_dm_timer *(*request_by_node)(struct device_node *np);
>> +   struct omap_dm_timer *(*request_specific)(int timer_id);
>> +   struct omap_dm_timer *(*request)(void);
>> +
>> +   int (*free)(struct omap_dm_timer *timer);
>> +
>> +   void(*enable)(struct omap_dm_timer *timer);
>> +   void(*disable)(struct omap_dm_timer *timer);
>> +
>> +   int (*get_irq)(struct omap_dm_timer *timer);
>> +   int (*set_int_enable)(struct omap_dm_timer *timer,
>> + unsigned int value);
>> +   int (*set_int_disable)(struct omap_dm_timer *timer, u32 mask);
>> +
>> +   struct clk *(*get_fclk)(struct omap_dm_timer *timer);
>> +
>> +   int (*start)(struct omap_dm_timer *timer);
>> +   int (*stop)(struct omap_dm_timer *timer);
>> +   int (*set_source)(struct omap_dm_timer *timer, int source);
>> +
>> +   int (*set_load)(struct omap_dm_timer *timer, int autoreload,
>> +   unsigned int value);
>> +   int (*set_match)(struct omap_dm_timer *timer, int enable,
>> +unsigned int match);
>> +   int (*set_pwm)(struct omap_dm_timer *timer, int def_on,
>> +  int toggle, int trigger);
>> +   int (*set_prescaler)(struct omap_dm_timer *timer, int prescaler);
>> +
>> +   unsigned int (*read_counter)(struct omap_dm_timer *timer);
>> +   int (*write_counter)(struct omap_dm_timer *timer,
>> +unsigned int value);
>> +   unsigned int (*read_status)(struct omap_dm_timer *timer);
>> +   int (*write_status)(struct omap_dm_timer *timer,
>> +   unsigned int value);
>> +};
>> +
>>   struct dmtimer_platform_data {
>>   /* set_timer_src - Only used for OMAP1 devices */
>>   int (*set_timer_src)(struct platform_device *pdev, int source);
> Have you looked into collapsing this into the set_source() option above
> for OMAP1? Looks like the only reason the pdev is needed is for
> retrieving the pdev id, which is also stored in the omap_dm_timer structure?

I would prefer not to touch the mach-omap1 part as part of this
migration series. I will revisit this once the migration is done.

> 
>>   u32 timer_capability;
>>   u32 timer_errata;
>>   int (*get_context_loss_count)(struct device *);
>> +   struct omap_dm_timer_ops *timer_ops;
> 
> Any reason why this is not a const? We don't expect this to change right.

Yes this can be.

> 
> regards
> Suman
> 
>>   };
>>
>>   #endif /* __PLATFORM_DATA_DMTIMER_OMAP_H__ */
>> -- 
>> 1.9.1
>>
>>
>> ___
>> linux-arm-kernel mailing list
>> linux-arm-ker...@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
> 


[PATCH v11 10/10] arm: omap: pdata-quirks: Remove unused timer pdata

2018-02-14 Thread Keerthy
Remove unused timer pdata.

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/mach-omap2/pdata-quirks.c | 32 
 1 file changed, 32 deletions(-)

diff --git a/arch/arm/mach-omap2/pdata-quirks.c 
b/arch/arm/mach-omap2/pdata-quirks.c
index 2455020..e7d7fc7 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -24,10 +24,8 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
-#include 
 
 #include "common.h"
 #include "common-board-devices.h"
@@ -477,33 +475,6 @@ void omap_auxdata_legacy_init(struct device *dev)
dev->platform_data = _gpio_auxdata;
 }
 
-/* Dual mode timer PWM callbacks platdata */
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-static struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = {
-   .request_by_node = omap_dm_timer_request_by_node,
-   .request_specific = omap_dm_timer_request_specific,
-   .request = omap_dm_timer_request,
-   .set_source = omap_dm_timer_set_source,
-   .get_irq = omap_dm_timer_get_irq,
-   .set_int_enable = omap_dm_timer_set_int_enable,
-   .set_int_disable = omap_dm_timer_set_int_disable,
-   .free = omap_dm_timer_free,
-   .enable = omap_dm_timer_enable,
-   .disable = omap_dm_timer_disable,
-   .get_fclk = omap_dm_timer_get_fclk,
-   .start = omap_dm_timer_start,
-   .stop = omap_dm_timer_stop,
-   .set_load = omap_dm_timer_set_load,
-   .set_match = omap_dm_timer_set_match,
-   .set_pwm = omap_dm_timer_set_pwm,
-   .set_prescaler = omap_dm_timer_set_prescaler,
-   .read_counter = omap_dm_timer_read_counter,
-   .write_counter = omap_dm_timer_write_counter,
-   .read_status = omap_dm_timer_read_status,
-   .write_status = omap_dm_timer_write_status,
-};
-#endif
-
 static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = {
.set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
 };
@@ -572,9 +543,6 @@ static void __init omap3_mcbsp_init(void) {}
OF_DEV_AUXDATA("ti,am4372-wkup-m3", 0x44d0, "44d0.wkup_m3",
   _m3_data),
 #endif
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-   OF_DEV_AUXDATA("ti,omap-dmtimer-pwm", 0, NULL, _dmtimer_pdata),
-#endif
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
   _iommu_pdata),
-- 
1.9.1



[PATCH v11 02/10] arm: omap: timer: Wrap the inline functions under OMAP2PLUS define

2018-02-14 Thread Keerthy
Wrap the inline functions under OMAP2PLUS/OMAP1 defines.
This patch also inlines omap_dm_timer_get_fclk function
for non OMAP1 Config.

Signed-off-by: Keerthy <j-keer...@ti.com>
Tested-by: Ladislav Michl <la...@linux-mips.org>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
---
 arch/arm/plat-omap/include/plat/dmtimer.h | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h 
b/arch/arm/plat-omap/include/plat/dmtimer.h
index 8b7d8a6..831174f 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -132,7 +132,16 @@ struct omap_dm_timer {
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
 
 u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
+
+#ifndef CONFIG_ARCH_OMAP1
 struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
+#else
+static inline
+struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
+{
+   return NULL;
+}
+#endif
 
 int omap_dm_timer_trigger(struct omap_dm_timer *timer);
 int omap_dm_timer_start(struct omap_dm_timer *timer);
@@ -272,6 +281,12 @@ struct omap_dm_timer {
 #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \
(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
 
+/*
+ * The below are inlined to optimize code size for system timers. Other code
+ * should not need these at all, see
+ * include/linux/platform_data/pwm_omap_dmtimer.h
+ */
+#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2PLUS)
 static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
int posted)
 {
@@ -410,5 +425,5 @@ static inline void __omap_dm_timer_write_status(struct 
omap_dm_timer *timer,
 {
writel_relaxed(value, timer->irq_stat);
 }
-
+#endif /* CONFIG_ARCH_OMAP1 || CONFIG_ARCH_OMAP2PLUS */
 #endif /* __ASM_ARCH_DMTIMER_H */
-- 
1.9.1



[PATCH v11 00/10] omap: dmtimer: Move driver out of plat-omap

2018-02-14 Thread Keerthy
The series moves dmtimer out of plat-omap to drivers/clocksource.
The series also does a bunch of changes to pwm-omap-dmtimer code
to adapt to the driver migration and clean up plat specific
pdata-quirks and use the dmtimer platform data.

Boot tested on DRA7-EVM and AM437X-GP-EVM.
Compile tested omap1_defconfig.

This is based on top of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/tmlind/linux-omap

omap-for-v4.17/soc branch.

Changes from V10:

  * Rebased on top of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/tmlind/linux-omap
omap-for-v4.17/soc branch.

Changes from v9:

  * Fixed a typo in patch 9/10
Changes from v8:

  * Reordered Patch 9/10 a bit.
Changes from V7:

  * Introduced of_node_put in Patch 9/10

Changes from V6:

  * Fixed error checking for pwm driver patch.
  * Removed one of the fixes from Ladis as per request.

Changes from V5:

  * Added couple of fixes from Ladis for  pwm-dmtimer.

Changes from v4:

  * Made OMAP_DM_TIMER config option silent.
  * Changed the driver name to timer-dm.c

Changes from v3:

  * Reverted to v2 approach of using dev_get_platdata to fetch dmtimer ops.

Changes from V2:

  * Wrapped the inline functions in header file under OMAP2PLUS
  * Added a new of helper function to fetch plat_data from of node. 

Keerthy (9):
  clocksource: dmtimer: Remove all the exports
  arm: omap: timer: Wrap the inline functions under OMAP2PLUS define
  arm: omap: Move dmtimer.h out of plat-omap
  clocksource: timer-ti-dm: Replace architecture specific guard with
clocksource
  arm: OMAP: Move dmtimer driver out of plat-omap to drivers under
clocksource
  dmtimer: Add timer ops to the platform data structure
  clocksource: dmtimer: Populate the timer ops to the pdata
  pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops
  arm: omap: pdata-quirks: Remove unused timer pdata

Ladislav Michl (1):
  clocksource: timer-dm: Hook device platform data if not already
assigned

 arch/arm/mach-omap1/pm.c   |  2 +-
 arch/arm/mach-omap1/timer.c|  2 +-
 arch/arm/mach-omap2/pdata-quirks.c | 32 --
 arch/arm/mach-omap2/timer.c|  2 +-
 arch/arm/plat-omap/Kconfig |  6 --
 arch/arm/plat-omap/Makefile|  1 -
 drivers/clocksource/Kconfig|  3 +
 drivers/clocksource/Makefile   |  1 +
 .../dmtimer.c => drivers/clocksource/timer-ti-dm.c | 64 ++--
 drivers/pwm/pwm-omap-dmtimer.c | 68 +-
 .../dmtimer.h => include/clocksource/timer-ti-dm.h | 25 ++--
 include/linux/platform_data/dmtimer-omap.h | 38 
 12 files changed, 138 insertions(+), 106 deletions(-)
 rename arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-ti-dm.c (94%)
 rename arch/arm/plat-omap/include/plat/dmtimer.h => 
include/clocksource/timer-ti-dm.h (96%)

-- 
1.9.1



[PATCH v11 03/10] arm: omap: Move dmtimer.h out of plat-omap

2018-02-14 Thread Keerthy
The header file is currently under plat-omap directory
under arch/omap. Move this out to an accessible place.

No Code changes done to the header file and renamed to timer-ti-dm.h.

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/mach-omap1/pm.c| 2 +-
 arch/arm/mach-omap1/timer.c | 2 +-
 arch/arm/mach-omap2/pdata-quirks.c  | 2 +-
 arch/arm/mach-omap2/timer.c | 2 +-
 arch/arm/plat-omap/dmtimer.c| 2 +-
 .../include/plat/dmtimer.h => include/clocksource/timer-ti-dm.h | 0
 6 files changed, 5 insertions(+), 5 deletions(-)
 rename arch/arm/plat-omap/include/plat/dmtimer.h => 
include/clocksource/timer-ti-dm.h (100%)

diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index f1135bf..3e1de14 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -55,7 +55,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include 
 
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
index 8fb1ec6..4447210 100644
--- a/arch/arm/mach-omap1/timer.c
+++ b/arch/arm/mach-omap1/timer.c
@@ -27,7 +27,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 #include "soc.h"
 
diff --git a/arch/arm/mach-omap2/pdata-quirks.c 
b/arch/arm/mach-omap2/pdata-quirks.c
index 6b433fc..2455020 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -27,7 +27,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "common.h"
 #include "common-board-devices.h"
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index d61fbd7..4fb4dc2 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -49,7 +49,7 @@
 #include "omap_hwmod.h"
 #include "omap_device.h"
 #include 
-#include 
+#include 
 #include "omap-pm.h"
 
 #include "soc.h"
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 72565fc..1d6aff8 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -47,7 +47,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 static u32 omap_reserved_systimers;
 static LIST_HEAD(omap_timer_list);
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h 
b/include/clocksource/timer-ti-dm.h
similarity index 100%
rename from arch/arm/plat-omap/include/plat/dmtimer.h
rename to include/clocksource/timer-ti-dm.h
-- 
1.9.1



[PATCH v11 05/10] arm: OMAP: Move dmtimer driver out of plat-omap to drivers under clocksource

2018-02-14 Thread Keerthy
Move the dmtimer driver out of plat-omap to clocksource.
So that non-omap devices also could use this.

No Code changes done to the driver file only renamed to timer-ti-dm.c.
Also removed the config dependencies for OMAP_DM_TIMER.

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/plat-omap/Kconfig| 6 --
 arch/arm/plat-omap/Makefile   | 1 -
 drivers/clocksource/Kconfig   | 3 +++
 drivers/clocksource/Makefile  | 1 +
 arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-ti-dm.c | 0
 5 files changed, 4 insertions(+), 7 deletions(-)
 rename arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-ti-dm.c (100%)

diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 7276afe..afc1a1d 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -106,12 +106,6 @@ config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
help
  PPA routine service ID for setting L2 auxiliary control register.
 
-config OMAP_DM_TIMER
-   bool "Use dual-mode timer"
-   depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
-   help
-Select this option if you want to use OMAP Dual-Mode timers.
-
 config OMAP_SERIAL_WAKE
bool "Enable wake-up events for serial ports"
depends on ARCH_OMAP1 && OMAP_MUX
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 47e1867..7215ada 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -9,5 +9,4 @@ obj-y := sram.o dma.o counter_32k.o
 
 # omap_device support (OMAP2+ only at the moment)
 
-obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index b3b4ed9..5995086 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -21,6 +21,9 @@ config CLKEVT_I8253
 config I8253_LOCK
bool
 
+config OMAP_DM_TIMER
+   bool
+
 config CLKBLD_I8253
def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index d6dec44..c8c5109 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EM_TIMER_STI)+= em_sti.o
 obj-$(CONFIG_CLKBLD_I8253) += i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)  += mmio.o
 obj-$(CONFIG_DIGICOLOR_TIMER)  += timer-digicolor.o
+obj-$(CONFIG_OMAP_DM_TIMER)+= timer-ti-dm.o
 obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)  += dw_apb_timer_of.o
 obj-$(CONFIG_FTTMR010_TIMER)   += timer-fttmr010.o
diff --git a/arch/arm/plat-omap/dmtimer.c b/drivers/clocksource/timer-ti-dm.c
similarity index 100%
rename from arch/arm/plat-omap/dmtimer.c
rename to drivers/clocksource/timer-ti-dm.c
-- 
1.9.1



[PATCH v11 01/10] clocksource: dmtimer: Remove all the exports

2018-02-14 Thread Keerthy
Remove all the unwanted exports from the driver

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/plat-omap/dmtimer.c | 27 ---
 1 file changed, 27 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index d443e48..72565fc 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -302,7 +302,6 @@ struct omap_dm_timer *omap_dm_timer_request(void)
 {
return _omap_dm_timer_request(REQUEST_ANY, NULL);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request);
 
 struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
@@ -315,7 +314,6 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 
return _omap_dm_timer_request(REQUEST_BY_ID, );
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
 
 /**
  * omap_dm_timer_request_by_cap - Request a timer by capability
@@ -330,7 +328,6 @@ struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
 {
return _omap_dm_timer_request(REQUEST_BY_CAP, );
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
 
 /**
  * omap_dm_timer_request_by_node - Request a timer by device-tree node
@@ -346,7 +343,6 @@ struct omap_dm_timer *omap_dm_timer_request_by_node(struct 
device_node *np)
 
return _omap_dm_timer_request(REQUEST_BY_NODE, np);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node);
 
 int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
@@ -359,7 +355,6 @@ int omap_dm_timer_free(struct omap_dm_timer *timer)
timer->reserved = 0;
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_free);
 
 void omap_dm_timer_enable(struct omap_dm_timer *timer)
 {
@@ -379,13 +374,11 @@ void omap_dm_timer_enable(struct omap_dm_timer *timer)
}
}
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
 
 void omap_dm_timer_disable(struct omap_dm_timer *timer)
 {
pm_runtime_put_sync(>pdev->dev);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 {
@@ -393,7 +386,6 @@ int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
return timer->irq;
return -EINVAL;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
 
 #if defined(CONFIG_ARCH_OMAP1)
 #include 
@@ -429,7 +421,6 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
return inputmask;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #else
 
@@ -439,7 +430,6 @@ struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer 
*timer)
return timer->fclk;
return NULL;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
 
 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 {
@@ -447,7 +437,6 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #endif
 
@@ -461,7 +450,6 @@ int omap_dm_timer_trigger(struct omap_dm_timer *timer)
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
 
 int omap_dm_timer_start(struct omap_dm_timer *timer)
 {
@@ -482,7 +470,6 @@ int omap_dm_timer_start(struct omap_dm_timer *timer)
timer->context.tclr = l;
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_start);
 
 int omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
@@ -506,7 +493,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
omap_dm_timer_disable(timer);
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 
 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
@@ -569,7 +555,6 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, 
int source)
 
return ret;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
 int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
unsigned int load)
@@ -595,7 +580,6 @@ int omap_dm_timer_set_load(struct omap_dm_timer *timer, int 
autoreload,
omap_dm_timer_disable(timer);
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
 
 /* Optimized set_load which removes costly spin wait in timer_start */
 int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
@@ -625,7 +609,6 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer 
*timer, int autoreload,
timer->context.tcrr = load;
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
 
 int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 unsigned int match)
@@ -650,7 +633,6 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, 
int enable,
omap_dm_timer_disable(timer);
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
 
 int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
   int toggle, int trigger)
@@ -676,7 +65

[PATCH v11 09/10] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops

2018-02-14 Thread Keerthy
Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.

Signed-off-by: Keerthy <j-keer...@ti.com>
Acked-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Claudiu Beznea <claudiu.bez...@microchip.com>
---
 drivers/pwm/pwm-omap-dmtimer.c | 68 ++
 1 file changed, 42 insertions(+), 26 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f3..665da3c 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
struct pwm_chip chip;
struct mutex mutex;
pwm_omap_dmtimer *dm_timer;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   const struct omap_dm_timer_ops *pdata;
struct platform_device *dm_timer_pdev;
 };
 
@@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 {
struct device_node *np = pdev->dev.of_node;
struct device_node *timer;
+   struct platform_device *timer_pdev;
struct pwm_omap_dmtimer_chip *omap;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct dmtimer_platform_data *timer_pdata;
+   const struct omap_dm_timer_ops *pdata;
pwm_omap_dmtimer *dm_timer;
u32 v;
-   int status;
+   int ret = 0;
 
-   pdata = dev_get_platdata(>dev);
-   if (!pdata) {
-   dev_err(>dev, "Missing dmtimer platform data\n");
-   return -EINVAL;
+   timer = of_parse_phandle(np, "ti,timers", 0);
+   if (!timer)
+   return -ENODEV;
+
+   timer_pdev = of_find_device_by_node(timer);
+   if (!timer_pdev) {
+   dev_err(>dev, "Unable to find Timer pdev\n");
+   ret = -ENODEV;
+   goto put;
}
 
-   if (!pdata->request_by_node ||
+   timer_pdata = dev_get_platdata(_pdev->dev);
+   if (!timer_pdata) {
+   dev_err(>dev, "dmtimer pdata structure NULL\n");
+   ret = -EINVAL;
+   goto put;
+   }
+
+   pdata = timer_pdata->timer_ops;
+
+   if (!pdata || !pdata->request_by_node ||
!pdata->free ||
!pdata->enable ||
!pdata->disable ||
@@ -267,21 +284,26 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
!pdata->set_prescaler ||
!pdata->write_counter) {
dev_err(>dev, "Incomplete dmtimer pdata structure\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto put;
}
 
-   timer = of_parse_phandle(np, "ti,timers", 0);
-   if (!timer)
-   return -ENODEV;
-
if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
dev_err(>dev, "Missing ti,timer-pwm capability\n");
-   return -ENODEV;
+   ret = -ENODEV;
+   goto put;
}
 
dm_timer = pdata->request_by_node(timer);
-   if (!dm_timer)
-   return -EPROBE_DEFER;
+   if (!dm_timer) {
+   ret = -EPROBE_DEFER;
+   goto put;
+   }
+
+put:
+   of_node_put(timer);
+   if (ret < 0)
+   return ret;
 
omap = devm_kzalloc(>dev, sizeof(*omap), GFP_KERNEL);
if (!omap) {
@@ -291,13 +313,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 
omap->pdata = pdata;
omap->dm_timer = dm_timer;
-
-   omap->dm_timer_pdev = of_find_device_by_node(timer);
-   if (!omap->dm_timer_pdev) {
-   dev_err(>dev, "Unable to find timer pdev\n");
-   omap->pdata->free(dm_timer);
-   return -EINVAL;
-   }
+   omap->dm_timer_pdev = timer_pdev;
 
/*
 * Ensure that the timer is stopped before we allow PWM core to call
@@ -322,11 +338,11 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 
mutex_init(>mutex);
 
-   status = pwmchip_add(>chip);
-   if (status < 0) {
+   ret = pwmchip_add(>chip);
+   if (ret < 0) {
dev_err(>dev, "failed to register PWM\n");
omap->pdata->free(omap->dm_timer);
-   return status;
+   return ret;
}
 
platform_set_drvdata(pdev, omap);
-- 
1.9.1



[PATCH v11 08/10] clocksource: timer-ti-dm: Hook device platform data if not already assigned

2018-02-14 Thread Keerthy
From: Ladislav Michl <la...@linux-mips.org>

In the case of device tree boot the device platform data is usually
NULL so hook the platform data obtained from the match.
As part of un-constify the platform_data pointer.

Signed-off-by: Ladislav Michl <la...@linux-mips.org>
Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
---
 drivers/clocksource/timer-ti-dm.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/clocksource/timer-ti-dm.c 
b/drivers/clocksource/timer-ti-dm.c
index 864019d..c5a49a3 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -806,14 +806,16 @@ static int omap_dm_timer_probe(struct platform_device 
*pdev)
struct omap_dm_timer *timer;
struct resource *mem, *irq;
struct device *dev = >dev;
-   const struct of_device_id *match;
const struct dmtimer_platform_data *pdata;
int ret;
 
-   match = of_match_device(of_match_ptr(omap_timer_match), dev);
-   pdata = match ? match->data : dev->platform_data;
+   pdata = of_device_get_match_data(dev);
+   if (!pdata)
+   pdata = dev_get_platdata(dev);
+   else
+   dev->platform_data = (void *)pdata;
 
-   if (!pdata && !dev->of_node) {
+   if (!pdata) {
dev_err(dev, "%s: no platform data.\n", __func__);
return -ENODEV;
}
-- 
1.9.1



[PATCH v11 06/10] timer-ti-dm: Add timer ops to the platform data structure

2018-02-14 Thread Keerthy
Add timer ops to the platform data structure

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 include/linux/platform_data/dmtimer-omap.h | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/include/linux/platform_data/dmtimer-omap.h 
b/include/linux/platform_data/dmtimer-omap.h
index a19b78d..757a0f9 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -20,12 +20,50 @@
 #ifndef __PLATFORM_DATA_DMTIMER_OMAP_H__
 #define __PLATFORM_DATA_DMTIMER_OMAP_H__
 
+struct omap_dm_timer_ops {
+   struct omap_dm_timer *(*request_by_node)(struct device_node *np);
+   struct omap_dm_timer *(*request_specific)(int timer_id);
+   struct omap_dm_timer *(*request)(void);
+
+   int (*free)(struct omap_dm_timer *timer);
+
+   void(*enable)(struct omap_dm_timer *timer);
+   void(*disable)(struct omap_dm_timer *timer);
+
+   int (*get_irq)(struct omap_dm_timer *timer);
+   int (*set_int_enable)(struct omap_dm_timer *timer,
+ unsigned int value);
+   int (*set_int_disable)(struct omap_dm_timer *timer, u32 mask);
+
+   struct clk *(*get_fclk)(struct omap_dm_timer *timer);
+
+   int (*start)(struct omap_dm_timer *timer);
+   int (*stop)(struct omap_dm_timer *timer);
+   int (*set_source)(struct omap_dm_timer *timer, int source);
+
+   int (*set_load)(struct omap_dm_timer *timer, int autoreload,
+   unsigned int value);
+   int (*set_match)(struct omap_dm_timer *timer, int enable,
+unsigned int match);
+   int (*set_pwm)(struct omap_dm_timer *timer, int def_on,
+  int toggle, int trigger);
+   int (*set_prescaler)(struct omap_dm_timer *timer, int prescaler);
+
+   unsigned int (*read_counter)(struct omap_dm_timer *timer);
+   int (*write_counter)(struct omap_dm_timer *timer,
+unsigned int value);
+   unsigned int (*read_status)(struct omap_dm_timer *timer);
+   int (*write_status)(struct omap_dm_timer *timer,
+   unsigned int value);
+};
+
 struct dmtimer_platform_data {
/* set_timer_src - Only used for OMAP1 devices */
int (*set_timer_src)(struct platform_device *pdev, int source);
u32 timer_capability;
u32 timer_errata;
int (*get_context_loss_count)(struct device *);
+   const struct omap_dm_timer_ops *timer_ops;
 };
 
 #endif /* __PLATFORM_DATA_DMTIMER_OMAP_H__ */
-- 
1.9.1



[PATCH v11 07/10] clocksource: timer-ti-dm: Populate the timer ops to the pdata

2018-02-14 Thread Keerthy
Add the timer ops to the platform data

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 drivers/clocksource/timer-ti-dm.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/clocksource/timer-ti-dm.c 
b/drivers/clocksource/timer-ti-dm.c
index 1d6aff8..864019d 100644
--- a/drivers/clocksource/timer-ti-dm.c
+++ b/drivers/clocksource/timer-ti-dm.c
@@ -922,8 +922,33 @@ static int omap_dm_timer_remove(struct platform_device 
*pdev)
return ret;
 }
 
+const static struct omap_dm_timer_ops dmtimer_ops = {
+   .request_by_node = omap_dm_timer_request_by_node,
+   .request_specific = omap_dm_timer_request_specific,
+   .request = omap_dm_timer_request,
+   .set_source = omap_dm_timer_set_source,
+   .get_irq = omap_dm_timer_get_irq,
+   .set_int_enable = omap_dm_timer_set_int_enable,
+   .set_int_disable = omap_dm_timer_set_int_disable,
+   .free = omap_dm_timer_free,
+   .enable = omap_dm_timer_enable,
+   .disable = omap_dm_timer_disable,
+   .get_fclk = omap_dm_timer_get_fclk,
+   .start = omap_dm_timer_start,
+   .stop = omap_dm_timer_stop,
+   .set_load = omap_dm_timer_set_load,
+   .set_match = omap_dm_timer_set_match,
+   .set_pwm = omap_dm_timer_set_pwm,
+   .set_prescaler = omap_dm_timer_set_prescaler,
+   .read_counter = omap_dm_timer_read_counter,
+   .write_counter = omap_dm_timer_write_counter,
+   .read_status = omap_dm_timer_read_status,
+   .write_status = omap_dm_timer_write_status,
+};
+
 static const struct dmtimer_platform_data omap3plus_pdata = {
.timer_errata = OMAP_TIMER_ERRATA_I103_I767,
+   .timer_ops = _ops,
 };
 
 static const struct of_device_id omap_timer_match[] = {
-- 
1.9.1



[PATCH v11 04/10] clocksource: timer-ti-dm: Replace architecture

2018-02-14 Thread Keerthy
Replace architecture specific guard with clocksource guard.

Signed-off-by: Keerthy <j-keer...@ti.com>
Replace architecture specific defines with clocksource
---
 include/clocksource/timer-ti-dm.h | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/include/clocksource/timer-ti-dm.h 
b/include/clocksource/timer-ti-dm.h
index 831174f..4f31095 100644
--- a/include/clocksource/timer-ti-dm.h
+++ b/include/clocksource/timer-ti-dm.h
@@ -1,6 +1,4 @@
 /*
- * arch/arm/plat-omap/include/plat/dmtimer.h
- *
  * OMAP Dual-Mode Timers
  *
  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
@@ -36,8 +34,8 @@
 #include 
 #include 
 
-#ifndef __ASM_ARCH_DMTIMER_H
-#define __ASM_ARCH_DMTIMER_H
+#ifndef __CLOCKSOURCE_DMTIMER_H
+#define __CLOCKSOURCE_DMTIMER_H
 
 /* clock sources */
 #define OMAP_TIMER_SRC_SYS_CLK 0x00
@@ -426,4 +424,4 @@ static inline void __omap_dm_timer_write_status(struct 
omap_dm_timer *timer,
writel_relaxed(value, timer->irq_stat);
 }
 #endif /* CONFIG_ARCH_OMAP1 || CONFIG_ARCH_OMAP2PLUS */
-#endif /* __ASM_ARCH_DMTIMER_H */
+#endif /* __CLOCKSOURCE_DMTIMER_H */
-- 
1.9.1



Re: [PATCH] mfd: tps65218: Reorder tps65218_regulator_id enum

2018-02-15 Thread Keerthy


On Friday 16 February 2018 09:47 AM, Dave Gerlach wrote:
> Commit 2dc4940360d4 ("regulator: tps65218: Remove all the compatibles")
> changes the probe function of drivers/regulator/tps65218-regulator.c so
> that it iterates through all available regulators and assumes that the
> regulator IDs are sequential and match the order present in the enum
> tps65218_regulator_id. However, for some reason the much older commit
> c0ea88b890d6 ("regulator: tps65218: add support for LS3 current
> regulator") updated all arrays with LS3 at the end but added it second
> to last for the enum.
> 
> Because of this long standing mismatch in order between the
> tps65218_regulator_id enum and the regulator_desc array in the tps65218
> regulator driver, the new probe function causes the strobe values to be
> associated with the wrong regulator ID. This causes LDO1 to fail to
> suspend in tps65218_pmic_set_suspend_disable due to not having anything
> probes for its strobe value. Fix the order in the enum so the probe
> function works as the update intended.

Reviewed-by: Keerthy <j-keer...@ti.com>

> 
> Fixes: 2dc4940360d4 ("regulator: tps65218: Remove all the compatibles")
> Signed-off-by: Dave Gerlach <d-gerl...@ti.com>
> ---
>  include/linux/mfd/tps65218.h | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/mfd/tps65218.h b/include/linux/mfd/tps65218.h
> index f069c518c0ed..c204d9a79436 100644
> --- a/include/linux/mfd/tps65218.h
> +++ b/include/linux/mfd/tps65218.h
> @@ -205,10 +205,10 @@ enum tps65218_regulator_id {
>   TPS65218_DCDC_4,
>   TPS65218_DCDC_5,
>   TPS65218_DCDC_6,
> - /* LS's */
> - TPS65218_LS_3,
>   /* LDOs */
>   TPS65218_LDO_1,
> + /* LS's */
> + TPS65218_LS_3,
>  };
>  
>  #define TPS65218_MAX_REG_ID  TPS65218_LDO_1
> 


Re: [PATCH v11 04/10] clocksource: timer-ti-dm: Replace architecture

2018-02-22 Thread Keerthy


On Friday 23 February 2018 12:15 AM, Tony Lindgren wrote:
> * Ladislav Michl <la...@linux-mips.org> [180222 10:58]:
>> On Thu, Feb 15, 2018 at 11:31:45AM +0530, Keerthy wrote:
>>> Replace architecture specific guard with clocksource guard.
>>>
>>> Signed-off-by: Keerthy <j-keer...@ti.com>
>>> Replace architecture specific defines with clocksource
>>
>> This looks like a bit unussual commit log. Also, what about merging
>> it with previous patch?
> 
> I'll just remove that line locally to avoid yet another set
> of patches being posted :)

Thanks!

> 
>> Btw, I tested whole serie again on the top of today's -next and it is
>> still working fine. What is preventing these patches from being merged?

Ladis,

Thanks once again.


> 
> Well I noticed we need a fix for omap1 that I just posted.
> And patch 4/10 needs the following select for omap16xx that
> I'll fold in.
> 
> I'll push it all to omap-for-v4.17/timer and will merge into
> my for-next after some more testing. It seems any further
> patching can be done after move to drivers.

Yes that would be great.

> 
> Regards,
> 
> Tony
> 
> 8< -
> --- a/arch/arm/mach-omap1/Kconfig
> +++ b/arch/arm/mach-omap1/Kconfig
> @@ -30,6 +30,7 @@ config ARCH_OMAP16XX
>   bool "OMAP16xx Based System"
>   select ARCH_OMAP_OTG
>   select CPU_ARM926T
> + select OMAP_DM_TIMER
>  
>  config OMAP_MUX
>   bool "OMAP multiplexing support"
> 


[PATCH v6 00/10] omap: dmtimer: Move driver out of plat-omap

2018-01-02 Thread Keerthy
The series moves dmtimer out of plat-omap to drivers/clocksource.
The series also does a bunch of changes to pwm-omap-dmtimer code
to adapt to the driver migration and clean up plat specific
pdata-quirks and use the dmtimer platform data.

Boot tested on DRA7-EVM and AM437X-GP-EVM.
Compile tested omap1_defconfig.

This is based on top of linux-next branch.

This is tested on on IGEPv2 (OMAP3430 based) by Ladis.

Changes from V5:

  * Added couple of fixes from Ladis for  pwm-dmtimer.

Changes from v4:

  * Made OMAP_DM_TIMER config option silent.
  * Changed the driver name to timer-dm.c

Changes from v3:

  * Reverted to v2 approach of using dev_get_platdata to fetch dmtimer ops.

Changes from V2:

  * Wrapped the inline functions in header file under OMAP2PLUS
  * Added a new of helper function to fetch plat_data from of node. 

Keerthy (8):
  clocksource: dmtimer: Remove all the exports
  arm: omap: timer: Wrap the inline functions under OMAP2PLUS define
  arm: omap: Move dmtimer.h out of plat-omap
  arm: OMAP: Move dmtimer driver out of plat-omap to drivers under
clocksource
  dmtimer: Add timer ops to the platform data structure
  clocksource: dmtimer: Populate the timer ops to the pdata
  pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops
  arm: omap: pdata-quirks: Remove unused timer pdata

Ladislav Michl (2):
  clocksource: timer-dm: Hook device platform data if not already
assigned
  clocksource: timer-dm: Check prescaler value

 arch/arm/mach-omap1/pm.c   |  2 +-
 arch/arm/mach-omap1/timer.c|  2 +-
 arch/arm/mach-omap2/omap_hwmod_2420_data.c |  2 +-
 arch/arm/mach-omap2/omap_hwmod_2430_data.c |  2 +-
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c |  2 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |  2 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |  2 +-
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c |  2 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c  |  2 +-
 arch/arm/mach-omap2/omap_hwmod_81xx_data.c |  2 +-
 arch/arm/mach-omap2/pdata-quirks.c | 32 ---
 arch/arm/mach-omap2/timer.c|  2 +-
 arch/arm/plat-omap/Kconfig |  6 --
 arch/arm/plat-omap/Makefile|  1 -
 drivers/clocksource/Kconfig|  3 +
 drivers/clocksource/Makefile   |  1 +
 .../dmtimer.c => drivers/clocksource/timer-dm.c| 67 +++---
 drivers/pwm/pwm-omap-dmtimer.c | 39 +++--
 .../include/plat => include/clocksource}/dmtimer.h |  8 ++-
 include/linux/platform_data/dmtimer-omap.h | 38 
 20 files changed, 117 insertions(+), 100 deletions(-)
 rename arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c (94%)
 rename {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h (97%)

-- 
1.9.1



[PATCH v6 02/10] arm: omap: timer: Wrap the inline functions under OMAP2PLUS define

2018-01-02 Thread Keerthy
Wrap the inline functions under OMAP2PLUS/OMAP1 defines.

Signed-off-by: Keerthy <j-keer...@ti.com>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/plat-omap/include/plat/dmtimer.h | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h 
b/arch/arm/plat-omap/include/plat/dmtimer.h
index dd79f30..862ad62 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -276,6 +276,12 @@ struct omap_dm_timer {
 #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \
(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
 
+/*
+ * The below are inlined to optimize code size for system timers. Other code
+ * should not need these at all, see
+ * include/linux/platform_data/pwm_omap_dmtimer.h
+ */
+#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2PLUS)
 static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
int posted)
 {
@@ -414,5 +420,5 @@ static inline void __omap_dm_timer_write_status(struct 
omap_dm_timer *timer,
 {
writel_relaxed(value, timer->irq_stat);
 }
-
+#endif /* CONFIG_ARCH_OMAP1 || CONFIG_ARCH_OMAP2PLUS */
 #endif /* __ASM_ARCH_DMTIMER_H */
-- 
1.9.1



[PATCH v6 05/10] dmtimer: Add timer ops to the platform data structure

2018-01-02 Thread Keerthy
Add timer ops to the platform data structure

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 include/linux/platform_data/dmtimer-omap.h | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/include/linux/platform_data/dmtimer-omap.h 
b/include/linux/platform_data/dmtimer-omap.h
index a19b78d..a3e1794 100644
--- a/include/linux/platform_data/dmtimer-omap.h
+++ b/include/linux/platform_data/dmtimer-omap.h
@@ -20,12 +20,50 @@
 #ifndef __PLATFORM_DATA_DMTIMER_OMAP_H__
 #define __PLATFORM_DATA_DMTIMER_OMAP_H__
 
+struct omap_dm_timer_ops {
+   struct omap_dm_timer *(*request_by_node)(struct device_node *np);
+   struct omap_dm_timer *(*request_specific)(int timer_id);
+   struct omap_dm_timer *(*request)(void);
+
+   int (*free)(struct omap_dm_timer *timer);
+
+   void(*enable)(struct omap_dm_timer *timer);
+   void(*disable)(struct omap_dm_timer *timer);
+
+   int (*get_irq)(struct omap_dm_timer *timer);
+   int (*set_int_enable)(struct omap_dm_timer *timer,
+ unsigned int value);
+   int (*set_int_disable)(struct omap_dm_timer *timer, u32 mask);
+
+   struct clk *(*get_fclk)(struct omap_dm_timer *timer);
+
+   int (*start)(struct omap_dm_timer *timer);
+   int (*stop)(struct omap_dm_timer *timer);
+   int (*set_source)(struct omap_dm_timer *timer, int source);
+
+   int (*set_load)(struct omap_dm_timer *timer, int autoreload,
+   unsigned int value);
+   int (*set_match)(struct omap_dm_timer *timer, int enable,
+unsigned int match);
+   int (*set_pwm)(struct omap_dm_timer *timer, int def_on,
+  int toggle, int trigger);
+   int (*set_prescaler)(struct omap_dm_timer *timer, int prescaler);
+
+   unsigned int (*read_counter)(struct omap_dm_timer *timer);
+   int (*write_counter)(struct omap_dm_timer *timer,
+unsigned int value);
+   unsigned int (*read_status)(struct omap_dm_timer *timer);
+   int (*write_status)(struct omap_dm_timer *timer,
+   unsigned int value);
+};
+
 struct dmtimer_platform_data {
/* set_timer_src - Only used for OMAP1 devices */
int (*set_timer_src)(struct platform_device *pdev, int source);
u32 timer_capability;
u32 timer_errata;
int (*get_context_loss_count)(struct device *);
+   struct omap_dm_timer_ops *timer_ops;
 };
 
 #endif /* __PLATFORM_DATA_DMTIMER_OMAP_H__ */
-- 
1.9.1



[PATCH v6 07/10] clocksource: timer-dm: Hook device platform data if not already assigned

2018-01-02 Thread Keerthy
From: Ladislav Michl <la...@linux-mips.org>

In the case of device tree boot the device platform data is usually
NULL so hook the platform data obtained from the match.
As part of un-constify the platform_data pointer.

Signed-off-by: Ladislav Michl <la...@linux-mips.org>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 drivers/clocksource/timer-dm.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/clocksource/timer-dm.c b/drivers/clocksource/timer-dm.c
index 1cbd954..60db173 100644
--- a/drivers/clocksource/timer-dm.c
+++ b/drivers/clocksource/timer-dm.c
@@ -806,14 +806,16 @@ static int omap_dm_timer_probe(struct platform_device 
*pdev)
struct omap_dm_timer *timer;
struct resource *mem, *irq;
struct device *dev = >dev;
-   const struct of_device_id *match;
const struct dmtimer_platform_data *pdata;
int ret;
 
-   match = of_match_device(of_match_ptr(omap_timer_match), dev);
-   pdata = match ? match->data : dev->platform_data;
+   pdata = of_device_get_match_data(dev);
+   if (!pdata)
+   pdata = dev_get_platdata(dev);
+   else
+   dev->platform_data = (void *)pdata;
 
-   if (!pdata && !dev->of_node) {
+   if (!pdata) {
dev_err(dev, "%s: no platform data.\n", __func__);
return -ENODEV;
}
-- 
1.9.1



[PATCH v6 08/10] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops

2018-01-02 Thread Keerthy
Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.

Signed-off-by: Keerthy <j-keer...@ti.com>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 drivers/pwm/pwm-omap-dmtimer.c | 39 ++-
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f3..3b27aff 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
struct pwm_chip chip;
struct mutex mutex;
pwm_omap_dmtimer *dm_timer;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct omap_dm_timer_ops *pdata;
struct platform_device *dm_timer_pdev;
 };
 
@@ -242,19 +243,33 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 {
struct device_node *np = pdev->dev.of_node;
struct device_node *timer;
+   struct platform_device *timer_pdev;
struct pwm_omap_dmtimer_chip *omap;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct dmtimer_platform_data *timer_pdata;
+   struct omap_dm_timer_ops *pdata;
pwm_omap_dmtimer *dm_timer;
u32 v;
int status;
 
-   pdata = dev_get_platdata(>dev);
-   if (!pdata) {
-   dev_err(>dev, "Missing dmtimer platform data\n");
+   timer = of_parse_phandle(np, "ti,timers", 0);
+   if (!timer)
+   return -ENODEV;
+
+   timer_pdev = of_find_device_by_node(timer);
+   if (!timer_pdev) {
+   dev_err(>dev, "Unable to find Timer pdev\n");
+   return -ENODEV;
+   }
+
+   timer_pdata = dev_get_platdata(_pdev->dev);
+   if (!timer_pdata) {
+   dev_err(>dev, "dmtimer pdata structure NULL\n");
return -EINVAL;
}
 
-   if (!pdata->request_by_node ||
+   pdata = timer_pdata->timer_ops;
+
+   if (!pdata || !pdata->request_by_node ||
!pdata->free ||
!pdata->enable ||
!pdata->disable ||
@@ -270,10 +285,6 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
return -EINVAL;
}
 
-   timer = of_parse_phandle(np, "ti,timers", 0);
-   if (!timer)
-   return -ENODEV;
-
if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
dev_err(>dev, "Missing ti,timer-pwm capability\n");
return -ENODEV;
@@ -291,13 +302,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 
omap->pdata = pdata;
omap->dm_timer = dm_timer;
-
-   omap->dm_timer_pdev = of_find_device_by_node(timer);
-   if (!omap->dm_timer_pdev) {
-   dev_err(>dev, "Unable to find timer pdev\n");
-   omap->pdata->free(dm_timer);
-   return -EINVAL;
-   }
+   omap->dm_timer_pdev = timer_pdev;
 
/*
 * Ensure that the timer is stopped before we allow PWM core to call
-- 
1.9.1



[PATCH v6 09/10] arm: omap: pdata-quirks: Remove unused timer pdata

2018-01-02 Thread Keerthy
Remove unused timer pdata.

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/mach-omap2/pdata-quirks.c | 32 
 1 file changed, 32 deletions(-)

diff --git a/arch/arm/mach-omap2/pdata-quirks.c 
b/arch/arm/mach-omap2/pdata-quirks.c
index ad9df86..e7d7fc7 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -24,10 +24,8 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
-#include 
 
 #include "common.h"
 #include "common-board-devices.h"
@@ -477,33 +475,6 @@ void omap_auxdata_legacy_init(struct device *dev)
dev->platform_data = _gpio_auxdata;
 }
 
-/* Dual mode timer PWM callbacks platdata */
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-static struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = {
-   .request_by_node = omap_dm_timer_request_by_node,
-   .request_specific = omap_dm_timer_request_specific,
-   .request = omap_dm_timer_request,
-   .set_source = omap_dm_timer_set_source,
-   .get_irq = omap_dm_timer_get_irq,
-   .set_int_enable = omap_dm_timer_set_int_enable,
-   .set_int_disable = omap_dm_timer_set_int_disable,
-   .free = omap_dm_timer_free,
-   .enable = omap_dm_timer_enable,
-   .disable = omap_dm_timer_disable,
-   .get_fclk = omap_dm_timer_get_fclk,
-   .start = omap_dm_timer_start,
-   .stop = omap_dm_timer_stop,
-   .set_load = omap_dm_timer_set_load,
-   .set_match = omap_dm_timer_set_match,
-   .set_pwm = omap_dm_timer_set_pwm,
-   .set_prescaler = omap_dm_timer_set_prescaler,
-   .read_counter = omap_dm_timer_read_counter,
-   .write_counter = omap_dm_timer_write_counter,
-   .read_status = omap_dm_timer_read_status,
-   .write_status = omap_dm_timer_write_status,
-};
-#endif
-
 static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = {
.set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
 };
@@ -572,9 +543,6 @@ static void __init omap3_mcbsp_init(void) {}
OF_DEV_AUXDATA("ti,am4372-wkup-m3", 0x44d0, "44d0.wkup_m3",
   _m3_data),
 #endif
-#if IS_ENABLED(CONFIG_OMAP_DM_TIMER)
-   OF_DEV_AUXDATA("ti,omap-dmtimer-pwm", 0, NULL, _dmtimer_pdata),
-#endif
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
   _iommu_pdata),
-- 
1.9.1



[PATCH v6 04/10] arm: OMAP: Move dmtimer driver out of plat-omap to drivers under clocksource

2018-01-02 Thread Keerthy
Move the dmtimer driver out of plat-omap to clocksource.
So that non-omap devices also could use this.

No Code changes done to the driver file only renamed to timer-dm.c.
Also removed the config dependencies for OMAP_DM_TIMER.

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/plat-omap/Kconfig | 6 --
 arch/arm/plat-omap/Makefile| 1 -
 drivers/clocksource/Kconfig| 3 +++
 drivers/clocksource/Makefile   | 1 +
 arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c | 0
 5 files changed, 4 insertions(+), 7 deletions(-)
 rename arch/arm/plat-omap/dmtimer.c => drivers/clocksource/timer-dm.c (100%)

diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 7276afe..afc1a1d 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -106,12 +106,6 @@ config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID
help
  PPA routine service ID for setting L2 auxiliary control register.
 
-config OMAP_DM_TIMER
-   bool "Use dual-mode timer"
-   depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
-   help
-Select this option if you want to use OMAP Dual-Mode timers.
-
 config OMAP_SERIAL_WAKE
bool "Enable wake-up events for serial ports"
depends on ARCH_OMAP1 && OMAP_MUX
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 47e1867..7215ada 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -9,5 +9,4 @@ obj-y := sram.o dma.o counter_32k.o
 
 # omap_device support (OMAP2+ only at the moment)
 
-obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index c729a88..3f799b2 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -21,6 +21,9 @@ config CLKEVT_I8253
 config I8253_LOCK
bool
 
+config OMAP_DM_TIMER
+   bool
+
 config CLKBLD_I8253
def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 72711f1..27b5497 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EM_TIMER_STI)+= em_sti.o
 obj-$(CONFIG_CLKBLD_I8253) += i8253.o
 obj-$(CONFIG_CLKSRC_MMIO)  += mmio.o
 obj-$(CONFIG_DIGICOLOR_TIMER)  += timer-digicolor.o
+obj-$(CONFIG_OMAP_DM_TIMER)+= timer-dm.o
 obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)  += dw_apb_timer_of.o
 obj-$(CONFIG_FTTMR010_TIMER)   += timer-fttmr010.o
diff --git a/arch/arm/plat-omap/dmtimer.c b/drivers/clocksource/timer-dm.c
similarity index 100%
rename from arch/arm/plat-omap/dmtimer.c
rename to drivers/clocksource/timer-dm.c
-- 
1.9.1



[PATCH v6 01/10] clocksource: dmtimer: Remove all the exports

2018-01-02 Thread Keerthy
Remove all the unwanted exports from the driver

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/plat-omap/dmtimer.c | 27 ---
 1 file changed, 27 deletions(-)

diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index d443e48..72565fc 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -302,7 +302,6 @@ struct omap_dm_timer *omap_dm_timer_request(void)
 {
return _omap_dm_timer_request(REQUEST_ANY, NULL);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request);
 
 struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
@@ -315,7 +314,6 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 
return _omap_dm_timer_request(REQUEST_BY_ID, );
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
 
 /**
  * omap_dm_timer_request_by_cap - Request a timer by capability
@@ -330,7 +328,6 @@ struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
 {
return _omap_dm_timer_request(REQUEST_BY_CAP, );
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
 
 /**
  * omap_dm_timer_request_by_node - Request a timer by device-tree node
@@ -346,7 +343,6 @@ struct omap_dm_timer *omap_dm_timer_request_by_node(struct 
device_node *np)
 
return _omap_dm_timer_request(REQUEST_BY_NODE, np);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node);
 
 int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
@@ -359,7 +355,6 @@ int omap_dm_timer_free(struct omap_dm_timer *timer)
timer->reserved = 0;
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_free);
 
 void omap_dm_timer_enable(struct omap_dm_timer *timer)
 {
@@ -379,13 +374,11 @@ void omap_dm_timer_enable(struct omap_dm_timer *timer)
}
}
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
 
 void omap_dm_timer_disable(struct omap_dm_timer *timer)
 {
pm_runtime_put_sync(>pdev->dev);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
 
 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
 {
@@ -393,7 +386,6 @@ int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
return timer->irq;
return -EINVAL;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
 
 #if defined(CONFIG_ARCH_OMAP1)
 #include 
@@ -429,7 +421,6 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
return inputmask;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #else
 
@@ -439,7 +430,6 @@ struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer 
*timer)
return timer->fclk;
return NULL;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
 
 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 {
@@ -447,7 +437,6 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
 
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 #endif
 
@@ -461,7 +450,6 @@ int omap_dm_timer_trigger(struct omap_dm_timer *timer)
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
 
 int omap_dm_timer_start(struct omap_dm_timer *timer)
 {
@@ -482,7 +470,6 @@ int omap_dm_timer_start(struct omap_dm_timer *timer)
timer->context.tclr = l;
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_start);
 
 int omap_dm_timer_stop(struct omap_dm_timer *timer)
 {
@@ -506,7 +493,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
omap_dm_timer_disable(timer);
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 
 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
@@ -569,7 +555,6 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, 
int source)
 
return ret;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
 
 int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
unsigned int load)
@@ -595,7 +580,6 @@ int omap_dm_timer_set_load(struct omap_dm_timer *timer, int 
autoreload,
omap_dm_timer_disable(timer);
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
 
 /* Optimized set_load which removes costly spin wait in timer_start */
 int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
@@ -625,7 +609,6 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer 
*timer, int autoreload,
timer->context.tcrr = load;
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
 
 int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
 unsigned int match)
@@ -650,7 +633,6 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, 
int enable,
omap_dm_timer_disable(timer);
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
 
 int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
   int toggle, int trigger)
@@ -676,7 +65

[PATCH v6 10/10] clocksource: timer-dm: Check prescaler value

2018-01-02 Thread Keerthy
From: Ladislav Michl 

Invalid prescaler value is silently ignored. Fix that
by returning -EINVAL in such case. As invalid value
disabled use of the prescaler, use -1 explicitely for
that purpose.

Signed-off-by: Ladislav Michl 
---
 drivers/clocksource/timer-dm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clocksource/timer-dm.c b/drivers/clocksource/timer-dm.c
index 60db173..01a9cb0 100644
--- a/drivers/clocksource/timer-dm.c
+++ b/drivers/clocksource/timer-dm.c
@@ -672,6 +672,9 @@ int omap_dm_timer_set_prescaler(struct omap_dm_timer 
*timer, int prescaler)
if (prescaler >= 0x00 && prescaler <= 0x07) {
l |= OMAP_TIMER_CTRL_PRE;
l |= prescaler << 2;
+   } else {
+   if (prescaler != -1)
+   return -EINVAL;
}
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
 
-- 
1.9.1



[PATCH v6 03/10] arm: omap: Move dmtimer.h out of plat-omap

2018-01-02 Thread Keerthy
The header file is currently under plat-omap directory
under arch/omap. Move this out to an accessible place.

No Code changes done to the header file.

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 arch/arm/mach-omap1/pm.c   | 2 +-
 arch/arm/mach-omap1/timer.c| 2 +-
 arch/arm/mach-omap2/omap_hwmod_2420_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_2430_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_54xx_data.c | 2 +-
 arch/arm/mach-omap2/omap_hwmod_7xx_data.c  | 2 +-
 arch/arm/mach-omap2/omap_hwmod_81xx_data.c | 2 +-
 arch/arm/mach-omap2/pdata-quirks.c | 2 +-
 arch/arm/mach-omap2/timer.c| 2 +-
 arch/arm/plat-omap/dmtimer.c   | 2 +-
 {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h | 0
 14 files changed, 13 insertions(+), 13 deletions(-)
 rename {arch/arm/plat-omap/include/plat => include/clocksource}/dmtimer.h 
(100%)

diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index f1135bf..a07d47cf 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -55,7 +55,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include 
 
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
index 8fb1ec6..7c057ab 100644
--- a/arch/arm/mach-omap1/timer.c
+++ b/arch/arm/mach-omap1/timer.c
@@ -27,7 +27,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 #include "soc.h"
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index 1a15a34..45c1043 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -16,7 +16,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 3801850..892ca58 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -18,7 +18,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c 
b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index beec4cd..82b51c0 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -11,7 +11,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #include "omap_hwmod.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 52c9d58..310aef5 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -25,7 +25,7 @@
 #include "l4_3xxx.h"
 #include 
 #include 
-#include 
+#include 
 
 #include "soc.h"
 #include "omap_hwmod.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index c477096..22e0e38 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -30,7 +30,7 @@
 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 988e7ea..530334e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index d05e553d..adabdef 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
index 84f1182..94f3bb1 100644
--- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -18,7 +18,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 

[PATCH v6 06/10] clocksource: dmtimer: Populate the timer ops to the pdata

2018-01-02 Thread Keerthy
Add the timer ops to the platform data

Signed-off-by: Keerthy <j-keer...@ti.com>
Reviewed-by: Sebastian Reichel <sebastian.reic...@collabora.co.uk>
Tested-by: Ladislav Michl <la...@linux-mips.org>
---
 drivers/clocksource/timer-dm.c | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/clocksource/timer-dm.c b/drivers/clocksource/timer-dm.c
index afe1dc9..1cbd954 100644
--- a/drivers/clocksource/timer-dm.c
+++ b/drivers/clocksource/timer-dm.c
@@ -922,8 +922,33 @@ static int omap_dm_timer_remove(struct platform_device 
*pdev)
return ret;
 }
 
+static struct omap_dm_timer_ops dmtimer_ops = {
+   .request_by_node = omap_dm_timer_request_by_node,
+   .request_specific = omap_dm_timer_request_specific,
+   .request = omap_dm_timer_request,
+   .set_source = omap_dm_timer_set_source,
+   .get_irq = omap_dm_timer_get_irq,
+   .set_int_enable = omap_dm_timer_set_int_enable,
+   .set_int_disable = omap_dm_timer_set_int_disable,
+   .free = omap_dm_timer_free,
+   .enable = omap_dm_timer_enable,
+   .disable = omap_dm_timer_disable,
+   .get_fclk = omap_dm_timer_get_fclk,
+   .start = omap_dm_timer_start,
+   .stop = omap_dm_timer_stop,
+   .set_load = omap_dm_timer_set_load,
+   .set_match = omap_dm_timer_set_match,
+   .set_pwm = omap_dm_timer_set_pwm,
+   .set_prescaler = omap_dm_timer_set_prescaler,
+   .read_counter = omap_dm_timer_read_counter,
+   .write_counter = omap_dm_timer_write_counter,
+   .read_status = omap_dm_timer_read_status,
+   .write_status = omap_dm_timer_write_status,
+};
+
 static const struct dmtimer_platform_data omap3plus_pdata = {
.timer_errata = OMAP_TIMER_ERRATA_I103_I767,
+   .timer_ops = _ops,
 };
 
 static const struct of_device_id omap_timer_match[] = {
-- 
1.9.1



[PATCH 3/4] clk: ti: Add functions to save/restore clk context

2018-06-18 Thread Keerthy
From: Russ Dill 

SoCs like AM43XX lose clock registers context during RTC-only
suspend. Hence add functions to save/restore the clock registers
context.

Signed-off-by: Keerthy 
Signed-off-by: Russ Dill 
---
 drivers/clk/ti/clock.h|   2 +
 drivers/clk/ti/divider.c  |  36 ++
 drivers/clk/ti/dpll.c |   6 +++
 drivers/clk/ti/dpll3xxx.c | 124 ++
 drivers/clk/ti/gate.c |   3 ++
 drivers/clk/ti/mux.c  |  29 +++
 include/linux/clk/ti.h|   6 +++
 7 files changed, 206 insertions(+)

diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
index b582780..26fbdf2 100644
--- a/drivers/clk/ti/clock.h
+++ b/drivers/clk/ti/clock.h
@@ -24,6 +24,7 @@ struct clk_omap_divider {
u8  flags;
s8  latch;
const struct clk_div_table  *table;
+   u32 context;
 };
 
 #define to_clk_omap_divider(_hw) container_of(_hw, struct clk_omap_divider, hw)
@@ -36,6 +37,7 @@ struct clk_omap_mux {
u8  shift;
s8  latch;
u8  flags;
+   u8  saved_parent;
 };
 
 #define to_clk_omap_mux(_hw) container_of(_hw, struct clk_omap_mux, hw)
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index aaa277d..4418e0d 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -268,10 +268,46 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, 
unsigned long rate,
return 0;
 }
 
+/**
+ * clk_divider_save_context - Save the divider value
+ * @hw: pointer  struct clk_hw
+ *
+ * Save the divider value
+ */
+static int clk_divider_save_context(struct clk_hw *hw)
+{
+   struct clk_omap_divider *divider = to_clk_omap_divider(hw);
+   u32 val;
+
+   val = ti_clk_ll_ops->clk_readl(>reg) >> divider->shift;
+   divider->context = val & div_mask(divider);
+
+   return 0;
+}
+
+/**
+ * clk_divider_restore_context - restore the saved the divider value
+ * @hw: pointer  struct clk_hw
+ *
+ * Restore the saved the divider value
+ */
+static void clk_divider_restore_context(struct clk_hw *hw)
+{
+   struct clk_omap_divider *divider = to_clk_omap_divider(hw);
+   u32 val;
+
+   val = ti_clk_ll_ops->clk_readl(>reg);
+   val &= ~(div_mask(divider) << divider->shift);
+   val |= divider->context << divider->shift;
+   ti_clk_ll_ops->clk_writel(val, >reg);
+}
+
 const struct clk_ops ti_clk_divider_ops = {
.recalc_rate = ti_clk_divider_recalc_rate,
.round_rate = ti_clk_divider_round_rate,
.set_rate = ti_clk_divider_set_rate,
+   .save_context = clk_divider_save_context,
+   .restore_context = clk_divider_restore_context,
 };
 
 static struct clk *_register_divider(struct device *dev, const char *name,
diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
index 7d33ca9..b1c4d8a 100644
--- a/drivers/clk/ti/dpll.c
+++ b/drivers/clk/ti/dpll.c
@@ -39,6 +39,8 @@
.set_rate_and_parent= _noncore_dpll_set_rate_and_parent,
.determine_rate = _dpll_regm4xen_determine_rate,
.get_parent = _init_dpll_parent,
+   .save_context   = _core_dpll_save_context,
+   .restore_context = _core_dpll_restore_context,
 };
 #else
 static const struct clk_ops dpll_m4xen_ck_ops = {};
@@ -62,6 +64,8 @@
.set_rate_and_parent= _noncore_dpll_set_rate_and_parent,
.determine_rate = _noncore_dpll_determine_rate,
.get_parent = _init_dpll_parent,
+   .save_context   = _noncore_dpll_save_context,
+   .restore_context = _noncore_dpll_restore_context,
 };
 
 static const struct clk_ops dpll_no_gate_ck_ops = {
@@ -72,6 +76,8 @@
.set_parent = _noncore_dpll_set_parent,
.set_rate_and_parent= _noncore_dpll_set_rate_and_parent,
.determine_rate = _noncore_dpll_determine_rate,
+   .save_context   = _noncore_dpll_save_context,
+   .restore_context = _noncore_dpll_restore_context
 };
 #else
 static const struct clk_ops dpll_core_ck_ops = {};
diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c
index 4534de2..44b6b64 100644
--- a/drivers/clk/ti/dpll3xxx.c
+++ b/drivers/clk/ti/dpll3xxx.c
@@ -782,6 +782,130 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
return rate;
 }
 
+/**
+ * omap3_core_dpll_save_context - Save the m and n values of the divider
+ * @hw: pointer  struct clk_hw
+ *
+ * Before the dpll registers are lost save the last rounded rate m and n
+ * and the enable mask.
+ */
+int omap3_core_dpll_save_context(struct clk_hw *hw)
+{
+   struct clk_hw_omap *clk = to_clk_hw_omap(hw);
+   struct dpll_data *dd;
+   u32 v;
+
+   dd = clk->dpll_data;
+
+   v = ti_clk_ll_ops->clk_readl(>control_reg);
+   clk->context = (v & dd->enable_mask) >> __ffs(dd->enable_mask);
+
+   if (clk

[PATCH 2/4] clk: clk: Add clk_dflt_restore

2018-06-18 Thread Keerthy
The default restore context function enables or disables
the clock based on the enable_count. This is done in cases
where the clock context is lost and based on the enable_count
the clock either needs to be enabled/disabled. This particularly
helps restore the state of gate clocks.

Signed-off-by: Keerthy 
---
 drivers/clk/clk.c| 19 +++
 include/linux/clk-provider.h |  2 ++
 2 files changed, 21 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 7347e06..c201b8b 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -910,6 +910,25 @@ static int clk_core_enable_lock(struct clk_core *core)
return ret;
 }
 
+/**
+ * clk_dflt_restore_context - restore context for poweroff
+ * @hw: the clk_hw pointer of clock whose state is to be restored
+ *
+ * The default restore context function enables or disables
+ * the clock based on the enable_count. This is done in cases
+ * where the clock context is lost and based on the enable_count
+ * the clock either needs to be enabled/disabled. This particularly
+ * helps restore the state of gate clocks.
+ */
+void clk_dflt_restore_context(struct clk_hw *hw)
+{
+   if (hw->clk->core->enable_count)
+   hw->clk->core->ops->enable(hw);
+   else
+   hw->clk->core->ops->disable(hw);
+}
+EXPORT_SYMBOL_GPL(clk_dflt_restore_context);
+
 static int _clk_save_context(struct clk_core *clk)
 {
struct clk_core *child;
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 7f30d62..3e0c61a 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -992,5 +992,7 @@ static inline void clk_writel(u32 val, u32 __iomem *reg)
 
 #endif /* platform dependent I/O accessors */
 
+void clk_dflt_restore_context(struct clk_hw *hw);
+
 #endif /* CONFIG_COMMON_CLK */
 #endif /* CLK_PROVIDER_H */
-- 
1.9.1



[PATCH 1/4] clk: clk: Add functions to save/restore clock context en-masse

2018-06-18 Thread Keerthy
From: Russ Dill 

Deep enough power saving mode can result into losing context of the clock
registers also, and they need to be restored once coming back from the power
saving mode. Hence add functions to save/restore clock context.

Signed-off-by: Keerthy 
Signed-off-by: Russ Dill 
---
 drivers/clk/clk.c| 74 
 include/linux/clk-provider.h |  7 +
 include/linux/clk.h  | 25 +++
 3 files changed, 106 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index a24a6af..7347e06 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -910,6 +910,80 @@ static int clk_core_enable_lock(struct clk_core *core)
return ret;
 }
 
+static int _clk_save_context(struct clk_core *clk)
+{
+   struct clk_core *child;
+   int ret = 0;
+
+   hlist_for_each_entry(child, >children, child_node) {
+   ret = _clk_save_context(child);
+   if (ret < 0)
+   return ret;
+   }
+
+   if (clk->ops && clk->ops->save_context)
+   ret = clk->ops->save_context(clk->hw);
+
+   return ret;
+}
+
+static void _clk_restore_context(struct clk_core *clk)
+{
+   struct clk_core *child;
+
+   if (clk->ops && clk->ops->restore_context)
+   clk->ops->restore_context(clk->hw);
+
+   hlist_for_each_entry(child, >children, child_node)
+   _clk_restore_context(child);
+}
+
+/**
+ * clk_save_context - save clock context for poweroff
+ *
+ * Saves the context of the clock register for powerstates in which the
+ * contents of the registers will be lost. Occurs deep within the suspend
+ * code.  Returns 0 on success.
+ */
+int clk_save_context(void)
+{
+   struct clk_core *clk;
+   int ret;
+
+   hlist_for_each_entry(clk, _root_list, child_node) {
+   ret = _clk_save_context(clk);
+   if (ret < 0)
+   return ret;
+   }
+
+   hlist_for_each_entry(clk, _orphan_list, child_node) {
+   ret = _clk_save_context(clk);
+   if (ret < 0)
+   return ret;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(clk_save_context);
+
+/**
+ * clk_restore_context - restore clock context after poweroff
+ *
+ * Restore the saved clock context upon resume.
+ *
+ */
+void clk_restore_context(void)
+{
+   struct clk_core *clk;
+
+   hlist_for_each_entry(clk, _root_list, child_node)
+   _clk_restore_context(clk);
+
+   hlist_for_each_entry(clk, _orphan_list, child_node)
+   _clk_restore_context(clk);
+}
+EXPORT_SYMBOL_GPL(clk_restore_context);
+
 /**
  * clk_enable - ungate a clock
  * @clk: the clk being ungated
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index b7cfa03..7f30d62 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -106,6 +106,11 @@ struct clk_rate_request {
  * Called with enable_lock held.  This function must not
  * sleep.
  *
+ * @save_context: Save the context of the clock in prepration for poweroff.
+ *
+ * @restore_context: Restore the context of the clock after a restoration
+ * of power.
+ *
  * @recalc_rateRecalculate the rate of this clock, by querying 
hardware. The
  * parent rate is an input parameter.  It is up to the caller to
  * ensure that the prepare_mutex is held across this call.
@@ -201,6 +206,8 @@ struct clk_ops {
void(*disable)(struct clk_hw *hw);
int (*is_enabled)(struct clk_hw *hw);
void(*disable_unused)(struct clk_hw *hw);
+   int (*save_context)(struct clk_hw *hw);
+   void(*restore_context)(struct clk_hw *hw);
unsigned long   (*recalc_rate)(struct clk_hw *hw,
unsigned long parent_rate);
long(*round_rate)(struct clk_hw *hw, unsigned long rate,
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 0dbd088..70a2662 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -596,6 +596,23 @@ int __must_check clk_bulk_enable(int num_clks,
  */
 struct clk *clk_get_sys(const char *dev_id, const char *con_id);
 
+/**
+ * clk_save_context - save clock context for poweroff
+ *
+ * Saves the context of the clock register for powerstates in which the
+ * contents of the registers will be lost. Occurs deep within the suspend
+ * code so locking is not necessary.
+ */
+int clk_save_context(void);
+
+/**
+ * clk_restore_context - restore clock context after poweroff
+ *
+ * This occurs with all clocks enabled. Occurs deep within the resume code
+ * so locking is not necessary.
+ */
+void clk_restore_context(void);
+
 #else /* !CONFIG_HAVE_CLK */
 
 static inline struct clk *clk_get(struct device *dev, const char *id)
@@ -695,6 +712,14 @@ st

[PATCH 4/4] soc: ti: pm33xx: Save/restore clk context based on enable_off_mode setting

2018-06-18 Thread Keerthy
Save/restore clk context based on enable_off_mode setting.
The context needs to be saved at the very end of suspend path
and restored at the beginning of resume path.

Signed-off-by: Keerthy 
---
 arch/arm/mach-omap2/pm33xx-core.c| 15 +++
 drivers/soc/ti/pm33xx.c  | 13 +
 include/linux/platform_data/pm33xx.h |  1 +
 3 files changed, 29 insertions(+)

diff --git a/arch/arm/mach-omap2/pm33xx-core.c 
b/arch/arm/mach-omap2/pm33xx-core.c
index 9b3755a..29f848f 100644
--- a/arch/arm/mach-omap2/pm33xx-core.c
+++ b/arch/arm/mach-omap2/pm33xx-core.c
@@ -37,6 +37,20 @@ static int __init am43xx_map_scu(void)
return 0;
 }
 
+static int am43xx_check_off_mode_enable(void)
+{
+   /*
+* Check for am437x-sk-evm which due to HW design cannot support
+* this mode reliably.
+*/
+   if (of_machine_is_compatible("ti,am437x-sk-evm") && enable_off_mode) {
+   pr_warn("WARNING: This platform does not support off-mode, 
entering DeepSleep suspend.\n");
+   return 0;
+   }
+
+   return enable_off_mode;
+}
+
 static int amx3_common_init(void)
 {
gfx_pwrdm = pwrdm_lookup("gfx_pwrdm");
@@ -161,6 +175,7 @@ static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void)
.init = am43xx_suspend_init,
.soc_suspend = am43xx_suspend,
.get_sram_addrs = amx3_get_sram_addrs,
+   .check_off_mode_enable = am43xx_check_off_mode_enable,
 };
 
 static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c
index 652739c..e749b8d 100644
--- a/drivers/soc/ti/pm33xx.c
+++ b/drivers/soc/ti/pm33xx.c
@@ -6,6 +6,7 @@
  * Vaibhav Bedia, Dave Gerlach
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -52,6 +53,14 @@ static int am33xx_pm_suspend(suspend_state_t suspend_state)
 {
int i, ret = 0;
 
+   /*
+* For RTC only mode with DDR in selfresh we need to save
+* clocks context at the very end
+*/
+   if (suspend_state == PM_SUSPEND_MEM &&
+   pm_ops->check_off_mode_enable())
+   clk_save_context();
+
ret = pm_ops->soc_suspend((unsigned long)suspend_state,
  am33xx_do_wfi_sram);
 
@@ -77,6 +86,10 @@ static int am33xx_pm_suspend(suspend_state_t suspend_state)
}
}
 
+   if (suspend_state == PM_SUSPEND_MEM &&
+   pm_ops->check_off_mode_enable())
+   clk_restore_context();
+
return ret;
 }
 
diff --git a/include/linux/platform_data/pm33xx.h 
b/include/linux/platform_data/pm33xx.h
index f9bed2a..36f7007 100644
--- a/include/linux/platform_data/pm33xx.h
+++ b/include/linux/platform_data/pm33xx.h
@@ -25,6 +25,7 @@ struct am33xx_pm_platform_data {
int (*init)(void);
int (*soc_suspend)(unsigned int state, int (*fn)(unsigned long));
struct  am33xx_pm_sram_addr *(*get_sram_addrs)(void);
+   int (*check_off_mode_enable)(void);
 };
 
 struct am33xx_pm_sram_data {
-- 
1.9.1



[PATCH 0/4] clk: clk: Add functions to save/restore clock context en-masse

2018-06-18 Thread Keerthy
Deep enough power saving mode can result into losing context of the clock
registers also, and they need to be restored once coming back from the power
saving mode. Hence add functions to save/restore clock context.

Tested for DS0 on am437x-gp-evm

Based on top of linux-next

Keerthy (2):
  clk: clk: Add clk_dflt_restore
  soc: ti: pm33xx: Save/restore clk context based on enable_off_mode
setting

Russ Dill (2):
  clk: clk: Add functions to save/restore clock context en-masse
  clk: ti: Add functions to save/restore clk context

 arch/arm/mach-omap2/pm33xx-core.c|  15 +
 drivers/clk/clk.c|  93 ++
 drivers/clk/ti/clock.h   |   2 +
 drivers/clk/ti/divider.c |  36 ++
 drivers/clk/ti/dpll.c|   6 ++
 drivers/clk/ti/dpll3xxx.c| 124 +++
 drivers/clk/ti/gate.c|   3 +
 drivers/clk/ti/mux.c |  29 
 drivers/soc/ti/pm33xx.c  |  13 
 include/linux/clk-provider.h |   9 +++
 include/linux/clk.h  |  25 +++
 include/linux/clk/ti.h   |   6 ++
 include/linux/platform_data/pm33xx.h |   1 +
 13 files changed, 362 insertions(+)

-- 
1.9.1



Re: [PATCH 01/14] thermal: ti-soc-thermal: fix TALERT IRQ handling for DRA752

2018-07-26 Thread Keerthy



On Wednesday 25 July 2018 07:57 PM, Bartlomiej Zolnierkiewicz wrote:
> On Wednesday, July 11, 2018 07:49:41 AM J, KEERTHY wrote:
>>
>> On 5/14/2018 5:12 PM, Bartlomiej Zolnierkiewicz wrote:
>>> .report_temperature is not set in dra752_data which
>>> results in temperature updates not being propagated by
>>> ti_bandgap_talert_irq_handler() (it doesn't make much
>>> sense to handle TALERT IRQ without reporting temperature
>>> updates to the thermal core). Fix it.
>>
>> ATM no one is using TALERT as the thermal software polls on the 
>> temperature. No real benefit from TALERT.
>>
>> TALERT is set at different temperature and software polling thresholds 
>> come from Device tree and i believe its best for software to go by 
>> polling and then act on trip points.
> 
> Could you please explain what do you mean by "no one is using
> TALERT"?
> 
> The code in ti_bandgap_probe() sets TALERT thresholds and requests
> IRQ if the TI_BANDGAP_FEATURE_TALERT feature flag is set (and this
> flag is set in omap4460_data, omap4470_data, omap5430_data and
> dra752_data).

The software thresholds and the polling takes care of reducing the
temperature. What i actually meant was we never relied on talert and the
polling takes care of keeping a check on the temperature.

Regards,
Keerthy

> 
> Best regards,
> --
> Bartlomiej Zolnierkiewicz
> Samsung R Institute Poland
> Samsung Electronics
> 


[PATCH] clocksource: ti-32k: Remove CLOCK_SOURCE_SUSPEND_NONSTOP flag

2018-08-02 Thread Keerthy
With the introduction of below commit:

commit 39232ed5a1793f67b11430c43ed8a9ed6e96c6eb

time: Introduce one suspend clocksource to compensate the suspend time

The suspend/resume fails on AM437x platforms as the source is not
a non-stop while trying to compensate time using this.

Hence remove the CLOCK_SOURCE_SUSPEND_NONSTOP flag.

Suggested-by: Grygorii Strashko 
Signed-off-by: Keerthy 
---
 drivers/clocksource/timer-ti-32k.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/clocksource/timer-ti-32k.c 
b/drivers/clocksource/timer-ti-32k.c
index 880a861..7368e8e 100644
--- a/drivers/clocksource/timer-ti-32k.c
+++ b/drivers/clocksource/timer-ti-32k.c
@@ -78,8 +78,7 @@ static u64 notrace ti_32k_read_cycles(struct clocksource *cs)
.rating = 250,
.read   = ti_32k_read_cycles,
.mask   = CLOCKSOURCE_MASK(32),
-   .flags  = CLOCK_SOURCE_IS_CONTINUOUS |
-   CLOCK_SOURCE_SUSPEND_NONSTOP,
+   .flags  = CLOCK_SOURCE_IS_CONTINUOUS, 
},
 };
 
-- 
1.9.1



Re: [PATCH] arm: dts: am4372: setup rtc as system-power-controller

2018-08-08 Thread Keerthy



On Wednesday 08 August 2018 02:36 PM, Tony Lindgren wrote:
> * Keerthy  [180725 05:59]:
>> RTC alarm2 is connected to pmic_en line and hence can be used to control
>> the pmic enabling/disabling. Hence add the system-power-controller for rtc
>> node.
>>
>> Signed-off-by: Keerthy 
>> ---
>>  arch/arm/boot/dts/am4372.dtsi | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
>> index f0cbd86..d4b7c59 100644
>> --- a/arch/arm/boot/dts/am4372.dtsi
>> +++ b/arch/arm/boot/dts/am4372.dtsi
>> @@ -469,6 +469,7 @@
>>  ti,hwmods = "rtc";
>>  clocks = <_32768_ck>;
>>  clock-names = "int-clk";
>> +system-power-controller;
>>  status = "disabled";
>>  };
>>  
> 
> Should this be queued as a fix for v4.19-rc series?

Yes this makes pmic to shutdown during power off.

> 
> Regards,
> 
> Tony
> 


[PATCH v6 2/2] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-08-15 Thread Keerthy
Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
over try again.

Signed-off-by: Keerthy 
---
 drivers/rtc/rtc-omap.c | 25 +++--
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 44ff4cc..320b4a5 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -421,12 +421,6 @@ static int omap_rtc_set_alarm(struct device *dev, struct 
rtc_wkalrm *alm)
  * The RTC can be used to control an external PMIC via the pmic_power_en pin,
  * which can be configured to transition to OFF on ALARM2 events.
  *
- * Notes:
- * The two-second alarm offset is the shortest offset possible as the alarm
- * registers must be set before the next timer update and the offset
- * calculation is too heavy for everything to be done within a single access
- * period (~15 us).
- *
  * Called with local interrupts disabled.
  */
 static void omap_rtc_power_off(void)
@@ -434,6 +428,7 @@ static void omap_rtc_power_off(void)
struct omap_rtc *rtc = omap_rtc_power_off_rtc;
struct rtc_time tm;
unsigned long now;
+   int seconds;
u32 val;
 
rtc->type->unlock(rtc);
@@ -441,11 +436,13 @@ static void omap_rtc_power_off(void)
val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
 
-   /* set alarm two seconds from now */
+again:
+   /* set alarm one second from now */
omap_rtc_read_time_raw(rtc, );
+   seconds = tm.tm_sec;
bcd2tm();
rtc_tm_to_time(, );
-   rtc_time_to_tm(now + 2, );
+   rtc_time_to_tm(now + 1, );
 
if (tm2bcd() < 0) {
dev_err(>rtc->dev, "power off failed\n");
@@ -470,14 +467,22 @@ static void omap_rtc_power_off(void)
val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
+
+   /* Retry in case roll over happened before alarm was armed. */
+   if (rtc_read(rtc, OMAP_RTC_SECONDS_REG) != seconds) {
+   val = rtc_read(rtc, OMAP_RTC_STATUS_REG);
+   if (!(val & OMAP_RTC_STATUS_ALARM2))
+   goto again;
+   }
+
rtc->type->lock(rtc);
 
/*
-* Wait for alarm to trigger (within two seconds) and external PMIC to
+* Wait for alarm to trigger (within one second) and external PMIC to
 * power off the system. Add a 500 ms margin for external latencies
 * (e.g. debounce circuits).
 */
-   mdelay(2500);
+   mdelay(1500);
 }
 
 static const struct rtc_class_ops omap_rtc_ops = {
-- 
1.9.1



[PATCH v6 1/2] rtc: omap: use of_device_is_system_power_controller function

2018-08-15 Thread Keerthy
Use of_device_is_system_power_controller instead of manually reading
the system-power-controller property from the device tree node.

Reviewed-by: Johan Hovold 
Signed-off-by: Keerthy 
---
 drivers/rtc/rtc-omap.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 323ff55..44ff4cc 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -721,8 +721,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
if (of_id) {
rtc->type = of_id->data;
rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
-   of_property_read_bool(pdev->dev.of_node,
-   "system-power-controller");
+   of_device_is_system_power_controller(pdev->dev.of_node);
} else {
id_entry = platform_get_device_id(pdev);
rtc->type = (void *)id_entry->driver_data;
-- 
1.9.1



Re: [PATCH v5 2/2] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-08-14 Thread Keerthy



On Wednesday 25 July 2018 03:00 PM, Alexandre Belloni wrote:
> Hi,
> 
> On 25/07/2018 11:21:22+0530, Keerthy wrote:
>> Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
>> over try again.
>>
>> Signed-off-by: Keerthy 
>> ---
>>
>> Changes in v5:
>>
>>   * Added an additional check to see if ALARM2 status is not set
>> before retrying.
>>   * Cleaned up comments
>>   * Also reduced mdelay to 1S lesser as per this commit
>>
>>  drivers/rtc/rtc-omap.c | 28 ++--
>>  1 file changed, 18 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
>> index 44ff4cc..caa6da6 100644
>> --- a/drivers/rtc/rtc-omap.c
>> +++ b/drivers/rtc/rtc-omap.c
>> @@ -421,12 +421,6 @@ static int omap_rtc_set_alarm(struct device *dev, 
>> struct rtc_wkalrm *alm)
>>   * The RTC can be used to control an external PMIC via the pmic_power_en 
>> pin,
>>   * which can be configured to transition to OFF on ALARM2 events.
>>   *
>> - * Notes:
>> - * The two-second alarm offset is the shortest offset possible as the alarm
>> - * registers must be set before the next timer update and the offset
>> - * calculation is too heavy for everything to be done within a single access
>> - * period (~15 us).
>> - *
>>   * Called with local interrupts disabled.
>>   */
>>  static void omap_rtc_power_off(void)
>> @@ -435,17 +429,20 @@ static void omap_rtc_power_off(void)
>>  struct rtc_time tm;
>>  unsigned long now;
>>  u32 val;
>> +int seconds;
>>  
>>  rtc->type->unlock(rtc);
>>  /* enable pmic_power_en control */
>>  val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
>>  rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
>>  
>> -/* set alarm two seconds from now */
>> +again:
>> +/* set alarm one second from now */
>>  omap_rtc_read_time_raw(rtc, );
>> +seconds = tm.tm_sec;
>>  bcd2tm();
>>  rtc_tm_to_time(, );
>> -rtc_time_to_tm(now + 2, );
>> +rtc_time_to_tm(now + 1, );
>>  
>>  if (tm2bcd() < 0) {
>>  dev_err(>rtc->dev, "power off failed\n");
>> @@ -470,14 +467,25 @@ static void omap_rtc_power_off(void)
>>  val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
>>  rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
>>  val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
>> +
>> +/*
>> + * first check if ALARM2 has fired, if not then check if
>> + * our calculations started right before the rollover, try again
>> + * in case of rollover
>> + */
>> +if (!(OMAP_RTC_STATUS_ALARM2 && rtc_read(omap_rtc_power_off_rtc,
>> + OMAP_RTC_STATUS_REG)) &&
>> +seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
>> +goto again;
>> +
> 
> Can you use a while loop instead of goto?

Apologies for the late reply. A one time retry should be able to take
care of the exception case.

> 
>>  rtc->type->lock(rtc);
>>  
>>  /*
>> - * Wait for alarm to trigger (within two seconds) and external PMIC to
>> + * Wait for alarm to trigger (within one second) and external PMIC to
>>   * power off the system. Add a 500 ms margin for external latencies
>>   * (e.g. debounce circuits).
>>   */
>> -mdelay(2500);
>> +mdelay(1500);
>>  }
>>  
>>  static const struct rtc_class_ops omap_rtc_ops = {
>> -- 
>> 1.9.1
>>
> 


Re: [PATCH v5 2/2] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-08-14 Thread Keerthy



On Tuesday 14 August 2018 02:53 PM, Johan Hovold wrote:
> On Wed, Jul 25, 2018 at 11:21:22AM +0530, Keerthy wrote:
>> Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
>> over try again.
>>
>> Signed-off-by: Keerthy 
>> ---
>>
>> Changes in v5:
>>
>>   * Added an additional check to see if ALARM2 status is not set
>> before retrying.
>>   * Cleaned up comments
>>   * Also reduced mdelay to 1S lesser as per this commit
>>
>>  drivers/rtc/rtc-omap.c | 28 ++--
>>  1 file changed, 18 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
>> index 44ff4cc..caa6da6 100644
>> --- a/drivers/rtc/rtc-omap.c
>> +++ b/drivers/rtc/rtc-omap.c
>> @@ -421,12 +421,6 @@ static int omap_rtc_set_alarm(struct device *dev, 
>> struct rtc_wkalrm *alm)
>>   * The RTC can be used to control an external PMIC via the pmic_power_en 
>> pin,
>>   * which can be configured to transition to OFF on ALARM2 events.
>>   *
>> - * Notes:
>> - * The two-second alarm offset is the shortest offset possible as the alarm
>> - * registers must be set before the next timer update and the offset
>> - * calculation is too heavy for everything to be done within a single access
>> - * period (~15 us).
>> - *
>>   * Called with local interrupts disabled.
>>   */
>>  static void omap_rtc_power_off(void)
>> @@ -435,17 +429,20 @@ static void omap_rtc_power_off(void)
>>  struct rtc_time tm;
>>  unsigned long now;
>>  u32 val;
>> +int seconds;
> 
> Nit: I'd place this above val to maintain the reverse xmas-tree style.

okay

> 
>>  
>>  rtc->type->unlock(rtc);
>>  /* enable pmic_power_en control */
>>  val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
>>  rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
>>  
>> -/* set alarm two seconds from now */
>> +again:
>> +/* set alarm one second from now */
>>  omap_rtc_read_time_raw(rtc, );
>> +seconds = tm.tm_sec;
>>  bcd2tm();
>>  rtc_tm_to_time(, );
>> -rtc_time_to_tm(now + 2, );
>> +rtc_time_to_tm(now + 1, );
>>  
>>  if (tm2bcd() < 0) {
>>  dev_err(>rtc->dev, "power off failed\n");
>> @@ -470,14 +467,25 @@ static void omap_rtc_power_off(void)
>>  val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
>>  rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
>>  val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
>> +
>> +/*
>> + * first check if ALARM2 has fired, if not then check if
>> + * our calculations started right before the rollover, try again
>> + * in case of rollover
>> + */
> 
> This is unnecessarily verbose; I'd rephrase it as something like:
> 
>   /* Retry in case roll over happened before alarm was armed. */

Okay

> 
>> +if (!(OMAP_RTC_STATUS_ALARM2 && rtc_read(omap_rtc_power_off_rtc,
>> + OMAP_RTC_STATUS_REG)) &&
>> +seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
>> +goto again;
> 
> And this is clearly broken. First, you use boolean && instead of the &
> bit operation.

Ah my bad. I will fix it.

> 
> Second, you need to check the status register *after* checking for
> roll-over, as I already mentioned.
> 
> Also, use the rtc pointer rather than omap_rtc_power_off_rtc, which will
> allow for more readable code.

Okay

> 
> I also strongly suggest you split the conditional, and use val to store
> the status register value, that is:
> 
>   if (rtc_read(rtc, OMAP_RTC_SECONDS_REG) != seconds) {
>   val = rtc_read(rtc, OMAP_RTC_STATUS_REG);
>   if (!(val & OMAP_RTC_STATUS_ALARM2))
>   goto again;
>   }
> 
>> +
>>  rtc->type->lock(rtc);
>>  
>>  /*
>> - * Wait for alarm to trigger (within two seconds) and external PMIC to
>> + * Wait for alarm to trigger (within one second) and external PMIC to
>>   * power off the system. Add a 500 ms margin for external latencies
>>   * (e.g. debounce circuits).
>>   */
>> -mdelay(2500);
>> +mdelay(1500);
>>  }
>>  
>>  static const struct rtc_class_ops omap_rtc_ops = {
> 
> Johan
> 


[PATCH] clocksource: ti-32k: Add CLOCK_SOURCE_SUSPEND_NONSTOP flag for non-am43 SoCs

2018-08-07 Thread Keerthy
The 32k clocksource is NONSTOP for non-am43 SoCs. Hence
add the flag for all the other SoCs.

Reported-by: Tony Lindgren 
Signed-off-by: Keerthy  
---
 drivers/clocksource/timer-ti-32k.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clocksource/timer-ti-32k.c 
b/drivers/clocksource/timer-ti-32k.c
index 29e2e1a..dd09171 100644
--- a/drivers/clocksource/timer-ti-32k.c
+++ b/drivers/clocksource/timer-ti-32k.c
@@ -97,6 +97,9 @@ static int __init ti_32k_timer_init(struct device_node *np)
return -ENXIO;
}
 
+   if (!of_machine_is_compatible("ti,am4372"))
+   ti_32k_timer.cs.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
+
ti_32k_timer.counter = ti_32k_timer.base;
 
/*
-- 
1.9.1



[PATCH v2] clocksource: ti-32k: Add CLOCK_SOURCE_SUSPEND_NONSTOP flag for non-am43 SoCs

2018-08-08 Thread Keerthy
The 32k clocksource is NONSTOP for non-am43 SoCs. Hence
add the flag for all the other SoCs.

Reported-by: Tony Lindgren 
Signed-off-by: Keerthy  
Acked-by: Tony Lindgren 
---

Changes in v2:

  * Changed am43 compatible to more generic ti,am43 to cover epos boards.
  * Added Tony's Ack.

 drivers/clocksource/timer-ti-32k.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clocksource/timer-ti-32k.c 
b/drivers/clocksource/timer-ti-32k.c
index 29e2e1a..dd09171 100644
--- a/drivers/clocksource/timer-ti-32k.c
+++ b/drivers/clocksource/timer-ti-32k.c
@@ -97,6 +97,9 @@ static int __init ti_32k_timer_init(struct device_node *np)
return -ENXIO;
}
 
+   if (!of_machine_is_compatible("ti,am43"))
+   ti_32k_timer.cs.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
+
ti_32k_timer.counter = ti_32k_timer.base;
 
/*
-- 
1.9.1



[PATCH] soc: ti: pm33xx: Enable DS0 for the platforms on which it is functional

2018-08-21 Thread Keerthy
Enable DS0 for only those platforms on which it is functional

Signed-off-by: Keerthy 
---
 arch/arm/mach-omap2/pm33xx-core.c| 5 +
 drivers/soc/ti/pm33xx.c  | 9 +
 include/linux/platform_data/pm33xx.h | 2 ++
 3 files changed, 16 insertions(+)

diff --git a/arch/arm/mach-omap2/pm33xx-core.c 
b/arch/arm/mach-omap2/pm33xx-core.c
index f4971e4..f0f6e8e 100644
--- a/arch/arm/mach-omap2/pm33xx-core.c
+++ b/arch/arm/mach-omap2/pm33xx-core.c
@@ -135,6 +135,11 @@ static int am43xx_suspend(unsigned int state, int 
(*fn)(unsigned long),
 {
int ret = 0;
 
+   if (!(args & WFI_FLAG_DEEP_SLEEP0)) {
+   pr_err("DS0 mode not supported\n");
+   return -ENOTSUPP;
+   }
+
amx3_pre_suspend_common();
scu_power_mode(scu_base, SCU_PM_POWEROFF);
ret = cpu_suspend(args, fn);
diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c
index d0dab32..53238d7 100644
--- a/drivers/soc/ti/pm33xx.c
+++ b/drivers/soc/ti/pm33xx.c
@@ -324,6 +324,15 @@ static int am33xx_pm_probe(struct platform_device *pdev)
suspend_wfi_flags |= WFI_FLAG_SAVE_EMIF;
suspend_wfi_flags |= WFI_FLAG_WAKE_M3;
 
+   /*
+* Deep Sleep0 mode is currently functional only on am437x-gp-evm,
+* am33xx-evm and boneblack family. Hence set the DS0 flag
+*/
+   if (of_machine_is_compatible("ti,am437x-gp-evm") ||
+   of_machine_is_compatible("ti,am335x-bone-black") ||
+   of_machine_is_compatible("ti,am335x-evm"))
+   suspend_wfi_flags |= WFI_FLAG_DEEP_SLEEP0;
+
ret = pm_ops->init();
if (ret) {
dev_err(dev, "Unable to call core pm init!\n");
diff --git a/include/linux/platform_data/pm33xx.h 
b/include/linux/platform_data/pm33xx.h
index fbf5ed7..5c54b64 100644
--- a/include/linux/platform_data/pm33xx.h
+++ b/include/linux/platform_data/pm33xx.h
@@ -28,12 +28,14 @@
  * WFI_FLAG_WAKE_M3: Disable MPU clock or clockdomain to cause wkup_m3 to
  *  execute when WFI instruction executes.
  * WFI_FLAG_RTC_ONLY: Configure the RTC to enter RTC+DDR mode.
+ * WFI_FLAG_DEEP_SLEEP0: Configure to enter Depp Sleep 0 mode.
  */
 #define WFI_FLAG_FLUSH_CACHE   BIT(0)
 #define WFI_FLAG_SELF_REFRESH  BIT(1)
 #define WFI_FLAG_SAVE_EMIF BIT(2)
 #define WFI_FLAG_WAKE_M3   BIT(3)
 #define WFI_FLAG_RTC_ONLY  BIT(4)
+#define WFI_FLAG_DEEP_SLEEP0   BIT(5)
 
 #ifndef __ASSEMBLER__
 struct am33xx_pm_sram_addr {
-- 
1.9.1



Re: [PATCH v4 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-07-20 Thread Keerthy



On Thursday 19 July 2018 06:16 PM, Keerthy wrote:
> 
> 
> On Thursday 19 July 2018 06:06 PM, Johan Hovold wrote:
>> On Thu, Jul 19, 2018 at 05:52:17PM +0530, Keerthy wrote:
>>> On Thursday 19 July 2018 05:23 PM, Keerthy wrote:
>>>> On Thursday 19 July 2018 03:32 PM, Johan Hovold wrote:
>>>>> On Thu, Jul 12, 2018 at 10:37:37AM +0530, Keerthy wrote:
>>
>>>>>> @@ -470,6 +476,9 @@ static void omap_rtc_power_off(void)
>>>>>>  val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
>>>>>>  rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
>>>>>>  val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
>>
>>>>>> +/* Our calculations started right before the rollover, try 
>>>>>> again */
>>
>>>>>> +if (seconds != rtc_read(omap_rtc_power_off_rtc, 
>>>>>> OMAP_RTC_SECONDS_REG))
>>>>>> +goto again;
>>>>>
>>>>> Here the alarm may have gone off as part of the roll over, in which case
>>>>> you shouldn't retry.
>>>>
>>>> Ex: We programmed at Sec = 2 and we expect ALARM2 to fire at sec = 3.
>>>>
>>>> In the event of Roll over before setting the
>>>> OMAP_RTC_INTERRUPTS_IT_ALARM2 bit in the OMAP_RTC_INTERRUPTS_REG will we
>>>> not miss the ALARM2 event? Then poweroff would fail right?
>>
>> Right, that would fail.
>>
>>>> Hence the attempt to retry the next second. This sequence would begin
>>>> right at the beginning of a new second and we expect the full sequence
>>>> to get over without having to retry again.
>>>>
>>>> Hope i am clear.
>>
>> Yes, sure, but my point is that could end up retrying also after the
>> alarm has fired correctly (e.g. due to latencies in turning of the
>> power)>
>> It may be enough to check OMAP_RTC_STATUS_REG before retrying.

On a second thought. Status gets set only after the next second.

if ALARM2 status bit is set that surely means interrupt has fired but if
it is not set then there are 2 possibilities

1) ALARM2 is missed as the roll over happened
2) ALARM2 yet to fire as we are yet to get to the next second.

On the other hand Seconds gives me clear indication if we missed the
interrupt or we are about to get one.

> 
> Ah okay. Yes this makes sense. I will use the status to retry.
> 
>>
>>> I tried to program the interrupt for the same second on the hardware and
>>> it does not fire. So to take care of roll over corner case one attempt
>>> to retry is needed.
>>
>> Yes, that's expected.
>>
>> Thanks,
>> 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
> 


Re: 4.18.0-rc1-next-20180619 boot failed on beagle board x15

2018-07-17 Thread Keerthy



On Tuesday 17 July 2018 01:33 PM, Tony Lindgren wrote:
> * Stephen Rothwell  [180717 08:03]:
>> Hi Tony,
>>
>> On Mon, 16 Jul 2018 23:08:08 -0700 Tony Lindgren  wrote:
>>>
>>> The following regression is still pending in next, see below.
>>>
>>> * Samuel Morris  [180702 13:35]:
>>>> On Mon, Jul 2, 2018 at 5:32 AM, Tony Lindgren  wrote:  
>>>>> Hi,
>>>>>
>>>>> * Roger Quadros  [180621 14:56]:  
>>>>>> On 21/06/18 17:31, Samuel Morris wrote:  
>>>>>>> On Thu, Jun 21, 2018 at 3:58 AM, Roger Quadros  wrote:  
>>>>>>>> +Rafael
>>>>>>>>
>>>>>>>> On 20/06/18 18:30, Samuel Morris wrote:  
>>>>>>>>> On Wed, Jun 20, 2018 at 8:58 AM, Roger Quadros  wrote: 
>>>>>>>>>  
>>>>>>>>>> Tony,
>>>>>>>>>>
>>>>>>>>>> On 20/06/18 13:29, Tony Lindgren wrote:  
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> * Naresh Kamboju  [180620 05:55]:  
>>>>>>>>>>>> Linux next (4.18.0-rc1-next-20180619) boot failed on beagle board 
>>>>>>>>>>>> x15.  
>>>>>>>>>>>
>>>>>>>>>>> Bisect points to commit aece27a2f01b ("ata: ahci_platform: allow 
>>>>>>>>>>> disabling of
>>>>>>>>>>> hotplug to save power").
>>>>>>>>>>>
>>>>>>>>>>> Reverting the patch makes things work again. Any ideas what
>>>>>>>>>>> might be going wrong here? Things clearly idle but then there
>>>>>>>>>>> seems to be some register access with clocks disabled.  
>>>>>
>>>>> So this issue is still happening as of next-20180702. Can you guys
>>>>> please revert the commit above while working on a better solution?  
>>>>
>>>> That's fine with me. I'm not very familiar with the process here, does
>>>> this require anything on my end? And would that require the
>>>> accompanying patch to be reverted: "ata: ahci: rpm_put port on
>>>> port_stop to match rpm_get in port_start"? There shouldn't be any
>>>> problem leaving that one in, but I just want to know before submitting
>>>> my next patch set.  
>>>
>>> Well usually the maintainer just reverts the regression causing
>>> patch in the related branch and that's it.
>>>
>>> Stephen, can you please revert in next until we hear back from
>>> Tejun?
>>
>> OK, I have reverted that commit from today.  Please let me know when the
>> problem is fixed in the libata tree ...

Hi Stephen,

Thanks for the revert.

commit 1dcbe5f2c615337cb7d4e13fab198ab716180733
Author: Stephen Rothwell 
Date:   Tue Jul 17 19:02:59 2018 +1000

With the above top commit i confirm that BEAGLE-X15, AM572X-IDK,
AM574X-IDK, DRA7, DRA72 TI platforms booted to prompt.

Regards,
Keerthy

> 
> Thanks!
> 
> Tony
> 
> 
> --
> 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 v5 2/2] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-07-24 Thread Keerthy
Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
over try again.

Signed-off-by: Keerthy 
---

Changes in v5:

  * Added an additional check to see if ALARM2 status is not set
before retrying.
  * Cleaned up comments
  * Also reduced mdelay to 1S lesser as per this commit

 drivers/rtc/rtc-omap.c | 28 ++--
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 44ff4cc..caa6da6 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -421,12 +421,6 @@ static int omap_rtc_set_alarm(struct device *dev, struct 
rtc_wkalrm *alm)
  * The RTC can be used to control an external PMIC via the pmic_power_en pin,
  * which can be configured to transition to OFF on ALARM2 events.
  *
- * Notes:
- * The two-second alarm offset is the shortest offset possible as the alarm
- * registers must be set before the next timer update and the offset
- * calculation is too heavy for everything to be done within a single access
- * period (~15 us).
- *
  * Called with local interrupts disabled.
  */
 static void omap_rtc_power_off(void)
@@ -435,17 +429,20 @@ static void omap_rtc_power_off(void)
struct rtc_time tm;
unsigned long now;
u32 val;
+   int seconds;
 
rtc->type->unlock(rtc);
/* enable pmic_power_en control */
val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
 
-   /* set alarm two seconds from now */
+again:
+   /* set alarm one second from now */
omap_rtc_read_time_raw(rtc, );
+   seconds = tm.tm_sec;
bcd2tm();
rtc_tm_to_time(, );
-   rtc_time_to_tm(now + 2, );
+   rtc_time_to_tm(now + 1, );
 
if (tm2bcd() < 0) {
dev_err(>rtc->dev, "power off failed\n");
@@ -470,14 +467,25 @@ static void omap_rtc_power_off(void)
val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
+
+   /*
+* first check if ALARM2 has fired, if not then check if
+* our calculations started right before the rollover, try again
+* in case of rollover
+*/
+   if (!(OMAP_RTC_STATUS_ALARM2 && rtc_read(omap_rtc_power_off_rtc,
+OMAP_RTC_STATUS_REG)) &&
+   seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
+   goto again;
+
rtc->type->lock(rtc);
 
/*
-* Wait for alarm to trigger (within two seconds) and external PMIC to
+* Wait for alarm to trigger (within one second) and external PMIC to
 * power off the system. Add a 500 ms margin for external latencies
 * (e.g. debounce circuits).
 */
-   mdelay(2500);
+   mdelay(1500);
 }
 
 static const struct rtc_class_ops omap_rtc_ops = {
-- 
1.9.1



[PATCH v5 1/2] rtc: omap: use of_device_is_system_power_controller function

2018-07-24 Thread Keerthy
Use of_device_is_system_power_controller instead of manually reading
the system-power-controller property from the device tree node.

Reviewed-by: Johan Hovold 
Signed-off-by: Keerthy 
---

Changes in v5:

  * Added Johan's Reviewed-by

 drivers/rtc/rtc-omap.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 323ff55..44ff4cc 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -721,8 +721,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
if (of_id) {
rtc->type = of_id->data;
rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
-   of_property_read_bool(pdev->dev.of_node,
-   "system-power-controller");
+   of_device_is_system_power_controller(pdev->dev.of_node);
} else {
id_entry = platform_get_device_id(pdev);
rtc->type = (void *)id_entry->driver_data;
-- 
1.9.1



[PATCH] arm: dts: am4372: setup rtc as system-power-controller

2018-07-24 Thread Keerthy
RTC alarm2 is connected to pmic_en line and hence can be used to control
the pmic enabling/disabling. Hence add the system-power-controller for rtc
node.

Signed-off-by: Keerthy 
---
 arch/arm/boot/dts/am4372.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index f0cbd86..d4b7c59 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -469,6 +469,7 @@
ti,hwmods = "rtc";
clocks = <_32768_ck>;
clock-names = "int-clk";
+   system-power-controller;
status = "disabled";
};
 
-- 
1.9.1



Re: [PATCH v4 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-07-19 Thread Keerthy



On Thursday 19 July 2018 05:23 PM, Keerthy wrote:
> 
> 
> On Thursday 19 July 2018 03:32 PM, Johan Hovold wrote:
>> On Thu, Jul 12, 2018 at 10:37:37AM +0530, Keerthy wrote:
>>> Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
>>> over try again.
>>>
>>> Signed-off-by: Keerthy 
>>> ---
>>>
>>> Changes in v4:
>>>
>>>   * Fixed a compilation issue.
>>>   * Extended the roll over check post interrupt programming.
>>>
>>>  drivers/rtc/rtc-omap.c | 13 +++--
>>>  1 file changed, 11 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
>>> index 323ff55..88da927 100644
>>> --- a/drivers/rtc/rtc-omap.c
>>> +++ b/drivers/rtc/rtc-omap.c
>>
>> First, the comment above this function would need to be updated as part
>> of this patch as it refers to the two-second alarm offset.
> 
> Yes, will change that.
> 
>>
>>> @@ -435,17 +435,23 @@ static void omap_rtc_power_off(void)
>>> struct rtc_time tm;
>>> unsigned long now;
>>> u32 val;
>>> +   int seconds;
>>>  
>>> rtc->type->unlock(rtc);
>>> /* enable pmic_power_en control */
>>> val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
>>> rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
>>>  
>>> -   /* set alarm two seconds from now */
>>> +again:
>>> +   /* Clear any existing ALARM2 event */
>>> +   rtc_writel(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM2);
>>
>> Why is this needed? Any pending interrupt is cleared at probe, and a
>> previous attempt to set the alarm really led to the alarm going off, why
>> would we retry?
> 
> Yes this is not needed.
> 
>>
>>> +
>>> +   /* set alarm one second from now */
>>> omap_rtc_read_time_raw(rtc, );
>>> +   seconds = tm.tm_sec;
>>> bcd2tm();
>>> rtc_tm_to_time(, );
>>> -   rtc_time_to_tm(now + 2, );
>>> +   rtc_time_to_tm(now + 1, );
>>>  
>>> if (tm2bcd() < 0) {
>>> dev_err(>rtc->dev, "power off failed\n");
>>> @@ -470,6 +476,9 @@ static void omap_rtc_power_off(void)
>>> val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
>>> rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
>>> val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
>>
>> Add a newline here.
> 
> Okay
> 
>>
>>> +   /* Our calculations started right before the rollover, try again */
>>
>> Nit: use all lower case unless writing full sentences, which also
>> matches most of the other comments in this file.
> 
> okay
> 
>>
>>> +   if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
>>> +   goto again;
>>
>> Here the alarm may have gone off as part of the roll over, in which case
>> you shouldn't retry.
> 
> Ex: We programmed at Sec = 2 and we expect ALARM2 to fire at sec = 3.
> 
> In the event of Roll over before setting the
> OMAP_RTC_INTERRUPTS_IT_ALARM2 bit in the OMAP_RTC_INTERRUPTS_REG will we
> not miss the ALARM2 event? Then poweroff would fail right?
> 
> Hence the attempt to retry the next second. This sequence would begin
> right at the beginning of a new second and we expect the full sequence
> to get over without having to retry again.
> 
> Hope i am clear.

I tried to program the interrupt for the same second on the hardware and
it does not fire. So to take care of roll over corner case one attempt
to retry is needed.

> 
>>
>> Add a newline here too.
> 
> Okay
> 
>>
>>> rtc->type->lock(rtc);
>>>  
>>> /*
>>
>> Thanks,
>> 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
> 


Re: [PATCH v4 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-07-19 Thread Keerthy



On Thursday 19 July 2018 06:06 PM, Johan Hovold wrote:
> On Thu, Jul 19, 2018 at 05:52:17PM +0530, Keerthy wrote:
>> On Thursday 19 July 2018 05:23 PM, Keerthy wrote:
>>> On Thursday 19 July 2018 03:32 PM, Johan Hovold wrote:
>>>> On Thu, Jul 12, 2018 at 10:37:37AM +0530, Keerthy wrote:
> 
>>>>> @@ -470,6 +476,9 @@ static void omap_rtc_power_off(void)
>>>>>   val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
>>>>>   rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
>>>>>   val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
> 
>>>>> + /* Our calculations started right before the rollover, try again */
> 
>>>>> + if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
>>>>> + goto again;
>>>>
>>>> Here the alarm may have gone off as part of the roll over, in which case
>>>> you shouldn't retry.
>>>
>>> Ex: We programmed at Sec = 2 and we expect ALARM2 to fire at sec = 3.
>>>
>>> In the event of Roll over before setting the
>>> OMAP_RTC_INTERRUPTS_IT_ALARM2 bit in the OMAP_RTC_INTERRUPTS_REG will we
>>> not miss the ALARM2 event? Then poweroff would fail right?
> 
> Right, that would fail.
> 
>>> Hence the attempt to retry the next second. This sequence would begin
>>> right at the beginning of a new second and we expect the full sequence
>>> to get over without having to retry again.
>>>
>>> Hope i am clear.
> 
> Yes, sure, but my point is that could end up retrying also after the
> alarm has fired correctly (e.g. due to latencies in turning of the
> power)>
> It may be enough to check OMAP_RTC_STATUS_REG before retrying.

Ah okay. Yes this makes sense. I will use the status to retry.

> 
>> I tried to program the interrupt for the same second on the hardware and
>> it does not fire. So to take care of roll over corner case one attempt
>> to retry is needed.
> 
> Yes, that's expected.
> 
> Thanks,
> Johan
> 


Re: [PATCH v4 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-07-19 Thread Keerthy



On Thursday 19 July 2018 03:32 PM, Johan Hovold wrote:
> On Thu, Jul 12, 2018 at 10:37:37AM +0530, Keerthy wrote:
>> Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
>> over try again.
>>
>> Signed-off-by: Keerthy 
>> ---
>>
>> Changes in v4:
>>
>>   * Fixed a compilation issue.
>>   * Extended the roll over check post interrupt programming.
>>
>>  drivers/rtc/rtc-omap.c | 13 +++--
>>  1 file changed, 11 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
>> index 323ff55..88da927 100644
>> --- a/drivers/rtc/rtc-omap.c
>> +++ b/drivers/rtc/rtc-omap.c
> 
> First, the comment above this function would need to be updated as part
> of this patch as it refers to the two-second alarm offset.

Yes, will change that.

> 
>> @@ -435,17 +435,23 @@ static void omap_rtc_power_off(void)
>>  struct rtc_time tm;
>>  unsigned long now;
>>  u32 val;
>> +int seconds;
>>  
>>  rtc->type->unlock(rtc);
>>  /* enable pmic_power_en control */
>>  val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
>>  rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
>>  
>> -/* set alarm two seconds from now */
>> +again:
>> +/* Clear any existing ALARM2 event */
>> +rtc_writel(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM2);
> 
> Why is this needed? Any pending interrupt is cleared at probe, and a
> previous attempt to set the alarm really led to the alarm going off, why
> would we retry?

Yes this is not needed.

> 
>> +
>> +/* set alarm one second from now */
>>  omap_rtc_read_time_raw(rtc, );
>> +seconds = tm.tm_sec;
>>  bcd2tm();
>>  rtc_tm_to_time(, );
>> -rtc_time_to_tm(now + 2, );
>> +rtc_time_to_tm(now + 1, );
>>  
>>  if (tm2bcd() < 0) {
>>  dev_err(>rtc->dev, "power off failed\n");
>> @@ -470,6 +476,9 @@ static void omap_rtc_power_off(void)
>>  val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
>>  rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
>>  val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
> 
> Add a newline here.

Okay

> 
>> +/* Our calculations started right before the rollover, try again */
> 
> Nit: use all lower case unless writing full sentences, which also
> matches most of the other comments in this file.

okay

> 
>> +if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
>> +goto again;
> 
> Here the alarm may have gone off as part of the roll over, in which case
> you shouldn't retry.

Ex: We programmed at Sec = 2 and we expect ALARM2 to fire at sec = 3.

In the event of Roll over before setting the
OMAP_RTC_INTERRUPTS_IT_ALARM2 bit in the OMAP_RTC_INTERRUPTS_REG will we
not miss the ALARM2 event? Then poweroff would fail right?

Hence the attempt to retry the next second. This sequence would begin
right at the beginning of a new second and we expect the full sequence
to get over without having to retry again.

Hope i am clear.

> 
> Add a newline here too.

Okay

> 
>>  rtc->type->lock(rtc);
>>  
>>  /*
> 
> Thanks,
> Johan
> 


Re: [PATCH 2/5] gpio: davinci: Use dev name for label and automatic base selection

2018-09-09 Thread Keerthy



On Sunday 09 September 2018 01:11 AM, Grygorii Strashko wrote:
> 
> 
> On 09/06/2018 09:16 AM, Keerthy wrote:
>>
>>
>> On Wednesday 05 September 2018 04:07 PM, Linus Walleij wrote:
>>> On Mon, Sep 3, 2018 at 7:40 AM Keerthy  wrote:
>>>> On Saturday 01 September 2018 12:43 AM, Andrew F. Davis wrote:
>>>>> Use dev_name to get a unique label and use -1 for a base to get our
>>>>> selection automatically. We pull in all GPIOs per chip now so this
>>>>> does not have the effect of out of order labels like before.
>>>>>
>>>>> We do these both together so we can drop all the static data in one
>>>>> patch. This also lets us normalize the return paths as we don't need
>>>>> any cleanup after this change.
>>>>
>>>> echo 28 > /sys/class/gpio/export
>>>> / # echo 28 > /sys/class/gpi[   12.839205] export_store: invalid GPIO 28
>>>> o/export
>>>> echo 2 > /sys/class/gp[   22.165728] export_store: invalid GPIO 2
>>>> io/export
>>>> / # echo 1 > /sys/class/gp[   25.961392] export_store: invalid GPIO 1
>>>> io/export
>>>> / # echo 3 > /sys/class/gp[   29.981918] export_store: invalid GPIO 3
>>>> io/export
>>>>
>>>> Export fails with this patch. I am testing this on keystone-k2g-evm.
>>>
>>> I think the GPIO got a new number didn't it?
>>>
>>> Did you check the gpio file in debugfs to see which number
>>> it got.
>>
>> Okay now its numbered differently:
>>
>> cat /sys/class/gpio/gpiochip340/ngpio
>> 144
>>
>> cat /sys/class/gpio/gpiochip272/ngpio
>> 68
> 
> could you or Andrew provide content of /debug/gpio before/after?
> And ls /sys/class/gpio/?

Output on K2G:

Before
==

cat /debug/gpio
gpiochip1: GPIOs 0-143, parent: platform/2603000.gpio, davinci_gpio.0:

gpiochip2: GPIOs 144-211, parent: platform/260a000.gpio, davinci_gpio.1:
 gpio-156 (|cd  ) in  lo

gpiochip0: GPIOs 484-511, parent: platform/2620240.keystone_dsp_gpio,
2620240.keystone_dsp_gpio:

 ls /sys/class/gpio/
export   gpiochip0gpiochip144  gpiochip484  unexport

cat /sys/class/gpio/gpiochip0/label
davinci_gpio.0

cat /sys/class/gpio/gpiochip144/label
davinci_gpio.1

cat /sys/class/gpio/gpiochip144/ngpio
68
/ # cat /sys/class/gpio/gpiochip0/ngpio
144


After
=

 cat /debug/gpio
gpiochip2: GPIOs 272-339, parent: platform/260a000.gpio, 260a000.gpio:
 gpio-284 (|cd  ) in  lo

gpiochip1: GPIOs 340-483, parent: platform/2603000.gpio, 2603000.gpio:

gpiochip0: GPIOs 484-511, parent: platform/2620240.keystone_dsp_gpio,
2620240.keystone_dsp_gpio:

ls /sys/class/gpio/
export   gpiochip272  gpiochip340  gpiochip484  unexport


cat /sys/class/gpio/gpiochip340/label
2603000.gpio
/ # cat /sys/class/gpio/gpiochip272/label
260a000.gpio
/ # cat /sys/class/gpio/gpiochip272/label

cat /sys/class/gpio/gpiochip272/ngpio
68
/ # cat /sys/class/gpio/gpiochip340/ngpio
144

In the case of SoCs that support multiple instances of Davinci GPIO IPs
it is harder to figure out the right gpio number to export.

>>
>> So gpio bank2 and bank1 have different gpio numbers. Is that acceptable?
>>
>>>
>>> This is sadly the global numberspace that we are tying to
>>> get rid of (new apps/scripts should use the chardev).
>>>
>>> Are there applications that rely on the sysfs ABI on DaVinci?
>>>
>>> In that case base needs to be prerseved.
> 
> Not only base, but label also - /sys/class/gpio/gpiochip0/label, as this is
> the way to find proper GPIO chip in sysfs using legacy GPIO ABI.
> 
> Linus, this platform is old and most of the users do not use new ABI 
> (chardev),
> so we could try change this, but need to be prepared for regressions reports.
> 

Totally agree with this.


Re: [PATCH 2/5] gpio: davinci: Use dev name for label and automatic base selection

2018-09-06 Thread Keerthy



On Wednesday 05 September 2018 04:07 PM, Linus Walleij wrote:
> On Mon, Sep 3, 2018 at 7:40 AM Keerthy  wrote:
>> On Saturday 01 September 2018 12:43 AM, Andrew F. Davis wrote:
>>> Use dev_name to get a unique label and use -1 for a base to get our
>>> selection automatically. We pull in all GPIOs per chip now so this
>>> does not have the effect of out of order labels like before.
>>>
>>> We do these both together so we can drop all the static data in one
>>> patch. This also lets us normalize the return paths as we don't need
>>> any cleanup after this change.
>>
>> echo 28 > /sys/class/gpio/export
>> / # echo 28 > /sys/class/gpi[   12.839205] export_store: invalid GPIO 28
>> o/export
>> echo 2 > /sys/class/gp[   22.165728] export_store: invalid GPIO 2
>> io/export
>> / # echo 1 > /sys/class/gp[   25.961392] export_store: invalid GPIO 1
>> io/export
>> / # echo 3 > /sys/class/gp[   29.981918] export_store: invalid GPIO 3
>> io/export
>>
>> Export fails with this patch. I am testing this on keystone-k2g-evm.
> 
> I think the GPIO got a new number didn't it?
> 
> Did you check the gpio file in debugfs to see which number
> it got.

Okay now its numbered differently:

cat /sys/class/gpio/gpiochip340/ngpio
144

cat /sys/class/gpio/gpiochip272/ngpio
68

So gpio bank2 and bank1 have different gpio numbers. Is that acceptable?

> 
> This is sadly the global numberspace that we are tying to
> get rid of (new apps/scripts should use the chardev).
> 
> Are there applications that rely on the sysfs ABI on DaVinci?
> 
> In that case base needs to be prerseved.
> 
> Yours,
> Linus Walleij
> 


Re: [PATCH] rtc: OMAP: Add support for rtc-only mode

2018-07-04 Thread Keerthy



On Wednesday 04 July 2018 01:11 PM, Alexandre Belloni wrote:
> Hi,
> 
> On 04/07/2018 12:03:45+0530, Keerthy wrote:
>> Prepare rtc driver for rtc-only mode. This involes splitting the power-off
>> function so that an external driver can initiate the programming of
>> setting the power_off to be triggered in the next second.
>>
> 
> I'm sorry, I don't see the point, can't you use
> of_device_is_system_power_controller and set the correct pm_power_off
> callback?

Thanks for the quick response.

The commit message did not capture that point apologies for that.
Basically there are two parts to this:

1) RTC plus DDR in self-refresh is power a saving mode where in the
entire system including the different voltage rails from PMIC are
shutdown except the ones feeding on to RTC and DDR. DDR is kept in
self-refresh hence the contents are preserved. RTC ALARM2 is connected
to PMIC_EN line once we the ALARM2 is triggered we enter the mode with
DDR in self-refresh and RTC Ticking. After a predetermined time an RTC
ALARM1 triggers waking up the system[1]. The control goes to bootloader.
The bootloader then checks RTC scratchpad registers to confirm it was an
rtc_only wakeup and follows a different path, configure bare minimal
clocks for ddr and then jumps to the resume address in another RTC
scratchpad registers and transfers the control to Kernel. Kernel then
restores the saved context. omap_rtc_power_off_program does the ALARM2
programming part.

 [1] http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf Page 2884

2) Power-off: This is usual poweroff mode. omap_rtc_power_off calls the
above omap_rtc_power_off_program function and in addition to that
programs the OMAP_RTC_PMIC_REG for any external wake ups for PMIC like
the pushbutton and shuts off the PMIC.

Hence the split in omap_rtc_power_off. The omap_rtc_power_off_program
caters to rtc_only mode which is NOT poweroff but more of a timed boot.

I can add all the details in the commit message in the next version.

Thanks for pointing to of_device_is_system_power_controller function i
can use this while assigning the pm_power_off function.

> 
>> Signed-off-by: Keerthy 
>> ---
>>  drivers/rtc/interface.c |  12 
>>  drivers/rtc/rtc-omap.c  | 164 
>> ++--
>>  include/linux/rtc.h |   2 +
>>  3 files changed, 130 insertions(+), 48 deletions(-)
>>
>> diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
>> index 6d4012d..d8b70f0 100644
>> --- a/drivers/rtc/interface.c
>> +++ b/drivers/rtc/interface.c
>> @@ -1139,3 +1139,15 @@ int rtc_set_offset(struct rtc_device *rtc, long 
>> offset)
>>  trace_rtc_set_offset(offset, ret);
>>  return ret;
>>  }
>> +
>> +/**
>> + * rtc_power_off_program - Some of the rtc are hooked on to PMIC_EN
>> + * line and can be used to power off the SoC.
>> + *
>> + * Kernel interface to program rtc to power off
>> + */
>> +void rtc_power_off_program(struct rtc_device *rtc)
>> +{
>> +rtc->ops->power_off_program(rtc->dev.parent);
>> +}
>> +EXPORT_SYMBOL_GPL(rtc_power_off_program);
>> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
>> index 3908639..4dcee1c 100644
>> --- a/drivers/rtc/rtc-omap.c
>> +++ b/drivers/rtc/rtc-omap.c
>> @@ -29,6 +29,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  
>>  /*
>> @@ -131,6 +132,8 @@
>>  #define KICK0_VALUE 0x83e70b13
>>  #define KICK1_VALUE 0x95a4f1e0
>>  
>> +#define SHUTDOWN_TIME_SEC   1
>> +
>>  struct omap_rtc;
>>  
>>  struct omap_rtc_device_type {
>> @@ -415,6 +418,77 @@ static int omap_rtc_set_alarm(struct device *dev, 
>> struct rtc_wkalrm *alm)
>>  
>>  static struct omap_rtc *omap_rtc_power_off_rtc;
>>  
>> +/**
>> + * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
>> + * generates pmic_pwr_enable control, which can be used to control an 
>> external
>> + * PMIC.
>> + */
>> +void omap_rtc_power_off_program(struct device *dev)
>> +{
>> +u32 val;
>> +struct rtc_time tm;
>> +unsigned long time;
>> +int seconds;
>> +
>> +omap_rtc_power_off_rtc->type->unlock(omap_rtc_power_off_rtc);
>> +
>> +/* Clear any existing ALARM2 event */
>> +rtc_writel(omap_rtc_power_off_rtc, OMAP_RTC_STATUS_REG,
>> +   OMAP_RTC_STATUS_ALARM2);
>> +
>> +pr_info("System will go to power_off state in approx. %d second\n",
>> +SHUTDOWN_TIME_SEC);
>> 

[PATCH 2/2] ARM: OMAP2+: sleep43xx: Add RTC-Mode support

2018-07-04 Thread Keerthy
Add support for RTC mode to low level suspend code. This includes
providing the rtc base address for the assembly code to configuring the
PMIC_PWR_EN line late in suspend to enter RTC+DDR mode.

Signed-off-by: Dave Gerlach 
Signed-off-by: Keerthy 
---
 arch/arm/mach-omap2/pm-asm-offsets.c |  2 ++
 arch/arm/mach-omap2/pm33xx-core.c| 10 +++
 arch/arm/mach-omap2/sleep33xx.S  |  8 +++--
 arch/arm/mach-omap2/sleep43xx.S  | 57 ++--
 drivers/soc/ti/pm33xx.c  |  1 +
 include/linux/platform_data/pm33xx.h |  3 ++
 6 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/pm-asm-offsets.c 
b/arch/arm/mach-omap2/pm-asm-offsets.c
index b9846b1..d202306 100644
--- a/arch/arm/mach-omap2/pm-asm-offsets.c
+++ b/arch/arm/mach-omap2/pm-asm-offsets.c
@@ -27,6 +27,8 @@ int main(void)
   offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_virt));
DEFINE(AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET,
   offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_phys));
+   DEFINE(AMX3_PM_RTC_BASE_VIRT_OFFSET,
+   offsetof(struct am33xx_pm_ro_sram_data, rtc_base_virt));
DEFINE(AMX3_PM_RO_SRAM_DATA_SIZE,
   sizeof(struct am33xx_pm_ro_sram_data));
 
diff --git a/arch/arm/mach-omap2/pm33xx-core.c 
b/arch/arm/mach-omap2/pm33xx-core.c
index e363b97..f4971e4 100644
--- a/arch/arm/mach-omap2/pm33xx-core.c
+++ b/arch/arm/mach-omap2/pm33xx-core.c
@@ -26,6 +26,7 @@
 static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
 static struct clockdomain *gfx_l4ls_clkdm;
 static void __iomem *scu_base;
+static struct omap_hwmod *rtc_oh;
 
 static int __init am43xx_map_scu(void)
 {
@@ -153,16 +154,25 @@ static struct am33xx_pm_sram_addr 
*amx3_get_sram_addrs(void)
return NULL;
 }
 
+void __iomem *am43xx_get_rtc_base_addr(void)
+{
+   rtc_oh = omap_hwmod_lookup("rtc");
+
+   return omap_hwmod_get_mpu_rt_va(rtc_oh);
+}
+
 static struct am33xx_pm_platform_data am33xx_ops = {
.init = am33xx_suspend_init,
.soc_suspend = am33xx_suspend,
.get_sram_addrs = amx3_get_sram_addrs,
+   .get_rtc_base_addr = am43xx_get_rtc_base_addr,
 };
 
 static struct am33xx_pm_platform_data am43xx_ops = {
.init = am43xx_suspend_init,
.soc_suspend = am43xx_suspend,
.get_sram_addrs = amx3_get_sram_addrs,
+   .get_rtc_base_addr = am43xx_get_rtc_base_addr,
 };
 
 static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
diff --git a/arch/arm/mach-omap2/sleep33xx.S b/arch/arm/mach-omap2/sleep33xx.S
index 3ef469f..47a8164 100644
--- a/arch/arm/mach-omap2/sleep33xx.S
+++ b/arch/arm/mach-omap2/sleep33xx.S
@@ -20,6 +20,9 @@
 #define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE   0x0003
 #define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE0x0002
 
+/* replicated define because linux/bitops.h cannot be included in assembly */
+#define BIT(nr)(1 << (nr))
+
.arm
.align 3
 
@@ -225,8 +228,6 @@ ENDPROC(am33xx_resume_from_deep_sleep)
  * Local variables
  */
.align
-resume_addr:
-   .word   cpu_resume - PAGE_OFFSET + 0x8000
 kernel_flush:
.word   v7_flush_dcache_all
 virt_mpu_clkctrl:
@@ -249,6 +250,9 @@ ENTRY(am33xx_pm_sram)
.word am33xx_emif_sram_table
.word am33xx_pm_ro_sram_data
 
+resume_addr:
+.word  cpu_resume - PAGE_OFFSET + 0x8000
+
 .align 3
 ENTRY(am33xx_pm_ro_sram_data)
.space AMX3_PM_RO_SRAM_DATA_SIZE
diff --git a/arch/arm/mach-omap2/sleep43xx.S b/arch/arm/mach-omap2/sleep43xx.S
index 0553adb..5b9343b 100644
--- a/arch/arm/mach-omap2/sleep43xx.S
+++ b/arch/arm/mach-omap2/sleep43xx.S
@@ -22,6 +22,9 @@
 #include "prm33xx.h"
 #include "prcm43xx.h"
 
+/* replicated define because linux/bitops.h cannot be included in assembly */
+#define BIT(nr)(1 << (nr))
+
 #define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 0x0003
 #define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE   0x0003
 #define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE0x0002
@@ -45,6 +48,13 @@
AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
 #define AM43XX_PRM_EMIF_CTRL_OFFSET0x0030
 
+#define RTC_SECONDS_REG0x0
+#define RTC_PMIC_REG   0x98
+#define RTC_PMIC_POWER_EN  BIT(16)
+#define RTC_PMIC_EXT_WAKEUP_STSBIT(12)
+#define RTC_PMIC_EXT_WAKEUP_POLBIT(4)
+#define RTC_PMIC_EXT_WAKEUP_EN BIT(0)
+
.arm
.align 3
 
@@ -144,6 +154,20 @@ sync:
ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
 
 cache_skip_flush:
+   /*
+* If we are trying to enter RTC+DDR mode we must perform
+* a read from the rtc address space to ensure 

[PATCH 1/2] ARM: OMAP2+: sleep33/43xx: Make sleep actions configurable

2018-07-04 Thread Keerthy
From: Dave Gerlach 

Add an argument to the sleep33xx and sleep43xx code to allow us to set
flags to determine which portions of the code get called in order to use
the same code for multiple power saving modes. This patch allows us to
decide whether or not we flush and disable caches, save EMIF context,
put the memory into self refresh and disable the EMIF, and/or invoke
the wkup_m3 when entering into WFI.

Signed-off-by: Dave Gerlach 
Signed-off-by: Tero Kristo 
Signed-off-by: Keerthy 
---
 arch/arm/mach-omap2/pm33xx-core.c| 10 ---
 arch/arm/mach-omap2/sleep33xx.S  | 44 ++
 arch/arm/mach-omap2/sleep43xx.S  | 53 +---
 drivers/soc/ti/pm33xx.c  | 15 +-
 include/linux/platform_data/pm33xx.h | 26 +-
 5 files changed, 138 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/pm33xx-core.c 
b/arch/arm/mach-omap2/pm33xx-core.c
index 9b3755a..e363b97 100644
--- a/arch/arm/mach-omap2/pm33xx-core.c
+++ b/arch/arm/mach-omap2/pm33xx-core.c
@@ -106,12 +106,13 @@ static void amx3_post_suspend_common(void)
pr_err("PM: GFX domain did not transition: %x\n", status);
 }
 
-static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long))
+static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long),
+ unsigned long args)
 {
int ret = 0;
 
amx3_pre_suspend_common();
-   ret = cpu_suspend(0, fn);
+   ret = cpu_suspend(args, fn);
amx3_post_suspend_common();
 
/*
@@ -128,13 +129,14 @@ static int am33xx_suspend(unsigned int state, int 
(*fn)(unsigned long))
return ret;
 }
 
-static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long))
+static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
+ unsigned long args)
 {
int ret = 0;
 
amx3_pre_suspend_common();
scu_power_mode(scu_base, SCU_PM_POWEROFF);
-   ret = cpu_suspend(0, fn);
+   ret = cpu_suspend(args, fn);
scu_power_mode(scu_base, SCU_PM_NORMAL);
amx3_post_suspend_common();
 
diff --git a/arch/arm/mach-omap2/sleep33xx.S b/arch/arm/mach-omap2/sleep33xx.S
index 322b3bb..3ef469f 100644
--- a/arch/arm/mach-omap2/sleep33xx.S
+++ b/arch/arm/mach-omap2/sleep33xx.S
@@ -8,6 +8,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,6 +26,16 @@
 ENTRY(am33xx_do_wfi)
stmfd   sp!, {r4 - r11, lr} @ save registers on stack
 
+   /* Save wfi_flags arg to data space */
+   mov r4, r0
+   adr r3, am33xx_pm_ro_sram_data
+   ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
+   str r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
+
+   /* Only flush cache is we know we are losing MPU context */
+   tst r4, #WFI_FLAG_FLUSH_CACHE
+   beq cache_skip_flush
+
/*
 * Flush all data from the L1 and L2 data cache before disabling
 * SCTLR.C bit.
@@ -48,14 +59,33 @@ ENTRY(am33xx_do_wfi)
ldr r1, kernel_flush
blx r1
 
+   adr r3, am33xx_pm_ro_sram_data
+   ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
+   ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
+
+cache_skip_flush:
+   /* Check if we want self refresh */
+   tst r4, #WFI_FLAG_SELF_REFRESH
+   beq emif_skip_enter_sr
+
adr r9, am33xx_emif_sram_table
 
ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
blx r3
 
+emif_skip_enter_sr:
+   /* Only necessary if PER is losing context */
+   tst r4, #WFI_FLAG_SAVE_EMIF
+   beq emif_skip_save
+
ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
blx r3
 
+emif_skip_save:
+   /* Only can disable EMIF if we have entered self refresh */
+   tst r4, #WFI_FLAG_SELF_REFRESH
+   beq emif_skip_disable
+
/* Disable EMIF */
ldr r1, virt_emif_clkctrl
ldr r2, [r1]
@@ -69,6 +99,10 @@ wait_emif_disable:
cmp r2, r3
bne wait_emif_disable
 
+emif_skip_disable:
+   tst r4, #WFI_FLAG_WAKE_M3
+   beq wkup_m3_skip
+
/*
 * For the MPU WFI to be registered as an interrupt
 * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
@@ -79,6 +113,7 @@ wait_emif_disable:
bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
str r2, [r1]
 
+wkup_m3_skip:
/*
 * Execute an ISB instruction to ensure that all of the
 * CP15 register changes have been committed.
@@ -132,10 +167,18 @@ wait_emif_enable:
cmp r2, r3
bne wait_emif_enable
 
+   /* Only necessary if PER is losing context */
+   tst r4, #WFI_FLAG_SELF_REFRESH
+   beq emif_skip_exit_sr_abt
 
+   adr r9, am33xx_emif_sram_table
ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
blx r1
 
+emif_skip_exit_sr_abt:
+   

[PATCH] rtc: OMAP: Add support for rtc-only mode

2018-07-04 Thread Keerthy
Prepare rtc driver for rtc-only mode. This involes splitting the power-off
function so that an external driver can initiate the programming of
setting the power_off to be triggered in the next second.

Signed-off-by: Keerthy 
---
 drivers/rtc/interface.c |  12 
 drivers/rtc/rtc-omap.c  | 164 ++--
 include/linux/rtc.h |   2 +
 3 files changed, 130 insertions(+), 48 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 6d4012d..d8b70f0 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -1139,3 +1139,15 @@ int rtc_set_offset(struct rtc_device *rtc, long offset)
trace_rtc_set_offset(offset, ret);
return ret;
 }
+
+/**
+ * rtc_power_off_program - Some of the rtc are hooked on to PMIC_EN
+ * line and can be used to power off the SoC.
+ *
+ * Kernel interface to program rtc to power off
+ */
+void rtc_power_off_program(struct rtc_device *rtc)
+{
+   rtc->ops->power_off_program(rtc->dev.parent);
+}
+EXPORT_SYMBOL_GPL(rtc_power_off_program);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 3908639..4dcee1c 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -131,6 +132,8 @@
 #defineKICK0_VALUE 0x83e70b13
 #defineKICK1_VALUE 0x95a4f1e0
 
+#define SHUTDOWN_TIME_SEC  1
+
 struct omap_rtc;
 
 struct omap_rtc_device_type {
@@ -415,6 +418,77 @@ static int omap_rtc_set_alarm(struct device *dev, struct 
rtc_wkalrm *alm)
 
 static struct omap_rtc *omap_rtc_power_off_rtc;
 
+/**
+ * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
+ * generates pmic_pwr_enable control, which can be used to control an external
+ * PMIC.
+ */
+void omap_rtc_power_off_program(struct device *dev)
+{
+   u32 val;
+   struct rtc_time tm;
+   unsigned long time;
+   int seconds;
+
+   omap_rtc_power_off_rtc->type->unlock(omap_rtc_power_off_rtc);
+
+   /* Clear any existing ALARM2 event */
+   rtc_writel(omap_rtc_power_off_rtc, OMAP_RTC_STATUS_REG,
+  OMAP_RTC_STATUS_ALARM2);
+
+   pr_info("System will go to power_off state in approx. %d second\n",
+   SHUTDOWN_TIME_SEC);
+
+again:
+   /* Read rtc time */
+   tm.tm_sec = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG);
+   seconds = tm.tm_sec;
+   tm.tm_min = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_MINUTES_REG);
+   tm.tm_hour = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_HOURS_REG);
+   tm.tm_mday = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_DAYS_REG);
+   tm.tm_mon = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_MONTHS_REG);
+   tm.tm_year = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_YEARS_REG);
+   bcd2tm();
+
+   /* Convert Gregorian date to seconds since 01-01-1970 00:00:00 */
+   rtc_tm_to_time(, );
+
+   /* Convert seconds since 01-01-1970 00:00:00 to Gregorian date */
+   rtc_time_to_tm(time + SHUTDOWN_TIME_SEC, );
+
+   if (tm2bcd() < 0)
+   return;
+
+   /* After wait_not_busy, we have at least 15us until the next second. */
+   rtc_wait_not_busy(omap_rtc_power_off_rtc);
+
+   /* Our calculations started right before the rollover, try again */
+   if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
+   goto again;
+
+   /*
+* pmic_pwr_enable is controlled by means of ALARM2 event. So here
+* programming alarm2 expiry time and enabling alarm2 interrupt
+*/
+   rtc_write(omap_rtc_power_off_rtc, OMAP_RTC_ALARM2_SECONDS_REG,
+ tm.tm_sec);
+   rtc_write(omap_rtc_power_off_rtc, OMAP_RTC_ALARM2_MINUTES_REG,
+ tm.tm_min);
+   rtc_write(omap_rtc_power_off_rtc, OMAP_RTC_ALARM2_HOURS_REG,
+ tm.tm_hour);
+   rtc_write(omap_rtc_power_off_rtc, OMAP_RTC_ALARM2_DAYS_REG,
+ tm.tm_mday);
+   rtc_write(omap_rtc_power_off_rtc, OMAP_RTC_ALARM2_MONTHS_REG,
+ tm.tm_mon);
+   rtc_write(omap_rtc_power_off_rtc, OMAP_RTC_ALARM2_YEARS_REG,
+ tm.tm_year);
+
+   /* Enable alarm2 interrupt */
+   val = rtc_readl(omap_rtc_power_off_rtc, OMAP_RTC_INTERRUPTS_REG);
+   rtc_writel(omap_rtc_power_off_rtc, OMAP_RTC_INTERRUPTS_REG, val |
+  OMAP_RTC_INTERRUPTS_IT_ALARM2);
+}
+
 /*
  * omap_rtc_poweroff: RTC-controlled power off
  *
@@ -431,45 +505,19 @@ static int omap_rtc_set_alarm(struct device *dev, struct 
rtc_wkalrm *alm)
  */
 static void omap_rtc_power_off(void)
 {
-   struct omap_rtc *rtc = omap_rtc_power_off_rtc;
-   struct rtc_time tm;
-   unsigned long now;
+   struct rtc_device *rtc = omap_rtc_power_off_rtc->rtc;
u32 val;
 
-   rtc->type->unlock(rtc);
-   /* enable pmic_power_en c

[PATCH v3 0/4] rtc: OMAP: Add support for rtc-only mode

2018-07-10 Thread Keerthy
Prepare rtc driver for rtc-only with DDR in self-refresh mode.
The patch series is based on top of Johan Hovald's series:

https://lkml.kernel.org/r/20180704090558.16647-1-jo...@kernel.org

Tested for suspend/resume and poweroff on am437x-gp-evm.

Keerthy (4):
  rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec
  rtc: OMAP: Add support for rtc-only mode
  rtc: omap: use of_device_is_system_power_controller function
  rtc: interface: Add power_off_program ops

 drivers/rtc/interface.c | 12 +
 drivers/rtc/rtc-omap.c  | 71 -
 include/linux/rtc.h |  2 ++
 3 files changed, 66 insertions(+), 19 deletions(-)

-- 
1.9.1



[PATCH v3 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-07-10 Thread Keerthy
Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
over try again.

Signed-off-by: Keerthy 
---
 drivers/rtc/rtc-omap.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 323ff55..14f2241 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -441,11 +441,12 @@ static void omap_rtc_power_off(void)
val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
 
-   /* set alarm two seconds from now */
+again:
+   /* set alarm one second from now */
omap_rtc_read_time_raw(rtc, );
bcd2tm();
rtc_tm_to_time(, );
-   rtc_time_to_tm(now + 2, );
+   rtc_time_to_tm(now + 1, );
 
if (tm2bcd() < 0) {
dev_err(>rtc->dev, "power off failed\n");
@@ -455,6 +456,10 @@ static void omap_rtc_power_off(void)
 
rtc_wait_not_busy(rtc);
 
+   /* Our calculations started right before the rollover, try again */
+   if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
+   goto again;
+
rtc_write(rtc, OMAP_RTC_ALARM2_SECONDS_REG, tm.tm_sec);
rtc_write(rtc, OMAP_RTC_ALARM2_MINUTES_REG, tm.tm_min);
rtc_write(rtc, OMAP_RTC_ALARM2_HOURS_REG, tm.tm_hour);
-- 
1.9.1



[PATCH v3 2/4] rtc: OMAP: Add support for rtc-only mode

2018-07-10 Thread Keerthy
Prepare rtc driver for rtc-only with DDR in self-refresh mode.
omap_rtc_power_off now should cater to two features:

1) RTC plus DDR in self-refresh is power a saving mode where in the
entire system including the different voltage rails from PMIC are
shutdown except the ones feeding on to RTC and DDR. DDR is kept in
self-refresh hence the contents are preserved. RTC ALARM2 is connected
to PMIC_EN line once we the ALARM2 is triggered we enter the mode with
DDR in self-refresh and RTC Ticking. After a predetermined time an RTC
ALARM1 triggers waking up the system[1]. The control goes to bootloader.
The bootloader then checks RTC scratchpad registers to confirm it was an
rtc_only wakeup and follows a different path, configure bare minimal
clocks for ddr and then jumps to the resume address in another RTC
scratchpad registers and transfers the control to Kernel. Kernel then
restores the saved context. omap_rtc_power_off_program does the ALARM2
programming part.

 [1] http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf Page 2884

2) Power-off: This is usual poweroff mode. omap_rtc_power_off calls the
above omap_rtc_power_off_program function and in addition to that
programs the OMAP_RTC_PMIC_REG for any external wake ups for PMIC like
the pushbutton and shuts off the PMIC.

Hence the split in omap_rtc_power_off.

Signed-off-by: Keerthy 
---
 drivers/rtc/rtc-omap.c | 58 +-
 1 file changed, 43 insertions(+), 15 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 14f2241..af46140 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -415,28 +415,23 @@ static int omap_rtc_set_alarm(struct device *dev, struct 
rtc_wkalrm *alm)
 
 static struct omap_rtc *omap_rtc_power_off_rtc;
 
-/*
- * omap_rtc_poweroff: RTC-controlled power off
- *
- * The RTC can be used to control an external PMIC via the pmic_power_en pin,
- * which can be configured to transition to OFF on ALARM2 events.
- *
- * Notes:
- * The two-second alarm offset is the shortest offset possible as the alarm
- * registers must be set before the next timer update and the offset
- * calculation is too heavy for everything to be done within a single access
- * period (~15 us).
- *
- * Called with local interrupts disabled.
+/**
+ * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
+ * generates pmic_pwr_enable control, which can be used to control an external
+ * PMIC.
  */
-static void omap_rtc_power_off(void)
+static int omap_rtc_power_off_program(struct device *dev)
 {
struct omap_rtc *rtc = omap_rtc_power_off_rtc;
struct rtc_time tm;
unsigned long now;
+   int seconds;
u32 val;
 
rtc->type->unlock(rtc);
+   /* Clear any existing ALARM2 event */
+   rtc_writel(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM2);
+
/* enable pmic_power_en control */
val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
@@ -444,6 +439,7 @@ static void omap_rtc_power_off(void)
 again:
/* set alarm one second from now */
omap_rtc_read_time_raw(rtc, );
+   seconds = tm.tm_sec;
bcd2tm();
rtc_tm_to_time(, );
rtc_time_to_tm(now + 1, );
@@ -451,7 +447,7 @@ static void omap_rtc_power_off(void)
if (tm2bcd() < 0) {
dev_err(>rtc->dev, "power off failed\n");
rtc->type->lock(rtc);
-   return;
+   return -EINVAL;
}
 
rtc_wait_not_busy(rtc);
@@ -477,6 +473,38 @@ static void omap_rtc_power_off(void)
val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
rtc->type->lock(rtc);
 
+   return 0;
+}
+
+/*
+ * omap_rtc_poweroff: RTC-controlled power off
+ *
+ * The RTC can be used to control an external PMIC via the pmic_power_en pin,
+ * which can be configured to transition to OFF on ALARM2 events.
+ *
+ * Notes:
+ * The one-second alarm offset is the shortest offset possible as the alarm
+ * registers must be set before the next timer update and the offset
+ * calculation is too heavy for everything to be done within a single access
+ * period (~15 us).
+ *
+ * Called with local interrupts disabled.
+ */
+static void omap_rtc_power_off(void)
+{
+   struct rtc_device *rtc = omap_rtc_power_off_rtc->rtc;
+   u32 val;
+
+   omap_rtc_power_off_program(rtc->dev.parent);
+
+   /* Set PMIC power enable and EXT_WAKEUP in case PB power on is used */
+   omap_rtc_power_off_rtc->type->unlock(omap_rtc_power_off_rtc);
+   val = rtc_readl(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG);
+   val |= OMAP_RTC_PMIC_POWER_EN_EN | OMAP_RTC_PMIC_EXT_WKUP_POL(0) |
+   OMAP_RTC_PMIC_EXT_WKUP_EN(0);
+   rtc_writel(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG, val);
+   omap_rtc_power_off_rtc->type->lock(omap_rtc_power_off_rtc);
+
/*
 

[PATCH v3 3/4] rtc: omap: use of_device_is_system_power_controller function

2018-07-10 Thread Keerthy
Use of_device_is_system_power_controller instead of manually reading
the system-power-controller property from the device tree node.

Signed-off-by: Keerthy 
---
 drivers/rtc/rtc-omap.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index af46140..75a12eb 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -754,8 +754,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
if (of_id) {
rtc->type = of_id->data;
rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
-   of_property_read_bool(pdev->dev.of_node,
-   "system-power-controller");
+   of_device_is_system_power_controller(pdev->dev.of_node);
} else {
id_entry = platform_get_device_id(pdev);
rtc->type = (void *)id_entry->driver_data;
-- 
1.9.1



[PATCH v3 4/4] rtc: interface: Add power_off_program to rtc_class_ops

2018-07-10 Thread Keerthy
Add an interface function to set up the rtc for a power_off
mode.

Signed-off-by: Keerthy 
---

Alexandre,

If you feel power_off_program will be very use case specific then
I can name this as custom_rtc_program so that even other rtc
drivers if need be can use this for a custom programming.

- Keerthy

 drivers/rtc/interface.c | 12 
 drivers/rtc/rtc-omap.c  |  1 +
 include/linux/rtc.h |  2 ++
 3 files changed, 15 insertions(+)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 6d4012d..c19668b9 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -1139,3 +1139,15 @@ int rtc_set_offset(struct rtc_device *rtc, long offset)
trace_rtc_set_offset(offset, ret);
return ret;
 }
+
+/**
+ * rtc_power_off_program - Some of the rtc are hooked on to PMIC_EN
+ * line and can be used to power off the SoC.
+ *
+ * Kernel interface to program rtc to power off
+ */
+int rtc_power_off_program(struct rtc_device *rtc)
+{
+   return rtc->ops->power_off_program(rtc->dev.parent);
+}
+EXPORT_SYMBOL_GPL(rtc_power_off_program);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 75a12eb..a1f9dde 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -519,6 +519,7 @@ static void omap_rtc_power_off(void)
.read_alarm = omap_rtc_read_alarm,
.set_alarm  = omap_rtc_set_alarm,
.alarm_irq_enable = omap_rtc_alarm_irq_enable,
+   .power_off_program = omap_rtc_power_off_program,
 };
 
 static const struct omap_rtc_device_type omap_rtc_default_type = {
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 6268208..3fc640c 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -85,6 +85,7 @@ struct rtc_class_ops {
int (*alarm_irq_enable)(struct device *, unsigned int enabled);
int (*read_offset)(struct device *, long *offset);
int (*set_offset)(struct device *, long offset);
+   int (*power_off_program)(struct device *dev);
 };
 
 typedef struct rtc_task {
@@ -229,6 +230,7 @@ int rtc_timer_start(struct rtc_device *rtc, struct 
rtc_timer *timer,
 int rtc_read_offset(struct rtc_device *rtc, long *offset);
 int rtc_set_offset(struct rtc_device *rtc, long offset);
 void rtc_timer_do_work(struct work_struct *work);
+int rtc_power_off_program(struct rtc_device *rtc);
 
 static inline bool is_leap_year(unsigned int year)
 {
-- 
1.9.1



[PATCH v4 0/4] rtc: OMAP: Add support for rtc-only mode

2018-07-11 Thread Keerthy
Prepare rtc driver for rtc-only with DDR in self-refresh mode.
The patch series is based on top of Johan Hovald's series:

https://lkml.kernel.org/r/20180704090558.16647-1-jo...@kernel.org

Tested for suspend/resume and poweroff on am437x-gp-evm. 

Keerthy (4):
  rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec
  rtc: OMAP: Add support for rtc-only mode
  rtc: omap: use of_device_is_system_power_controller function
  rtc: interface: Add power_off_program to rtc_class_ops

 drivers/rtc/interface.c | 12 +
 drivers/rtc/rtc-omap.c  | 70 +++--
 include/linux/rtc.h |  2 ++
 3 files changed, 65 insertions(+), 19 deletions(-)

-- 
1.9.1



[PATCH v4 4/4] rtc: interface: Add power_off_program to rtc_class_ops

2018-07-11 Thread Keerthy
Add an interface function to set up the rtc for a power_off
mode.

Signed-off-by: Keerthy 
---
 drivers/rtc/interface.c | 12 
 drivers/rtc/rtc-omap.c  |  1 +
 include/linux/rtc.h |  2 ++
 3 files changed, 15 insertions(+)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 6d4012d..c19668b9 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -1139,3 +1139,15 @@ int rtc_set_offset(struct rtc_device *rtc, long offset)
trace_rtc_set_offset(offset, ret);
return ret;
 }
+
+/**
+ * rtc_power_off_program - Some of the rtc are hooked on to PMIC_EN
+ * line and can be used to power off the SoC.
+ *
+ * Kernel interface to program rtc to power off
+ */
+int rtc_power_off_program(struct rtc_device *rtc)
+{
+   return rtc->ops->power_off_program(rtc->dev.parent);
+}
+EXPORT_SYMBOL_GPL(rtc_power_off_program);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 3610efd..9c9ea44 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -518,6 +518,7 @@ static void omap_rtc_power_off(void)
.read_alarm = omap_rtc_read_alarm,
.set_alarm  = omap_rtc_set_alarm,
.alarm_irq_enable = omap_rtc_alarm_irq_enable,
+   .power_off_program = omap_rtc_power_off_program,
 };
 
 static const struct omap_rtc_device_type omap_rtc_default_type = {
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 6268208..3fc640c 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -85,6 +85,7 @@ struct rtc_class_ops {
int (*alarm_irq_enable)(struct device *, unsigned int enabled);
int (*read_offset)(struct device *, long *offset);
int (*set_offset)(struct device *, long offset);
+   int (*power_off_program)(struct device *dev);
 };
 
 typedef struct rtc_task {
@@ -229,6 +230,7 @@ int rtc_timer_start(struct rtc_device *rtc, struct 
rtc_timer *timer,
 int rtc_read_offset(struct rtc_device *rtc, long *offset);
 int rtc_set_offset(struct rtc_device *rtc, long offset);
 void rtc_timer_do_work(struct work_struct *work);
+int rtc_power_off_program(struct rtc_device *rtc);
 
 static inline bool is_leap_year(unsigned int year)
 {
-- 
1.9.1



[PATCH v4 3/4] rtc: omap: use of_device_is_system_power_controller function

2018-07-11 Thread Keerthy
Use of_device_is_system_power_controller instead of manually reading
the system-power-controller property from the device tree node.

Signed-off-by: Keerthy 
---
 drivers/rtc/rtc-omap.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index cb19ece..3610efd 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -753,8 +753,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
if (of_id) {
rtc->type = of_id->data;
rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
-   of_property_read_bool(pdev->dev.of_node,
-   "system-power-controller");
+   of_device_is_system_power_controller(pdev->dev.of_node);
} else {
id_entry = platform_get_device_id(pdev);
rtc->type = (void *)id_entry->driver_data;
-- 
1.9.1



[PATCH v4 2/4] rtc: OMAP: Add support for rtc-only mode

2018-07-11 Thread Keerthy
Prepare rtc driver for rtc-only with DDR in self-refresh mode.
omap_rtc_power_off now should cater to two features:

1) RTC plus DDR in self-refresh is power a saving mode where in the
entire system including the different voltage rails from PMIC are
shutdown except the ones feeding on to RTC and DDR. DDR is kept in
self-refresh hence the contents are preserved. RTC ALARM2 is connected
to PMIC_EN line once we the ALARM2 is triggered we enter the mode with
DDR in self-refresh and RTC Ticking. After a predetermined time an RTC
ALARM1 triggers waking up the system[1]. The control goes to bootloader.
The bootloader then checks RTC scratchpad registers to confirm it was an
rtc_only wakeup and follows a different path, configure bare minimal
clocks for ddr and then jumps to the resume address in another RTC
scratchpad registers and transfers the control to Kernel. Kernel then
restores the saved context. omap_rtc_power_off_program does the ALARM2
programming part.

 [1] http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf Page 2884

2) Power-off: This is usual poweroff mode. omap_rtc_power_off calls the
above omap_rtc_power_off_program function and in addition to that
programs the OMAP_RTC_PMIC_REG for any external wake ups for PMIC like
the pushbutton and shuts off the PMIC.

Hence the split in omap_rtc_power_off.

Signed-off-by: Keerthy 
---
 drivers/rtc/rtc-omap.c | 53 --
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 88da927..cb19ece 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -415,21 +415,12 @@ static int omap_rtc_set_alarm(struct device *dev, struct 
rtc_wkalrm *alm)
 
 static struct omap_rtc *omap_rtc_power_off_rtc;
 
-/*
- * omap_rtc_poweroff: RTC-controlled power off
- *
- * The RTC can be used to control an external PMIC via the pmic_power_en pin,
- * which can be configured to transition to OFF on ALARM2 events.
- *
- * Notes:
- * The two-second alarm offset is the shortest offset possible as the alarm
- * registers must be set before the next timer update and the offset
- * calculation is too heavy for everything to be done within a single access
- * period (~15 us).
- *
- * Called with local interrupts disabled.
+/**
+ * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
+ * generates pmic_pwr_enable control, which can be used to control an external
+ * PMIC.
  */
-static void omap_rtc_power_off(void)
+static int omap_rtc_power_off_program(struct device *dev)
 {
struct omap_rtc *rtc = omap_rtc_power_off_rtc;
struct rtc_time tm;
@@ -456,7 +447,7 @@ static void omap_rtc_power_off(void)
if (tm2bcd() < 0) {
dev_err(>rtc->dev, "power off failed\n");
rtc->type->lock(rtc);
-   return;
+   return -EINVAL;
}
 
rtc_wait_not_busy(rtc);
@@ -481,6 +472,38 @@ static void omap_rtc_power_off(void)
goto again;
rtc->type->lock(rtc);
 
+   return 0;
+}
+
+/*
+ * omap_rtc_poweroff: RTC-controlled power off
+ *
+ * The RTC can be used to control an external PMIC via the pmic_power_en pin,
+ * which can be configured to transition to OFF on ALARM2 events.
+ *
+ * Notes:
+ * The one-second alarm offset is the shortest offset possible as the alarm
+ * registers must be set before the next timer update and the offset
+ * calculation is too heavy for everything to be done within a single access
+ * period (~15 us).
+ *
+ * Called with local interrupts disabled.
+ */
+static void omap_rtc_power_off(void)
+{
+   struct rtc_device *rtc = omap_rtc_power_off_rtc->rtc;
+   u32 val;
+
+   omap_rtc_power_off_program(rtc->dev.parent);
+
+   /* Set PMIC power enable and EXT_WAKEUP in case PB power on is used */
+   omap_rtc_power_off_rtc->type->unlock(omap_rtc_power_off_rtc);
+   val = rtc_readl(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG);
+   val |= OMAP_RTC_PMIC_POWER_EN_EN | OMAP_RTC_PMIC_EXT_WKUP_POL(0) |
+   OMAP_RTC_PMIC_EXT_WKUP_EN(0);
+   rtc_writel(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG, val);
+   omap_rtc_power_off_rtc->type->lock(omap_rtc_power_off_rtc);
+
/*
 * Wait for alarm to trigger (within two seconds) and external PMIC to
 * power off the system. Add a 500 ms margin for external latencies
-- 
1.9.1



[PATCH v4 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec

2018-07-11 Thread Keerthy
Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
over try again.

Signed-off-by: Keerthy 
---

Changes in v4:

  * Fixed a compilation issue.
  * Extended the roll over check post interrupt programming.

 drivers/rtc/rtc-omap.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 323ff55..88da927 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -435,17 +435,23 @@ static void omap_rtc_power_off(void)
struct rtc_time tm;
unsigned long now;
u32 val;
+   int seconds;
 
rtc->type->unlock(rtc);
/* enable pmic_power_en control */
val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
 
-   /* set alarm two seconds from now */
+again:
+   /* Clear any existing ALARM2 event */
+   rtc_writel(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM2);
+
+   /* set alarm one second from now */
omap_rtc_read_time_raw(rtc, );
+   seconds = tm.tm_sec;
bcd2tm();
rtc_tm_to_time(, );
-   rtc_time_to_tm(now + 2, );
+   rtc_time_to_tm(now + 1, );
 
if (tm2bcd() < 0) {
dev_err(>rtc->dev, "power off failed\n");
@@ -470,6 +476,9 @@ static void omap_rtc_power_off(void)
val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG);
rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG,
val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
+   /* Our calculations started right before the rollover, try again */
+   if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
+   goto again;
rtc->type->lock(rtc);
 
/*
-- 
1.9.1



Re: [PATCH v2] rtc: OMAP: Add support for rtc-only mode

2018-07-09 Thread Keerthy



On Monday 09 July 2018 02:59 PM, Alexandre Belloni wrote:
> On 09/07/2018 09:55:53+0200, Johan Hovold wrote:
>> On Mon, Jul 09, 2018 at 11:41:49AM +0530, Keerthy wrote:
>>> Prepare rtc driver for rtc-only with DDR in self-refresh mode.
>>> omap_rtc_power_off now should cater to two features:
>>>
>>> 1) RTC plus DDR in self-refresh is power a saving mode where in the
>>> entire system including the different voltage rails from PMIC are
>>> shutdown except the ones feeding on to RTC and DDR. DDR is kept in
>>> self-refresh hence the contents are preserved. RTC ALARM2 is connected
>>> to PMIC_EN line once we the ALARM2 is triggered we enter the mode with
>>> DDR in self-refresh and RTC Ticking. After a predetermined time an RTC
>>> ALARM1 triggers waking up the system[1]. The control goes to bootloader.
>>> The bootloader then checks RTC scratchpad registers to confirm it was an
>>> rtc_only wakeup and follows a different path, configure bare minimal
>>> clocks for ddr and then jumps to the resume address in another RTC
>>> scratchpad registers and transfers the control to Kernel. Kernel then
>>> restores the saved context. omap_rtc_power_off_program does the ALARM2
>>> programming part.
>>>
>>>  [1] http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf Page 2884
>>>
>>> 2) Power-off: This is usual poweroff mode. omap_rtc_power_off calls the
>>> above omap_rtc_power_off_program function and in addition to that
>>> programs the OMAP_RTC_PMIC_REG for any external wake ups for PMIC like
>>> the pushbutton and shuts off the PMIC.
>>>
>>> Hence the split in omap_rtc_power_off.
>>>
>>> Signed-off-by: Keerthy 
>>> ---
>>>
>>> Changes in v2:
>>>
>>>   * Add details in the commit log.
>>>   * Use of_device_is_system_power_controller to check if rtc node is
>>> indeed the system power control instead of manually reading property.
>>>
>>>  drivers/rtc/interface.c |  12 
>>>  drivers/rtc/rtc-omap.c  | 167 
>>> +---
>>>  include/linux/rtc.h |   2 +
>>>  3 files changed, 131 insertions(+), 50 deletions(-)
>>>
>>> diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
>>> index 6d4012d..d8b70f0 100644
>>> --- a/drivers/rtc/interface.c
>>> +++ b/drivers/rtc/interface.c
>>> @@ -1139,3 +1139,15 @@ int rtc_set_offset(struct rtc_device *rtc, long 
>>> offset)
>>> trace_rtc_set_offset(offset, ret);
>>> return ret;
>>>  }
>>> +
>>> +/**
>>> + * rtc_power_off_program - Some of the rtc are hooked on to PMIC_EN
>>> + * line and can be used to power off the SoC.
>>> + *
>>> + * Kernel interface to program rtc to power off
>>> + */
>>> +void rtc_power_off_program(struct rtc_device *rtc)
>>> +{
>>> +   rtc->ops->power_off_program(rtc->dev.parent);
>>> +}
>>> +EXPORT_SYMBOL_GPL(rtc_power_off_program);
>>
>> We typically do not add new interfaces without any users, so this will
>> probably have to go in along with the corresponding omap changes for
>> rtc-only mode.
>>
> 
> I'm probably not smart enough but I still don't get why you need to add
> an interface at all, especially one that will result in a NULL pointer
> dereference on 99.6% of the drivers.
> 
> This is so specific to your use case that this has zero chance to be
> reused by another driver.

Alexandre,

So are you suggesting use an EXPORT API from omap-rtc driver alone?
as it is too specific to one use case?

- Keerthy
> 


[PATCH v2 2/2] ARM: OMAP2+: sleep33/43xx: Add RTC-Mode support

2018-07-09 Thread Keerthy
Add support for RTC mode to low level suspend code. This includes
providing the rtc base address for the assembly code to configuring the
PMIC_PWR_EN line late in suspend to enter RTC+DDR mode.

Note: This patch also fold in left out space parameter for
am33xx_emif_sram_table and am43xx_emif_sram_table

Signed-off-by: Dave Gerlach 
Signed-off-by: Keerthy 
---

Changes in v2:

  * Swapped the bit definitons from patch 2 to 1

 arch/arm/mach-omap2/pm-asm-offsets.c |  2 ++
 arch/arm/mach-omap2/pm33xx-core.c| 10 +++
 arch/arm/mach-omap2/sleep33xx.S  |  5 ++--
 arch/arm/mach-omap2/sleep43xx.S  | 54 ++--
 drivers/soc/ti/pm33xx.c  |  1 +
 include/linux/platform_data/pm33xx.h |  3 ++
 6 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/pm-asm-offsets.c 
b/arch/arm/mach-omap2/pm-asm-offsets.c
index b9846b1..d202306 100644
--- a/arch/arm/mach-omap2/pm-asm-offsets.c
+++ b/arch/arm/mach-omap2/pm-asm-offsets.c
@@ -27,6 +27,8 @@ int main(void)
   offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_virt));
DEFINE(AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET,
   offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_phys));
+   DEFINE(AMX3_PM_RTC_BASE_VIRT_OFFSET,
+  offsetof(struct am33xx_pm_ro_sram_data, rtc_base_virt));
DEFINE(AMX3_PM_RO_SRAM_DATA_SIZE,
   sizeof(struct am33xx_pm_ro_sram_data));
 
diff --git a/arch/arm/mach-omap2/pm33xx-core.c 
b/arch/arm/mach-omap2/pm33xx-core.c
index e363b97..f4971e4 100644
--- a/arch/arm/mach-omap2/pm33xx-core.c
+++ b/arch/arm/mach-omap2/pm33xx-core.c
@@ -26,6 +26,7 @@
 static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
 static struct clockdomain *gfx_l4ls_clkdm;
 static void __iomem *scu_base;
+static struct omap_hwmod *rtc_oh;
 
 static int __init am43xx_map_scu(void)
 {
@@ -153,16 +154,25 @@ static struct am33xx_pm_sram_addr 
*amx3_get_sram_addrs(void)
return NULL;
 }
 
+void __iomem *am43xx_get_rtc_base_addr(void)
+{
+   rtc_oh = omap_hwmod_lookup("rtc");
+
+   return omap_hwmod_get_mpu_rt_va(rtc_oh);
+}
+
 static struct am33xx_pm_platform_data am33xx_ops = {
.init = am33xx_suspend_init,
.soc_suspend = am33xx_suspend,
.get_sram_addrs = amx3_get_sram_addrs,
+   .get_rtc_base_addr = am43xx_get_rtc_base_addr,
 };
 
 static struct am33xx_pm_platform_data am43xx_ops = {
.init = am43xx_suspend_init,
.soc_suspend = am43xx_suspend,
.get_sram_addrs = amx3_get_sram_addrs,
+   .get_rtc_base_addr = am43xx_get_rtc_base_addr,
 };
 
 static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
diff --git a/arch/arm/mach-omap2/sleep33xx.S b/arch/arm/mach-omap2/sleep33xx.S
index 8d0d53b..47a8164 100644
--- a/arch/arm/mach-omap2/sleep33xx.S
+++ b/arch/arm/mach-omap2/sleep33xx.S
@@ -228,8 +228,6 @@ ENDPROC(am33xx_resume_from_deep_sleep)
  * Local variables
  */
.align
-resume_addr:
-   .word   cpu_resume - PAGE_OFFSET + 0x8000
 kernel_flush:
.word   v7_flush_dcache_all
 virt_mpu_clkctrl:
@@ -252,6 +250,9 @@ ENTRY(am33xx_pm_sram)
.word am33xx_emif_sram_table
.word am33xx_pm_ro_sram_data
 
+resume_addr:
+.word  cpu_resume - PAGE_OFFSET + 0x8000
+
 .align 3
 ENTRY(am33xx_pm_ro_sram_data)
.space AMX3_PM_RO_SRAM_DATA_SIZE
diff --git a/arch/arm/mach-omap2/sleep43xx.S b/arch/arm/mach-omap2/sleep43xx.S
index cd7e95f..5b9343b 100644
--- a/arch/arm/mach-omap2/sleep43xx.S
+++ b/arch/arm/mach-omap2/sleep43xx.S
@@ -48,6 +48,13 @@
AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
 #define AM43XX_PRM_EMIF_CTRL_OFFSET0x0030
 
+#define RTC_SECONDS_REG0x0
+#define RTC_PMIC_REG   0x98
+#define RTC_PMIC_POWER_EN  BIT(16)
+#define RTC_PMIC_EXT_WAKEUP_STSBIT(12)
+#define RTC_PMIC_EXT_WAKEUP_POLBIT(4)
+#define RTC_PMIC_EXT_WAKEUP_EN BIT(0)
+
.arm
.align 3
 
@@ -147,6 +154,20 @@ sync:
ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
 
 cache_skip_flush:
+   /*
+* If we are trying to enter RTC+DDR mode we must perform
+* a read from the rtc address space to ensure translation
+* presence in the TLB to avoid page table walk after DDR
+* is unavailable.
+*/
+   tst r4, #WFI_FLAG_RTC_ONLY
+   beq skip_rtc_va_refresh
+
+   adr r3, am43xx_pm_ro_sram_data
+   ldr r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
+   ldr r0, [r1]
+
+skip_rtc_va_refresh:
/* Check if we want self refresh */
tst r4, #WFI_FLAG_SELF_REFRESH
beq emif_skip_enter_sr
@@ -182,6 +203,34 @@ wait_emif_disable:
bne wait_emif_disable
 
 emif_skip_disable:
+   

[PATCH v2] rtc: OMAP: Add support for rtc-only mode

2018-07-09 Thread Keerthy
Prepare rtc driver for rtc-only with DDR in self-refresh mode.
omap_rtc_power_off now should cater to two features:

1) RTC plus DDR in self-refresh is power a saving mode where in the
entire system including the different voltage rails from PMIC are
shutdown except the ones feeding on to RTC and DDR. DDR is kept in
self-refresh hence the contents are preserved. RTC ALARM2 is connected
to PMIC_EN line once we the ALARM2 is triggered we enter the mode with
DDR in self-refresh and RTC Ticking. After a predetermined time an RTC
ALARM1 triggers waking up the system[1]. The control goes to bootloader.
The bootloader then checks RTC scratchpad registers to confirm it was an
rtc_only wakeup and follows a different path, configure bare minimal
clocks for ddr and then jumps to the resume address in another RTC
scratchpad registers and transfers the control to Kernel. Kernel then
restores the saved context. omap_rtc_power_off_program does the ALARM2
programming part.

 [1] http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf Page 2884

2) Power-off: This is usual poweroff mode. omap_rtc_power_off calls the
above omap_rtc_power_off_program function and in addition to that
programs the OMAP_RTC_PMIC_REG for any external wake ups for PMIC like
the pushbutton and shuts off the PMIC.

Hence the split in omap_rtc_power_off.

Signed-off-by: Keerthy 
---

Changes in v2:

  * Add details in the commit log.
  * Use of_device_is_system_power_controller to check if rtc node is
indeed the system power control instead of manually reading property.

 drivers/rtc/interface.c |  12 
 drivers/rtc/rtc-omap.c  | 167 +---
 include/linux/rtc.h |   2 +
 3 files changed, 131 insertions(+), 50 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 6d4012d..d8b70f0 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -1139,3 +1139,15 @@ int rtc_set_offset(struct rtc_device *rtc, long offset)
trace_rtc_set_offset(offset, ret);
return ret;
 }
+
+/**
+ * rtc_power_off_program - Some of the rtc are hooked on to PMIC_EN
+ * line and can be used to power off the SoC.
+ *
+ * Kernel interface to program rtc to power off
+ */
+void rtc_power_off_program(struct rtc_device *rtc)
+{
+   rtc->ops->power_off_program(rtc->dev.parent);
+}
+EXPORT_SYMBOL_GPL(rtc_power_off_program);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 3908639..7f45e02 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -131,6 +132,8 @@
 #defineKICK0_VALUE 0x83e70b13
 #defineKICK1_VALUE 0x95a4f1e0
 
+#define SHUTDOWN_TIME_SEC  1
+
 struct omap_rtc;
 
 struct omap_rtc_device_type {
@@ -415,6 +418,77 @@ static int omap_rtc_set_alarm(struct device *dev, struct 
rtc_wkalrm *alm)
 
 static struct omap_rtc *omap_rtc_power_off_rtc;
 
+/**
+ * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
+ * generates pmic_pwr_enable control, which can be used to control an external
+ * PMIC.
+ */
+void omap_rtc_power_off_program(struct device *dev)
+{
+   u32 val;
+   struct rtc_time tm;
+   unsigned long time;
+   int seconds;
+
+   omap_rtc_power_off_rtc->type->unlock(omap_rtc_power_off_rtc);
+
+   /* Clear any existing ALARM2 event */
+   rtc_writel(omap_rtc_power_off_rtc, OMAP_RTC_STATUS_REG,
+  OMAP_RTC_STATUS_ALARM2);
+
+   pr_info("System will go to power_off state in approx. %d second\n",
+   SHUTDOWN_TIME_SEC);
+
+again:
+   /* Read rtc time */
+   tm.tm_sec = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG);
+   seconds = tm.tm_sec;
+   tm.tm_min = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_MINUTES_REG);
+   tm.tm_hour = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_HOURS_REG);
+   tm.tm_mday = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_DAYS_REG);
+   tm.tm_mon = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_MONTHS_REG);
+   tm.tm_year = rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_YEARS_REG);
+   bcd2tm();
+
+   /* Convert Gregorian date to seconds since 01-01-1970 00:00:00 */
+   rtc_tm_to_time(, );
+
+   /* Convert seconds since 01-01-1970 00:00:00 to Gregorian date */
+   rtc_time_to_tm(time + SHUTDOWN_TIME_SEC, );
+
+   if (tm2bcd() < 0)
+   return;
+
+   /* After wait_not_busy, we have at least 15us until the next second. */
+   rtc_wait_not_busy(omap_rtc_power_off_rtc);
+
+   /* Our calculations started right before the rollover, try again */
+   if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
+   goto again;
+
+   /*
+* pmic_pwr_enable is controlled by means of ALARM2 event. So here
+* programming alarm2 expiry time and enabling alarm2 interrupt
+

Re: [PATCH v2] rtc: OMAP: Add support for rtc-only mode

2018-07-09 Thread Keerthy



On Monday 09 July 2018 01:25 PM, Johan Hovold wrote:
> On Mon, Jul 09, 2018 at 11:41:49AM +0530, Keerthy wrote:
>> Prepare rtc driver for rtc-only with DDR in self-refresh mode.
>> omap_rtc_power_off now should cater to two features:
>>
>> 1) RTC plus DDR in self-refresh is power a saving mode where in the
>> entire system including the different voltage rails from PMIC are
>> shutdown except the ones feeding on to RTC and DDR. DDR is kept in
>> self-refresh hence the contents are preserved. RTC ALARM2 is connected
>> to PMIC_EN line once we the ALARM2 is triggered we enter the mode with
>> DDR in self-refresh and RTC Ticking. After a predetermined time an RTC
>> ALARM1 triggers waking up the system[1]. The control goes to bootloader.
>> The bootloader then checks RTC scratchpad registers to confirm it was an
>> rtc_only wakeup and follows a different path, configure bare minimal
>> clocks for ddr and then jumps to the resume address in another RTC
>> scratchpad registers and transfers the control to Kernel. Kernel then
>> restores the saved context. omap_rtc_power_off_program does the ALARM2
>> programming part.
>>
>>  [1] http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf Page 2884
>>
>> 2) Power-off: This is usual poweroff mode. omap_rtc_power_off calls the
>> above omap_rtc_power_off_program function and in addition to that
>> programs the OMAP_RTC_PMIC_REG for any external wake ups for PMIC like
>> the pushbutton and shuts off the PMIC.
>>
>> Hence the split in omap_rtc_power_off.
>>
>> Signed-off-by: Keerthy 
>> ---
>>
>> Changes in v2:
>>
>>   * Add details in the commit log.
>>   * Use of_device_is_system_power_controller to check if rtc node is
>> indeed the system power control instead of manually reading property.
>>
>>  drivers/rtc/interface.c |  12 
>>  drivers/rtc/rtc-omap.c  | 167 
>> +---
>>  include/linux/rtc.h |   2 +
>>  3 files changed, 131 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
>> index 6d4012d..d8b70f0 100644
>> --- a/drivers/rtc/interface.c
>> +++ b/drivers/rtc/interface.c
>> @@ -1139,3 +1139,15 @@ int rtc_set_offset(struct rtc_device *rtc, long 
>> offset)
>>  trace_rtc_set_offset(offset, ret);
>>  return ret;
>>  }
>> +
>> +/**
>> + * rtc_power_off_program - Some of the rtc are hooked on to PMIC_EN
>> + * line and can be used to power off the SoC.
>> + *
>> + * Kernel interface to program rtc to power off
>> + */
>> +void rtc_power_off_program(struct rtc_device *rtc)
>> +{
>> +rtc->ops->power_off_program(rtc->dev.parent);
>> +}
>> +EXPORT_SYMBOL_GPL(rtc_power_off_program);
> 
> We typically do not add new interfaces without any users, so this will
> probably have to go in along with the corresponding omap changes for
> rtc-only mode.

Yea okay.

> 
> Also, would you not like to be able to detect suspend failures by
> having the function return a status integer?

sure. Will make it integer returning function.

> 
>> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
>> index 3908639..7f45e02 100644
>> --- a/drivers/rtc/rtc-omap.c
>> +++ b/drivers/rtc/rtc-omap.c
>> @@ -29,6 +29,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  
>>  /*
>> @@ -131,6 +132,8 @@
>>  #define KICK0_VALUE 0x83e70b13
>>  #define KICK1_VALUE 0x95a4f1e0
>>  
>> +#define SHUTDOWN_TIME_SEC   1
> 
> IIRC setting the alarm two seconds into the future was essential to
> avoid missing an alarm and failing to power off the SoC. You're now
> changing this, not only for your future rtc-only use, but for the
> current power-off feature without even commenting on it.
> 
>> +
>>  struct omap_rtc;
>>  
>>  struct omap_rtc_device_type {
>> @@ -415,6 +418,77 @@ static int omap_rtc_set_alarm(struct device *dev, 
>> struct rtc_wkalrm *alm)
>>  
>>  static struct omap_rtc *omap_rtc_power_off_rtc;
>>  
>> +/**
>> + * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
>> + * generates pmic_pwr_enable control, which can be used to control an 
>> external
>> + * PMIC.
>> + */
>> +void omap_rtc_power_off_program(struct device *dev)
>> +{
>> +u32 val;
>> +struct rtc_time tm;
>> +unsigned long time;
>> +int seconds;
>

[PATCH v2 1/2] ARM: OMAP2+: sleep33/43xx: Make sleep actions configurable

2018-07-09 Thread Keerthy
From: Dave Gerlach 

Add an argument to the sleep33xx and sleep43xx code to allow us to set
flags to determine which portions of the code get called in order to use
the same code for multiple power saving modes. This patch allows us to
decide whether or not we flush and disable caches, save EMIF context,
put the memory into self refresh and disable the EMIF, and/or invoke
the wkup_m3 when entering into WFI.

Signed-off-by: Dave Gerlach 
Signed-off-by: Tero Kristo 
Signed-off-by: Keerthy 
---

Changes in v2:

  * Swapped the bit definitons from patch 2 to 1.

 arch/arm/mach-omap2/pm33xx-core.c| 10 ---
 arch/arm/mach-omap2/sleep33xx.S  | 47 ++
 arch/arm/mach-omap2/sleep43xx.S  | 56 +---
 drivers/soc/ti/pm33xx.c  | 15 +-
 include/linux/platform_data/pm33xx.h | 26 -
 5 files changed, 144 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-omap2/pm33xx-core.c 
b/arch/arm/mach-omap2/pm33xx-core.c
index 9b3755a..e363b97 100644
--- a/arch/arm/mach-omap2/pm33xx-core.c
+++ b/arch/arm/mach-omap2/pm33xx-core.c
@@ -106,12 +106,13 @@ static void amx3_post_suspend_common(void)
pr_err("PM: GFX domain did not transition: %x\n", status);
 }
 
-static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long))
+static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long),
+ unsigned long args)
 {
int ret = 0;
 
amx3_pre_suspend_common();
-   ret = cpu_suspend(0, fn);
+   ret = cpu_suspend(args, fn);
amx3_post_suspend_common();
 
/*
@@ -128,13 +129,14 @@ static int am33xx_suspend(unsigned int state, int 
(*fn)(unsigned long))
return ret;
 }
 
-static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long))
+static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
+ unsigned long args)
 {
int ret = 0;
 
amx3_pre_suspend_common();
scu_power_mode(scu_base, SCU_PM_POWEROFF);
-   ret = cpu_suspend(0, fn);
+   ret = cpu_suspend(args, fn);
scu_power_mode(scu_base, SCU_PM_NORMAL);
amx3_post_suspend_common();
 
diff --git a/arch/arm/mach-omap2/sleep33xx.S b/arch/arm/mach-omap2/sleep33xx.S
index 322b3bb..8d0d53b 100644
--- a/arch/arm/mach-omap2/sleep33xx.S
+++ b/arch/arm/mach-omap2/sleep33xx.S
@@ -8,6 +8,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -19,12 +20,25 @@
 #define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE   0x0003
 #define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE0x0002
 
+/* replicated define because linux/bitops.h cannot be included in assembly */
+#define BIT(nr)(1 << (nr))
+
.arm
.align 3
 
 ENTRY(am33xx_do_wfi)
stmfd   sp!, {r4 - r11, lr} @ save registers on stack
 
+   /* Save wfi_flags arg to data space */
+   mov r4, r0
+   adr r3, am33xx_pm_ro_sram_data
+   ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
+   str r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
+
+   /* Only flush cache is we know we are losing MPU context */
+   tst r4, #WFI_FLAG_FLUSH_CACHE
+   beq cache_skip_flush
+
/*
 * Flush all data from the L1 and L2 data cache before disabling
 * SCTLR.C bit.
@@ -48,14 +62,33 @@ ENTRY(am33xx_do_wfi)
ldr r1, kernel_flush
blx r1
 
+   adr r3, am33xx_pm_ro_sram_data
+   ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
+   ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
+
+cache_skip_flush:
+   /* Check if we want self refresh */
+   tst r4, #WFI_FLAG_SELF_REFRESH
+   beq emif_skip_enter_sr
+
adr r9, am33xx_emif_sram_table
 
ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
blx r3
 
+emif_skip_enter_sr:
+   /* Only necessary if PER is losing context */
+   tst r4, #WFI_FLAG_SAVE_EMIF
+   beq emif_skip_save
+
ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
blx r3
 
+emif_skip_save:
+   /* Only can disable EMIF if we have entered self refresh */
+   tst r4, #WFI_FLAG_SELF_REFRESH
+   beq emif_skip_disable
+
/* Disable EMIF */
ldr r1, virt_emif_clkctrl
ldr r2, [r1]
@@ -69,6 +102,10 @@ wait_emif_disable:
cmp r2, r3
bne wait_emif_disable
 
+emif_skip_disable:
+   tst r4, #WFI_FLAG_WAKE_M3
+   beq wkup_m3_skip
+
/*
 * For the MPU WFI to be registered as an interrupt
 * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
@@ -79,6 +116,7 @@ wait_emif_disable:
bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
str r2, [r1]
 
+wkup_m3_skip:
/*
 * Execute an ISB instruction to ensure that all of the
 * CP15 register changes have been commi

Re: [PATCH 2/3] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler

2018-01-23 Thread Keerthy


On Wednesday 24 January 2018 10:56 AM, Keerthy wrote:
> 
> 
> On Monday 22 January 2018 04:23 PM, Ladislav Michl wrote:
>> Dear Claudiu,
>>
>> On Mon, Jan 22, 2018 at 11:17:08AM +0200, Claudiu Beznea wrote:
>>> On 17.01.2018 23:47, Ladislav Michl wrote:
>>>> @@ -334,18 +348,18 @@ static int pwm_omap_dmtimer_probe(struct 
>>>> platform_device *pdev)
>>>>  
>>>>mutex_init(>mutex);
>>>>  
>>>> -  status = pwmchip_add(>chip);
>>>> -  if (status < 0) {
>>>> +  ret = pwmchip_add(>chip);
>>>> +  if (ret < 0) {
>>>>dev_err(>dev, "failed to register PWM\n");
>>>> -  omap->pdata->free(omap->dm_timer);
>>>> -  ret = status;
>>>> -  goto put;
>>>> +  goto free;
>>>>}
>>>>  
>>>>platform_set_drvdata(pdev, omap);
>>> >From documentation: "of_parse_phandle(): Returns the device_node pointer 
>>> >with refcount
>>> incremented. Use of_node_put() on it when done."
>>> In case of success the of_node_put() should also be called as I see.
>>
>> Based on you previous suggestions found here:
>> https://patchwork.kernel.org/patch/10140209/
>> I'd say this fix belongs to patch which introduces of_node_put() in the error
>> path. I'll then rebase this patches on top of the fix.
> 
> Agreed. I missed the success path as i assumed only error paths needed
> te of_node_put(). I will post v8 of this patch alone as other patches
> can be left untouched. Hope that is okay.

Ladis,

I posted v8 of the above mentioned patch alone.

https://marc.info/?l=linux-omap=151677273619960=2

Thanks,
Keerthy
> 
> Regards,
> Keerthy
>>
>> Thank you,
>>  ladis
>>


Re: [PATCH 2/3] pwm: pwm-omap-dmtimer: Fix frequency when using prescaler

2018-01-23 Thread Keerthy


On Monday 22 January 2018 04:23 PM, Ladislav Michl wrote:
> Dear Claudiu,
> 
> On Mon, Jan 22, 2018 at 11:17:08AM +0200, Claudiu Beznea wrote:
>> On 17.01.2018 23:47, Ladislav Michl wrote:
>>> @@ -334,18 +348,18 @@ static int pwm_omap_dmtimer_probe(struct 
>>> platform_device *pdev)
>>>  
>>> mutex_init(>mutex);
>>>  
>>> -   status = pwmchip_add(>chip);
>>> -   if (status < 0) {
>>> +   ret = pwmchip_add(>chip);
>>> +   if (ret < 0) {
>>> dev_err(>dev, "failed to register PWM\n");
>>> -   omap->pdata->free(omap->dm_timer);
>>> -   ret = status;
>>> -   goto put;
>>> +   goto free;
>>> }
>>>  
>>> platform_set_drvdata(pdev, omap);
>> >From documentation: "of_parse_phandle(): Returns the device_node pointer 
>> >with refcount
>> incremented. Use of_node_put() on it when done."
>> In case of success the of_node_put() should also be called as I see.
> 
> Based on you previous suggestions found here:
> https://patchwork.kernel.org/patch/10140209/
> I'd say this fix belongs to patch which introduces of_node_put() in the error
> path. I'll then rebase this patches on top of the fix.

Agreed. I missed the success path as i assumed only error paths needed
te of_node_put(). I will post v8 of this patch alone as other patches
can be left untouched. Hope that is okay.

Regards,
Keerthy
> 
> Thank you,
>   ladis
> 


[PATCH v8 8/9] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops

2018-01-23 Thread Keerthy
Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.

Signed-off-by: Keerthy <j-keer...@ti.com>
Acked-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Claudiu Beznea <claudiu.bez...@microchip.com>
---

Changes in v8:

  * Added of_node_put call in success case of probe.

Boot tested on am437x-gp-evm and dra7xx-evm.
Also compile tested omap1_defconfig with other patches of v7
posted here:

https://www.spinics.net/lists/linux-omap/msg141100.html

With v8 version of Patch 8/9.

 drivers/pwm/pwm-omap-dmtimer.c | 68 ++
 1 file changed, 42 insertions(+), 26 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f3..c00e474 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
struct pwm_chip chip;
struct mutex mutex;
pwm_omap_dmtimer *dm_timer;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct omap_dm_timer_ops *pdata;
struct platform_device *dm_timer_pdev;
 };
 
@@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 {
struct device_node *np = pdev->dev.of_node;
struct device_node *timer;
+   struct platform_device *timer_pdev;
struct pwm_omap_dmtimer_chip *omap;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct dmtimer_platform_data *timer_pdata;
+   struct omap_dm_timer_ops *pdata;
pwm_omap_dmtimer *dm_timer;
u32 v;
-   int status;
+   int status, ret = 0;
 
-   pdata = dev_get_platdata(>dev);
-   if (!pdata) {
-   dev_err(>dev, "Missing dmtimer platform data\n");
-   return -EINVAL;
+   timer = of_parse_phandle(np, "ti,timers", 0);
+   if (!timer)
+   return -ENODEV;
+
+   timer_pdev = of_find_device_by_node(timer);
+   if (!timer_pdev) {
+   dev_err(>dev, "Unable to find Timer pdev\n");
+   ret = -ENODEV;
+   goto put;
}
 
-   if (!pdata->request_by_node ||
+   timer_pdata = dev_get_platdata(_pdev->dev);
+   if (!timer_pdata) {
+   dev_err(>dev, "dmtimer pdata structure NULL\n");
+   ret = -EINVAL;
+   goto put;
+   }
+
+   pdata = timer_pdata->timer_ops;
+
+   if (!pdata || !pdata->request_by_node ||
!pdata->free ||
!pdata->enable ||
!pdata->disable ||
@@ -267,37 +284,32 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
!pdata->set_prescaler ||
!pdata->write_counter) {
dev_err(>dev, "Incomplete dmtimer pdata structure\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto put;
}
 
-   timer = of_parse_phandle(np, "ti,timers", 0);
-   if (!timer)
-   return -ENODEV;
-
if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
dev_err(>dev, "Missing ti,timer-pwm capability\n");
-   return -ENODEV;
+   ret = -ENODEV;
+   goto put;
}
 
dm_timer = pdata->request_by_node(timer);
-   if (!dm_timer)
-   return -EPROBE_DEFER;
+   if (!dm_timer) {
+   ret = -EPROBE_DEFER;
+   goto put;
+   }
 
omap = devm_kzalloc(>dev, sizeof(*omap), GFP_KERNEL);
if (!omap) {
pdata->free(dm_timer);
-   return -ENOMEM;
+   ret = -ENOMEM;
+   goto put;
}
 
omap->pdata = pdata;
omap->dm_timer = dm_timer;
-
-   omap->dm_timer_pdev = of_find_device_by_node(timer);
-   if (!omap->dm_timer_pdev) {
-   dev_err(>dev, "Unable to find timer pdev\n");
-   omap->pdata->free(dm_timer);
-   return -EINVAL;
-   }
+   omap->dm_timer_pdev = timer_pdev;
 
/*
 * Ensure that the timer is stopped before we allow PWM core to call
@@ -326,12 +338,16 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
if (status < 0) {
dev_err(>dev, "failed to register PWM\n");
omap->pdata->free(omap->dm_timer);
-   return status;
+   ret = status;
+   goto put;
}
 
platform_set_drvdata(pdev, omap);
 
-   return 0;
+put:
+   of_node_put(timer);
+
+   return ret;
 }
 
 static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
-- 
1.9.1



Re: [PATCH v8 8/9] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops

2018-01-24 Thread Keerthy


On Wednesday 24 January 2018 12:54 PM, Ladislav Michl wrote:
> Keerthy,
> 
> On Wed, Jan 24, 2018 at 11:14:40AM +0530, Keerthy wrote:
>> Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.
>>
>> Signed-off-by: Keerthy <j-keer...@ti.com>
>> Acked-by: Neil Armstrong <narmstr...@baylibre.com>
>> Reviewed-by: Claudiu Beznea <claudiu.bez...@microchip.com>
>> ---
>>
>> Changes in v8:
>>
>>   * Added of_node_put call in success case of probe.
>>
>> Boot tested on am437x-gp-evm and dra7xx-evm.
>> Also compile tested omap1_defconfig with other patches of v7
>> posted here:
>>
>> https://www.spinics.net/lists/linux-omap/msg141100.html
>>
>> With v8 version of Patch 8/9.
>>
>>  drivers/pwm/pwm-omap-dmtimer.c | 68 
>> ++
>>  1 file changed, 42 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
>> index 5ad42f3..c00e474 100644
>> --- a/drivers/pwm/pwm-omap-dmtimer.c
>> +++ b/drivers/pwm/pwm-omap-dmtimer.c
>> @@ -23,6 +23,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>> @@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
>>  struct pwm_chip chip;
>>  struct mutex mutex;
>>  pwm_omap_dmtimer *dm_timer;
>> -struct pwm_omap_dmtimer_pdata *pdata;
>> +struct omap_dm_timer_ops *pdata;
>>  struct platform_device *dm_timer_pdev;
>>  };
>>  
>> @@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct 
>> platform_device *pdev)
>>  {
>>  struct device_node *np = pdev->dev.of_node;
>>  struct device_node *timer;
>> +struct platform_device *timer_pdev;
>>  struct pwm_omap_dmtimer_chip *omap;
>> -struct pwm_omap_dmtimer_pdata *pdata;
>> +struct dmtimer_platform_data *timer_pdata;
>> +struct omap_dm_timer_ops *pdata;
>>  pwm_omap_dmtimer *dm_timer;
>>  u32 v;
>> -int status;
>> +int status, ret = 0;
>>  
>> -pdata = dev_get_platdata(>dev);
>> -if (!pdata) {
>> -dev_err(>dev, "Missing dmtimer platform data\n");
>> -return -EINVAL;
>> +timer = of_parse_phandle(np, "ti,timers", 0);
>> +if (!timer)
>> +return -ENODEV;
>> +
>> +timer_pdev = of_find_device_by_node(timer);
>> +if (!timer_pdev) {
>> +dev_err(>dev, "Unable to find Timer pdev\n");
>> +ret = -ENODEV;
>> +goto put;
>>  }
>>  
>> -if (!pdata->request_by_node ||
>> +timer_pdata = dev_get_platdata(_pdev->dev);
>> +if (!timer_pdata) {
>> +dev_err(>dev, "dmtimer pdata structure NULL\n");
>> +ret = -EINVAL;
>> +goto put;
>> +}
>> +
>> +pdata = timer_pdata->timer_ops;
>> +
>> +if (!pdata || !pdata->request_by_node ||
>>  !pdata->free ||
>>  !pdata->enable ||
>>  !pdata->disable ||
>> @@ -267,37 +284,32 @@ static int pwm_omap_dmtimer_probe(struct 
>> platform_device *pdev)
>>  !pdata->set_prescaler ||
>>  !pdata->write_counter) {
>>  dev_err(>dev, "Incomplete dmtimer pdata structure\n");
>> -return -EINVAL;
>> +ret = -EINVAL;
>> +goto put;
>>  }
>>  
>> -timer = of_parse_phandle(np, "ti,timers", 0);
>> -if (!timer)
>> -return -ENODEV;
>> -
>>  if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
>>  dev_err(>dev, "Missing ti,timer-pwm capability\n");
>> -return -ENODEV;
>> +ret = -ENODEV;
>> +goto put;
> 
> Should we call of_node_put() even from here? of_get_property() failed, so
> reference was not updated.

The of_node_put to balance the of_parse_handle called for timer. I hope
that is what you wanted to check right?

> 
>>  }
>>  
>>  dm_timer = pdata->request_by_node(timer);
> 
> And timer seems to be used only here, so calling
>   of_node_put(timer);
> just here should be enough.

Okay yes. This can be optimized. of_node_put(timer); can be called
here and the instances below need not have that additional step.

> 
>> -if (!dm_timer)
>> -return -E

Re: [PATCH v9 8/9] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops

2018-01-24 Thread Keerthy


On Wednesday 24 January 2018 04:49 PM, Keerthy wrote:
> Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.
> 
> Signed-off-by: Keerthy <j-keer...@ti.com>
> Acked-by: Neil Armstrong <narmstr...@baylibre.com>
> Reviewed-by: Claudiu Beznea <claudiu.bez...@microchip.com>
> ---
> Changes in v9:
> 
>   * Reorganized the place where of_node_put was called.
> 
> Changes in v8:
> 
>   * Added of_node_put call in success case of probe.
> 
> Boot tested on am437x-gp-evm and dra7xx-evm.
> Also compile tested omap1_defconfig with other patches of v7
> posted here:
> 
> https://www.spinics.net/lists/linux-omap/msg141100.html
> 
> With v9 version of Patch 8/9.
> 
>  drivers/pwm/pwm-omap-dmtimer.c | 66 
> ++
>  1 file changed, 41 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
> index 5ad42f3..aaf8d328 100644
> --- a/drivers/pwm/pwm-omap-dmtimer.c
> +++ b/drivers/pwm/pwm-omap-dmtimer.c
> @@ -23,6 +23,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
>   struct pwm_chip chip;
>   struct mutex mutex;
>   pwm_omap_dmtimer *dm_timer;
> - struct pwm_omap_dmtimer_pdata *pdata;
> + struct omap_dm_timer_ops *pdata;
>   struct platform_device *dm_timer_pdev;
>  };
>  
> @@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct 
> platform_device *pdev)
>  {
>   struct device_node *np = pdev->dev.of_node;
>   struct device_node *timer;
> + struct platform_device *timer_pdev;
>   struct pwm_omap_dmtimer_chip *omap;
> - struct pwm_omap_dmtimer_pdata *pdata;
> + struct dmtimer_platform_data *timer_pdata;
> + struct omap_dm_timer_ops *pdata;
>   pwm_omap_dmtimer *dm_timer;
>   u32 v;
> - int status;
> + int ret = 0;
>  
> - pdata = dev_get_platdata(>dev);
> - if (!pdata) {
> - dev_err(>dev, "Missing dmtimer platform data\n");
> - return -EINVAL;
> + timer = of_parse_phandle(np, "ti,timers", 0);
> + if (!timer)
> + return -ENODEV;
> +
> + timer_pdev = of_find_device_by_node(timer);
> + if (!timer_pdev) {
> + dev_err(>dev, "Unable to find Timer pdev\n");
> + ret = -ENODEV;
> + goto put;
>   }
>  
> - if (!pdata->request_by_node ||
> + timer_pdata = dev_get_platdata(_pdev->dev);
> + if (!timer_pdata) {
> + dev_err(>dev, "dmtimer pdata structure NULL\n");
> + ret = -EINVAL;
> + goto put;
> + }
> +
> + pdata = timer_pdata->timer_ops;
> +
> + if (!pdata || !pdata->request_by_node ||
>   !pdata->free ||
>   !pdata->enable ||
>   !pdata->disable ||
> @@ -267,21 +284,26 @@ static int pwm_omap_dmtimer_probe(struct 
> platform_device *pdev)
>   !pdata->set_prescaler ||
>   !pdata->write_counter) {
>   dev_err(>dev, "Incomplete dmtimer pdata structure\n");
> - return -EINVAL;
> + ret = -EINVAL;
> + goto put;
>   }
>  
> - timer = of_parse_phandle(np, "ti,timers", 0);
> - if (!timer)
> - return -ENODEV;
> -
>   if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
>   dev_err(>dev, "Missing ti,timer-pwm capability\n");
> - return -ENODEV;
> + ret = -ENODEV;
> + goto put;
>   }
>  
>   dm_timer = pdata->request_by_node(timer);
> - if (!dm_timer)
> - return -EPROBE_DEFER;
> + if (!dm_timer) {
> + ret = -EPROBE_DEFER;
> + goto put;
> + }
> +
> +put:
> + of_node_put(timer);
> + if (ret < 0)
> + return ret;
>  
>   omap = devm_kzalloc(>dev, sizeof(*omap), GFP_KERNEL);
>   if (!omap) {
> @@ -291,13 +313,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
> *pdev)
>  
>   omap->pdata = pdata;
>   omap->dm_timer = dm_timer;
> -
> - omap->dm_timer_pdev = of_find_device_by_node(timer);
> - if (!omap->dm_timer_pdev) {
> - dev_err(>dev, "Unable to find timer pdev\n");
> - omap->pdata->free(dm_timer);
> - return -EINVAL;
> - }
> + omap->dm_timer_pdev = timer_pdev;
>  
>   /*
>* Ensure that the timer is stopped before we allow PWM core to call
> @@ -322,8 +338,8 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
> *pdev)
>  
>   mutex_init(>mutex);
>  
> - status = pwmchip_add(>chip);
> - if (status < 0) {
> + ret = pwmchip_add(>chip);
> + if (ret < 0) {
>   dev_err(>dev, "failed to register PWM\n");
>   omap->pdata->free(omap->dm_timer);
>   return status;

There is a mistake here please ignore this. I will send v10 in a bit!

> 


[PATCH v9 8/9] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops

2018-01-24 Thread Keerthy
Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.

Signed-off-by: Keerthy <j-keer...@ti.com>
Acked-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Claudiu Beznea <claudiu.bez...@microchip.com>
---
Changes in v9:

  * Reorganized the place where of_node_put was called.

Changes in v8:

  * Added of_node_put call in success case of probe.

Boot tested on am437x-gp-evm and dra7xx-evm.
Also compile tested omap1_defconfig with other patches of v7
posted here:

https://www.spinics.net/lists/linux-omap/msg141100.html

With v9 version of Patch 8/9.

 drivers/pwm/pwm-omap-dmtimer.c | 66 ++
 1 file changed, 41 insertions(+), 25 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f3..aaf8d328 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
struct pwm_chip chip;
struct mutex mutex;
pwm_omap_dmtimer *dm_timer;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct omap_dm_timer_ops *pdata;
struct platform_device *dm_timer_pdev;
 };
 
@@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 {
struct device_node *np = pdev->dev.of_node;
struct device_node *timer;
+   struct platform_device *timer_pdev;
struct pwm_omap_dmtimer_chip *omap;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct dmtimer_platform_data *timer_pdata;
+   struct omap_dm_timer_ops *pdata;
pwm_omap_dmtimer *dm_timer;
u32 v;
-   int status;
+   int ret = 0;
 
-   pdata = dev_get_platdata(>dev);
-   if (!pdata) {
-   dev_err(>dev, "Missing dmtimer platform data\n");
-   return -EINVAL;
+   timer = of_parse_phandle(np, "ti,timers", 0);
+   if (!timer)
+   return -ENODEV;
+
+   timer_pdev = of_find_device_by_node(timer);
+   if (!timer_pdev) {
+   dev_err(>dev, "Unable to find Timer pdev\n");
+   ret = -ENODEV;
+   goto put;
}
 
-   if (!pdata->request_by_node ||
+   timer_pdata = dev_get_platdata(_pdev->dev);
+   if (!timer_pdata) {
+   dev_err(>dev, "dmtimer pdata structure NULL\n");
+   ret = -EINVAL;
+   goto put;
+   }
+
+   pdata = timer_pdata->timer_ops;
+
+   if (!pdata || !pdata->request_by_node ||
!pdata->free ||
!pdata->enable ||
!pdata->disable ||
@@ -267,21 +284,26 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
!pdata->set_prescaler ||
!pdata->write_counter) {
dev_err(>dev, "Incomplete dmtimer pdata structure\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto put;
}
 
-   timer = of_parse_phandle(np, "ti,timers", 0);
-   if (!timer)
-   return -ENODEV;
-
if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
dev_err(>dev, "Missing ti,timer-pwm capability\n");
-   return -ENODEV;
+   ret = -ENODEV;
+   goto put;
}
 
dm_timer = pdata->request_by_node(timer);
-   if (!dm_timer)
-   return -EPROBE_DEFER;
+   if (!dm_timer) {
+   ret = -EPROBE_DEFER;
+   goto put;
+   }
+
+put:
+   of_node_put(timer);
+   if (ret < 0)
+   return ret;
 
omap = devm_kzalloc(>dev, sizeof(*omap), GFP_KERNEL);
if (!omap) {
@@ -291,13 +313,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 
omap->pdata = pdata;
omap->dm_timer = dm_timer;
-
-   omap->dm_timer_pdev = of_find_device_by_node(timer);
-   if (!omap->dm_timer_pdev) {
-   dev_err(>dev, "Unable to find timer pdev\n");
-   omap->pdata->free(dm_timer);
-   return -EINVAL;
-   }
+   omap->dm_timer_pdev = timer_pdev;
 
/*
 * Ensure that the timer is stopped before we allow PWM core to call
@@ -322,8 +338,8 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 
mutex_init(>mutex);
 
-   status = pwmchip_add(>chip);
-   if (status < 0) {
+   ret = pwmchip_add(>chip);
+   if (ret < 0) {
dev_err(>dev, "failed to register PWM\n");
omap->pdata->free(omap->dm_timer);
return status;
-- 
1.9.1



[PATCH v10 8/9] pwm: pwm-omap-dmtimer: Adapt driver to utilize dmtimer pdata ops

2018-01-24 Thread Keerthy
Adapt driver to utilize dmtimer pdata ops instead of pdata-quirks.

Signed-off-by: Keerthy <j-keer...@ti.com>
Acked-by: Neil Armstrong <narmstr...@baylibre.com>
Reviewed-by: Claudiu Beznea <claudiu.bez...@microchip.com>
---

Changes in v10:

  * Corrected a return variable.

Changes in v9:

  * Reorganized the place where of_node_put was called.

Changes in v8:

  * Added of_node_put call in success case of probe.

Boot tested on am437x-gp-evm and dra7xx-evm.
Also compile tested omap1_defconfig with other patches of v7
posted here:

https://www.spinics.net/lists/linux-omap/msg141100.html

With v10 version of Patch 8/9.

 drivers/pwm/pwm-omap-dmtimer.c | 68 ++
 1 file changed, 42 insertions(+), 26 deletions(-)

diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f3..724b273 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
struct pwm_chip chip;
struct mutex mutex;
pwm_omap_dmtimer *dm_timer;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct omap_dm_timer_ops *pdata;
struct platform_device *dm_timer_pdev;
 };
 
@@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 {
struct device_node *np = pdev->dev.of_node;
struct device_node *timer;
+   struct platform_device *timer_pdev;
struct pwm_omap_dmtimer_chip *omap;
-   struct pwm_omap_dmtimer_pdata *pdata;
+   struct dmtimer_platform_data *timer_pdata;
+   struct omap_dm_timer_ops *pdata;
pwm_omap_dmtimer *dm_timer;
u32 v;
-   int status;
+   int ret = 0;
 
-   pdata = dev_get_platdata(>dev);
-   if (!pdata) {
-   dev_err(>dev, "Missing dmtimer platform data\n");
-   return -EINVAL;
+   timer = of_parse_phandle(np, "ti,timers", 0);
+   if (!timer)
+   return -ENODEV;
+
+   timer_pdev = of_find_device_by_node(timer);
+   if (!timer_pdev) {
+   dev_err(>dev, "Unable to find Timer pdev\n");
+   ret = -ENODEV;
+   goto put;
}
 
-   if (!pdata->request_by_node ||
+   timer_pdata = dev_get_platdata(_pdev->dev);
+   if (!timer_pdata) {
+   dev_err(>dev, "dmtimer pdata structure NULL\n");
+   ret = -EINVAL;
+   goto put;
+   }
+
+   pdata = timer_pdata->timer_ops;
+
+   if (!pdata || !pdata->request_by_node ||
!pdata->free ||
!pdata->enable ||
!pdata->disable ||
@@ -267,21 +284,26 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
!pdata->set_prescaler ||
!pdata->write_counter) {
dev_err(>dev, "Incomplete dmtimer pdata structure\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto put;
}
 
-   timer = of_parse_phandle(np, "ti,timers", 0);
-   if (!timer)
-   return -ENODEV;
-
if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
dev_err(>dev, "Missing ti,timer-pwm capability\n");
-   return -ENODEV;
+   ret = -ENODEV;
+   goto put;
}
 
dm_timer = pdata->request_by_node(timer);
-   if (!dm_timer)
-   return -EPROBE_DEFER;
+   if (!dm_timer) {
+   ret = -EPROBE_DEFER;
+   goto put;
+   }
+
+put:
+   of_node_put(timer);
+   if (ret < 0)
+   return ret;
 
omap = devm_kzalloc(>dev, sizeof(*omap), GFP_KERNEL);
if (!omap) {
@@ -291,13 +313,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 
omap->pdata = pdata;
omap->dm_timer = dm_timer;
-
-   omap->dm_timer_pdev = of_find_device_by_node(timer);
-   if (!omap->dm_timer_pdev) {
-   dev_err(>dev, "Unable to find timer pdev\n");
-   omap->pdata->free(dm_timer);
-   return -EINVAL;
-   }
+   omap->dm_timer_pdev = timer_pdev;
 
/*
 * Ensure that the timer is stopped before we allow PWM core to call
@@ -322,11 +338,11 @@ static int pwm_omap_dmtimer_probe(struct platform_device 
*pdev)
 
mutex_init(>mutex);
 
-   status = pwmchip_add(>chip);
-   if (status < 0) {
+   ret = pwmchip_add(>chip);
+   if (ret < 0) {
dev_err(>dev, "failed to register PWM\n");
omap->pdata->free(omap->dm_timer);
-   return status;
+   return ret;
}
 
platform_set_drvdata(pdev, omap);
-- 
1.9.1



[PATCH] dt-bindings: power: Introduce suspend states supported properties

2018-09-11 Thread Keerthy
Introuduce linux generic suspend states supported properties.
It is convenient for the generic suspend path to have
the knowledge of the suspend states supported based on the
device tree properties based on which it can either be suspended
or safely bailed out of suspend if none of the suspend states
are supported.

Signed-off-by: Keerthy 
---
 .../devicetree/bindings/power/power-states.txt | 22 ++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/power-states.txt

diff --git a/Documentation/devicetree/bindings/power/power-states.txt 
b/Documentation/devicetree/bindings/power/power-states.txt
new file mode 100644
index 000..bb80b36
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/power-states.txt
@@ -0,0 +1,22 @@
+* Generic system suspend states support
+
+Most platforms support multiple suspend states. Define system
+suspend states so that one can target appropriate low power
+states based on the SoC capabilities.
+
+linux,suspend-to-memory-supported
+
+Upon suspend to memory the system context is saved to primary memory.
+All the clocks for all the peripherals including CPU are gated.
+
+linux,suspend-power-off-supported
+
+In this case in additon to the clocks all the voltage resources are
+turned off except the ones needed to keep the primary memory
+and a wake up source that can trigger a wakeup event.
+
+linux,suspend-to-disk-supported
+
+Upon suspend to disk that system context is saved to secondary memory.
+All the clocks for all the peripherals including CPU are gated. Even
+the primary memory is turned off.
-- 
1.9.1



Re: [PATCH 08/14] ARM: OMAP2: Add functions to save and restore pinctrl context.

2018-04-13 Thread Keerthy


On Thursday 12 April 2018 07:46 PM, Tony Lindgren wrote:
> Hi,
> 
> * Keerthy <j-keer...@ti.com> [180412 03:56]:
>> From: Russ Dill <russ.d...@gmail.com>
>>
>> This adds a pair of context save/restore functions to save/restore the
>> state of a set of pinctrl registers. This simplifies some of the AM33XX
>> PM code as some of the pinctrl registers are lost when the per power
>> domain loses power. The pincrtl code can perform the necessary
>> save/restore.
> 
> So where's the patch adding callers to this code?

This series was to get all the additional save/restores needed for the
rtc+ddr mode. Caller patch is in the main patch that implements that
mode that i will be posting once the ground is set.

Based on enable_off_mode being set this function was called only for
rtc+ddr mode.

> 
> If this cannot be done from regular driver suspend/resume calls,
> this probably should be done from cpu_pm notifiers CPU_PM_ENTER and
> CPU_PM_EXIT. We should also do the same for GPIO BTW.

I will look into that. Thanks for suggestion.

> 
> BTW, the subject line is wrong here, it should be "pinctrl" :)

Oops yes that should be pinctrl.

> 
> Regards,
> 
> Tony
> 


[PATCH 02/14] ARM: OMAP2: Add functions to save and restore clockdomain context en-masse.

2018-04-11 Thread Keerthy
From: Russ Dill <russ.d...@ti.com>

This is used to support suspend modes like RTC-only and hibernate where
the state of the registers controlling clockdomains is lost.

Signed-off-by: Russ Dill <russ.d...@ti.com>
Signed-off-by: Dave Gerlach <d-gerl...@ti.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 arch/arm/mach-omap2/clockdomain.c | 46 +
 arch/arm/mach-omap2/clockdomain.h |  8 ++
 arch/arm/mach-omap2/cm33xx.c  | 53 +++
 arch/arm/mach-omap2/cminst44xx.c  | 43 +++
 4 files changed, 150 insertions(+)

diff --git a/arch/arm/mach-omap2/clockdomain.c 
b/arch/arm/mach-omap2/clockdomain.c
index b79b1ca..0906380 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -1307,3 +1307,49 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, 
struct omap_hwmod *oh)
return 0;
 }
 
+/**
+ * _clkdm_save_context - save the context for the control of this clkdm
+ *
+ * Due to a suspend or hibernation operation, the state of the registers
+ * controlling this clkdm will be lost, save their context.
+ */
+static int _clkdm_save_context(struct clockdomain *clkdm, void *ununsed)
+{
+   if (!arch_clkdm || !arch_clkdm->clkdm_save_context)
+   return -EINVAL;
+
+   return arch_clkdm->clkdm_save_context(clkdm);
+}
+
+/**
+ * _clkdm_restore_context - restore context for control of this clkdm
+ *
+ * Restore the register values for this clockdomain.
+ */
+static int _clkdm_restore_context(struct clockdomain *clkdm, void *ununsed)
+{
+   if (!arch_clkdm || !arch_clkdm->clkdm_restore_context)
+   return -EINVAL;
+
+   return arch_clkdm->clkdm_restore_context(clkdm);
+}
+
+/**
+ * clkdm_save_context - Saves the context for each registered clkdm
+ *
+ * Save the context for each registered clockdomain.
+ */
+void clkdm_save_context(void)
+{
+   clkdm_for_each(_clkdm_save_context, NULL);
+}
+
+/**
+ * clkdm_restore_context - Restores the context for each registered clkdm
+ *
+ * Restore the context for each registered clockdomain.
+ */
+void clkdm_restore_context(void)
+{
+   clkdm_for_each(_clkdm_restore_context, NULL);
+}
diff --git a/arch/arm/mach-omap2/clockdomain.h 
b/arch/arm/mach-omap2/clockdomain.h
index 24667a5..c7d0953 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -141,6 +141,7 @@ struct clockdomain {
int usecount;
int forcewake_count;
struct list_head node;
+   u32 context;
 };
 
 /**
@@ -159,6 +160,8 @@ struct clockdomain {
  * @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
  * @clkdm_clk_enable: Put the clkdm in right state for a clock enable
  * @clkdm_clk_disable: Put the clkdm in right state for a clock disable
+ * @clkdm_save_context: Save the current clkdm context
+ * @clkdm_restore_context: Restore the clkdm context
  */
 struct clkdm_ops {
int (*clkdm_add_wkdep)(struct clockdomain *clkdm1, struct 
clockdomain *clkdm2);
@@ -175,6 +178,8 @@ struct clkdm_ops {
void(*clkdm_deny_idle)(struct clockdomain *clkdm);
int (*clkdm_clk_enable)(struct clockdomain *clkdm);
int (*clkdm_clk_disable)(struct clockdomain *clkdm);
+   int (*clkdm_save_context)(struct clockdomain *clkdm);
+   int (*clkdm_restore_context)(struct clockdomain *clkdm);
 };
 
 int clkdm_register_platform_funcs(struct clkdm_ops *co);
@@ -214,6 +219,9 @@ int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, 
void *user),
 int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
 int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
 
+void clkdm_save_context(void);
+void clkdm_restore_context(void);
+
 extern void __init omap242x_clockdomains_init(void);
 extern void __init omap243x_clockdomains_init(void);
 extern void __init omap3xxx_clockdomains_init(void);
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index 1cc0247..084d454 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -72,6 +72,17 @@ static inline u32 am33xx_cm_rmw_reg_bits(u32 mask, u32 bits, 
s16 inst, s16 idx)
return v;
 }
 
+static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask)
+{
+   u32 v;
+
+   v = am33xx_cm_read_reg(inst, idx);
+   v &= mask;
+   v >>= __ffs(mask);
+
+   return v;
+}
+
 /**
  * _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
  * @inst: CM instance register offset (*_INST macro)
@@ -338,6 +349,46 @@ static u32 am33xx_cm_xlate_clkctrl(u8 part, u16 inst, u16 
offset)
return cm_base.pa + inst + offset;
 }
 
+/**
+ * am33xx_clkdm_save_context - Save the clockdomain transition context
+ * @clkdm: The clockdomain pointer whose context needs to be saved
+ *
+ * Save the clockdomain transition context.

[PATCH 07/14] ARM: AM43XX: Add functions to save/restore am43xx control registers

2018-04-11 Thread Keerthy
From: Tero Kristo <t-kri...@ti.com>

These registers are part of the wkup domain and are lost during RTC only
suspend and also hibernation, so storing/restoring their state is
necessary.

Signed-off-by: Tero Kristo <t-kri...@ti.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 arch/arm/mach-omap2/control.c | 94 +--
 arch/arm/mach-omap2/control.h | 15 ++-
 2 files changed, 105 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index d92aa9a..d094ae3 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -622,7 +622,8 @@ void __init omap3_ctrl_init(void)
 
 #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
 
-#if defined(CONFIG_SOC_AM33XX) && defined(CONFIG_PM)
+#if defined(CONFIG_PM)
+#if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
 static unsigned long am33xx_control_reg_offsets[] = {
AM33XX_CONTROL_SYSCONFIG_OFFSET,
AM33XX_CONTROL_STATUS_OFFSET,
@@ -674,7 +675,65 @@ void __init omap3_ctrl_init(void)
AM33XX_CONTROL_RESET_ISO_OFFSET,
 };
 
-static u32 am33xx_control_vals[ARRAY_SIZE(am33xx_control_reg_offsets)];
+static unsigned long am43xx_control_reg_offsets[] = {
+   AM33XX_CONTROL_SYSCONFIG_OFFSET,
+   AM33XX_CONTROL_STATUS_OFFSET,
+   AM43XX_CONTROL_MPU_L2_CTRL_OFFSET,
+   AM33XX_CONTROL_CORE_SLDO_CTRL_OFFSET,
+   AM33XX_CONTROL_MPU_SLDO_CTRL_OFFSET,
+   AM33XX_CONTROL_CLK32KDIVRATIO_CTRL_OFFSET,
+   AM33XX_CONTROL_BANDGAP_CTRL_OFFSET,
+   AM33XX_CONTROL_BANDGAP_TRIM_OFFSET,
+   AM33XX_CONTROL_PLL_CLKINPULOW_CTRL_OFFSET,
+   AM33XX_CONTROL_MOSC_CTRL_OFFSET,
+   AM33XX_CONTROL_DEEPSLEEP_CTRL_OFFSET,
+   AM43XX_CONTROL_DISPLAY_PLL_SEL_OFFSET,
+   AM33XX_CONTROL_INIT_PRIORITY_0_OFFSET,
+   AM33XX_CONTROL_INIT_PRIORITY_1_OFFSET,
+   AM33XX_CONTROL_TPTC_CFG_OFFSET,
+   AM33XX_CONTROL_USB_CTRL0_OFFSET,
+   AM33XX_CONTROL_USB_CTRL1_OFFSET,
+   AM43XX_CONTROL_USB_CTRL2_OFFSET,
+   AM43XX_CONTROL_GMII_SEL_OFFSET,
+   AM43XX_CONTROL_MPUSS_CTRL_OFFSET,
+   AM43XX_CONTROL_TIMER_CASCADE_CTRL_OFFSET,
+   AM43XX_CONTROL_PWMSS_CTRL_OFFSET,
+   AM33XX_CONTROL_MREQPRIO_0_OFFSET,
+   AM33XX_CONTROL_MREQPRIO_1_OFFSET,
+   AM33XX_CONTROL_HW_EVENT_SEL_GRP1_OFFSET,
+   AM33XX_CONTROL_HW_EVENT_SEL_GRP2_OFFSET,
+   AM33XX_CONTROL_HW_EVENT_SEL_GRP3_OFFSET,
+   AM33XX_CONTROL_HW_EVENT_SEL_GRP4_OFFSET,
+   AM33XX_CONTROL_SMRT_CTRL_OFFSET,
+   AM33XX_CONTROL_MPUSS_HW_DEBUG_SEL_OFFSET,
+   AM43XX_CONTROL_CQDETECT_STS_OFFSET,
+   AM43XX_CONTROL_CQDETECT_STS2_OFFSET,
+   AM43XX_CONTROL_VTP_CTRL_OFFSET,
+   AM33XX_CONTROL_VREF_CTRL_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_0_3_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_4_7_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_8_11_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_12_15_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_16_19_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_20_23_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_24_27_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_28_31_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_32_35_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_36_39_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_40_43_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_44_47_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_48_51_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_52_55_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_56_59_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_60_63_OFFSET,
+   AM33XX_CONTROL_TIMER_EVT_CAPT_OFFSET,
+   AM33XX_CONTROL_ECAP_EVT_CAPT_OFFSET,
+   AM33XX_CONTROL_ADC_EVT_CAPT_OFFSET,
+   AM43XX_CONTROL_ADC1_EVT_CAPT_OFFSET,
+   AM33XX_CONTROL_RESET_ISO_OFFSET,
+};
+
+static u32 am33xx_control_vals[ARRAY_SIZE(am43xx_control_reg_offsets)];
 
 /**
  * am33xx_control_save_context - Save the wakeup domain registers
@@ -703,7 +762,36 @@ void am33xx_control_restore_context(void)
omap_ctrl_writel(am33xx_control_vals[i],
 am33xx_control_reg_offsets[i]);
 }
-#endif /* CONFIG_SOC_AM33XX && CONFIG_PM */
+
+/**
+ * am43xx_control_save_context - Save the wakeup domain registers
+ *
+ * Save the wkup domain registers
+ */
+void am43xx_control_save_context(void)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(am43xx_control_reg_offsets); i++)
+   am33xx_control_vals[i] =
+   omap_ctrl_readl(am43xx_control_reg_offsets[i]);
+}
+
+/**
+ * am43xx_control_restore_context - Restore the wakeup domain registers
+ *
+ * Restore the wkup domain registers
+ */
+void am43xx_control_restore_context(void)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(am43xx_control_reg_offsets); i++)
+   omap_ctrl_writel(am33xx_control_vals[i],
+am43xx_control_reg_offsets[i]);
+}
+#endif /* CONFIG_PM */
+#endif /* CON

[PATCH 00/14] arm: OMAP: AM437X: Save restores patches for rtc mode with DDR In self-refresh

2018-04-11 Thread Keerthy
RTC plus DDR in self-refresh is power a saving mode where in the entire
system including the different voltage rails from PMIC are shutdown except
the ones feeding on to RTC and DDR. DDR is kept in self-refresh hence the
contents are preserved. RTC ALARM2 is connected to PMIC_EN line once
we the ALARM2 is triggered we enter the mode with DDR in self-refresh
and RTC Ticking. After a predetermined time an RTC ALARM1 triggers waking
up the system. The control goes to bootloader. The bootloader then checks
RTC scratchpad registers to confirm it was an rtc_only wakeup and follows
a different path, configure bare minimal clocks for ddr and then jumps to
the resume address in another RTC scratchpad registers and transfers the
control to Kernel. Kernel then restores the saved context.

This series is a prerequisite for the rtc mode with DDR in self
refresh mode for am437x series of SoCs. As all the voltage domains
are shut off apart from RTC and DDR is kept in self refresh
additional save/restores are needed.

The series applies cleanly against linux-next branch.

This mode works only with u-boot built with am43xx_evm_rtconly_defconfig

Dave Gerlach (5):
  memory: ti-emif-sram: Add resume function to recopy sram code
  ARM: OMAP2+: omap_hwmod: Introduce HWMOD_NEEDS_REIDLE
  gpio: omap: Restore power_mode configuration at resume time
  ARM: hwmod: RTC: Don't assume lock/unlock will be called with irq
enabled
  ARM: OMAP2+: prm44xx: Introduce context save/restore for am43 PRCM IO

Keerthy (1):
  OMAP: CLK: CLKSRC: Add suspend resume hooks

Russ Dill (7):
  ARM: OMAP2: Add functions to save and restore clockdomain context
en-masse.
  ARM: OMAP2: Add functions to save and restore omap hwmod context
en-masse.
  ARM: OMAP2: Add functions to save and restore powerdomain context
  ARM: AM33XX: Add functions to save/restore am33xx control registers.
  ARM: OMAP2: Add functions to save and restore pinctrl context.
  ARM: OMAP2: Drop the concept of certain power domains not being able
to lose context.
  gpio: omap: Drop the concept of gpio banks not being able to lose
context.

Tero Kristo (1):
  ARM: AM43XX: Add functions to save/restore am43xx control registers

 arch/arm/mach-omap2/clockdomain.c  |  46 +
 arch/arm/mach-omap2/clockdomain.h  |   8 +
 arch/arm/mach-omap2/cm33xx.c   |  53 ++
 arch/arm/mach-omap2/cminst44xx.c   |  43 +
 arch/arm/mach-omap2/control.c  | 172 ++
 arch/arm/mach-omap2/control.h  |  65 +++
 arch/arm/mach-omap2/omap_device.c  |  50 +
 arch/arm/mach-omap2/omap_device.h  |   1 +
 arch/arm/mach-omap2/omap_hwmod.c   | 202 +
 arch/arm/mach-omap2/omap_hwmod.h   |  21 +++
 .../mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c |  14 +-
 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |   3 +-
 arch/arm/mach-omap2/omap_hwmod_reset.c |  12 +-
 arch/arm/mach-omap2/powerdomain.c  |  75 +---
 arch/arm/mach-omap2/powerdomain.h  |   8 +-
 arch/arm/mach-omap2/prm.h  |   2 +
 arch/arm/mach-omap2/prm33xx.c  |  31 
 arch/arm/mach-omap2/prm44xx.c  |  79 
 arch/arm/mach-omap2/timer.c|  37 
 drivers/gpio/gpio-omap.c   |  40 ++--
 drivers/memory/ti-emif-pm.c|  24 +++
 drivers/pinctrl/core.c |   1 +
 drivers/pinctrl/core.h |   1 -
 drivers/pinctrl/pinctrl-single.c   |  50 +
 drivers/pinctrl/pinmux.c   |  22 +++
 include/linux/pinctrl/pinctrl.h|   7 +
 include/linux/pinctrl/pinmux.h |  16 ++
 include/linux/platform_data/gpio-omap.h|   1 -
 28 files changed, 1019 insertions(+), 65 deletions(-)

-- 
1.9.1



[PATCH 04/14] ARM: OMAP2: Add functions to save and restore omap hwmod context en-masse.

2018-04-11 Thread Keerthy
From: Russ Dill <russ.d...@ti.com>

This is used to support suspend modes like RTC-only and hibernate where
the state of these registers is lost.

After the PRCM loses context in the case of an RTC+DDR cycle omap_hwmod
attempts to return all hwmods to their previous state, however certain
hwmods cannot just be disabled when in their default state, which is why
they need the special handling present in that patch when no driver is
present.

In RTC+DDR mode, even if all drivers are present, the modules are all
returned to their previous state before any driver resume happens so we
will still face the issue described above. This can be prevented by
calling _reidle on all hwmods that need it for any module that is being
disabled to return to it's previous state.

Signed-off-by: Dave Gerlach <d-gerl...@ti.com>
Signed-off-by: Russ Dill <russ.d...@ti.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod.c | 67 
 arch/arm/mach-omap2/omap_hwmod.h |  4 +++
 2 files changed, 71 insertions(+)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 90ad8e7..f6782b4 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -4096,3 +4096,70 @@ const char *omap_hwmod_get_main_clk(struct omap_hwmod 
*oh)
 
return oh->main_clk;
 }
+
+/**
+ * omap_hwmod_save_context - Saves the HW reset line state of submodules
+ * @oh: struct omap_hwmod *
+ * @unused: (unused, caller should pass NULL)
+ *
+ * Saves the HW reset line state of all the submodules in the hwmod
+ */
+static int omap_hwmod_save_context(struct omap_hwmod *oh, void *unused)
+{
+   int i;
+
+   for (i = 0; i < oh->rst_lines_cnt; i++)
+   oh->rst_lines[i].context =
+   _read_hardreset(oh, oh->rst_lines[i].name);
+   return 0;
+}
+
+/**
+ * omap_hwmod_restore_context - Restores the HW reset line state of submodules
+ * @oh: struct omap_hwmod *
+ * @unused: (unused, caller should pass NULL)
+ *
+ * Restores the HW reset line state of all the submodules in the hwmod
+ */
+static int omap_hwmod_restore_context(struct omap_hwmod *oh, void *unused)
+{
+   int i;
+
+   for (i = 0; i < oh->rst_lines_cnt; i++)
+   if (oh->rst_lines[i].context)
+   _assert_hardreset(oh, oh->rst_lines[i].name);
+   else
+   _deassert_hardreset(oh, oh->rst_lines[i].name);
+
+   if (oh->_state == _HWMOD_STATE_ENABLED) {
+   if (soc_ops.enable_module)
+   soc_ops.enable_module(oh);
+   } else {
+   if (oh->flags & HWMOD_NEEDS_REIDLE)
+   _reidle(oh);
+   else if (soc_ops.disable_module)
+   soc_ops.disable_module(oh);
+   }
+
+   return 0;
+}
+
+/**
+ * omap_hwmods_save_context - Saves the HW reset line state for all hwmods
+ *
+ * Saves the HW reset line state of all the registered hwmods
+ */
+void omap_hwmods_save_context(void)
+{
+   omap_hwmod_for_each(omap_hwmod_save_context, NULL);
+}
+
+/**
+ * omap_hwmods_restore_context - Restores the HW reset line state for all 
hwmods
+ *
+ * Restores the HW reset line state of all the registered hwmods
+ */
+void omap_hwmods_restore_context(void)
+{
+   omap_hwmod_for_each(omap_hwmod_restore_context, NULL);
+}
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index f35638b..b5e050e 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -168,6 +168,7 @@ struct omap_hwmod_rst_info {
const char  *name;
u8  rst_shift;
u8  st_shift;
+   u8  context;
 };
 
 /**
@@ -678,6 +679,9 @@ int omap_hwmod_for_each_by_class(const char *classname,
 
 const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);
 
+void omap_hwmods_save_context(void);
+void omap_hwmods_restore_context(void);
+
 /*
  *
  */
-- 
1.9.1



[PATCH 14/14] ARM: OMAP2+: prm44xx: Introduce context save/restore for am43 PRCM IO

2018-04-11 Thread Keerthy
From: Dave Gerlach <d-gerl...@ti.com>

There are two registers on am43x needed for IO daisy chain wake to work
properly, however currently after an RTC+DDR cycle they are lost. We
must take care to save and restore these before and after entering RTC
mode otherwise IO daisy chain wake will stop working from DeepSleep
after resuming.

Signed-off-by: Dave Gerlach <d-gerl...@ti.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 arch/arm/mach-omap2/prm.h |  2 ++
 arch/arm/mach-omap2/prm44xx.c | 29 +
 2 files changed, 31 insertions(+)

diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index f0fb508..32e275f 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -179,6 +179,8 @@ int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 
part, s16 prm_mod,
 u32 omap_prm_vp_check_txdone(u8 vp_id);
 void omap_prm_vp_clear_txdone(u8 vp_id);
 
+void am43xx_prm_save_context(void);
+void am43xx_prm_restore_context(void);
 #endif
 
 
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 47b657c..0de 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -57,6 +57,13 @@
.reconfigure_io_chain   = _prm_reconfigure_io_chain,
 };
 
+struct omap_prm_irq_context {
+   unsigned long irq_enable;
+   unsigned long pm_ctrl;
+};
+
+static struct omap_prm_irq_context omap_prm_context;
+
 /*
  * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST
  *   hardware register (which are specific to OMAP44xx SoCs) to reset
@@ -739,6 +746,28 @@ struct pwrdm_ops omap4_pwrdm_operations = {
 
 static int omap44xx_prm_late_init(void);
 
+void am43xx_prm_save_context(void)
+{
+   omap_prm_context.irq_enable =
+   omap4_prm_read_inst_reg(AM43XX_PRM_OCP_SOCKET_INST,
+   omap4_prcm_irq_setup.mask);
+
+   omap_prm_context.pm_ctrl =
+   omap4_prm_read_inst_reg(AM43XX_PRM_DEVICE_INST,
+   omap4_prcm_irq_setup.pm_ctrl);
+}
+
+void am43xx_prm_restore_context(void)
+{
+   omap4_prm_write_inst_reg(omap_prm_context.irq_enable,
+OMAP4430_PRM_OCP_SOCKET_INST,
+omap4_prcm_irq_setup.mask);
+
+   omap4_prm_write_inst_reg(omap_prm_context.pm_ctrl,
+AM43XX_PRM_DEVICE_INST,
+omap4_prcm_irq_setup.pm_ctrl);
+}
+
 /*
  * XXX document
  */
-- 
1.9.1



[PATCH 13/14] ARM: hwmod: RTC: Don't assume lock/unlock will be called with irq enabled

2018-04-11 Thread Keerthy
From: Dave Gerlach <d-gerl...@ti.com>

When the RTC lock and unlock functions were introduced it was likely
assumed that they would always be called from irq enabled context, hence
the use of local_irq_disable/enable. This is no longer true as the
RTC+DDR path makes a late call during the suspend path after irqs
have been disabled to enable the RTC hwmod which calls both unlock and
lock, leading to IRQs being reenabled through the local_irq_enable call
in omap_hwmod_rtc_lock call.

To avoid this change the local_irq_disable/enable to
local_irq_save/restore to ensure that from whatever context this is
called the proper IRQ configuration is maintained.

Signed-off-by: Dave Gerlach <d-gerl...@ti.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_reset.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_reset.c 
b/arch/arm/mach-omap2/omap_hwmod_reset.c
index b68f9c0..d5ddba0 100644
--- a/arch/arm/mach-omap2/omap_hwmod_reset.c
+++ b/arch/arm/mach-omap2/omap_hwmod_reset.c
@@ -92,11 +92,13 @@ static void omap_rtc_wait_not_busy(struct omap_hwmod *oh)
  */
 void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
 {
-   local_irq_disable();
+   unsigned long flags;
+
+   local_irq_save(flags);
omap_rtc_wait_not_busy(oh);
omap_hwmod_write(OMAP_RTC_KICK0_VALUE, oh, OMAP_RTC_KICK0_REG);
omap_hwmod_write(OMAP_RTC_KICK1_VALUE, oh, OMAP_RTC_KICK1_REG);
-   local_irq_enable();
+   local_irq_restore(flags);
 }
 
 /**
@@ -110,9 +112,11 @@ void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
  */
 void omap_hwmod_rtc_lock(struct omap_hwmod *oh)
 {
-   local_irq_disable();
+   unsigned long flags;
+
+   local_irq_save(flags);
omap_rtc_wait_not_busy(oh);
omap_hwmod_write(0x0, oh, OMAP_RTC_KICK0_REG);
omap_hwmod_write(0x0, oh, OMAP_RTC_KICK1_REG);
-   local_irq_enable();
+   local_irq_restore(flags);
 }
-- 
1.9.1



[PATCH 09/14] ARM: OMAP2: Drop the concept of certain power domains not being able to lose context.

2018-04-11 Thread Keerthy
From: Russ Dill <russ.d...@ti.com>

It isn't much of a win, and with hibernation, everything loses context.
So Drop the concept of certain power domains not being able to lose
context.

Signed-off-by: Russ Dill <russ.d...@ti.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c | 41 ---
 arch/arm/mach-omap2/powerdomain.h |  1 -
 2 files changed, 42 deletions(-)

diff --git a/arch/arm/mach-omap2/powerdomain.c 
b/arch/arm/mach-omap2/powerdomain.c
index ee693f6..f180d22 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -1160,47 +1160,6 @@ int pwrdm_get_context_loss_count(struct powerdomain 
*pwrdm)
 }
 
 /**
- * pwrdm_can_ever_lose_context - can this powerdomain ever lose context?
- * @pwrdm: struct powerdomain *
- *
- * Given a struct powerdomain * @pwrdm, returns 1 if the powerdomain
- * can lose either memory or logic context or if @pwrdm is invalid, or
- * returns 0 otherwise.  This function is not concerned with how the
- * powerdomain registers are programmed (i.e., to go off or not); it's
- * concerned with whether it's ever possible for this powerdomain to
- * go off while some other part of the chip is active.  This function
- * assumes that every powerdomain can go to either ON or INACTIVE.
- */
-bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
-{
-   int i;
-
-   if (!pwrdm) {
-   pr_debug("powerdomain: %s: invalid powerdomain pointer\n",
-__func__);
-   return 1;
-   }
-
-   if (pwrdm->pwrsts & PWRSTS_OFF)
-   return 1;
-
-   if (pwrdm->pwrsts & PWRSTS_RET) {
-   if (pwrdm->pwrsts_logic_ret & PWRSTS_OFF)
-   return 1;
-
-   for (i = 0; i < pwrdm->banks; i++)
-   if (pwrdm->pwrsts_mem_ret[i] & PWRSTS_OFF)
-   return 1;
-   }
-
-   for (i = 0; i < pwrdm->banks; i++)
-   if (pwrdm->pwrsts_mem_on[i] & PWRSTS_OFF)
-   return 1;
-
-   return 0;
-}
-
-/**
  * pwrdm_save_context - save powerdomain registers
  *
  * Register state is going to be lost due to a suspend or hibernate
diff --git a/arch/arm/mach-omap2/powerdomain.h 
b/arch/arm/mach-omap2/powerdomain.h
index 9a907fb..a5bdc28 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -247,7 +247,6 @@ u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
 int pwrdm_pre_transition(struct powerdomain *pwrdm);
 int pwrdm_post_transition(struct powerdomain *pwrdm);
 int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
-bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
 
 extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 state);
 
-- 
1.9.1



[PATCH 06/14] ARM: AM33XX: Add functions to save/restore am33xx control registers.

2018-04-11 Thread Keerthy
From: Russ Dill <russ.d...@ti.com>

These registers are part of the wkup domain and are lost during RTC only
suspend and also hibernation, so storing/restoring their state is
necessary.

Signed-off-by: Russ Dill <russ.d...@ti.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 arch/arm/mach-omap2/control.c | 84 +++
 arch/arm/mach-omap2/control.h | 52 +++
 2 files changed, 136 insertions(+)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 180da403..d92aa9a 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -619,8 +619,92 @@ void __init omap3_ctrl_init(void)
 
omap3_ctrl_setup_d2d_padconf();
 }
+
 #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
 
+#if defined(CONFIG_SOC_AM33XX) && defined(CONFIG_PM)
+static unsigned long am33xx_control_reg_offsets[] = {
+   AM33XX_CONTROL_SYSCONFIG_OFFSET,
+   AM33XX_CONTROL_STATUS_OFFSET,
+   AM33XX_CONTROL_CORTEX_VBBLDO_CTRL_OFFSET,
+   AM33XX_CONTROL_CORE_SLDO_CTRL_OFFSET,
+   AM33XX_CONTROL_MPU_SLDO_CTRL_OFFSET,
+   AM33XX_CONTROL_CLK32KDIVRATIO_CTRL_OFFSET,
+   AM33XX_CONTROL_BANDGAP_CTRL_OFFSET,
+   AM33XX_CONTROL_BANDGAP_TRIM_OFFSET,
+   AM33XX_CONTROL_PLL_CLKINPULOW_CTRL_OFFSET,
+   AM33XX_CONTROL_MOSC_CTRL_OFFSET,
+   AM33XX_CONTROL_RCOSC_CTRL_OFFSET,
+   AM33XX_CONTROL_DEEPSLEEP_CTRL_OFFSET,
+   AM33XX_CONTROL_INIT_PRIORITY_0_OFFSET,
+   AM33XX_CONTROL_INIT_PRIORITY_1_OFFSET,
+   AM33XX_CONTROL_MMU_CFG_OFFSET,
+   AM33XX_CONTROL_TPTC_CFG_OFFSET,
+   AM33XX_CONTROL_USB_CTRL0_OFFSET,
+   AM33XX_CONTROL_USB_CTRL1_OFFSET,
+   AM33XX_CONTROL_USB_WKUP_CTRL_OFFSET,
+   AM33XX_CONTROL_MREQPRIO_0_OFFSET,
+   AM33XX_CONTROL_MREQPRIO_1_OFFSET,
+   AM33XX_CONTROL_HW_EVENT_SEL_GRP1_OFFSET,
+   AM33XX_CONTROL_HW_EVENT_SEL_GRP2_OFFSET,
+   AM33XX_CONTROL_HW_EVENT_SEL_GRP3_OFFSET,
+   AM33XX_CONTROL_HW_EVENT_SEL_GRP4_OFFSET,
+   AM33XX_CONTROL_SMRT_CTRL_OFFSET,
+   AM33XX_CONTROL_MPUSS_HW_DEBUG_SEL_OFFSET,
+   AM33XX_CONTROL_VREF_CTRL_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_0_3_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_4_7_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_8_11_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_12_15_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_16_19_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_20_23_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_24_27_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_28_31_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_32_35_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_36_39_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_40_43_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_44_47_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_48_51_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_52_55_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_56_59_OFFSET,
+   AM33XX_CONTROL_TPCC_EVT_MUX_60_63_OFFSET,
+   AM33XX_CONTROL_TIMER_EVT_CAPT_OFFSET,
+   AM33XX_CONTROL_ECAP_EVT_CAPT_OFFSET,
+   AM33XX_CONTROL_ADC_EVT_CAPT_OFFSET,
+   AM33XX_CONTROL_RESET_ISO_OFFSET,
+};
+
+static u32 am33xx_control_vals[ARRAY_SIZE(am33xx_control_reg_offsets)];
+
+/**
+ * am33xx_control_save_context - Save the wakeup domain registers
+ *
+ * Save the wkup domain registers
+ */
+void am33xx_control_save_context(void)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(am33xx_control_reg_offsets); i++)
+   am33xx_control_vals[i] =
+   omap_ctrl_readl(am33xx_control_reg_offsets[i]);
+}
+
+/**
+ * am33xx_control_restore_context - Restore the wakeup domain registers
+ *
+ * Restore the wkup domain registers
+ */
+void am33xx_control_restore_context(void)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(am33xx_control_reg_offsets); i++)
+   omap_ctrl_writel(am33xx_control_vals[i],
+am33xx_control_reg_offsets[i]);
+}
+#endif /* CONFIG_SOC_AM33XX && CONFIG_PM */
+
 struct control_init_data {
int index;
void __iomem *mem;
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index ec406bc..4c50199 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -409,6 +409,56 @@
 #define AM33XX_DEV_FEATURE 0x604
 #define AM33XX_SGX_MASKBIT(29)
 
+/* Additional AM33XX CONTROL registers */
+#define AM33XX_CONTROL_SYSCONFIG_OFFSET0x0010
+#define AM33XX_CONTROL_STATUS_OFFSET   0x0040
+#define AM33XX_CONTROL_CORTEX_VBBLDO_CTRL_OFFSET   0x041c
+#define AM33XX_CONTROL_CORE_SLDO_CTRL_OFFSET   0x0428
+#define AM33XX_CONTROL_MPU_SLDO_CTRL_OFFSET0x042c
+#define AM33XX_CONTROL_CLK32KDIVRATIO_CTRL_OFFSET  0x0444
+#define AM33XX_CONTROL_BANDGAP_CTRL_OFFSET 0x0448
+#define AM33XX_CONTROL_BANDGAP_TRIM_OFFSET 0x044c
+#define AM33XX_CONTROL

[PATCH 11/14] gpio: omap: Restore power_mode configuration at resume time

2018-04-11 Thread Keerthy
From: Dave Gerlach <d-gerl...@ti.com>

Commit 2dc983c565e0 ("gpio/omap: cleanup prepare_for_idle and
resume_after_idle") introduces omap2_gpio_prepare_for_idle and
omap2_gpio_resume_after_idle to properly configure gpios that are used
as wake sources. When entering off mode, omap2_gpio_prepare_for_idle
can set a flag indicating off-mode entry is desired, however once this
flag is set it is never cleared, so any additional calls to this
function, regardless of the mode, have this flag set.

This patch restores the pwr_mode flag to 0 in
omap2_gpio_resume_after_idle to ensure the flag is not misconfigured
during non off-mode operation.

Signed-off-by: Dave Gerlach <d-gerl...@ti.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 drivers/gpio/gpio-omap.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 34fde30..84d664b 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -1476,6 +1476,8 @@ void omap2_gpio_resume_after_idle(void)
continue;
 
pm_runtime_get_sync(bank->chip.parent);
+
+   bank->power_mode = 0;
}
 }
 #endif
-- 
1.9.1



[PATCH 08/14] ARM: OMAP2: Add functions to save and restore pinctrl context.

2018-04-11 Thread Keerthy
From: Russ Dill <russ.d...@gmail.com>

This adds a pair of context save/restore functions to save/restore the
state of a set of pinctrl registers. This simplifies some of the AM33XX
PM code as some of the pinctrl registers are lost when the per power
domain loses power. The pincrtl code can perform the necessary
save/restore.

This will also be necessary for hibernation and RTC only sleep, as all
pinctrl registers all lost.

Signed-off-by: Russ Dill <russ.d...@gmail.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 drivers/pinctrl/core.c   |  1 +
 drivers/pinctrl/core.h   |  1 -
 drivers/pinctrl/pinctrl-single.c | 50 
 drivers/pinctrl/pinmux.c | 22 ++
 include/linux/pinctrl/pinctrl.h  |  7 ++
 include/linux/pinctrl/pinmux.h   | 16 +
 6 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index e5a3030..1a9ae64 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -119,6 +119,7 @@ struct pinctrl_dev *get_pinctrl_dev_from_devname(const char 
*devname)
 
return NULL;
 }
+EXPORT_SYMBOL_GPL(get_pinctrl_dev_from_devname);
 
 struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np)
 {
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index 8cf2eba..e587c29 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -226,7 +226,6 @@ int pinctrl_generic_remove_group(struct pinctrl_dev 
*pctldev,
 
 #endif /* CONFIG_GENERIC_PINCTRL_GROUPS */
 
-struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
 struct pinctrl_dev *get_pinctrl_dev_from_of_node(struct device_node *np);
 int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
 const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin);
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index a7c5eb3..2fc3317 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -144,6 +144,7 @@ struct pcs_soc_data {
  * struct pcs_device - pinctrl device instance
  * @res:   resources
  * @base:  virtual address of the controller
+ * @saved_vals: saved values for the controller
  * @size:  size of the ioremapped area
  * @dev:   device entry
  * @np:device tree node
@@ -172,6 +173,7 @@ struct pcs_soc_data {
 struct pcs_device {
struct resource *res;
void __iomem *base;
+   void *saved_vals;
unsigned size;
struct device *dev;
struct device_node *np;
@@ -372,6 +374,52 @@ static int pcs_set_mux(struct pinctrl_dev *pctldev, 
unsigned fselector,
return 0;
 }
 
+static int pcs_save_context(struct pinctrl_dev *pctldev)
+{
+   struct pcs_device *pcs;
+   int i;
+
+   pcs = pinctrl_dev_get_drvdata(pctldev);
+
+   if (!pcs->saved_vals)
+   pcs->saved_vals = devm_kzalloc(pcs->dev, pcs->size, GFP_ATOMIC);
+
+   switch (pcs->width) {
+   case 32:
+   for (i = 0; i < pcs->size; i += 4)
+   *(u32 *)(pcs->saved_vals + i) =
+   pcs->read(pcs->base + i);
+   break;
+   case 16:
+   for (i = 0; i < pcs->size; i += 2)
+   *(u16 *)(pcs->saved_vals + i) =
+   pcs->read(pcs->base + i);
+   break;
+   }
+   return 0;
+}
+
+static void pcs_restore_context(struct pinctrl_dev *pctldev)
+{
+   struct pcs_device *pcs;
+   int i;
+
+   pcs = pinctrl_dev_get_drvdata(pctldev);
+
+   switch (pcs->width) {
+   case 32:
+   for (i = 0; i < pcs->size; i += 4)
+   pcs->write(*(u32 *)(pcs->saved_vals + i),
+   pcs->base + i);
+   break;
+   case 16:
+   for (i = 0; i < pcs->size; i += 2)
+   pcs->write(*(u16 *)(pcs->saved_vals + i),
+   pcs->base + i);
+   break;
+   }
+}
+
 static int pcs_request_gpio(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range, unsigned pin)
 {
@@ -420,6 +468,8 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev,
.get_function_name = pinmux_generic_get_function_name,
.get_function_groups = pinmux_generic_get_function_groups,
.set_mux = pcs_set_mux,
+   .save_context = pcs_save_context,
+   .restore_context = pcs_restore_context,
.gpio_request_enable = pcs_request_gpio,
 };
 
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index b8e9bda..b144e0d 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -312,6 +312,28 @@ static int pinmux_func_name_to_selector(struct pinctrl_dev 
*pctldev,
return -EINVAL;
 }
 
+in

[PATCH 10/14] gpio: omap: Drop the concept of gpio banks not being able to lose context.

2018-04-11 Thread Keerthy
From: Russ Dill <russ.d...@ti.com>

It isn't much of a win, and with hibernation, everything loses context.

Signed-off-by: Russ Dill <russ.d...@ti.com>
Signed-off-by: Keerthy <j-keer...@ti.com>
---
 drivers/gpio/gpio-omap.c| 38 -
 include/linux/platform_data/gpio-omap.h |  1 -
 2 files changed, 14 insertions(+), 25 deletions(-)

diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 35971a3..34fde30 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -68,7 +68,7 @@ struct gpio_bank {
bool dbck_enabled;
bool is_mpuio;
bool dbck_flag;
-   bool loses_context;
+
bool context_valid;
int stride;
u32 width;
@@ -1198,15 +1198,9 @@ static int omap_gpio_probe(struct platform_device *pdev)
 #ifdef CONFIG_OF_GPIO
bank->chip.of_node = of_node_get(node);
 #endif
-   if (node) {
-   if (!of_property_read_bool(node, "ti,gpio-always-on"))
-   bank->loses_context = true;
-   } else {
-   bank->loses_context = pdata->loses_context;
-
-   if (bank->loses_context)
-   bank->get_context_loss_count =
-   pdata->get_context_loss_count;
+   if (!node) {
+   bank->get_context_loss_count =
+   pdata->get_context_loss_count;
}
 
if (bank->regs->set_dataout && bank->regs->clr_dataout)
@@ -1365,7 +1359,7 @@ static int omap_gpio_runtime_resume(struct device *dev)
 * been initialised and so initialise it now. Also initialise
 * the context loss count.
 */
-   if (bank->loses_context && !bank->context_valid) {
+   if (!bank->context_valid) {
omap_gpio_init_context(bank);
 
if (bank->get_context_loss_count)
@@ -1386,17 +1380,13 @@ static int omap_gpio_runtime_resume(struct device *dev)
writel_relaxed(bank->context.risingdetect,
 bank->base + bank->regs->risingdetect);
 
-   if (bank->loses_context) {
-   if (!bank->get_context_loss_count) {
-   omap_gpio_restore_context(bank);
-   } else {
-   c = bank->get_context_loss_count(dev);
-   if (c != bank->context_loss_count) {
-   omap_gpio_restore_context(bank);
-   } else {
-   raw_spin_unlock_irqrestore(>lock, flags);
-   return 0;
-   }
+   if (!bank->get_context_loss_count) {
+   omap_gpio_restore_context(bank);
+   } else {
+   c = bank->get_context_loss_count(bank->chip.parent);
+   if (c != bank->context_loss_count) {
+   raw_spin_unlock_irqrestore(>lock, flags);
+   return 0;
}
}
 
@@ -1468,7 +1458,7 @@ void omap2_gpio_prepare_for_idle(int pwr_mode)
struct gpio_bank *bank;
 
list_for_each_entry(bank, _gpio_list, node) {
-   if (!BANK_USED(bank) || !bank->loses_context)
+   if (!BANK_USED(bank))
continue;
 
bank->power_mode = pwr_mode;
@@ -1482,7 +1472,7 @@ void omap2_gpio_resume_after_idle(void)
struct gpio_bank *bank;
 
list_for_each_entry(bank, _gpio_list, node) {
-   if (!BANK_USED(bank) || !bank->loses_context)
+   if (!BANK_USED(bank))
continue;
 
pm_runtime_get_sync(bank->chip.parent);
diff --git a/include/linux/platform_data/gpio-omap.h 
b/include/linux/platform_data/gpio-omap.h
index 8612855..77eb187 100644
--- a/include/linux/platform_data/gpio-omap.h
+++ b/include/linux/platform_data/gpio-omap.h
@@ -193,7 +193,6 @@ struct omap_gpio_platform_data {
int bank_width; /* GPIO bank width */
int bank_stride;/* Only needed for omap1 MPUIO */
bool dbck_flag; /* dbck required or not - True for OMAP3&4 */
-   bool loses_context; /* whether the bank would ever lose context */
bool is_mpuio;  /* whether the bank is of type MPUIO */
u32 non_wakeup_gpios;
 
-- 
1.9.1



[PATCH 12/14] OMAP: CLK: CLKSRC: Add suspend resume hooks

2018-04-11 Thread Keerthy
Add the save and restore for clksrc as part of suspend and resume
so that it saves the counter value and restores. This is needed in
modes like rtc+ddr in self-refresh not doing this stalls the time.

Signed-off-by: Keerthy <j-keer...@ti.com>
---
 arch/arm/mach-omap2/timer.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 4fb4dc2..35fef97 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -442,6 +442,38 @@ static int __init __maybe_unused 
omap2_sync32k_clocksource_init(void)
return ret;
 }
 
+static unsigned int omap2_gptimer_clksrc_load;
+
+static void omap2_gptimer_clksrc_suspend(struct clocksource *unused)
+{
+   struct omap_hwmod *oh;
+
+   omap2_gptimer_clksrc_load =
+   __omap_dm_timer_read_counter(, OMAP_TIMER_NONPOSTED);
+
+   oh = omap_hwmod_lookup(clocksource_gpt.name);
+   if (!oh)
+   return;
+
+   omap_hwmod_idle(oh);
+}
+
+static void omap2_gptimer_clksrc_resume(struct clocksource *unused)
+{
+   struct omap_hwmod *oh;
+
+   oh = omap_hwmod_lookup(clocksource_gpt.name);
+   if (!oh)
+   return;
+
+   omap_hwmod_enable(oh);
+
+   __omap_dm_timer_load_start(,
+  OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR,
+  omap2_gptimer_clksrc_load,
+  OMAP_TIMER_NONPOSTED);
+}
+
 static void __init omap2_gptimer_clocksource_init(int gptimer_id,
  const char *fck_source,
  const char *property)
@@ -451,6 +483,11 @@ static void __init omap2_gptimer_clocksource_init(int 
gptimer_id,
clksrc.id = gptimer_id;
clksrc.errata = omap_dm_timer_get_errata();
 
+   if (soc_is_am43xx()) {
+   clocksource_gpt.suspend = omap2_gptimer_clksrc_suspend;
+   clocksource_gpt.resume = omap2_gptimer_clksrc_resume;
+   }
+
res = omap_dm_timer_init_one(, fck_source, property,
 _gpt.name,
 OMAP_TIMER_NONPOSTED);
-- 
1.9.1



[PATCH 05/14] ARM: OMAP2: Add functions to save and restore powerdomain context

2018-04-11 Thread Keerthy
From: Russ Dill <russ.d...@ti.com>

The powerdomain control registers are stored in the WKUP powerdomain on
AM33XX/AM43XX, which is lost on RTC-only suspend and also hibernate. This
adds context save and restore functions for those registers.
Sometimes the powerdomain state does not need to change,
perhaps we only need to change memory retention states, so make
sure the restored state is different from the current state before we wait
for a transition.

Signed-off-by: Keerthy <j-keer...@ti.com>
Signed-off-by: Dave Gerlach <d-gerl...@ti.com>
Signed-off-by: Russ Dill <russ.d...@ti.com>
---
 arch/arm/mach-omap2/powerdomain.c | 60 +++
 arch/arm/mach-omap2/powerdomain.h |  7 +
 arch/arm/mach-omap2/prm33xx.c | 31 
 arch/arm/mach-omap2/prm44xx.c | 50 
 4 files changed, 148 insertions(+)

diff --git a/arch/arm/mach-omap2/powerdomain.c 
b/arch/arm/mach-omap2/powerdomain.c
index 76eb6ec..ee693f6 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -1199,3 +1199,63 @@ bool pwrdm_can_ever_lose_context(struct powerdomain 
*pwrdm)
 
return 0;
 }
+
+/**
+ * pwrdm_save_context - save powerdomain registers
+ *
+ * Register state is going to be lost due to a suspend or hibernate
+ * event. Save the powerdomain registers.
+ */
+static int pwrdm_save_context(struct powerdomain *pwrdm, void *unused)
+{
+   if (arch_pwrdm && arch_pwrdm->pwrdm_save_context)
+   arch_pwrdm->pwrdm_save_context(pwrdm);
+   return 0;
+}
+
+/**
+ * pwrdm_save_context - restore powerdomain registers
+ *
+ * Restore powerdomain control registers after a suspend or resume
+ * event.
+ */
+static int pwrdm_restore_context(struct powerdomain *pwrdm, void *unused)
+{
+   if (arch_pwrdm && arch_pwrdm->pwrdm_restore_context)
+   arch_pwrdm->pwrdm_restore_context(pwrdm);
+   return 0;
+}
+
+static int pwrdm_lost_power(struct powerdomain *pwrdm, void *unused)
+{
+   int state;
+
+   /*
+* Power has been lost across all powerdomains, increment the
+* counter.
+*/
+
+   state = pwrdm_read_pwrst(pwrdm);
+   if (state != PWRDM_POWER_OFF) {
+   pwrdm->state_counter[state]++;
+   pwrdm->state_counter[PWRDM_POWER_OFF]++;
+   }
+   pwrdm->state = state;
+
+   return 0;
+}
+
+void pwrdms_save_context(void)
+{
+   pwrdm_for_each(pwrdm_save_context, NULL);
+}
+
+void pwrdms_restore_context(void)
+{
+   pwrdm_for_each(pwrdm_restore_context, NULL);
+}
+
+void pwrdms_lost_power(void)
+{
+   pwrdm_for_each(pwrdm_lost_power, NULL);
+}
diff --git a/arch/arm/mach-omap2/powerdomain.h 
b/arch/arm/mach-omap2/powerdomain.h
index 28a796c..9a907fb 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -144,6 +144,7 @@ struct powerdomain {
s64 timer;
s64 state_timer[PWRDM_MAX_PWRSTS];
 #endif
+   u32 context;
 };
 
 /**
@@ -198,6 +199,8 @@ struct pwrdm_ops {
int (*pwrdm_set_lowpwrstchange)(struct powerdomain *pwrdm);
int (*pwrdm_wait_transition)(struct powerdomain *pwrdm);
int (*pwrdm_has_voltdm)(void);
+   void(*pwrdm_save_context)(struct powerdomain *pwrdm);
+   void(*pwrdm_restore_context)(struct powerdomain *pwrdm);
 };
 
 int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs);
@@ -273,4 +276,8 @@ u8 pwrdm_get_valid_lp_state(struct powerdomain *pwrdm,
 extern void pwrdm_lock(struct powerdomain *pwrdm);
 extern void pwrdm_unlock(struct powerdomain *pwrdm);
 
+extern void pwrdms_save_context(void);
+extern void pwrdms_restore_context(void);
+
+extern void pwrdms_lost_power(void);
 #endif
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index ebaf80d..d514166 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -342,6 +342,35 @@ static void am33xx_prm_global_warm_sw_reset(void)
  AM33XX_PRM_RSTCTRL_OFFSET);
 }
 
+static void am33xx_pwrdm_save_context(struct powerdomain *pwrdm)
+{
+   pwrdm->context = am33xx_prm_read_reg(pwrdm->prcm_offs,
+   pwrdm->pwrstctrl_offs);
+   /*
+* Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request,
+* reading back a 1 indicates a request in progress.
+*/
+   pwrdm->context &= ~AM33XX_LOWPOWERSTATECHANGE_MASK;
+}
+
+static void am33xx_pwrdm_restore_context(struct powerdomain *pwrdm)
+{
+   int st, ctrl;
+
+   st = am33xx_prm_read_reg(pwrdm->prcm_offs,
+pwrdm->pwrstst_offs);
+
+   am33xx_prm_write_reg(pwrdm->context, pwrdm->prcm_offs,
+pwrdm->pwrstctrl_offs);
+
+   /* Make sure we only wait for a transition if there is one */

<    4   5   6   7   8   9   10   11   12   13   >