diff mbox

[v4] Thermal: exynos: Add sysfs node supporting exynos's emulation mode.

Message ID 1351823091-2540-1-git-send-email-jonghwa3.lee@samsung.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Jonghwa Lee Nov. 2, 2012, 2:24 a.m. UTC
This patch supports exynos's emulation mode with newly created sysfs node.
Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
management unit. Thermal emulation mode supports software debug for TMU's
operation. User can set temperature manually with software code and TMU
will read current temperature from user value not from sensor's value.
This patch includes also documentary placed under Documentation/thermal/.

Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
---
v4
 - Fix Typo.
 - Remove unnecessary codes.
 - Add comments about feature of exynos emulation operation to the document.

v3
 - Remove unnecessay variables.
 - Do some code clean in exynos_tmu_emulation_store().
 - Make wrapping function of sysfs node creation function to use
   #ifdefs in minimum.

v2
 exynos_thermal.c
 - Fix build error occured by wrong emulation control register name.
 - Remove exynos5410 dependent codes.
 exynos_thermal_emulation
 - Align indentation.

 Documentation/thermal/exynos_thermal_emulation |   56 +++++++++++++++
 drivers/thermal/Kconfig                        |    9 +++
 drivers/thermal/exynos_thermal.c               |   91 ++++++++++++++++++++++++
 3 files changed, 156 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/thermal/exynos_thermal_emulation

Comments

durgadoss.r@intel.com Nov. 2, 2012, 5:13 a.m. UTC | #1
Hi Lee,

> -----Original Message-----
> From: Jonghwa Lee [mailto:jonghwa3.lee@samsung.com]
> Sent: Friday, November 02, 2012 7:55 AM
> To: linux-pm@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org; Brown, Len; R, Durgadoss; Rafael J.
> Wysocki; Amit Dinel Kachhap; MyungJoo Ham; Kyungmin Park; Jonghwa Lee
> Subject: [PATCH v4] Thermal: exynos: Add sysfs node supporting exynos's
> emulation mode.
> 
> This patch supports exynos's emulation mode with newly created sysfs node.
> Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
> management unit. Thermal emulation mode supports software debug for
> TMU's
> operation. User can set temperature manually with software code and TMU
> will read current temperature from user value not from sensor's value.
> This patch includes also documentary placed under
> Documentation/thermal/.
> 

Thanks for fixing the comments. 
Please CC linux-acpi, when you submit thermal patches, going forward.
I am CCing Rui for now, for him to review/merge this patch.

Reviewed-by: Durgadoss R <durgadoss.r@intel.com>

Thanks,
Durga

> Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
> ---
> v4
>  - Fix Typo.
>  - Remove unnecessary codes.
>  - Add comments about feature of exynos emulation operation to the
> document.
> 
> v3
>  - Remove unnecessay variables.
>  - Do some code clean in exynos_tmu_emulation_store().
>  - Make wrapping function of sysfs node creation function to use
>    #ifdefs in minimum.
> 
> v2
>  exynos_thermal.c
>  - Fix build error occured by wrong emulation control register name.
>  - Remove exynos5410 dependent codes.
>  exynos_thermal_emulation
>  - Align indentation.
> 
>  Documentation/thermal/exynos_thermal_emulation |   56
> +++++++++++++++
>  drivers/thermal/Kconfig                        |    9 +++
>  drivers/thermal/exynos_thermal.c               |   91
> ++++++++++++++++++++++++
>  3 files changed, 156 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/thermal/exynos_thermal_emulation
> 
> diff --git a/Documentation/thermal/exynos_thermal_emulation
> b/Documentation/thermal/exynos_thermal_emulation
> new file mode 100644
> index 0000000..a6ea06f
> --- /dev/null
> +++ b/Documentation/thermal/exynos_thermal_emulation
> @@ -0,0 +1,56 @@
> +EXYNOS EMULATION MODE
> +========================
> +
> +Copyright (C) 2012 Samsung Electronics
> +
> +Written by Jonghwa Lee <jonghwa3.lee@samsung.com>
> +
> +Description
> +-----------
> +
> +Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
> management unit.
> +Thermal emulation mode supports software debug for TMU's operation.
> User can set temperature
> +manually with software code and TMU will read current temperature from
> user value not from
> +sensor's value.
> +
> +Enabling CONFIG_EXYNOS_THERMAL_EMUL option will make this support
> in available.
> +When it's enabled, sysfs node will be created under
> +/sys/bus/platform/devices/'exynos device name'/ with name of
> 'emulation'.
> +
> +The sysfs node, 'emulation', will contain value 0 for the initial state. When
> you input any
> +temperature you want to update to sysfs node, it automatically enable
> emulation mode and
> +current temperature will be changed into it.
> +(Exynos also supports user changable delay time which would be used to
> delay of
> + changing temperature. However, this node only uses same delay of real
> sensing time, 938us.)
> +
> +Exynos emulation mode requires synchronous of value changing and
> enabling. It means when you
> +want to update the any value of delay or next temperature, then you have
> to enable emulation
> +mode at the same time. (Or you have to keep the mode enabling.) If you
> don't, it fails to
> +change the value to updated one and just use last succeessful value
> repeatedly. That's why
> +this node gives users the right to change termerpature only. Just one
> interface makes it more
> +simply to use.
> +
> +Disabling emulation mode only requires writing value 0 to sysfs node.
> +
> +
> +TEMP	120 |
> +	    |
> +	100 |
> +	    |
> +	 80 |
> +	    |		     	 	 +-----------
> +	 60 |      		     	 |	    |
> +	    |	           +-------------|          |
> +	 40 |              |         	 |          |
> +   	    |		   |	     	 |          |
> +	 20 |		   |	     	 |          +----------
> +	    |	 	   |	     	 |          |          |
> +  	  0
> |______________|_____________|__________|__________|_______
> __
> +		   A	    	 A	    A	   	       A     TIME
> +		   |<----->|	 |<----->|  |<----->|	       |
> +		   | 938us |  	 |	 |  |       |          |
> +emulation    :  0  50	   |  	 70      |  20      |          0
> +current temp :   sensor   50		 70         20	      sensor
> +
> +
> +
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index e1cb6bd..c02a66c 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -55,3 +55,12 @@ config EXYNOS_THERMAL
>  	help
>  	  If you say yes here you get support for TMU (Thermal Managment
>  	  Unit) on SAMSUNG EXYNOS series of SoC.
> +
> +config EXYNOS_THERMAL_EMUL
> +	bool "EXYNOS TMU emulation mode support"
> +	depends on !CPU_EXYNOS4210 && EXYNOS_THERMAL
> +	help
> +	  Exynos 4412 and 4414 and 5 series has emulation mode on TMU.
> +	  Enable this option will be make sysfs node in exynos thermal
> platform
> +	  device directory to support emulation mode. With emulation mode
> sysfs
> +	  node, you can manually input temperature to TMU for simulation
> purpose.
> diff --git a/drivers/thermal/exynos_thermal.c
> b/drivers/thermal/exynos_thermal.c
> index fd03e85..eebd4e5 100644
> --- a/drivers/thermal/exynos_thermal.c
> +++ b/drivers/thermal/exynos_thermal.c
> @@ -99,6 +99,14 @@
>  #define IDLE_INTERVAL 10000
>  #define MCELSIUS	1000
> 
> +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
> +#define EXYNOS_EMUL_TIME	0x57F0
> +#define EXYNOS_EMUL_TIME_SHIFT	16
> +#define EXYNOS_EMUL_DATA_SHIFT	8
> +#define EXYNOS_EMUL_DATA_MASK	0xFF
> +#define EXYNOS_EMUL_ENABLE	0x1
> +#endif /* CONFIG_EXYNOS_THERMAL_EMUL */
> +
>  /* CPU Zone information */
>  #define PANIC_ZONE      4
>  #define WARN_ZONE       3
> @@ -832,6 +840,82 @@ static inline struct  exynos_tmu_platform_data
> *exynos_get_driver_data(
>  	return (struct exynos_tmu_platform_data *)
>  			platform_get_device_id(pdev)->driver_data;
>  }
> +
> +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
> +static ssize_t exynos_tmu_emulation_show(struct device *dev,
> +					 struct device_attribute *attr,
> +					 char *buf)
> +{
> +	struct platform_device *pdev = container_of(dev,
> +					struct platform_device, dev);
> +	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> +	unsigned int reg;
> +	u8 temp_code;
> +	int temp = 0;
> +
> +	mutex_lock(&data->lock);
> +	clk_enable(data->clk);
> +	reg = readl(data->base + EXYNOS_EMUL_CON);
> +	clk_disable(data->clk);
> +	mutex_unlock(&data->lock);
> +
> +	if (reg & EXYNOS_EMUL_ENABLE) {
> +		reg >>= EXYNOS_EMUL_DATA_SHIFT;
> +		temp_code = reg & EXYNOS_EMUL_DATA_MASK;
> +		temp = code_to_temp(data, temp_code);
> +	}
> +
> +	return sprintf(buf, "%d\n", temp);
> +}
> +
> +static ssize_t exynos_tmu_emulation_store(struct device *dev,
> +					struct device_attribute *attr,
> +					const char *buf, size_t count)
> +{
> +	struct platform_device *pdev = container_of(dev,
> +					struct platform_device, dev);
> +	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> +	unsigned int reg;
> +	int temp;
> +
> +	if (!sscanf(buf, "%d\n", &temp) || temp < 0)
> +		return -EINVAL;
> +
> +	mutex_lock(&data->lock);
> +	clk_enable(data->clk);
> +
> +	reg = readl(data->base + EXYNOS_EMUL_CON);
> +
> +	if (temp)
> +		reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT)
> |
> +			(temp_to_code(data, temp) <<
> EXYNOS_EMUL_DATA_SHIFT) |
> +			EXYNOS_EMUL_ENABLE;
> +	else
> +		reg &= ~EXYNOS_EMUL_ENABLE;
> +
> +	writel(reg, data->base + EXYNOS_EMUL_CON);
> +
> +	clk_disable(data->clk);
> +	mutex_unlock(&data->lock);
> +
> +	return count;
> +}
> +
> +static DEVICE_ATTR(emulation, 0644, exynos_tmu_emulation_show,
> +					exynos_tmu_emulation_store);
> +static int create_emulation_sysfs(struct device *dev)
> +{
> +	return device_create_file(dev, &dev_attr_emulation);
> +}
> +static void remove_emulation_sysfs(struct device *dev)
> +{
> +	device_remove_file(dev, &dev_attr_emulation);
> +}
> +#else
> +static inline int create_emulation_sysfs(struct device *dev) {return 0;}
> +static inline void remove_emulation_sysfs(struct device *dev){}
> +#endif
> +
>  static int __devinit exynos_tmu_probe(struct platform_device *pdev)
>  {
>  	struct exynos_tmu_data *data;
> @@ -930,6 +1014,11 @@ static int __devinit exynos_tmu_probe(struct
> platform_device *pdev)
>  		dev_err(&pdev->dev, "Failed to register thermal
> interface\n");
>  		goto err_clk;
>  	}
> +
> +	ret = create_emulation_sysfs(&pdev->dev);
> +	if (ret)
> +		dev_err(&pdev->dev, "Failed to create emulation mode
> sysfs node\n");
> +
>  	return 0;
>  err_clk:
>  	platform_set_drvdata(pdev, NULL);
> @@ -941,6 +1030,8 @@ static int __devexit exynos_tmu_remove(struct
> platform_device *pdev)
>  {
>  	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> 
> +	remove_emulation_sysfs(&pdev->dev);
> +
>  	exynos_tmu_control(pdev, false);
> 
>  	exynos_unregister_thermal();
> --
> 1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Zhang, Rui Nov. 7, 2012, 6:36 a.m. UTC | #2
On Thu, 2012-11-01 at 23:13 -0600, R, Durgadoss wrote:
> Hi Lee,
> 
> > -----Original Message-----
> > From: Jonghwa Lee [mailto:jonghwa3.lee@samsung.com]
> > Sent: Friday, November 02, 2012 7:55 AM
> > To: linux-pm@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org; Brown, Len; R, Durgadoss; Rafael J.
> > Wysocki; Amit Dinel Kachhap; MyungJoo Ham; Kyungmin Park; Jonghwa Lee
> > Subject: [PATCH v4] Thermal: exynos: Add sysfs node supporting exynos's
> > emulation mode.
> > 
> > This patch supports exynos's emulation mode with newly created sysfs node.
> > Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
> > management unit. Thermal emulation mode supports software debug for
> > TMU's
> > operation. User can set temperature manually with software code and TMU
> > will read current temperature from user value not from sensor's value.
> > This patch includes also documentary placed under
> > Documentation/thermal/.
> > 
> 
first of all, what would happen if overheat happens during emulation?

I just had a thought about if we can introduce this to the generic
thermal layer.
to do this, we only need to:
1) introduce tz->emulation
2) introduce thermal_get_temp()
      static int thermal_get_temp(tz) {
          if (tz->emulation)
              return tz->emulation;
          else
              return tz->ops->get_temp(tz);
      }
3) replace tz->ops->get_temp() with thermal_get_temp() in thermal layer
4) introduce /sys/class/thermal/thermal_zoneX/emulation
5) when setting /sys/class/thermal/thermal_zoneX/emulation,
   a) set tz->emulation
   b) invoke thermal_zone_device_update();
this is a pure software emulation solution but it would work on all
generic thermal layer users.

do you think this proposal would work properly?
if yes, I'd like to see if it is valuable for the other platform thermal
drivers.

thanks,
rui
> Thanks for fixing the comments. 
> Please CC linux-acpi, when you submit thermal patches, going forward.
> I am CCing Rui for now, for him to review/merge this patch.
> 
> Reviewed-by: Durgadoss R <durgadoss.r@intel.com>
> 
> Thanks,
> Durga
> 
> > Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
> > ---
> > v4
> >  - Fix Typo.
> >  - Remove unnecessary codes.
> >  - Add comments about feature of exynos emulation operation to the
> > document.
> > 
> > v3
> >  - Remove unnecessay variables.
> >  - Do some code clean in exynos_tmu_emulation_store().
> >  - Make wrapping function of sysfs node creation function to use
> >    #ifdefs in minimum.
> > 
> > v2
> >  exynos_thermal.c
> >  - Fix build error occured by wrong emulation control register name.
> >  - Remove exynos5410 dependent codes.
> >  exynos_thermal_emulation
> >  - Align indentation.
> > 
> >  Documentation/thermal/exynos_thermal_emulation |   56
> > +++++++++++++++
> >  drivers/thermal/Kconfig                        |    9 +++
> >  drivers/thermal/exynos_thermal.c               |   91
> > ++++++++++++++++++++++++
> >  3 files changed, 156 insertions(+), 0 deletions(-)
> >  create mode 100644 Documentation/thermal/exynos_thermal_emulation
> > 
> > diff --git a/Documentation/thermal/exynos_thermal_emulation
> > b/Documentation/thermal/exynos_thermal_emulation
> > new file mode 100644
> > index 0000000..a6ea06f
> > --- /dev/null
> > +++ b/Documentation/thermal/exynos_thermal_emulation
> > @@ -0,0 +1,56 @@
> > +EXYNOS EMULATION MODE
> > +========================
> > +
> > +Copyright (C) 2012 Samsung Electronics
> > +
> > +Written by Jonghwa Lee <jonghwa3.lee@samsung.com>
> > +
> > +Description
> > +-----------
> > +
> > +Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
> > management unit.
> > +Thermal emulation mode supports software debug for TMU's operation.
> > User can set temperature
> > +manually with software code and TMU will read current temperature from
> > user value not from
> > +sensor's value.
> > +
> > +Enabling CONFIG_EXYNOS_THERMAL_EMUL option will make this support
> > in available.
> > +When it's enabled, sysfs node will be created under
> > +/sys/bus/platform/devices/'exynos device name'/ with name of
> > 'emulation'.
> > +
> > +The sysfs node, 'emulation', will contain value 0 for the initial state. When
> > you input any
> > +temperature you want to update to sysfs node, it automatically enable
> > emulation mode and
> > +current temperature will be changed into it.
> > +(Exynos also supports user changable delay time which would be used to
> > delay of
> > + changing temperature. However, this node only uses same delay of real
> > sensing time, 938us.)
> > +
> > +Exynos emulation mode requires synchronous of value changing and
> > enabling. It means when you
> > +want to update the any value of delay or next temperature, then you have
> > to enable emulation
> > +mode at the same time. (Or you have to keep the mode enabling.) If you
> > don't, it fails to
> > +change the value to updated one and just use last succeessful value
> > repeatedly. That's why
> > +this node gives users the right to change termerpature only. Just one
> > interface makes it more
> > +simply to use.
> > +
> > +Disabling emulation mode only requires writing value 0 to sysfs node.
> > +
> > +
> > +TEMP	120 |
> > +	    |
> > +	100 |
> > +	    |
> > +	 80 |
> > +	    |		     	 	 +-----------
> > +	 60 |      		     	 |	    |
> > +	    |	           +-------------|          |
> > +	 40 |              |         	 |          |
> > +   	    |		   |	     	 |          |
> > +	 20 |		   |	     	 |          +----------
> > +	    |	 	   |	     	 |          |          |
> > +  	  0
> > |______________|_____________|__________|__________|_______
> > __
> > +		   A	    	 A	    A	   	       A     TIME
> > +		   |<----->|	 |<----->|  |<----->|	       |
> > +		   | 938us |  	 |	 |  |       |          |
> > +emulation    :  0  50	   |  	 70      |  20      |          0
> > +current temp :   sensor   50		 70         20	      sensor
> > +
> > +
> > +
> > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > index e1cb6bd..c02a66c 100644
> > --- a/drivers/thermal/Kconfig
> > +++ b/drivers/thermal/Kconfig
> > @@ -55,3 +55,12 @@ config EXYNOS_THERMAL
> >  	help
> >  	  If you say yes here you get support for TMU (Thermal Managment
> >  	  Unit) on SAMSUNG EXYNOS series of SoC.
> > +
> > +config EXYNOS_THERMAL_EMUL
> > +	bool "EXYNOS TMU emulation mode support"
> > +	depends on !CPU_EXYNOS4210 && EXYNOS_THERMAL
> > +	help
> > +	  Exynos 4412 and 4414 and 5 series has emulation mode on TMU.
> > +	  Enable this option will be make sysfs node in exynos thermal
> > platform
> > +	  device directory to support emulation mode. With emulation mode
> > sysfs
> > +	  node, you can manually input temperature to TMU for simulation
> > purpose.
> > diff --git a/drivers/thermal/exynos_thermal.c
> > b/drivers/thermal/exynos_thermal.c
> > index fd03e85..eebd4e5 100644
> > --- a/drivers/thermal/exynos_thermal.c
> > +++ b/drivers/thermal/exynos_thermal.c
> > @@ -99,6 +99,14 @@
> >  #define IDLE_INTERVAL 10000
> >  #define MCELSIUS	1000
> > 
> > +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
> > +#define EXYNOS_EMUL_TIME	0x57F0
> > +#define EXYNOS_EMUL_TIME_SHIFT	16
> > +#define EXYNOS_EMUL_DATA_SHIFT	8
> > +#define EXYNOS_EMUL_DATA_MASK	0xFF
> > +#define EXYNOS_EMUL_ENABLE	0x1
> > +#endif /* CONFIG_EXYNOS_THERMAL_EMUL */
> > +
> >  /* CPU Zone information */
> >  #define PANIC_ZONE      4
> >  #define WARN_ZONE       3
> > @@ -832,6 +840,82 @@ static inline struct  exynos_tmu_platform_data
> > *exynos_get_driver_data(
> >  	return (struct exynos_tmu_platform_data *)
> >  			platform_get_device_id(pdev)->driver_data;
> >  }
> > +
> > +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
> > +static ssize_t exynos_tmu_emulation_show(struct device *dev,
> > +					 struct device_attribute *attr,
> > +					 char *buf)
> > +{
> > +	struct platform_device *pdev = container_of(dev,
> > +					struct platform_device, dev);
> > +	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> > +	unsigned int reg;
> > +	u8 temp_code;
> > +	int temp = 0;
> > +
> > +	mutex_lock(&data->lock);
> > +	clk_enable(data->clk);
> > +	reg = readl(data->base + EXYNOS_EMUL_CON);
> > +	clk_disable(data->clk);
> > +	mutex_unlock(&data->lock);
> > +
> > +	if (reg & EXYNOS_EMUL_ENABLE) {
> > +		reg >>= EXYNOS_EMUL_DATA_SHIFT;
> > +		temp_code = reg & EXYNOS_EMUL_DATA_MASK;
> > +		temp = code_to_temp(data, temp_code);
> > +	}
> > +
> > +	return sprintf(buf, "%d\n", temp);
> > +}
> > +
> > +static ssize_t exynos_tmu_emulation_store(struct device *dev,
> > +					struct device_attribute *attr,
> > +					const char *buf, size_t count)
> > +{
> > +	struct platform_device *pdev = container_of(dev,
> > +					struct platform_device, dev);
> > +	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> > +	unsigned int reg;
> > +	int temp;
> > +
> > +	if (!sscanf(buf, "%d\n", &temp) || temp < 0)
> > +		return -EINVAL;
> > +
> > +	mutex_lock(&data->lock);
> > +	clk_enable(data->clk);
> > +
> > +	reg = readl(data->base + EXYNOS_EMUL_CON);
> > +
> > +	if (temp)
> > +		reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT)
> > |
> > +			(temp_to_code(data, temp) <<
> > EXYNOS_EMUL_DATA_SHIFT) |
> > +			EXYNOS_EMUL_ENABLE;
> > +	else
> > +		reg &= ~EXYNOS_EMUL_ENABLE;
> > +
> > +	writel(reg, data->base + EXYNOS_EMUL_CON);
> > +
> > +	clk_disable(data->clk);
> > +	mutex_unlock(&data->lock);
> > +
> > +	return count;
> > +}
> > +
> > +static DEVICE_ATTR(emulation, 0644, exynos_tmu_emulation_show,
> > +					exynos_tmu_emulation_store);
> > +static int create_emulation_sysfs(struct device *dev)
> > +{
> > +	return device_create_file(dev, &dev_attr_emulation);
> > +}
> > +static void remove_emulation_sysfs(struct device *dev)
> > +{
> > +	device_remove_file(dev, &dev_attr_emulation);
> > +}
> > +#else
> > +static inline int create_emulation_sysfs(struct device *dev) {return 0;}
> > +static inline void remove_emulation_sysfs(struct device *dev){}
> > +#endif
> > +
> >  static int __devinit exynos_tmu_probe(struct platform_device *pdev)
> >  {
> >  	struct exynos_tmu_data *data;
> > @@ -930,6 +1014,11 @@ static int __devinit exynos_tmu_probe(struct
> > platform_device *pdev)
> >  		dev_err(&pdev->dev, "Failed to register thermal
> > interface\n");
> >  		goto err_clk;
> >  	}
> > +
> > +	ret = create_emulation_sysfs(&pdev->dev);
> > +	if (ret)
> > +		dev_err(&pdev->dev, "Failed to create emulation mode
> > sysfs node\n");
> > +
> >  	return 0;
> >  err_clk:
> >  	platform_set_drvdata(pdev, NULL);
> > @@ -941,6 +1030,8 @@ static int __devexit exynos_tmu_remove(struct
> > platform_device *pdev)
> >  {
> >  	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> > 
> > +	remove_emulation_sysfs(&pdev->dev);
> > +
> >  	exynos_tmu_control(pdev, false);
> > 
> >  	exynos_unregister_thermal();
> > --
> > 1.7.4.1
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
durgadoss.r@intel.com Nov. 7, 2012, 7:06 a.m. UTC | #3
SGkgUnVpLA0KDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogWmhhbmcs
IFJ1aQ0KPiBTZW50OiBXZWRuZXNkYXksIE5vdmVtYmVyIDA3LCAyMDEyIDEyOjA3IFBNDQo+IFRv
OiBSLCBEdXJnYWRvc3MNCj4gQ2M6IEpvbmdod2EgTGVlOyBsaW51eC1wbUB2Z2VyLmtlcm5lbC5v
cmc7IGxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5lbC5vcmc7DQo+IEJyb3duLCBMZW47IFJhZmFlbCBK
LiBXeXNvY2tpOyBBbWl0IERpbmVsIEthY2hoYXA7IE15dW5nSm9vIEhhbTsNCj4gS3l1bmdtaW4g
UGFyaw0KPiBTdWJqZWN0OiBSRTogW1BBVENIIHY0XSBUaGVybWFsOiBleHlub3M6IEFkZCBzeXNm
cyBub2RlIHN1cHBvcnRpbmcNCj4gZXh5bm9zJ3MgZW11bGF0aW9uIG1vZGUuDQo+IA0KPiBPbiBU
aHUsIDIwMTItMTEtMDEgYXQgMjM6MTMgLTA2MDAsIFIsIER1cmdhZG9zcyB3cm90ZToNCj4gPiBI
aSBMZWUsDQo+ID4NCj4gPiA+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+ID4gPiBGcm9t
OiBKb25naHdhIExlZSBbbWFpbHRvOmpvbmdod2EzLmxlZUBzYW1zdW5nLmNvbV0NCj4gPiA+IFNl
bnQ6IEZyaWRheSwgTm92ZW1iZXIgMDIsIDIwMTIgNzo1NSBBTQ0KPiA+ID4gVG86IGxpbnV4LXBt
QHZnZXIua2VybmVsLm9yZw0KPiA+ID4gQ2M6IGxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5lbC5vcmc7
IEJyb3duLCBMZW47IFIsIER1cmdhZG9zczsgUmFmYWVsIEouDQo+ID4gPiBXeXNvY2tpOyBBbWl0
IERpbmVsIEthY2hoYXA7IE15dW5nSm9vIEhhbTsgS3l1bmdtaW4gUGFyazsgSm9uZ2h3YQ0KPiBM
ZWUNCj4gPiA+IFN1YmplY3Q6IFtQQVRDSCB2NF0gVGhlcm1hbDogZXh5bm9zOiBBZGQgc3lzZnMg
bm9kZSBzdXBwb3J0aW5nDQo+IGV4eW5vcydzDQo+ID4gPiBlbXVsYXRpb24gbW9kZS4NCj4gPiA+
DQo+ID4gPiBUaGlzIHBhdGNoIHN1cHBvcnRzIGV4eW5vcydzIGVtdWxhdGlvbiBtb2RlIHdpdGgg
bmV3bHkgY3JlYXRlZCBzeXNmcw0KPiBub2RlLg0KPiA+ID4gRXh5bm9zIDR4MTIgKDQyMTIsIDQ0
MTIpIGFuZCA1IHNlcmllcyBwcm92aWRlIGVtdWxhdGlvbiBtb2RlIGZvcg0KPiB0aGVybWFsDQo+
ID4gPiBtYW5hZ2VtZW50IHVuaXQuIFRoZXJtYWwgZW11bGF0aW9uIG1vZGUgc3VwcG9ydHMgc29m
dHdhcmUgZGVidWcgZm9yDQo+ID4gPiBUTVUncw0KPiA+ID4gb3BlcmF0aW9uLiBVc2VyIGNhbiBz
ZXQgdGVtcGVyYXR1cmUgbWFudWFsbHkgd2l0aCBzb2Z0d2FyZSBjb2RlIGFuZA0KPiBUTVUNCj4g
PiA+IHdpbGwgcmVhZCBjdXJyZW50IHRlbXBlcmF0dXJlIGZyb20gdXNlciB2YWx1ZSBub3QgZnJv
bSBzZW5zb3IncyB2YWx1ZS4NCj4gPiA+IFRoaXMgcGF0Y2ggaW5jbHVkZXMgYWxzbyBkb2N1bWVu
dGFyeSBwbGFjZWQgdW5kZXINCj4gPiA+IERvY3VtZW50YXRpb24vdGhlcm1hbC8uDQo+ID4gPg0K
PiA+DQo+IGZpcnN0IG9mIGFsbCwgd2hhdCB3b3VsZCBoYXBwZW4gaWYgb3ZlcmhlYXQgaGFwcGVu
cyBkdXJpbmcgZW11bGF0aW9uPw0KPiANCj4gSSBqdXN0IGhhZCBhIHRob3VnaHQgYWJvdXQgaWYg
d2UgY2FuIGludHJvZHVjZSB0aGlzIHRvIHRoZSBnZW5lcmljDQo+IHRoZXJtYWwgbGF5ZXIuDQoN
ClN1cmUsIHdlIGNhbi4NCg0KPiB0byBkbyB0aGlzLCB3ZSBvbmx5IG5lZWQgdG86DQo+IDEpIGlu
dHJvZHVjZSB0ei0+ZW11bGF0aW9uDQo+IDIpIGludHJvZHVjZSB0aGVybWFsX2dldF90ZW1wKCkN
Cj4gICAgICAgc3RhdGljIGludCB0aGVybWFsX2dldF90ZW1wKHR6KSB7DQo+ICAgICAgICAgICBp
ZiAodHotPmVtdWxhdGlvbikNCj4gICAgICAgICAgICAgICByZXR1cm4gdHotPmVtdWxhdGlvbjsN
Cj4gICAgICAgICAgIGVsc2UNCj4gICAgICAgICAgICAgICByZXR1cm4gdHotPm9wcy0+Z2V0X3Rl
bXAodHopOw0KPiAgICAgICB9DQo+IDMpIHJlcGxhY2UgdHotPm9wcy0+Z2V0X3RlbXAoKSB3aXRo
IHRoZXJtYWxfZ2V0X3RlbXAoKSBpbiB0aGVybWFsIGxheWVyDQo+IDQpIGludHJvZHVjZSAvc3lz
L2NsYXNzL3RoZXJtYWwvdGhlcm1hbF96b25lWC9lbXVsYXRpb24NCj4gNSkgd2hlbiBzZXR0aW5n
IC9zeXMvY2xhc3MvdGhlcm1hbC90aGVybWFsX3pvbmVYL2VtdWxhdGlvbiwNCj4gICAgYSkgc2V0
IHR6LT5lbXVsYXRpb24NCj4gICAgYikgaW52b2tlIHRoZXJtYWxfem9uZV9kZXZpY2VfdXBkYXRl
KCk7DQo+IHRoaXMgaXMgYSBwdXJlIHNvZnR3YXJlIGVtdWxhdGlvbiBzb2x1dGlvbiBidXQgaXQg
d291bGQgd29yayBvbiBhbGwNCj4gZ2VuZXJpYyB0aGVybWFsIGxheWVyIHVzZXJzLg0KPiANCj4g
ZG8geW91IHRoaW5rIHRoaXMgcHJvcG9zYWwgd291bGQgd29yayBwcm9wZXJseT8NCg0KWWVzLCB0
aGlzIHNob3VsZCB3b3JrLi4NCkJ1dCwgSSBhbSB3b3JraW5nIG9uICh0b3Agb2YgeW91ciAtbmV4
dCB0cmVlKSB0byBhZGQgbXVsdGlwbGUgc2Vuc29yIHN1cHBvcnQgdG8NCnRoZXJtYWwgZnJhbWV3
b3JrLihXaGF0IHdlIGRpc2N1c3NlZCBpbiBQbHVtYmVycyB0aGlzIHllYXIpLg0KVGhpcyBjaGFu
Z2VzIEFQSXMgcXVpdGUgYSBiaXQgaW4gdGhlIHRoZXJtYWwgZnJhbWV3b3JrLg0KU28sIHdlIHdp
bGwgYWRkIHRoaXMgZW11bGF0aW9uIHN1cHBvcnQgYWZ0ZXIgdGhlIGFib3ZlIGNoYW5nZXMgYXJl
DQppbi4gV2hhdCBkbyB5b3UgdGhpbmsgPw0KDQpUaGFua3MsDQpEdXJnYQ0KDQo+IGlmIHllcywg
SSdkIGxpa2UgdG8gc2VlIGlmIGl0IGlzIHZhbHVhYmxlIGZvciB0aGUgb3RoZXIgcGxhdGZvcm0g
dGhlcm1hbA0KPiBkcml2ZXJzLg0KPiANCj4gdGhhbmtzLA0KPiBydWkNCj4gPiBUaGFua3MgZm9y
IGZpeGluZyB0aGUgY29tbWVudHMuDQo+ID4gUGxlYXNlIENDIGxpbnV4LWFjcGksIHdoZW4geW91
IHN1Ym1pdCB0aGVybWFsIHBhdGNoZXMsIGdvaW5nIGZvcndhcmQuDQo+ID4gSSBhbSBDQ2luZyBS
dWkgZm9yIG5vdywgZm9yIGhpbSB0byByZXZpZXcvbWVyZ2UgdGhpcyBwYXRjaC4NCj4gPg0KPiA+
IFJldmlld2VkLWJ5OiBEdXJnYWRvc3MgUiA8ZHVyZ2Fkb3NzLnJAaW50ZWwuY29tPg0KPiA+DQo+
ID4gVGhhbmtzLA0KPiA+IER1cmdhDQo+ID4NCj4gPiA+IFNpZ25lZC1vZmYtYnk6IEpvbmdod2Eg
TGVlIDxqb25naHdhMy5sZWVAc2Ftc3VuZy5jb20+DQo+ID4gPiAtLS0NCj4gPiA+IHY0DQo+ID4g
PiAgLSBGaXggVHlwby4NCj4gPiA+ICAtIFJlbW92ZSB1bm5lY2Vzc2FyeSBjb2Rlcy4NCj4gPiA+
ICAtIEFkZCBjb21tZW50cyBhYm91dCBmZWF0dXJlIG9mIGV4eW5vcyBlbXVsYXRpb24gb3BlcmF0
aW9uIHRvIHRoZQ0KPiA+ID4gZG9jdW1lbnQuDQo+ID4gPg0KPiA+ID4gdjMNCj4gPiA+ICAtIFJl
bW92ZSB1bm5lY2Vzc2F5IHZhcmlhYmxlcy4NCj4gPiA+ICAtIERvIHNvbWUgY29kZSBjbGVhbiBp
biBleHlub3NfdG11X2VtdWxhdGlvbl9zdG9yZSgpLg0KPiA+ID4gIC0gTWFrZSB3cmFwcGluZyBm
dW5jdGlvbiBvZiBzeXNmcyBub2RlIGNyZWF0aW9uIGZ1bmN0aW9uIHRvIHVzZQ0KPiA+ID4gICAg
I2lmZGVmcyBpbiBtaW5pbXVtLg0KPiA+ID4NCj4gPiA+IHYyDQo+ID4gPiAgZXh5bm9zX3RoZXJt
YWwuYw0KPiA+ID4gIC0gRml4IGJ1aWxkIGVycm9yIG9jY3VyZWQgYnkgd3JvbmcgZW11bGF0aW9u
IGNvbnRyb2wgcmVnaXN0ZXIgbmFtZS4NCj4gPiA+ICAtIFJlbW92ZSBleHlub3M1NDEwIGRlcGVu
ZGVudCBjb2Rlcy4NCj4gPiA+ICBleHlub3NfdGhlcm1hbF9lbXVsYXRpb24NCj4gPiA+ICAtIEFs
aWduIGluZGVudGF0aW9uLg0KPiA+ID4NCj4gPiA+ICBEb2N1bWVudGF0aW9uL3RoZXJtYWwvZXh5
bm9zX3RoZXJtYWxfZW11bGF0aW9uIHwgICA1Ng0KPiA+ID4gKysrKysrKysrKysrKysrDQo+ID4g
PiAgZHJpdmVycy90aGVybWFsL0tjb25maWcgICAgICAgICAgICAgICAgICAgICAgICB8ICAgIDkg
KysrDQo+ID4gPiAgZHJpdmVycy90aGVybWFsL2V4eW5vc190aGVybWFsLmMgICAgICAgICAgICAg
ICB8ICAgOTENCj4gPiA+ICsrKysrKysrKysrKysrKysrKysrKysrKw0KPiA+ID4gIDMgZmlsZXMg
Y2hhbmdlZCwgMTU2IGluc2VydGlvbnMoKyksIDAgZGVsZXRpb25zKC0pDQo+ID4gPiAgY3JlYXRl
IG1vZGUgMTAwNjQ0DQo+IERvY3VtZW50YXRpb24vdGhlcm1hbC9leHlub3NfdGhlcm1hbF9lbXVs
YXRpb24NCj4gPiA+DQo+ID4gPiBkaWZmIC0tZ2l0IGEvRG9jdW1lbnRhdGlvbi90aGVybWFsL2V4
eW5vc190aGVybWFsX2VtdWxhdGlvbg0KPiA+ID4gYi9Eb2N1bWVudGF0aW9uL3RoZXJtYWwvZXh5
bm9zX3RoZXJtYWxfZW11bGF0aW9uDQo+ID4gPiBuZXcgZmlsZSBtb2RlIDEwMDY0NA0KPiA+ID4g
aW5kZXggMDAwMDAwMC4uYTZlYTA2Zg0KPiA+ID4gLS0tIC9kZXYvbnVsbA0KPiA+ID4gKysrIGIv
RG9jdW1lbnRhdGlvbi90aGVybWFsL2V4eW5vc190aGVybWFsX2VtdWxhdGlvbg0KPiA+ID4gQEAg
LTAsMCArMSw1NiBAQA0KPiA+ID4gK0VYWU5PUyBFTVVMQVRJT04gTU9ERQ0KPiA+ID4gKz09PT09
PT09PT09PT09PT09PT09PT09PQ0KPiA+ID4gKw0KPiA+ID4gK0NvcHlyaWdodCAoQykgMjAxMiBT
YW1zdW5nIEVsZWN0cm9uaWNzDQo+ID4gPiArDQo+ID4gPiArV3JpdHRlbiBieSBKb25naHdhIExl
ZSA8am9uZ2h3YTMubGVlQHNhbXN1bmcuY29tPg0KPiA+ID4gKw0KPiA+ID4gK0Rlc2NyaXB0aW9u
DQo+ID4gPiArLS0tLS0tLS0tLS0NCj4gPiA+ICsNCj4gPiA+ICtFeHlub3MgNHgxMiAoNDIxMiwg
NDQxMikgYW5kIDUgc2VyaWVzIHByb3ZpZGUgZW11bGF0aW9uIG1vZGUgZm9yDQo+IHRoZXJtYWwN
Cj4gPiA+IG1hbmFnZW1lbnQgdW5pdC4NCj4gPiA+ICtUaGVybWFsIGVtdWxhdGlvbiBtb2RlIHN1
cHBvcnRzIHNvZnR3YXJlIGRlYnVnIGZvciBUTVUncw0KPiBvcGVyYXRpb24uDQo+ID4gPiBVc2Vy
IGNhbiBzZXQgdGVtcGVyYXR1cmUNCj4gPiA+ICttYW51YWxseSB3aXRoIHNvZnR3YXJlIGNvZGUg
YW5kIFRNVSB3aWxsIHJlYWQgY3VycmVudCB0ZW1wZXJhdHVyZQ0KPiBmcm9tDQo+ID4gPiB1c2Vy
IHZhbHVlIG5vdCBmcm9tDQo+ID4gPiArc2Vuc29yJ3MgdmFsdWUuDQo+ID4gPiArDQo+ID4gPiAr
RW5hYmxpbmcgQ09ORklHX0VYWU5PU19USEVSTUFMX0VNVUwgb3B0aW9uIHdpbGwgbWFrZSB0aGlz
DQo+IHN1cHBvcnQNCj4gPiA+IGluIGF2YWlsYWJsZS4NCj4gPiA+ICtXaGVuIGl0J3MgZW5hYmxl
ZCwgc3lzZnMgbm9kZSB3aWxsIGJlIGNyZWF0ZWQgdW5kZXINCj4gPiA+ICsvc3lzL2J1cy9wbGF0
Zm9ybS9kZXZpY2VzLydleHlub3MgZGV2aWNlIG5hbWUnLyB3aXRoIG5hbWUgb2YNCj4gPiA+ICdl
bXVsYXRpb24nLg0KPiA+ID4gKw0KPiA+ID4gK1RoZSBzeXNmcyBub2RlLCAnZW11bGF0aW9uJywg
d2lsbCBjb250YWluIHZhbHVlIDAgZm9yIHRoZSBpbml0aWFsIHN0YXRlLg0KPiBXaGVuDQo+ID4g
PiB5b3UgaW5wdXQgYW55DQo+ID4gPiArdGVtcGVyYXR1cmUgeW91IHdhbnQgdG8gdXBkYXRlIHRv
IHN5c2ZzIG5vZGUsIGl0IGF1dG9tYXRpY2FsbHkgZW5hYmxlDQo+ID4gPiBlbXVsYXRpb24gbW9k
ZSBhbmQNCj4gPiA+ICtjdXJyZW50IHRlbXBlcmF0dXJlIHdpbGwgYmUgY2hhbmdlZCBpbnRvIGl0
Lg0KPiA+ID4gKyhFeHlub3MgYWxzbyBzdXBwb3J0cyB1c2VyIGNoYW5nYWJsZSBkZWxheSB0aW1l
IHdoaWNoIHdvdWxkIGJlIHVzZWQNCj4gdG8NCj4gPiA+IGRlbGF5IG9mDQo+ID4gPiArIGNoYW5n
aW5nIHRlbXBlcmF0dXJlLiBIb3dldmVyLCB0aGlzIG5vZGUgb25seSB1c2VzIHNhbWUgZGVsYXkg
b2YgcmVhbA0KPiA+ID4gc2Vuc2luZyB0aW1lLCA5Mzh1cy4pDQo+ID4gPiArDQo+ID4gPiArRXh5
bm9zIGVtdWxhdGlvbiBtb2RlIHJlcXVpcmVzIHN5bmNocm9ub3VzIG9mIHZhbHVlIGNoYW5naW5n
IGFuZA0KPiA+ID4gZW5hYmxpbmcuIEl0IG1lYW5zIHdoZW4geW91DQo+ID4gPiArd2FudCB0byB1
cGRhdGUgdGhlIGFueSB2YWx1ZSBvZiBkZWxheSBvciBuZXh0IHRlbXBlcmF0dXJlLCB0aGVuIHlv
dQ0KPiBoYXZlDQo+ID4gPiB0byBlbmFibGUgZW11bGF0aW9uDQo+ID4gPiArbW9kZSBhdCB0aGUg
c2FtZSB0aW1lLiAoT3IgeW91IGhhdmUgdG8ga2VlcCB0aGUgbW9kZSBlbmFibGluZy4pIElmDQo+
IHlvdQ0KPiA+ID4gZG9uJ3QsIGl0IGZhaWxzIHRvDQo+ID4gPiArY2hhbmdlIHRoZSB2YWx1ZSB0
byB1cGRhdGVkIG9uZSBhbmQganVzdCB1c2UgbGFzdCBzdWNjZWVzc2Z1bCB2YWx1ZQ0KPiA+ID4g
cmVwZWF0ZWRseS4gVGhhdCdzIHdoeQ0KPiA+ID4gK3RoaXMgbm9kZSBnaXZlcyB1c2VycyB0aGUg
cmlnaHQgdG8gY2hhbmdlIHRlcm1lcnBhdHVyZSBvbmx5LiBKdXN0IG9uZQ0KPiA+ID4gaW50ZXJm
YWNlIG1ha2VzIGl0IG1vcmUNCj4gPiA+ICtzaW1wbHkgdG8gdXNlLg0KPiA+ID4gKw0KPiA+ID4g
K0Rpc2FibGluZyBlbXVsYXRpb24gbW9kZSBvbmx5IHJlcXVpcmVzIHdyaXRpbmcgdmFsdWUgMCB0
byBzeXNmcyBub2RlLg0KPiA+ID4gKw0KPiA+ID4gKw0KPiA+ID4gK1RFTVAJMTIwIHwNCj4gPiA+
ICsJICAgIHwNCj4gPiA+ICsJMTAwIHwNCj4gPiA+ICsJICAgIHwNCj4gPiA+ICsJIDgwIHwNCj4g
PiA+ICsJICAgIHwJCSAgICAgCSAJICstLS0tLS0tLS0tLQ0KPiA+ID4gKwkgNjAgfCAgICAgIAkJ
ICAgICAJIHwJICAgIHwNCj4gPiA+ICsJICAgIHwJICAgICAgICAgICArLS0tLS0tLS0tLS0tLXwg
ICAgICAgICAgfA0KPiA+ID4gKwkgNDAgfCAgICAgICAgICAgICAgfCAgICAgICAgIAkgfCAgICAg
ICAgICB8DQo+ID4gPiArICAgCSAgICB8CQkgICB8CSAgICAgCSB8ICAgICAgICAgIHwNCj4gPiA+
ICsJIDIwIHwJCSAgIHwJICAgICAJIHwgICAgICAgICAgKy0tLS0tLS0tLS0NCj4gPiA+ICsJICAg
IHwJIAkgICB8CSAgICAgCSB8ICAgICAgICAgIHwgICAgICAgICAgfA0KPiA+ID4gKyAgCSAgMA0K
PiA+ID4NCj4gfF9fX19fX19fX19fX19ffF9fX19fX19fX19fX198X19fX19fX19fX3xfX19fX19f
X19ffF9fX19fX18NCj4gPiA+IF9fDQo+ID4gPiArCQkgICBBCSAgICAJIEEJICAgIEEJICAgCSAg
ICAgICBBICAgICBUSU1FDQo+ID4gPiArCQkgICB8PC0tLS0tPnwJIHw8LS0tLS0+fCAgfDwtLS0t
LT58CSAgICAgICB8DQo+ID4gPiArCQkgICB8IDkzOHVzIHwgIAkgfAkgfCAgfCAgICAgICB8ICAg
ICAgICAgIHwNCj4gPiA+ICtlbXVsYXRpb24gICAgOiAgMCAgNTAJICAgfCAgCSA3MCAgICAgIHwg
IDIwICAgICAgfCAgICAgICAgICAwDQo+ID4gPiArY3VycmVudCB0ZW1wIDogICBzZW5zb3IgICA1
MAkJIDcwICAgICAgICAgMjAJICAgICAgc2Vuc29yDQo+ID4gPiArDQo+ID4gPiArDQo+ID4gPiAr
DQo+ID4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy90aGVybWFsL0tjb25maWcgYi9kcml2ZXJzL3Ro
ZXJtYWwvS2NvbmZpZw0KPiA+ID4gaW5kZXggZTFjYjZiZC4uYzAyYTY2YyAxMDA2NDQNCj4gPiA+
IC0tLSBhL2RyaXZlcnMvdGhlcm1hbC9LY29uZmlnDQo+ID4gPiArKysgYi9kcml2ZXJzL3RoZXJt
YWwvS2NvbmZpZw0KPiA+ID4gQEAgLTU1LDMgKzU1LDEyIEBAIGNvbmZpZyBFWFlOT1NfVEhFUk1B
TA0KPiA+ID4gIAloZWxwDQo+ID4gPiAgCSAgSWYgeW91IHNheSB5ZXMgaGVyZSB5b3UgZ2V0IHN1
cHBvcnQgZm9yIFRNVSAoVGhlcm1hbCBNYW5hZ21lbnQNCj4gPiA+ICAJICBVbml0KSBvbiBTQU1T
VU5HIEVYWU5PUyBzZXJpZXMgb2YgU29DLg0KPiA+ID4gKw0KPiA+ID4gK2NvbmZpZyBFWFlOT1Nf
VEhFUk1BTF9FTVVMDQo+ID4gPiArCWJvb2wgIkVYWU5PUyBUTVUgZW11bGF0aW9uIG1vZGUgc3Vw
cG9ydCINCj4gPiA+ICsJZGVwZW5kcyBvbiAhQ1BVX0VYWU5PUzQyMTAgJiYgRVhZTk9TX1RIRVJN
QUwNCj4gPiA+ICsJaGVscA0KPiA+ID4gKwkgIEV4eW5vcyA0NDEyIGFuZCA0NDE0IGFuZCA1IHNl
cmllcyBoYXMgZW11bGF0aW9uIG1vZGUgb24gVE1VLg0KPiA+ID4gKwkgIEVuYWJsZSB0aGlzIG9w
dGlvbiB3aWxsIGJlIG1ha2Ugc3lzZnMgbm9kZSBpbiBleHlub3MgdGhlcm1hbA0KPiA+ID4gcGxh
dGZvcm0NCj4gPiA+ICsJICBkZXZpY2UgZGlyZWN0b3J5IHRvIHN1cHBvcnQgZW11bGF0aW9uIG1v
ZGUuIFdpdGggZW11bGF0aW9uIG1vZGUNCj4gPiA+IHN5c2ZzDQo+ID4gPiArCSAgbm9kZSwgeW91
IGNhbiBtYW51YWxseSBpbnB1dCB0ZW1wZXJhdHVyZSB0byBUTVUgZm9yIHNpbXVsYXRpb24NCj4g
PiA+IHB1cnBvc2UuDQo+ID4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy90aGVybWFsL2V4eW5vc190
aGVybWFsLmMNCj4gPiA+IGIvZHJpdmVycy90aGVybWFsL2V4eW5vc190aGVybWFsLmMNCj4gPiA+
IGluZGV4IGZkMDNlODUuLmVlYmQ0ZTUgMTAwNjQ0DQo+ID4gPiAtLS0gYS9kcml2ZXJzL3RoZXJt
YWwvZXh5bm9zX3RoZXJtYWwuYw0KPiA+ID4gKysrIGIvZHJpdmVycy90aGVybWFsL2V4eW5vc190
aGVybWFsLmMNCj4gPiA+IEBAIC05OSw2ICs5OSwxNCBAQA0KPiA+ID4gICNkZWZpbmUgSURMRV9J
TlRFUlZBTCAxMDAwMA0KPiA+ID4gICNkZWZpbmUgTUNFTFNJVVMJMTAwMA0KPiA+ID4NCj4gPiA+
ICsjaWZkZWYgQ09ORklHX0VYWU5PU19USEVSTUFMX0VNVUwNCj4gPiA+ICsjZGVmaW5lIEVYWU5P
U19FTVVMX1RJTUUJMHg1N0YwDQo+ID4gPiArI2RlZmluZSBFWFlOT1NfRU1VTF9USU1FX1NISUZU
CTE2DQo+ID4gPiArI2RlZmluZSBFWFlOT1NfRU1VTF9EQVRBX1NISUZUCTgNCj4gPiA+ICsjZGVm
aW5lIEVYWU5PU19FTVVMX0RBVEFfTUFTSwkweEZGDQo+ID4gPiArI2RlZmluZSBFWFlOT1NfRU1V
TF9FTkFCTEUJMHgxDQo+ID4gPiArI2VuZGlmIC8qIENPTkZJR19FWFlOT1NfVEhFUk1BTF9FTVVM
ICovDQo+ID4gPiArDQo+ID4gPiAgLyogQ1BVIFpvbmUgaW5mb3JtYXRpb24gKi8NCj4gPiA+ICAj
ZGVmaW5lIFBBTklDX1pPTkUgICAgICA0DQo+ID4gPiAgI2RlZmluZSBXQVJOX1pPTkUgICAgICAg
Mw0KPiA+ID4gQEAgLTgzMiw2ICs4NDAsODIgQEAgc3RhdGljIGlubGluZSBzdHJ1Y3QgIGV4eW5v
c190bXVfcGxhdGZvcm1fZGF0YQ0KPiA+ID4gKmV4eW5vc19nZXRfZHJpdmVyX2RhdGEoDQo+ID4g
PiAgCXJldHVybiAoc3RydWN0IGV4eW5vc190bXVfcGxhdGZvcm1fZGF0YSAqKQ0KPiA+ID4gIAkJ
CXBsYXRmb3JtX2dldF9kZXZpY2VfaWQocGRldiktPmRyaXZlcl9kYXRhOw0KPiA+ID4gIH0NCj4g
PiA+ICsNCj4gPiA+ICsjaWZkZWYgQ09ORklHX0VYWU5PU19USEVSTUFMX0VNVUwNCj4gPiA+ICtz
dGF0aWMgc3NpemVfdCBleHlub3NfdG11X2VtdWxhdGlvbl9zaG93KHN0cnVjdCBkZXZpY2UgKmRl
diwNCj4gPiA+ICsJCQkJCSBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwNCj4gPiA+ICsJ
CQkJCSBjaGFyICpidWYpDQo+ID4gPiArew0KPiA+ID4gKwlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNl
ICpwZGV2ID0gY29udGFpbmVyX29mKGRldiwNCj4gPiA+ICsJCQkJCXN0cnVjdCBwbGF0Zm9ybV9k
ZXZpY2UsIGRldik7DQo+ID4gPiArCXN0cnVjdCBleHlub3NfdG11X2RhdGEgKmRhdGEgPSBwbGF0
Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsNCj4gPiA+ICsJdW5zaWduZWQgaW50IHJlZzsNCj4gPiA+
ICsJdTggdGVtcF9jb2RlOw0KPiA+ID4gKwlpbnQgdGVtcCA9IDA7DQo+ID4gPiArDQo+ID4gPiAr
CW11dGV4X2xvY2soJmRhdGEtPmxvY2spOw0KPiA+ID4gKwljbGtfZW5hYmxlKGRhdGEtPmNsayk7
DQo+ID4gPiArCXJlZyA9IHJlYWRsKGRhdGEtPmJhc2UgKyBFWFlOT1NfRU1VTF9DT04pOw0KPiA+
ID4gKwljbGtfZGlzYWJsZShkYXRhLT5jbGspOw0KPiA+ID4gKwltdXRleF91bmxvY2soJmRhdGEt
PmxvY2spOw0KPiA+ID4gKw0KPiA+ID4gKwlpZiAocmVnICYgRVhZTk9TX0VNVUxfRU5BQkxFKSB7
DQo+ID4gPiArCQlyZWcgPj49IEVYWU5PU19FTVVMX0RBVEFfU0hJRlQ7DQo+ID4gPiArCQl0ZW1w
X2NvZGUgPSByZWcgJiBFWFlOT1NfRU1VTF9EQVRBX01BU0s7DQo+ID4gPiArCQl0ZW1wID0gY29k
ZV90b190ZW1wKGRhdGEsIHRlbXBfY29kZSk7DQo+ID4gPiArCX0NCj4gPiA+ICsNCj4gPiA+ICsJ
cmV0dXJuIHNwcmludGYoYnVmLCAiJWRcbiIsIHRlbXApOw0KPiA+ID4gK30NCj4gPiA+ICsNCj4g
PiA+ICtzdGF0aWMgc3NpemVfdCBleHlub3NfdG11X2VtdWxhdGlvbl9zdG9yZShzdHJ1Y3QgZGV2
aWNlICpkZXYsDQo+ID4gPiArCQkJCQlzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwNCj4g
PiA+ICsJCQkJCWNvbnN0IGNoYXIgKmJ1Ziwgc2l6ZV90IGNvdW50KQ0KPiA+ID4gK3sNCj4gPiA+
ICsJc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiA9IGNvbnRhaW5lcl9vZihkZXYsDQo+ID4g
PiArCQkJCQlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlLCBkZXYpOw0KPiA+ID4gKwlzdHJ1Y3QgZXh5
bm9zX3RtdV9kYXRhICpkYXRhID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7DQo+ID4gPiAr
CXVuc2lnbmVkIGludCByZWc7DQo+ID4gPiArCWludCB0ZW1wOw0KPiA+ID4gKw0KPiA+ID4gKwlp
ZiAoIXNzY2FuZihidWYsICIlZFxuIiwgJnRlbXApIHx8IHRlbXAgPCAwKQ0KPiA+ID4gKwkJcmV0
dXJuIC1FSU5WQUw7DQo+ID4gPiArDQo+ID4gPiArCW11dGV4X2xvY2soJmRhdGEtPmxvY2spOw0K
PiA+ID4gKwljbGtfZW5hYmxlKGRhdGEtPmNsayk7DQo+ID4gPiArDQo+ID4gPiArCXJlZyA9IHJl
YWRsKGRhdGEtPmJhc2UgKyBFWFlOT1NfRU1VTF9DT04pOw0KPiA+ID4gKw0KPiA+ID4gKwlpZiAo
dGVtcCkNCj4gPiA+ICsJCXJlZyA9IChFWFlOT1NfRU1VTF9USU1FIDw8IEVYWU5PU19FTVVMX1RJ
TUVfU0hJRlQpDQo+ID4gPiB8DQo+ID4gPiArCQkJKHRlbXBfdG9fY29kZShkYXRhLCB0ZW1wKSA8
PA0KPiA+ID4gRVhZTk9TX0VNVUxfREFUQV9TSElGVCkgfA0KPiA+ID4gKwkJCUVYWU5PU19FTVVM
X0VOQUJMRTsNCj4gPiA+ICsJZWxzZQ0KPiA+ID4gKwkJcmVnICY9IH5FWFlOT1NfRU1VTF9FTkFC
TEU7DQo+ID4gPiArDQo+ID4gPiArCXdyaXRlbChyZWcsIGRhdGEtPmJhc2UgKyBFWFlOT1NfRU1V
TF9DT04pOw0KPiA+ID4gKw0KPiA+ID4gKwljbGtfZGlzYWJsZShkYXRhLT5jbGspOw0KPiA+ID4g
KwltdXRleF91bmxvY2soJmRhdGEtPmxvY2spOw0KPiA+ID4gKw0KPiA+ID4gKwlyZXR1cm4gY291
bnQ7DQo+ID4gPiArfQ0KPiA+ID4gKw0KPiA+ID4gK3N0YXRpYyBERVZJQ0VfQVRUUihlbXVsYXRp
b24sIDA2NDQsIGV4eW5vc190bXVfZW11bGF0aW9uX3Nob3csDQo+ID4gPiArCQkJCQlleHlub3Nf
dG11X2VtdWxhdGlvbl9zdG9yZSk7DQo+ID4gPiArc3RhdGljIGludCBjcmVhdGVfZW11bGF0aW9u
X3N5c2ZzKHN0cnVjdCBkZXZpY2UgKmRldikNCj4gPiA+ICt7DQo+ID4gPiArCXJldHVybiBkZXZp
Y2VfY3JlYXRlX2ZpbGUoZGV2LCAmZGV2X2F0dHJfZW11bGF0aW9uKTsNCj4gPiA+ICt9DQo+ID4g
PiArc3RhdGljIHZvaWQgcmVtb3ZlX2VtdWxhdGlvbl9zeXNmcyhzdHJ1Y3QgZGV2aWNlICpkZXYp
DQo+ID4gPiArew0KPiA+ID4gKwlkZXZpY2VfcmVtb3ZlX2ZpbGUoZGV2LCAmZGV2X2F0dHJfZW11
bGF0aW9uKTsNCj4gPiA+ICt9DQo+ID4gPiArI2Vsc2UNCj4gPiA+ICtzdGF0aWMgaW5saW5lIGlu
dCBjcmVhdGVfZW11bGF0aW9uX3N5c2ZzKHN0cnVjdCBkZXZpY2UgKmRldikge3JldHVybiAwO30N
Cj4gPiA+ICtzdGF0aWMgaW5saW5lIHZvaWQgcmVtb3ZlX2VtdWxhdGlvbl9zeXNmcyhzdHJ1Y3Qg
ZGV2aWNlICpkZXYpe30NCj4gPiA+ICsjZW5kaWYNCj4gPiA+ICsNCj4gPiA+ICBzdGF0aWMgaW50
IF9fZGV2aW5pdCBleHlub3NfdG11X3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYp
DQo+ID4gPiAgew0KPiA+ID4gIAlzdHJ1Y3QgZXh5bm9zX3RtdV9kYXRhICpkYXRhOw0KPiA+ID4g
QEAgLTkzMCw2ICsxMDE0LDExIEBAIHN0YXRpYyBpbnQgX19kZXZpbml0IGV4eW5vc190bXVfcHJv
YmUoc3RydWN0DQo+ID4gPiBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQo+ID4gPiAgCQlkZXZfZXJy
KCZwZGV2LT5kZXYsICJGYWlsZWQgdG8gcmVnaXN0ZXIgdGhlcm1hbA0KPiA+ID4gaW50ZXJmYWNl
XG4iKTsNCj4gPiA+ICAJCWdvdG8gZXJyX2NsazsNCj4gPiA+ICAJfQ0KPiA+ID4gKw0KPiA+ID4g
KwlyZXQgPSBjcmVhdGVfZW11bGF0aW9uX3N5c2ZzKCZwZGV2LT5kZXYpOw0KPiA+ID4gKwlpZiAo
cmV0KQ0KPiA+ID4gKwkJZGV2X2VycigmcGRldi0+ZGV2LCAiRmFpbGVkIHRvIGNyZWF0ZSBlbXVs
YXRpb24gbW9kZQ0KPiA+ID4gc3lzZnMgbm9kZVxuIik7DQo+ID4gPiArDQo+ID4gPiAgCXJldHVy
biAwOw0KPiA+ID4gIGVycl9jbGs6DQo+ID4gPiAgCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYs
IE5VTEwpOw0KPiA+ID4gQEAgLTk0MSw2ICsxMDMwLDggQEAgc3RhdGljIGludCBfX2RldmV4aXQg
ZXh5bm9zX3RtdV9yZW1vdmUoc3RydWN0DQo+ID4gPiBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQo+
ID4gPiAgew0KPiA+ID4gIAlzdHJ1Y3QgZXh5bm9zX3RtdV9kYXRhICpkYXRhID0gcGxhdGZvcm1f
Z2V0X2RydmRhdGEocGRldik7DQo+ID4gPg0KPiA+ID4gKwlyZW1vdmVfZW11bGF0aW9uX3N5c2Zz
KCZwZGV2LT5kZXYpOw0KPiA+ID4gKw0KPiA+ID4gIAlleHlub3NfdG11X2NvbnRyb2wocGRldiwg
ZmFsc2UpOw0KPiA+ID4NCj4gPiA+ICAJZXh5bm9zX3VucmVnaXN0ZXJfdGhlcm1hbCgpOw0KPiA+
ID4gLS0NCj4gPiA+IDEuNy40LjENCj4gPg0KPiANCg0K
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Amit Kachhap Nov. 8, 2012, 9:24 a.m. UTC | #4
Hi Jonghwa Lee,

I tested this patch and it looks good. I have some minor comments below,

Reviewed-by: Amit Daniel Kachhap <amit.kachhap@linaro.org>

Thanks,
Amit Daniel
On 2 November 2012 07:54, Jonghwa Lee <jonghwa3.lee@samsung.com> wrote:
> This patch supports exynos's emulation mode with newly created sysfs node.
> Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
> management unit. Thermal emulation mode supports software debug for TMU's
> operation. User can set temperature manually with software code and TMU
> will read current temperature from user value not from sensor's value.
> This patch includes also documentary placed under Documentation/thermal/.
>
> Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
> ---
> v4
>  - Fix Typo.
>  - Remove unnecessary codes.
>  - Add comments about feature of exynos emulation operation to the document.
>
> v3
>  - Remove unnecessay variables.
>  - Do some code clean in exynos_tmu_emulation_store().
>  - Make wrapping function of sysfs node creation function to use
>    #ifdefs in minimum.
>
> v2
>  exynos_thermal.c
>  - Fix build error occured by wrong emulation control register name.
>  - Remove exynos5410 dependent codes.
>  exynos_thermal_emulation
>  - Align indentation.
>
>  Documentation/thermal/exynos_thermal_emulation |   56 +++++++++++++++
>  drivers/thermal/Kconfig                        |    9 +++
>  drivers/thermal/exynos_thermal.c               |   91 ++++++++++++++++++++++++
>  3 files changed, 156 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/thermal/exynos_thermal_emulation
>
> diff --git a/Documentation/thermal/exynos_thermal_emulation b/Documentation/thermal/exynos_thermal_emulation
> new file mode 100644
> index 0000000..a6ea06f
> --- /dev/null
> +++ b/Documentation/thermal/exynos_thermal_emulation
> @@ -0,0 +1,56 @@
> +EXYNOS EMULATION MODE
> +========================
> +
> +Copyright (C) 2012 Samsung Electronics
> +
> +Written by Jonghwa Lee <jonghwa3.lee@samsung.com>
> +
> +Description
> +-----------
> +
> +Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal management unit.
> +Thermal emulation mode supports software debug for TMU's operation. User can set temperature
> +manually with software code and TMU will read current temperature from user value not from
> +sensor's value.
> +
> +Enabling CONFIG_EXYNOS_THERMAL_EMUL option will make this support in available.
> +When it's enabled, sysfs node will be created under
> +/sys/bus/platform/devices/'exynos device name'/ with name of 'emulation'.
> +
> +The sysfs node, 'emulation', will contain value 0 for the initial state. When you input any
> +temperature you want to update to sysfs node, it automatically enable emulation mode and
> +current temperature will be changed into it.
> +(Exynos also supports user changable delay time which would be used to delay of
> + changing temperature. However, this node only uses same delay of real sensing time, 938us.)
> +
> +Exynos emulation mode requires synchronous of value changing and enabling. It means when you
> +want to update the any value of delay or next temperature, then you have to enable emulation
> +mode at the same time. (Or you have to keep the mode enabling.) If you don't, it fails to
> +change the value to updated one and just use last succeessful value repeatedly. That's why
> +this node gives users the right to change termerpature only. Just one interface makes it more
> +simply to use.
> +
> +Disabling emulation mode only requires writing value 0 to sysfs node.
> +
> +
> +TEMP   120 |
> +           |
> +       100 |
> +           |
> +        80 |
> +           |                            +-----------
> +        60 |                            |          |
> +           |              +-------------|          |
> +        40 |              |             |          |
> +           |              |             |          |
> +        20 |              |             |          +----------
> +           |              |             |          |          |
> +         0 |______________|_____________|__________|__________|_________
> +                  A             A          A                  A     TIME
> +                  |<----->|     |<----->|  |<----->|          |
> +                  | 938us |     |       |  |       |          |
> +emulation    :  0  50     |     70      |  20      |          0
> +current temp :   sensor   50            70         20        sensor
> +
> +
> +
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index e1cb6bd..c02a66c 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -55,3 +55,12 @@ config EXYNOS_THERMAL
>         help
>           If you say yes here you get support for TMU (Thermal Managment
>           Unit) on SAMSUNG EXYNOS series of SoC.
> +
> +config EXYNOS_THERMAL_EMUL
> +       bool "EXYNOS TMU emulation mode support"
> +       depends on !CPU_EXYNOS4210 && EXYNOS_THERMAL
Instead of using CPU_EXYNOS4210 here it is better to use data->soc ==
SOC_ARCH_EXYNOS4210 inside the emulation show/store functions.
> +       help
> +         Exynos 4412 and 4414 and 5 series has emulation mode on TMU.
> +         Enable this option will be make sysfs node in exynos thermal platform
> +         device directory to support emulation mode. With emulation mode sysfs
> +         node, you can manually input temperature to TMU for simulation purpose.
> diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
> index fd03e85..eebd4e5 100644
> --- a/drivers/thermal/exynos_thermal.c
> +++ b/drivers/thermal/exynos_thermal.c
> @@ -99,6 +99,14 @@
>  #define IDLE_INTERVAL 10000
>  #define MCELSIUS       1000
>
> +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
> +#define EXYNOS_EMUL_TIME       0x57F0
> +#define EXYNOS_EMUL_TIME_SHIFT 16
> +#define EXYNOS_EMUL_DATA_SHIFT 8
> +#define EXYNOS_EMUL_DATA_MASK  0xFF
> +#define EXYNOS_EMUL_ENABLE     0x1
> +#endif /* CONFIG_EXYNOS_THERMAL_EMUL */
> +
>  /* CPU Zone information */
>  #define PANIC_ZONE      4
>  #define WARN_ZONE       3
> @@ -832,6 +840,82 @@ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
>         return (struct exynos_tmu_platform_data *)
>                         platform_get_device_id(pdev)->driver_data;
>  }
> +
> +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
> +static ssize_t exynos_tmu_emulation_show(struct device *dev,
> +                                        struct device_attribute *attr,
> +                                        char *buf)
> +{
> +       struct platform_device *pdev = container_of(dev,
> +                                       struct platform_device, dev);
> +       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> +       unsigned int reg;
> +       u8 temp_code;
> +       int temp = 0;
> +
> +       mutex_lock(&data->lock);
> +       clk_enable(data->clk);
> +       reg = readl(data->base + EXYNOS_EMUL_CON);
> +       clk_disable(data->clk);
> +       mutex_unlock(&data->lock);
> +
> +       if (reg & EXYNOS_EMUL_ENABLE) {
> +               reg >>= EXYNOS_EMUL_DATA_SHIFT;
> +               temp_code = reg & EXYNOS_EMUL_DATA_MASK;
> +               temp = code_to_temp(data, temp_code);
> +       }
> +
> +       return sprintf(buf, "%d\n", temp);
Currently in  /sys/devices/virtual/thermal/thermal_zone0/ all
temperatures are shown in millicelsius so it is better show this in
millicelsius also.
> +}
> +
> +static ssize_t exynos_tmu_emulation_store(struct device *dev,
> +                                       struct device_attribute *attr,
> +                                       const char *buf, size_t count)
> +{
> +       struct platform_device *pdev = container_of(dev,
> +                                       struct platform_device, dev);
> +       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> +       unsigned int reg;
> +       int temp;
> +
> +       if (!sscanf(buf, "%d\n", &temp) || temp < 0)
> +               return -EINVAL;
> +
> +       mutex_lock(&data->lock);
> +       clk_enable(data->clk);
> +
> +       reg = readl(data->base + EXYNOS_EMUL_CON);
> +
> +       if (temp)
> +               reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
> +                       (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) |
Same as above.
> +                       EXYNOS_EMUL_ENABLE;
> +       else
> +               reg &= ~EXYNOS_EMUL_ENABLE;
> +
> +       writel(reg, data->base + EXYNOS_EMUL_CON);
> +
> +       clk_disable(data->clk);
> +       mutex_unlock(&data->lock);
> +
> +       return count;
> +}
> +
> +static DEVICE_ATTR(emulation, 0644, exynos_tmu_emulation_show,
> +                                       exynos_tmu_emulation_store);
> +static int create_emulation_sysfs(struct device *dev)
> +{
> +       return device_create_file(dev, &dev_attr_emulation);
> +}
> +static void remove_emulation_sysfs(struct device *dev)
> +{
> +       device_remove_file(dev, &dev_attr_emulation);
> +}
> +#else
> +static inline int create_emulation_sysfs(struct device *dev) {return 0;}
> +static inline void remove_emulation_sysfs(struct device *dev){}
> +#endif
> +
>  static int __devinit exynos_tmu_probe(struct platform_device *pdev)
>  {
>         struct exynos_tmu_data *data;
> @@ -930,6 +1014,11 @@ static int __devinit exynos_tmu_probe(struct platform_device *pdev)
>                 dev_err(&pdev->dev, "Failed to register thermal interface\n");
>                 goto err_clk;
>         }
> +
> +       ret = create_emulation_sysfs(&pdev->dev);
> +       if (ret)
> +               dev_err(&pdev->dev, "Failed to create emulation mode sysfs node\n");
> +
>         return 0;
>  err_clk:
>         platform_set_drvdata(pdev, NULL);
> @@ -941,6 +1030,8 @@ static int __devexit exynos_tmu_remove(struct platform_device *pdev)
>  {
>         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
>
> +       remove_emulation_sysfs(&pdev->dev);
> +
>         exynos_tmu_control(pdev, false);
>
>         exynos_unregister_thermal();
> --
> 1.7.4.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Zhang, Rui Nov. 21, 2012, 2 a.m. UTC | #5
On Thu, 2012-11-08 at 14:54 +0530, Amit Kachhap wrote:
> Hi Jonghwa Lee,
> 
> I tested this patch and it looks good. I have some minor comments below,
> 
> Reviewed-by: Amit Daniel Kachhap <amit.kachhap@linaro.org>
> 
Hi, Lee,

I suppose there should be an updated version being sent out soon, right?

Thanks,
rui

> Thanks,
> Amit Daniel
> On 2 November 2012 07:54, Jonghwa Lee <jonghwa3.lee@samsung.com> wrote:
> > This patch supports exynos's emulation mode with newly created sysfs node.
> > Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
> > management unit. Thermal emulation mode supports software debug for TMU's
> > operation. User can set temperature manually with software code and TMU
> > will read current temperature from user value not from sensor's value.
> > This patch includes also documentary placed under Documentation/thermal/.
> >
> > Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
> > ---
> > v4
> >  - Fix Typo.
> >  - Remove unnecessary codes.
> >  - Add comments about feature of exynos emulation operation to the document.
> >
> > v3
> >  - Remove unnecessay variables.
> >  - Do some code clean in exynos_tmu_emulation_store().
> >  - Make wrapping function of sysfs node creation function to use
> >    #ifdefs in minimum.
> >
> > v2
> >  exynos_thermal.c
> >  - Fix build error occured by wrong emulation control register name.
> >  - Remove exynos5410 dependent codes.
> >  exynos_thermal_emulation
> >  - Align indentation.
> >
> >  Documentation/thermal/exynos_thermal_emulation |   56 +++++++++++++++
> >  drivers/thermal/Kconfig                        |    9 +++
> >  drivers/thermal/exynos_thermal.c               |   91 ++++++++++++++++++++++++
> >  3 files changed, 156 insertions(+), 0 deletions(-)
> >  create mode 100644 Documentation/thermal/exynos_thermal_emulation
> >
> > diff --git a/Documentation/thermal/exynos_thermal_emulation b/Documentation/thermal/exynos_thermal_emulation
> > new file mode 100644
> > index 0000000..a6ea06f
> > --- /dev/null
> > +++ b/Documentation/thermal/exynos_thermal_emulation
> > @@ -0,0 +1,56 @@
> > +EXYNOS EMULATION MODE
> > +========================
> > +
> > +Copyright (C) 2012 Samsung Electronics
> > +
> > +Written by Jonghwa Lee <jonghwa3.lee@samsung.com>
> > +
> > +Description
> > +-----------
> > +
> > +Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal management unit.
> > +Thermal emulation mode supports software debug for TMU's operation. User can set temperature
> > +manually with software code and TMU will read current temperature from user value not from
> > +sensor's value.
> > +
> > +Enabling CONFIG_EXYNOS_THERMAL_EMUL option will make this support in available.
> > +When it's enabled, sysfs node will be created under
> > +/sys/bus/platform/devices/'exynos device name'/ with name of 'emulation'.
> > +
> > +The sysfs node, 'emulation', will contain value 0 for the initial state. When you input any
> > +temperature you want to update to sysfs node, it automatically enable emulation mode and
> > +current temperature will be changed into it.
> > +(Exynos also supports user changable delay time which would be used to delay of
> > + changing temperature. However, this node only uses same delay of real sensing time, 938us.)
> > +
> > +Exynos emulation mode requires synchronous of value changing and enabling. It means when you
> > +want to update the any value of delay or next temperature, then you have to enable emulation
> > +mode at the same time. (Or you have to keep the mode enabling.) If you don't, it fails to
> > +change the value to updated one and just use last succeessful value repeatedly. That's why
> > +this node gives users the right to change termerpature only. Just one interface makes it more
> > +simply to use.
> > +
> > +Disabling emulation mode only requires writing value 0 to sysfs node.
> > +
> > +
> > +TEMP   120 |
> > +           |
> > +       100 |
> > +           |
> > +        80 |
> > +           |                            +-----------
> > +        60 |                            |          |
> > +           |              +-------------|          |
> > +        40 |              |             |          |
> > +           |              |             |          |
> > +        20 |              |             |          +----------
> > +           |              |             |          |          |
> > +         0 |______________|_____________|__________|__________|_________
> > +                  A             A          A                  A     TIME
> > +                  |<----->|     |<----->|  |<----->|          |
> > +                  | 938us |     |       |  |       |          |
> > +emulation    :  0  50     |     70      |  20      |          0
> > +current temp :   sensor   50            70         20        sensor
> > +
> > +
> > +
> > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> > index e1cb6bd..c02a66c 100644
> > --- a/drivers/thermal/Kconfig
> > +++ b/drivers/thermal/Kconfig
> > @@ -55,3 +55,12 @@ config EXYNOS_THERMAL
> >         help
> >           If you say yes here you get support for TMU (Thermal Managment
> >           Unit) on SAMSUNG EXYNOS series of SoC.
> > +
> > +config EXYNOS_THERMAL_EMUL
> > +       bool "EXYNOS TMU emulation mode support"
> > +       depends on !CPU_EXYNOS4210 && EXYNOS_THERMAL
> Instead of using CPU_EXYNOS4210 here it is better to use data->soc ==
> SOC_ARCH_EXYNOS4210 inside the emulation show/store functions.
> > +       help
> > +         Exynos 4412 and 4414 and 5 series has emulation mode on TMU.
> > +         Enable this option will be make sysfs node in exynos thermal platform
> > +         device directory to support emulation mode. With emulation mode sysfs
> > +         node, you can manually input temperature to TMU for simulation purpose.
> > diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
> > index fd03e85..eebd4e5 100644
> > --- a/drivers/thermal/exynos_thermal.c
> > +++ b/drivers/thermal/exynos_thermal.c
> > @@ -99,6 +99,14 @@
> >  #define IDLE_INTERVAL 10000
> >  #define MCELSIUS       1000
> >
> > +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
> > +#define EXYNOS_EMUL_TIME       0x57F0
> > +#define EXYNOS_EMUL_TIME_SHIFT 16
> > +#define EXYNOS_EMUL_DATA_SHIFT 8
> > +#define EXYNOS_EMUL_DATA_MASK  0xFF
> > +#define EXYNOS_EMUL_ENABLE     0x1
> > +#endif /* CONFIG_EXYNOS_THERMAL_EMUL */
> > +
> >  /* CPU Zone information */
> >  #define PANIC_ZONE      4
> >  #define WARN_ZONE       3
> > @@ -832,6 +840,82 @@ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
> >         return (struct exynos_tmu_platform_data *)
> >                         platform_get_device_id(pdev)->driver_data;
> >  }
> > +
> > +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
> > +static ssize_t exynos_tmu_emulation_show(struct device *dev,
> > +                                        struct device_attribute *attr,
> > +                                        char *buf)
> > +{
> > +       struct platform_device *pdev = container_of(dev,
> > +                                       struct platform_device, dev);
> > +       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> > +       unsigned int reg;
> > +       u8 temp_code;
> > +       int temp = 0;
> > +
> > +       mutex_lock(&data->lock);
> > +       clk_enable(data->clk);
> > +       reg = readl(data->base + EXYNOS_EMUL_CON);
> > +       clk_disable(data->clk);
> > +       mutex_unlock(&data->lock);
> > +
> > +       if (reg & EXYNOS_EMUL_ENABLE) {
> > +               reg >>= EXYNOS_EMUL_DATA_SHIFT;
> > +               temp_code = reg & EXYNOS_EMUL_DATA_MASK;
> > +               temp = code_to_temp(data, temp_code);
> > +       }
> > +
> > +       return sprintf(buf, "%d\n", temp);
> Currently in  /sys/devices/virtual/thermal/thermal_zone0/ all
> temperatures are shown in millicelsius so it is better show this in
> millicelsius also.
> > +}
> > +
> > +static ssize_t exynos_tmu_emulation_store(struct device *dev,
> > +                                       struct device_attribute *attr,
> > +                                       const char *buf, size_t count)
> > +{
> > +       struct platform_device *pdev = container_of(dev,
> > +                                       struct platform_device, dev);
> > +       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> > +       unsigned int reg;
> > +       int temp;
> > +
> > +       if (!sscanf(buf, "%d\n", &temp) || temp < 0)
> > +               return -EINVAL;
> > +
> > +       mutex_lock(&data->lock);
> > +       clk_enable(data->clk);
> > +
> > +       reg = readl(data->base + EXYNOS_EMUL_CON);
> > +
> > +       if (temp)
> > +               reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
> > +                       (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) |
> Same as above.
> > +                       EXYNOS_EMUL_ENABLE;
> > +       else
> > +               reg &= ~EXYNOS_EMUL_ENABLE;
> > +
> > +       writel(reg, data->base + EXYNOS_EMUL_CON);
> > +
> > +       clk_disable(data->clk);
> > +       mutex_unlock(&data->lock);
> > +
> > +       return count;
> > +}
> > +
> > +static DEVICE_ATTR(emulation, 0644, exynos_tmu_emulation_show,
> > +                                       exynos_tmu_emulation_store);
> > +static int create_emulation_sysfs(struct device *dev)
> > +{
> > +       return device_create_file(dev, &dev_attr_emulation);
> > +}
> > +static void remove_emulation_sysfs(struct device *dev)
> > +{
> > +       device_remove_file(dev, &dev_attr_emulation);
> > +}
> > +#else
> > +static inline int create_emulation_sysfs(struct device *dev) {return 0;}
> > +static inline void remove_emulation_sysfs(struct device *dev){}
> > +#endif
> > +
> >  static int __devinit exynos_tmu_probe(struct platform_device *pdev)
> >  {
> >         struct exynos_tmu_data *data;
> > @@ -930,6 +1014,11 @@ static int __devinit exynos_tmu_probe(struct platform_device *pdev)
> >                 dev_err(&pdev->dev, "Failed to register thermal interface\n");
> >                 goto err_clk;
> >         }
> > +
> > +       ret = create_emulation_sysfs(&pdev->dev);
> > +       if (ret)
> > +               dev_err(&pdev->dev, "Failed to create emulation mode sysfs node\n");
> > +
> >         return 0;
> >  err_clk:
> >         platform_set_drvdata(pdev, NULL);
> > @@ -941,6 +1030,8 @@ static int __devexit exynos_tmu_remove(struct platform_device *pdev)
> >  {
> >         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
> >
> > +       remove_emulation_sysfs(&pdev->dev);
> > +
> >         exynos_tmu_control(pdev, false);
> >
> >         exynos_unregister_thermal();
> > --
> > 1.7.4.1
> >


--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jonghwa Lee Nov. 21, 2012, 2:19 a.m. UTC | #6
On 2012? 11? 21? 11:00, Zhang Rui wrote:
> On Thu, 2012-11-08 at 14:54 +0530, Amit Kachhap wrote:
>> Hi Jonghwa Lee,
>>
>> I tested this patch and it looks good. I have some minor comments below,
>>
>> Reviewed-by: Amit Daniel Kachhap <amit.kachhap@linaro.org>
>>
> Hi, Lee,
>
> I suppose there should be an updated version being sent out soon, right?
>
> Thanks,
> rui
Hi, Rui,

Yes, there is. I'll re-post it as soon.

Thanks.
>> Thanks,
>> Amit Daniel
>> On 2 November 2012 07:54, Jonghwa Lee <jonghwa3.lee@samsung.com> wrote:
>>> This patch supports exynos's emulation mode with newly created sysfs node.
>>> Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
>>> management unit. Thermal emulation mode supports software debug for TMU's
>>> operation. User can set temperature manually with software code and TMU
>>> will read current temperature from user value not from sensor's value.
>>> This patch includes also documentary placed under Documentation/thermal/.
>>>
>>> Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
>>> ---
>>> v4
>>>  - Fix Typo.
>>>  - Remove unnecessary codes.
>>>  - Add comments about feature of exynos emulation operation to the document.
>>>
>>> v3
>>>  - Remove unnecessay variables.
>>>  - Do some code clean in exynos_tmu_emulation_store().
>>>  - Make wrapping function of sysfs node creation function to use
>>>    #ifdefs in minimum.
>>>
>>> v2
>>>  exynos_thermal.c
>>>  - Fix build error occured by wrong emulation control register name.
>>>  - Remove exynos5410 dependent codes.
>>>  exynos_thermal_emulation
>>>  - Align indentation.
>>>
>>>  Documentation/thermal/exynos_thermal_emulation |   56 +++++++++++++++
>>>  drivers/thermal/Kconfig                        |    9 +++
>>>  drivers/thermal/exynos_thermal.c               |   91 ++++++++++++++++++++++++
>>>  3 files changed, 156 insertions(+), 0 deletions(-)
>>>  create mode 100644 Documentation/thermal/exynos_thermal_emulation
>>>
>>> diff --git a/Documentation/thermal/exynos_thermal_emulation b/Documentation/thermal/exynos_thermal_emulation
>>> new file mode 100644
>>> index 0000000..a6ea06f
>>> --- /dev/null
>>> +++ b/Documentation/thermal/exynos_thermal_emulation
>>> @@ -0,0 +1,56 @@
>>> +EXYNOS EMULATION MODE
>>> +========================
>>> +
>>> +Copyright (C) 2012 Samsung Electronics
>>> +
>>> +Written by Jonghwa Lee <jonghwa3.lee@samsung.com>
>>> +
>>> +Description
>>> +-----------
>>> +
>>> +Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal management unit.
>>> +Thermal emulation mode supports software debug for TMU's operation. User can set temperature
>>> +manually with software code and TMU will read current temperature from user value not from
>>> +sensor's value.
>>> +
>>> +Enabling CONFIG_EXYNOS_THERMAL_EMUL option will make this support in available.
>>> +When it's enabled, sysfs node will be created under
>>> +/sys/bus/platform/devices/'exynos device name'/ with name of 'emulation'.
>>> +
>>> +The sysfs node, 'emulation', will contain value 0 for the initial state. When you input any
>>> +temperature you want to update to sysfs node, it automatically enable emulation mode and
>>> +current temperature will be changed into it.
>>> +(Exynos also supports user changable delay time which would be used to delay of
>>> + changing temperature. However, this node only uses same delay of real sensing time, 938us.)
>>> +
>>> +Exynos emulation mode requires synchronous of value changing and enabling. It means when you
>>> +want to update the any value of delay or next temperature, then you have to enable emulation
>>> +mode at the same time. (Or you have to keep the mode enabling.) If you don't, it fails to
>>> +change the value to updated one and just use last succeessful value repeatedly. That's why
>>> +this node gives users the right to change termerpature only. Just one interface makes it more
>>> +simply to use.
>>> +
>>> +Disabling emulation mode only requires writing value 0 to sysfs node.
>>> +
>>> +
>>> +TEMP   120 |
>>> +           |
>>> +       100 |
>>> +           |
>>> +        80 |
>>> +           |                            +-----------
>>> +        60 |                            |          |
>>> +           |              +-------------|          |
>>> +        40 |              |             |          |
>>> +           |              |             |          |
>>> +        20 |              |             |          +----------
>>> +           |              |             |          |          |
>>> +         0 |______________|_____________|__________|__________|_________
>>> +                  A             A          A                  A     TIME
>>> +                  |<----->|     |<----->|  |<----->|          |
>>> +                  | 938us |     |       |  |       |          |
>>> +emulation    :  0  50     |     70      |  20      |          0
>>> +current temp :   sensor   50            70         20        sensor
>>> +
>>> +
>>> +
>>> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
>>> index e1cb6bd..c02a66c 100644
>>> --- a/drivers/thermal/Kconfig
>>> +++ b/drivers/thermal/Kconfig
>>> @@ -55,3 +55,12 @@ config EXYNOS_THERMAL
>>>         help
>>>           If you say yes here you get support for TMU (Thermal Managment
>>>           Unit) on SAMSUNG EXYNOS series of SoC.
>>> +
>>> +config EXYNOS_THERMAL_EMUL
>>> +       bool "EXYNOS TMU emulation mode support"
>>> +       depends on !CPU_EXYNOS4210 && EXYNOS_THERMAL
>> Instead of using CPU_EXYNOS4210 here it is better to use data->soc ==
>> SOC_ARCH_EXYNOS4210 inside the emulation show/store functions.
>>> +       help
>>> +         Exynos 4412 and 4414 and 5 series has emulation mode on TMU.
>>> +         Enable this option will be make sysfs node in exynos thermal platform
>>> +         device directory to support emulation mode. With emulation mode sysfs
>>> +         node, you can manually input temperature to TMU for simulation purpose.
>>> diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
>>> index fd03e85..eebd4e5 100644
>>> --- a/drivers/thermal/exynos_thermal.c
>>> +++ b/drivers/thermal/exynos_thermal.c
>>> @@ -99,6 +99,14 @@
>>>  #define IDLE_INTERVAL 10000
>>>  #define MCELSIUS       1000
>>>
>>> +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
>>> +#define EXYNOS_EMUL_TIME       0x57F0
>>> +#define EXYNOS_EMUL_TIME_SHIFT 16
>>> +#define EXYNOS_EMUL_DATA_SHIFT 8
>>> +#define EXYNOS_EMUL_DATA_MASK  0xFF
>>> +#define EXYNOS_EMUL_ENABLE     0x1
>>> +#endif /* CONFIG_EXYNOS_THERMAL_EMUL */
>>> +
>>>  /* CPU Zone information */
>>>  #define PANIC_ZONE      4
>>>  #define WARN_ZONE       3
>>> @@ -832,6 +840,82 @@ static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
>>>         return (struct exynos_tmu_platform_data *)
>>>                         platform_get_device_id(pdev)->driver_data;
>>>  }
>>> +
>>> +#ifdef CONFIG_EXYNOS_THERMAL_EMUL
>>> +static ssize_t exynos_tmu_emulation_show(struct device *dev,
>>> +                                        struct device_attribute *attr,
>>> +                                        char *buf)
>>> +{
>>> +       struct platform_device *pdev = container_of(dev,
>>> +                                       struct platform_device, dev);
>>> +       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
>>> +       unsigned int reg;
>>> +       u8 temp_code;
>>> +       int temp = 0;
>>> +
>>> +       mutex_lock(&data->lock);
>>> +       clk_enable(data->clk);
>>> +       reg = readl(data->base + EXYNOS_EMUL_CON);
>>> +       clk_disable(data->clk);
>>> +       mutex_unlock(&data->lock);
>>> +
>>> +       if (reg & EXYNOS_EMUL_ENABLE) {
>>> +               reg >>= EXYNOS_EMUL_DATA_SHIFT;
>>> +               temp_code = reg & EXYNOS_EMUL_DATA_MASK;
>>> +               temp = code_to_temp(data, temp_code);
>>> +       }
>>> +
>>> +       return sprintf(buf, "%d\n", temp);
>> Currently in  /sys/devices/virtual/thermal/thermal_zone0/ all
>> temperatures are shown in millicelsius so it is better show this in
>> millicelsius also.
>>> +}
>>> +
>>> +static ssize_t exynos_tmu_emulation_store(struct device *dev,
>>> +                                       struct device_attribute *attr,
>>> +                                       const char *buf, size_t count)
>>> +{
>>> +       struct platform_device *pdev = container_of(dev,
>>> +                                       struct platform_device, dev);
>>> +       struct exynos_tmu_data *data = platform_get_drvdata(pdev);
>>> +       unsigned int reg;
>>> +       int temp;
>>> +
>>> +       if (!sscanf(buf, "%d\n", &temp) || temp < 0)
>>> +               return -EINVAL;
>>> +
>>> +       mutex_lock(&data->lock);
>>> +       clk_enable(data->clk);
>>> +
>>> +       reg = readl(data->base + EXYNOS_EMUL_CON);
>>> +
>>> +       if (temp)
>>> +               reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
>>> +                       (temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) |
>> Same as above.
>>> +                       EXYNOS_EMUL_ENABLE;
>>> +       else
>>> +               reg &= ~EXYNOS_EMUL_ENABLE;
>>> +
>>> +       writel(reg, data->base + EXYNOS_EMUL_CON);
>>> +
>>> +       clk_disable(data->clk);
>>> +       mutex_unlock(&data->lock);
>>> +
>>> +       return count;
>>> +}
>>> +
>>> +static DEVICE_ATTR(emulation, 0644, exynos_tmu_emulation_show,
>>> +                                       exynos_tmu_emulation_store);
>>> +static int create_emulation_sysfs(struct device *dev)
>>> +{
>>> +       return device_create_file(dev, &dev_attr_emulation);
>>> +}
>>> +static void remove_emulation_sysfs(struct device *dev)
>>> +{
>>> +       device_remove_file(dev, &dev_attr_emulation);
>>> +}
>>> +#else
>>> +static inline int create_emulation_sysfs(struct device *dev) {return 0;}
>>> +static inline void remove_emulation_sysfs(struct device *dev){}
>>> +#endif
>>> +
>>>  static int __devinit exynos_tmu_probe(struct platform_device *pdev)
>>>  {
>>>         struct exynos_tmu_data *data;
>>> @@ -930,6 +1014,11 @@ static int __devinit exynos_tmu_probe(struct platform_device *pdev)
>>>                 dev_err(&pdev->dev, "Failed to register thermal interface\n");
>>>                 goto err_clk;
>>>         }
>>> +
>>> +       ret = create_emulation_sysfs(&pdev->dev);
>>> +       if (ret)
>>> +               dev_err(&pdev->dev, "Failed to create emulation mode sysfs node\n");
>>> +
>>>         return 0;
>>>  err_clk:
>>>         platform_set_drvdata(pdev, NULL);
>>> @@ -941,6 +1030,8 @@ static int __devexit exynos_tmu_remove(struct platform_device *pdev)
>>>  {
>>>         struct exynos_tmu_data *data = platform_get_drvdata(pdev);
>>>
>>> +       remove_emulation_sysfs(&pdev->dev);
>>> +
>>>         exynos_tmu_control(pdev, false);
>>>
>>>         exynos_unregister_thermal();
>>> --
>>> 1.7.4.1
>>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/thermal/exynos_thermal_emulation b/Documentation/thermal/exynos_thermal_emulation
new file mode 100644
index 0000000..a6ea06f
--- /dev/null
+++ b/Documentation/thermal/exynos_thermal_emulation
@@ -0,0 +1,56 @@ 
+EXYNOS EMULATION MODE
+========================
+
+Copyright (C) 2012 Samsung Electronics
+
+Written by Jonghwa Lee <jonghwa3.lee@samsung.com>
+
+Description
+-----------
+
+Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal management unit.
+Thermal emulation mode supports software debug for TMU's operation. User can set temperature
+manually with software code and TMU will read current temperature from user value not from
+sensor's value.
+
+Enabling CONFIG_EXYNOS_THERMAL_EMUL option will make this support in available.
+When it's enabled, sysfs node will be created under
+/sys/bus/platform/devices/'exynos device name'/ with name of 'emulation'.
+
+The sysfs node, 'emulation', will contain value 0 for the initial state. When you input any
+temperature you want to update to sysfs node, it automatically enable emulation mode and
+current temperature will be changed into it.
+(Exynos also supports user changable delay time which would be used to delay of
+ changing temperature. However, this node only uses same delay of real sensing time, 938us.)
+
+Exynos emulation mode requires synchronous of value changing and enabling. It means when you
+want to update the any value of delay or next temperature, then you have to enable emulation 
+mode at the same time. (Or you have to keep the mode enabling.) If you don't, it fails to
+change the value to updated one and just use last succeessful value repeatedly. That's why
+this node gives users the right to change termerpature only. Just one interface makes it more
+simply to use.
+
+Disabling emulation mode only requires writing value 0 to sysfs node.
+
+
+TEMP	120 |
+	    |
+	100 |
+	    |
+	 80 |
+	    |		     	 	 +-----------
+	 60 |      		     	 |	    |
+	    |	           +-------------|          |
+	 40 |              |         	 |          |
+   	    |		   |	     	 |          |
+	 20 |		   |	     	 |          +----------
+	    |	 	   |	     	 |          |          |
+  	  0 |______________|_____________|__________|__________|_________
+		   A	    	 A	    A	   	       A     TIME
+		   |<----->|	 |<----->|  |<----->|	       |
+		   | 938us |  	 |	 |  |       |          |
+emulation    :  0  50	   |  	 70      |  20      |          0
+current temp :   sensor   50		 70         20	      sensor
+
+
+
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index e1cb6bd..c02a66c 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -55,3 +55,12 @@  config EXYNOS_THERMAL
 	help
 	  If you say yes here you get support for TMU (Thermal Managment
 	  Unit) on SAMSUNG EXYNOS series of SoC.
+
+config EXYNOS_THERMAL_EMUL
+	bool "EXYNOS TMU emulation mode support"
+	depends on !CPU_EXYNOS4210 && EXYNOS_THERMAL
+	help
+	  Exynos 4412 and 4414 and 5 series has emulation mode on TMU.
+	  Enable this option will be make sysfs node in exynos thermal platform
+	  device directory to support emulation mode. With emulation mode sysfs
+	  node, you can manually input temperature to TMU for simulation purpose.
diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c
index fd03e85..eebd4e5 100644
--- a/drivers/thermal/exynos_thermal.c
+++ b/drivers/thermal/exynos_thermal.c
@@ -99,6 +99,14 @@ 
 #define IDLE_INTERVAL 10000
 #define MCELSIUS	1000
 
+#ifdef CONFIG_EXYNOS_THERMAL_EMUL
+#define EXYNOS_EMUL_TIME	0x57F0
+#define EXYNOS_EMUL_TIME_SHIFT	16
+#define EXYNOS_EMUL_DATA_SHIFT	8
+#define EXYNOS_EMUL_DATA_MASK	0xFF
+#define EXYNOS_EMUL_ENABLE	0x1
+#endif /* CONFIG_EXYNOS_THERMAL_EMUL */
+
 /* CPU Zone information */
 #define PANIC_ZONE      4
 #define WARN_ZONE       3
@@ -832,6 +840,82 @@  static inline struct  exynos_tmu_platform_data *exynos_get_driver_data(
 	return (struct exynos_tmu_platform_data *)
 			platform_get_device_id(pdev)->driver_data;
 }
+
+#ifdef CONFIG_EXYNOS_THERMAL_EMUL
+static ssize_t exynos_tmu_emulation_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct platform_device *pdev = container_of(dev,
+					struct platform_device, dev);
+	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+	unsigned int reg;
+	u8 temp_code;
+	int temp = 0;
+
+	mutex_lock(&data->lock);
+	clk_enable(data->clk);
+	reg = readl(data->base + EXYNOS_EMUL_CON);
+	clk_disable(data->clk);
+	mutex_unlock(&data->lock);
+
+	if (reg & EXYNOS_EMUL_ENABLE) {
+		reg >>= EXYNOS_EMUL_DATA_SHIFT;
+		temp_code = reg & EXYNOS_EMUL_DATA_MASK;
+		temp = code_to_temp(data, temp_code);
+	}
+
+	return sprintf(buf, "%d\n", temp);
+}
+
+static ssize_t exynos_tmu_emulation_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	struct platform_device *pdev = container_of(dev,
+					struct platform_device, dev);
+	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
+	unsigned int reg;
+	int temp;
+
+	if (!sscanf(buf, "%d\n", &temp) || temp < 0)
+		return -EINVAL;
+
+	mutex_lock(&data->lock);
+	clk_enable(data->clk);
+
+	reg = readl(data->base + EXYNOS_EMUL_CON);
+
+	if (temp)
+		reg = (EXYNOS_EMUL_TIME << EXYNOS_EMUL_TIME_SHIFT) |
+			(temp_to_code(data, temp) << EXYNOS_EMUL_DATA_SHIFT) |
+			EXYNOS_EMUL_ENABLE;
+	else
+		reg &= ~EXYNOS_EMUL_ENABLE;
+
+	writel(reg, data->base + EXYNOS_EMUL_CON);
+
+	clk_disable(data->clk);
+	mutex_unlock(&data->lock);
+
+	return count;
+}
+
+static DEVICE_ATTR(emulation, 0644, exynos_tmu_emulation_show,
+					exynos_tmu_emulation_store);
+static int create_emulation_sysfs(struct device *dev)
+{
+	return device_create_file(dev, &dev_attr_emulation);
+}
+static void remove_emulation_sysfs(struct device *dev)
+{
+	device_remove_file(dev, &dev_attr_emulation);
+}
+#else
+static inline int create_emulation_sysfs(struct device *dev) {return 0;}
+static inline void remove_emulation_sysfs(struct device *dev){}
+#endif
+
 static int __devinit exynos_tmu_probe(struct platform_device *pdev)
 {
 	struct exynos_tmu_data *data;
@@ -930,6 +1014,11 @@  static int __devinit exynos_tmu_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "Failed to register thermal interface\n");
 		goto err_clk;
 	}
+
+	ret = create_emulation_sysfs(&pdev->dev);
+	if (ret)
+		dev_err(&pdev->dev, "Failed to create emulation mode sysfs node\n");
+
 	return 0;
 err_clk:
 	platform_set_drvdata(pdev, NULL);
@@ -941,6 +1030,8 @@  static int __devexit exynos_tmu_remove(struct platform_device *pdev)
 {
 	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
 
+	remove_emulation_sysfs(&pdev->dev);
+
 	exynos_tmu_control(pdev, false);
 
 	exynos_unregister_thermal();