Re: [RFC PATCH 09/11] ARM: OMAP4+: thermal: introduce bandgap temperature sensor

2012-05-29 Thread Cousson, Benoit

On 5/28/2012 1:16 PM, Eduardo Valentin wrote:

Hello again,

On Fri, May 25, 2012 at 05:49:44PM +0200, Cousson Benoit wrote:

On 5/25/2012 10:25 AM, Eduardo Valentin wrote:


big cut


+
+static const struct omap_bandgap_data omap4460_data = {
+   .has_talert = true,
+   .has_tshut = true,
+   .fclock_name = bandgap_ts_fclk,
+   .div_ck_name = div_ts_ck,


None of these clock data should be there ideally. You should ensure
that the proper device alias will be there using clkdev entries.


In fact, it is a shame that it would be needed to have this entries there :-(



Except that with DT, it will not work without the clock DT binding :-(

I think Rob posted a latest update based on CCF... but for the
moment we are stuck :-(


OK. But would it work for BG as well as it seams to be a special case?




+   .conv_table = omap4460_adc_to_temp,
+   .sensors = {
+   {
+   .registers =omap4460_mpu_temp_sensor_registers,
+   .ts_data =omap4460_mpu_temp_sensor_data,
+   .domain = cpu,
+   },
+   },
+   .sensor_count = 1,
+};
+
+static const struct omap_bandgap_data omap5430_data = {
+   .has_talert = true,
+   .has_tshut = true,
+   .fclock_name = ts_clk_div_ck,
+   .div_ck_name = ts_clk_div_ck,
+   .conv_table = omap5430_adc_to_temp,
+   .sensors = {
+   {
+   .registers =omap5430_mpu_temp_sensor_registers,
+   .ts_data =omap5430_mpu_temp_sensor_data,
+   .domain = cpu,
+   },
+   {
+   .registers =omap5430_gpu_temp_sensor_registers,
+   .ts_data =omap5430_gpu_temp_sensor_data,
+   .domain = gpu,
+   },
+   {
+   .registers =omap5430_core_temp_sensor_registers,
+   .ts_data =omap5430_core_temp_sensor_data,
+   .domain = core,
+   },
+   },
+   .sensor_count = 3,


It can probably be replaced by a sizeof.


ARRAY_SIZE prob, will check.


Ah, yes, that's one... I was looking for it for forgot the name :-)


+};
+
+static const struct of_device_id of_omap_bandgap_match[] = {
+   /*
+* TODO: Add support to 4430
+* { .compatible = ti,omap4430-bandgap, .data = , },
+*/
+   {
+   .compatible = ti,omap4460-bandgap,
+   .data = (void *)omap4460_data,


No need to cast toward a void *.


In this case, there is a need, because the omap4460_data is const but the .data 
field isn't. So I need to force it.




+   },
+   {
+   .compatible = ti,omap5430-bandgap,
+   .data = (void *)omap5430_data,
+   },
+   /* Sentinel */
+   { },
+};
+
+static struct omap_bandgap *omap_bandgap_build(struct platform_device *pdev)
+{
+   struct device_node *node = pdev-dev.of_node;
+   const struct of_device_id *of_id;
+   struct omap_bandgap *bg_ptr;


bg_ptr is not a super name.


Got a better name? Just don't want a long one to avoid code bending at 80th 
column...


My concern was mainly with the _ptr, it looks like a Hungarian notation. 
:-)...


Maybe bg only? Or omap_bg?






+   u32 prop;
+
+   /* just for the sake */
+   if (!node) {
+   dev_err(pdev-dev, no platform information available\n);
+   return ERR_PTR(-EINVAL);
+   }


Not needed, just do the of_match_device here directly.


Indeed...




+
+   bg_ptr = devm_kzalloc(pdev-dev, sizeof(struct omap_bandgap),
+   GFP_KERNEL);
+   if (!bg_ptr) {
+   dev_err(pdev-dev, Unable to allocate mem for driver ref\n);
+   return ERR_PTR(-ENOMEM);
+   }
+
+   of_id = of_match_device(of_omap_bandgap_match,pdev-dev);
+   if (of_id)
+   bg_ptr-pdata = of_id-data;


Nit: This is not really pdata anymore, so you should maybe remove
the p to avoid confusion.


OK...




+
+   if (bg_ptr-pdata-has_tshut) {
+   if (of_property_read_u32(node, ti,tshut-gpio,prop)   0) {
+   dev_err(pdev-dev, missing tshut gpio in device 
tree\n);
+   return ERR_PTR(-EINVAL);
+   }
+   bg_ptr-tshut_gpio = prop;
+   if (!gpio_is_valid(bg_ptr-tshut_gpio)) {
+   dev_err(pdev-dev, invalid gpio for tshut (%d)\n,
+   bg_ptr-tshut_gpio);
+   return ERR_PTR(-EINVAL);
+   }
+   }
+
+   return bg_ptr;
+}
+
+static
+int __devinit omap_bandgap_probe(struct platform_device *pdev)
+{
+   struct device *cdev = pdev-dev.parent;
+   struct omap_bandgap *bg_ptr;
+   int clk_rate, ret = 0, i;
+
+   if (!cdev) {
+   dev_err(pdev-dev, no omap control ref in our parent\n);
+   return -EINVAL;
+ 

Re: [RFC PATCH 09/11] ARM: OMAP4+: thermal: introduce bandgap temperature sensor

2012-05-29 Thread Mike Turquette
On 20120529-15:14, Cousson, Benoit wrote:
 On 5/28/2012 1:16 PM, Eduardo Valentin wrote:
 In fact I didn't touch the clk data on purpose and left the clock handling
 as is. On my side I didn't know how the clock struct would look like with DT,
 so, I didn't mess with it.
 
 Do you have a reference to check the work in progress for clock DT ?
 
 Rob sent a pull request, it seems that now it is up to Mike T. :-)
 
 http://lists-archives.com/linux-kernel/27640907-dt-clk-binding-support.html
 

Due to the on-going discussion around those patches I haven't pulled
yet.  If everyone agrees once the dust settles then I'll take them in.

Regards,
Mike

--
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: [RFC PATCH 09/11] ARM: OMAP4+: thermal: introduce bandgap temperature sensor

2012-05-28 Thread Eduardo Valentin
Hello Konstantin,

On Fri, May 25, 2012 at 08:39:09PM +0400, Konstantin Baydarov wrote:
   Hi.
 On 05/25/2012 12:25 PM, Eduardo Valentin wrote:
  In the System Control Module, OMAP supplies a voltage reference
  and a temperature sensor feature that are gathered in the band
  gap voltage and temperature sensor (VBGAPTS) module. The band
  gap provides current and voltage reference for its internal
  circuits and other analog IP blocks. The analog-to-digital
  converter (ADC) produces an output value that is proportional
  to the silicon temperature.
 
  This patch provides a platform driver which expose this feature.
  It is moduled as a MFD child of the System Control Module core
  MFD driver.
 
  This driver provides only APIs to access the device properties,
  like temperature, thresholds and update rate.
 
  Signed-off-by: Eduardo Valentin eduardo.valen...@ti.com
  Signed-off-by: Keerthy j-keer...@ti.com
  ---
   .../devicetree/bindings/thermal/omap_bandgap.txt   |   27 +
   drivers/thermal/Kconfig|   13 +
   drivers/thermal/Makefile   |4 +-
   drivers/thermal/omap-bandgap.c | 1601 
  
   drivers/thermal/omap-bandgap.h |   63 +
   5 files changed, 1707 insertions(+), 1 deletions(-)
   create mode 100644 
  Documentation/devicetree/bindings/thermal/omap_bandgap.txt
   create mode 100644 drivers/thermal/omap-bandgap.c
   create mode 100644 drivers/thermal/omap-bandgap.h
 
 
 Add private spin lock in omap-bandgap driver to prevent blocking of
 control module general registers access.

Thanks for sending this out. I will rethink these drivers wrt to locking and 
will
your proposal.

 I wasn't able to test - I have panda 4430 board.

Right, we definetly need to have it probing on 4430, I will check how we can 
close on that.

 
 TODO:
 Prevent over-usage of spin_lock/spin_unlock for sequential calls of
 bg_writel().

OK...

 
 Signed-off-by: Konstantin Baydarov kbaida...@dev.rtsoft.ru
 
 Index: omap-thermal/drivers/mfd/omap-control-core.c
 ===
 --- omap-thermal.orig/drivers/mfd/omap-control-core.c
 +++ omap-thermal/drivers/mfd/omap-control-core.c
 @@ -67,6 +67,19 @@ EXPORT_SYMBOL_GPL(omap_control_readl);
  int omap_control_writel(struct device *dev, u32 val, u32 reg)
  {
   struct omap_control *omap_control = dev_get_drvdata(dev);
 +
 + if (!omap_control)
 + return -EINVAL;
 +
 + writel(val, omap_control-base + reg);
 +
 + return 0;
 +}
 +EXPORT_SYMBOL_GPL(omap_control_writel);
 +
 +int omap_control_lock_writel(struct device *dev, u32 val, u32 reg)
 +{
 + struct omap_control *omap_control = dev_get_drvdata(dev);
   unsigned long flags;
  
   if (!omap_control)
 @@ -78,7 +91,7 @@ int omap_control_writel(struct device *d
  
   return 0;
  }
 -EXPORT_SYMBOL_GPL(omap_control_writel);
 +EXPORT_SYMBOL_GPL(omap_control_lock_writel);
  
  /**
   * omap_control_get: returns the control module device pinter
 @@ -136,6 +149,9 @@ static int __devinit omap_control_probe(
   struct device_node *np = dev-of_node;
   struct omap_control *omap_control;
  
 + printk(\n\t\t  omap_control_probe(): enter );
 + dump_stack();
 +
   omap_control = devm_kzalloc(dev, sizeof(*omap_control), GFP_KERNEL);
   if (!omap_control) {
   dev_err(dev, not enough memory for omap_control\n);
 Index: omap-thermal/drivers/thermal/omap-bandgap.c
 ===
 --- omap-thermal.orig/drivers/thermal/omap-bandgap.c
 +++ omap-thermal/drivers/thermal/omap-bandgap.c
 @@ -154,6 +154,7 @@ struct temp_sensor_registers {
   u32 status_cold_mask;
  
   u32 bgap_efuse;
 + spinlock_t  bg_reg_lock;

Indeed. I agree we should have this per sensor. Need to revisit the existing 
mutex as well though.

  };
  
  /**
 @@ -579,6 +580,17 @@ omap5430_adc_to_temp[OMAP5430_ADC_END_VA
   124600, 124900, 125000, 125000, 125000, 125000,
  };
  
 +static int bg_writel(struct device *dev, u32 val, u32 reg, spinlock_t *lock)
 +{
 + unsigned long flags;
 + int ret;
 +
 + spin_lock_irqsave(lock, flags);
 + ret = omap_control_writel(dev, val, reg);
 + spin_unlock_irqrestore(lock, flags);

In fact this doesn't help much in the bulk writes case. As you have already 
mentioned,
ideally we should lock, perform the operation, then unlock, instead of several
lock/write/unlock sequences.

 + return ret;
 +}
 +
  static irqreturn_t talert_irq_handler(int irq, void *data)
  {
   struct omap_bandgap *bg_ptr = data;
 @@ -615,7 +627,7 @@ static irqreturn_t talert_irq_handler(in
   ctrl |= tsr-mask_hot_mask;
   }
  
 - r |= omap_control_writel(cdev, ctrl, tsr-bgap_mask_ctrl);
 + r |= bg_writel(cdev, ctrl, tsr-bgap_mask_ctrl, 
 tsr-bg_reg_lock);
  
   if (r) 

Re: [RFC PATCH 09/11] ARM: OMAP4+: thermal: introduce bandgap temperature sensor

2012-05-28 Thread Eduardo Valentin
Hello again,

On Fri, May 25, 2012 at 05:49:44PM +0200, Cousson Benoit wrote:
 On 5/25/2012 10:25 AM, Eduardo Valentin wrote:

big cut

 +
 +static const struct omap_bandgap_data omap4460_data = {
 +.has_talert = true,
 +.has_tshut = true,
 +.fclock_name = bandgap_ts_fclk,
 +.div_ck_name = div_ts_ck,
 
 None of these clock data should be there ideally. You should ensure
 that the proper device alias will be there using clkdev entries.

In fact, it is a shame that it would be needed to have this entries there :-(

 
 Except that with DT, it will not work without the clock DT binding :-(
 
 I think Rob posted a latest update based on CCF... but for the
 moment we are stuck :-(

OK. But would it work for BG as well as it seams to be a special case?

 
 +.conv_table = omap4460_adc_to_temp,
 +.sensors = {
 +{
 +.registers =omap4460_mpu_temp_sensor_registers,
 +.ts_data =omap4460_mpu_temp_sensor_data,
 +.domain = cpu,
 +},
 +},
 +.sensor_count = 1,
 +};
 +
 +static const struct omap_bandgap_data omap5430_data = {
 +.has_talert = true,
 +.has_tshut = true,
 +.fclock_name = ts_clk_div_ck,
 +.div_ck_name = ts_clk_div_ck,
 +.conv_table = omap5430_adc_to_temp,
 +.sensors = {
 +{
 +.registers =omap5430_mpu_temp_sensor_registers,
 +.ts_data =omap5430_mpu_temp_sensor_data,
 +.domain = cpu,
 +},
 +{
 +.registers =omap5430_gpu_temp_sensor_registers,
 +.ts_data =omap5430_gpu_temp_sensor_data,
 +.domain = gpu,
 +},
 +{
 +.registers =omap5430_core_temp_sensor_registers,
 +.ts_data =omap5430_core_temp_sensor_data,
 +.domain = core,
 +},
 +},
 +.sensor_count = 3,
 
 It can probably be replaced by a sizeof.

ARRAY_SIZE prob, will check.

 
 +};
 +
 +static const struct of_device_id of_omap_bandgap_match[] = {
 +/*
 + * TODO: Add support to 4430
 + * { .compatible = ti,omap4430-bandgap, .data = , },
 + */
 +{
 +.compatible = ti,omap4460-bandgap,
 +.data = (void *)omap4460_data,
 
 No need to cast toward a void *.

In this case, there is a need, because the omap4460_data is const but the .data 
field isn't. So I need to force it.

 
 +},
 +{
 +.compatible = ti,omap5430-bandgap,
 +.data = (void *)omap5430_data,
 +},
 +/* Sentinel */
 +{ },
 +};
 +
 +static struct omap_bandgap *omap_bandgap_build(struct platform_device *pdev)
 +{
 +struct device_node *node = pdev-dev.of_node;
 +const struct of_device_id *of_id;
 +struct omap_bandgap *bg_ptr;
 
 bg_ptr is not a super name.

Got a better name? Just don't want a long one to avoid code bending at 80th 
column...

 
 +u32 prop;
 +
 +/* just for the sake */
 +if (!node) {
 +dev_err(pdev-dev, no platform information available\n);
 +return ERR_PTR(-EINVAL);
 +}
 
 Not needed, just do the of_match_device here directly.

Indeed...

 
 +
 +bg_ptr = devm_kzalloc(pdev-dev, sizeof(struct omap_bandgap),
 +GFP_KERNEL);
 +if (!bg_ptr) {
 +dev_err(pdev-dev, Unable to allocate mem for driver ref\n);
 +return ERR_PTR(-ENOMEM);
 +}
 +
 +of_id = of_match_device(of_omap_bandgap_match,pdev-dev);
 +if (of_id)
 +bg_ptr-pdata = of_id-data;
 
 Nit: This is not really pdata anymore, so you should maybe remove
 the p to avoid confusion.

OK...

 
 +
 +if (bg_ptr-pdata-has_tshut) {
 +if (of_property_read_u32(node, ti,tshut-gpio,prop)  0) {
 +dev_err(pdev-dev, missing tshut gpio in device 
 tree\n);
 +return ERR_PTR(-EINVAL);
 +}
 +bg_ptr-tshut_gpio = prop;
 +if (!gpio_is_valid(bg_ptr-tshut_gpio)) {
 +dev_err(pdev-dev, invalid gpio for tshut (%d)\n,
 +bg_ptr-tshut_gpio);
 +return ERR_PTR(-EINVAL);
 +}
 +}
 +
 +return bg_ptr;
 +}
 +
 +static
 +int __devinit omap_bandgap_probe(struct platform_device *pdev)
 +{
 +struct device *cdev = pdev-dev.parent;
 +struct omap_bandgap *bg_ptr;
 +int clk_rate, ret = 0, i;
 +
 +if (!cdev) {
 +dev_err(pdev-dev, no omap control ref in our parent\n);
 +return -EINVAL;
 +}
 +
 +bg_ptr = omap_bandgap_build(pdev);
 +if (IS_ERR_OR_NULL(bg_ptr)) {
 +dev_err(pdev-dev, failed to fetch platform data\n);
 +return PTR_ERR(bg_ptr);
 +}
 +
 +if (bg_ptr-pdata-has_talert) {
 
 Nit2: Yeah, in fact instead of pdata, conf or settings seems to
 be more representative of what this structure really contain.

conf looks good to 

[RFC PATCH 09/11] ARM: OMAP4+: thermal: introduce bandgap temperature sensor

2012-05-25 Thread Eduardo Valentin
In the System Control Module, OMAP supplies a voltage reference
and a temperature sensor feature that are gathered in the band
gap voltage and temperature sensor (VBGAPTS) module. The band
gap provides current and voltage reference for its internal
circuits and other analog IP blocks. The analog-to-digital
converter (ADC) produces an output value that is proportional
to the silicon temperature.

This patch provides a platform driver which expose this feature.
It is moduled as a MFD child of the System Control Module core
MFD driver.

This driver provides only APIs to access the device properties,
like temperature, thresholds and update rate.

Signed-off-by: Eduardo Valentin eduardo.valen...@ti.com
Signed-off-by: Keerthy j-keer...@ti.com
---
 .../devicetree/bindings/thermal/omap_bandgap.txt   |   27 +
 drivers/thermal/Kconfig|   13 +
 drivers/thermal/Makefile   |4 +-
 drivers/thermal/omap-bandgap.c | 1601 
 drivers/thermal/omap-bandgap.h |   63 +
 5 files changed, 1707 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/thermal/omap_bandgap.txt
 create mode 100644 drivers/thermal/omap-bandgap.c
 create mode 100644 drivers/thermal/omap-bandgap.h

diff --git a/Documentation/devicetree/bindings/thermal/omap_bandgap.txt 
b/Documentation/devicetree/bindings/thermal/omap_bandgap.txt
new file mode 100644
index 000..430bcf8
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/omap_bandgap.txt
@@ -0,0 +1,27 @@
+* Texas Instrument OMAP SCM bandgap bindings
+
+In the System Control Module, OMAP supplies a voltage reference
+and a temperature sensor feature that are gathered in the band
+gap voltage and temperature sensor (VBGAPTS) module. The band
+gap provides current and voltage reference for its internal
+circuits and other analog IP blocks. The analog-to-digital
+converter (ADC) produces an output value that is proportional
+to the silicon temperature.
+
+Required properties:
+- compatible : Should be:
+  - ti,omap4460-control-bandgap : for OMAP4460 bandgap
+  - ti,omap5430-control-bandgap : for OMAP5430 bandgap
+- interrupts : this entry should indicate which interrupt line
+the talert signal is routed to;
+Specific:
+- ti,tshut-gpio : this entry should be used to inform which GPIO
+line the tshut signal is routed to;
+
+Example:
+
+bandgap {
+   compatible = ti,omap4460-control-bandgap;
+   interrupts = 0 126 4; /* talert */
+   ti,tshut-gpio = 86;
+};
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 514a691..ffdd240 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -26,3 +26,16 @@ config SPEAR_THERMAL
help
  Enable this to plug the SPEAr thermal sensor driver into the Linux
  thermal framework
+
+config OMAP_BANDGAP
+   tristate Texas Instruments OMAP4+ temperature sensor driver
+   depends on THERMAL
+   depends on MFD_OMAP_CONTROL
+   help
+ If you say yes here you get support for the Texas Instruments
+ OMAP4460+ on die bandgap temperature sensor support. The register
+ set is part of system control module.
+
+ This includes alert interrupts generation and also the TSHUT
+ support.
+
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index a9fff0b..5ff1af1 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -3,4 +3,6 @@
 #
 
 obj-$(CONFIG_THERMAL)  += thermal_sys.o
-obj-$(CONFIG_SPEAR_THERMAL)+= spear_thermal.o
\ No newline at end of file
+obj-$(CONFIG_SPEAR_THERMAL)+= spear_thermal.o
+obj-$(CONFIG_OMAP_BANDGAP) += omap-thermal.o
+omap-thermal-y := omap-bandgap.o
diff --git a/drivers/thermal/omap-bandgap.c b/drivers/thermal/omap-bandgap.c
new file mode 100644
index 000..3d5a12b
--- /dev/null
+++ b/drivers/thermal/omap-bandgap.c
@@ -0,0 +1,1601 @@
+/*
+ * OMAP4 Bandgap temperature sensor driver
+ *
+ * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Author: J Keerthy j-keer...@ti.com
+ * Author: Moiz Sonasath m-sonas...@ti.com
+ * Couple of fixes, DT and MFD adaptation:
+ *   Eduardo Valentin eduardo.valen...@ti.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include 

Re: [RFC PATCH 09/11] ARM: OMAP4+: thermal: introduce bandgap temperature sensor

2012-05-25 Thread Konstantin Baydarov
  Hi.
On 05/25/2012 12:25 PM, Eduardo Valentin wrote:
 In the System Control Module, OMAP supplies a voltage reference
 and a temperature sensor feature that are gathered in the band
 gap voltage and temperature sensor (VBGAPTS) module. The band
 gap provides current and voltage reference for its internal
 circuits and other analog IP blocks. The analog-to-digital
 converter (ADC) produces an output value that is proportional
 to the silicon temperature.

 This patch provides a platform driver which expose this feature.
 It is moduled as a MFD child of the System Control Module core
 MFD driver.

 This driver provides only APIs to access the device properties,
 like temperature, thresholds and update rate.

 Signed-off-by: Eduardo Valentin eduardo.valen...@ti.com
 Signed-off-by: Keerthy j-keer...@ti.com
 ---
  .../devicetree/bindings/thermal/omap_bandgap.txt   |   27 +
  drivers/thermal/Kconfig|   13 +
  drivers/thermal/Makefile   |4 +-
  drivers/thermal/omap-bandgap.c | 1601 
 
  drivers/thermal/omap-bandgap.h |   63 +
  5 files changed, 1707 insertions(+), 1 deletions(-)
  create mode 100644 Documentation/devicetree/bindings/thermal/omap_bandgap.txt
  create mode 100644 drivers/thermal/omap-bandgap.c
  create mode 100644 drivers/thermal/omap-bandgap.h


Add private spin lock in omap-bandgap driver to prevent blocking of
control module general registers access.
I wasn't able to test - I have panda 4430 board.

TODO:
Prevent over-usage of spin_lock/spin_unlock for sequential calls of
bg_writel().

Signed-off-by: Konstantin Baydarov kbaida...@dev.rtsoft.ru

Index: omap-thermal/drivers/mfd/omap-control-core.c
===
--- omap-thermal.orig/drivers/mfd/omap-control-core.c
+++ omap-thermal/drivers/mfd/omap-control-core.c
@@ -67,6 +67,19 @@ EXPORT_SYMBOL_GPL(omap_control_readl);
 int omap_control_writel(struct device *dev, u32 val, u32 reg)
 {
struct omap_control *omap_control = dev_get_drvdata(dev);
+
+   if (!omap_control)
+   return -EINVAL;
+
+   writel(val, omap_control-base + reg);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(omap_control_writel);
+
+int omap_control_lock_writel(struct device *dev, u32 val, u32 reg)
+{
+   struct omap_control *omap_control = dev_get_drvdata(dev);
unsigned long flags;
 
if (!omap_control)
@@ -78,7 +91,7 @@ int omap_control_writel(struct device *d
 
return 0;
 }
-EXPORT_SYMBOL_GPL(omap_control_writel);
+EXPORT_SYMBOL_GPL(omap_control_lock_writel);
 
 /**
  * omap_control_get: returns the control module device pinter
@@ -136,6 +149,9 @@ static int __devinit omap_control_probe(
struct device_node *np = dev-of_node;
struct omap_control *omap_control;
 
+   printk(\n\t\t  omap_control_probe(): enter );
+   dump_stack();
+
omap_control = devm_kzalloc(dev, sizeof(*omap_control), GFP_KERNEL);
if (!omap_control) {
dev_err(dev, not enough memory for omap_control\n);
Index: omap-thermal/drivers/thermal/omap-bandgap.c
===
--- omap-thermal.orig/drivers/thermal/omap-bandgap.c
+++ omap-thermal/drivers/thermal/omap-bandgap.c
@@ -154,6 +154,7 @@ struct temp_sensor_registers {
u32 status_cold_mask;
 
u32 bgap_efuse;
+   spinlock_t  bg_reg_lock;
 };
 
 /**
@@ -579,6 +580,17 @@ omap5430_adc_to_temp[OMAP5430_ADC_END_VA
124600, 124900, 125000, 125000, 125000, 125000,
 };
 
+static int bg_writel(struct device *dev, u32 val, u32 reg, spinlock_t *lock)
+{
+   unsigned long flags;
+   int ret;
+
+   spin_lock_irqsave(lock, flags);
+   ret = omap_control_writel(dev, val, reg);
+   spin_unlock_irqrestore(lock, flags);
+   return ret;
+}
+
 static irqreturn_t talert_irq_handler(int irq, void *data)
 {
struct omap_bandgap *bg_ptr = data;
@@ -615,7 +627,7 @@ static irqreturn_t talert_irq_handler(in
ctrl |= tsr-mask_hot_mask;
}
 
-   r |= omap_control_writel(cdev, ctrl, tsr-bgap_mask_ctrl);
+   r |= bg_writel(cdev, ctrl, tsr-bgap_mask_ctrl, 
tsr-bg_reg_lock);
 
if (r) {
dev_err(bg_ptr-dev, failed to ack talert 
interrupt\n);
@@ -705,7 +717,7 @@ static int temp_sensor_unmask_interrupts
reg_val |= tsr-mask_cold_mask;
else
reg_val = ~tsr-mask_cold_mask;
-   err |= omap_control_writel(cdev, reg_val, tsr-bgap_mask_ctrl);
+   err |= bg_writel(cdev, reg_val, tsr-bgap_mask_ctrl, tsr-bg_reg_lock);
 
if (err) {
dev_err(bg_ptr-dev, failed to unmask interrupts\n);
@@ -751,14 +763,14 @@ int temp_sensor_configure_thot(struct om
/* write the new t_cold value */
reg_val = thresh_val