diff mbox

[4/8] Thermal: Add Thermal_trip sysfs node

Message ID 1355822977-4804-5-git-send-email-durgadoss.r@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Zhang Rui
Headers show

Commit Message

durgadoss.r@intel.com Dec. 18, 2012, 9:29 a.m. UTC
This patch adds a thermal_trip directory under
/sys/class/thermal/zoneX. This directory contains
the trip point values for sensors bound to this
zone.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
---
 drivers/thermal/thermal_sys.c |  237 ++++++++++++++++++++++++++++++++++++++++-
 include/linux/thermal.h       |   37 +++++++
 2 files changed, 272 insertions(+), 2 deletions(-)

Comments

Greg KH Dec. 20, 2012, 5:42 a.m. UTC | #1
On Tue, Dec 18, 2012 at 02:59:33PM +0530, Durgadoss R wrote:
> This patch adds a thermal_trip directory under
> /sys/class/thermal/zoneX. This directory contains
> the trip point values for sensors bound to this
> zone.

Eeek, you just broke userspace tools that now can no longer see these
entries :(

Why do you need to create a subdirectory?  As you found out, doing so
isn't the easiest, right?  That is on purpose.

I really wouldn't recommend doing this at all, please stick within the
'struct device' framework here, don't create new kobjects and hang sysfs
files off of them.

thanks,

greg k-h
--
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 Dec. 20, 2012, 7:52 a.m. UTC | #2
Hi Greg,

Thank you for looking at this.

> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Thursday, December 20, 2012 11:12 AM
> To: R, Durgadoss
> Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org;
> hongbo.zhang@linaro.org; wni@nvidia.com
> Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> 
> On Tue, Dec 18, 2012 at 02:59:33PM +0530, Durgadoss R wrote:
> > This patch adds a thermal_trip directory under
> > /sys/class/thermal/zoneX. This directory contains
> > the trip point values for sensors bound to this
> > zone.
> 
> Eeek, you just broke userspace tools that now can no longer see these
> entries :(
> 
> Why do you need to create a subdirectory?  As you found out, doing so
> isn't the easiest, right?  That is on purpose.

Yes, I observed the complexity.

> 
> I really wouldn't recommend doing this at all, please stick within the
> 'struct device' framework here, don't create new kobjects and hang sysfs
> files off of them.

But, we cannot put all _trip directly under ZoneX directory. We can remove the
thermal_trip directory, and put sensorY_trip under /sys/class/thermal/zoneX/.
But this sensorY_trip needs to be a directory which has four sysfs nodes named,
active, passive, crit, hot.

Rui, What do you think about this ?

The only other way I see, is directly put sensorY_trip_[active/passive/hot/crit]
which will create way too many nodes, under /sys/class/thermal/zoneX/.

Thanks,
Durga

> 
> thanks,
> 
> greg k-h
--
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
Greg KH Dec. 20, 2012, 4:12 p.m. UTC | #3
On Thu, Dec 20, 2012 at 07:52:03AM +0000, R, Durgadoss wrote:
> > On Tue, Dec 18, 2012 at 02:59:33PM +0530, Durgadoss R wrote:
> > > This patch adds a thermal_trip directory under
> > > /sys/class/thermal/zoneX. This directory contains
> > > the trip point values for sensors bound to this
> > > zone.
> > 
> > Eeek, you just broke userspace tools that now can no longer see these
> > entries :(
> > 
> > Why do you need to create a subdirectory?  As you found out, doing so
> > isn't the easiest, right?  That is on purpose.
> 
> Yes, I observed the complexity.
> 
> > 
> > I really wouldn't recommend doing this at all, please stick within the
> > 'struct device' framework here, don't create new kobjects and hang sysfs
> > files off of them.
> 
> But, we cannot put all _trip directly under ZoneX directory.

Why not?  What is preventing this?

> We can remove the thermal_trip directory, and put sensorY_trip under
> /sys/class/thermal/zoneX/.  But this sensorY_trip needs to be a
> directory which has four sysfs nodes named, active, passive, crit,
> hot.
> 
> Rui, What do you think about this ?
> 
> The only other way I see, is directly put sensorY_trip_[active/passive/hot/crit]
> which will create way too many nodes, under /sys/class/thermal/zoneX/.

What is "too many"?  20000?  50000?  How many are we talking about here?
What is the limiting factor that is preventing this from all going into
one directory?

thanks,

greg k-h
--
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 Dec. 20, 2012, 4:25 p.m. UTC | #4
> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Thursday, December 20, 2012 9:42 PM
> To: R, Durgadoss
> Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org;
> hongbo.zhang@linaro.org; wni@nvidia.com
> Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> 
> On Thu, Dec 20, 2012 at 07:52:03AM +0000, R, Durgadoss wrote:
> > > On Tue, Dec 18, 2012 at 02:59:33PM +0530, Durgadoss R wrote:
> > > > This patch adds a thermal_trip directory under
> > > > /sys/class/thermal/zoneX. This directory contains
> > > > the trip point values for sensors bound to this
> > > > zone.
> > >
> > > Eeek, you just broke userspace tools that now can no longer see these
> > > entries :(
> > >
> > > Why do you need to create a subdirectory?  As you found out, doing so
> > > isn't the easiest, right?  That is on purpose.
> >
> > Yes, I observed the complexity.
> >
> > >
> > > I really wouldn't recommend doing this at all, please stick within the
> > > 'struct device' framework here, don't create new kobjects and hang sysfs
> > > files off of them.
> >
> > But, we cannot put all _trip directly under ZoneX directory.
> 
> Why not?  What is preventing this?
> 
> > We can remove the thermal_trip directory, and put sensorY_trip under
> > /sys/class/thermal/zoneX/.  But this sensorY_trip needs to be a
> > directory which has four sysfs nodes named, active, passive, crit,
> > hot.
> >
> > Rui, What do you think about this ?
> >
> > The only other way I see, is directly put
> sensorY_trip_[active/passive/hot/crit]
> > which will create way too many nodes, under /sys/class/thermal/zoneX/.
> 
> What is "too many"?  20000?  50000?  How many are we talking about here?

Not in 1000's though..

> What is the limiting factor that is preventing this from all going into
> one directory?

We support a MAX of 12 sensors per zone today, which will lead to
12 * 4, 48 nodes under this directory named
sensorY_trip_[active/passive/hot/crit], besides the other nodes.

Thanks,
Durga
--
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
Greg KH Dec. 20, 2012, 4:38 p.m. UTC | #5
On Thu, Dec 20, 2012 at 04:25:32PM +0000, R, Durgadoss wrote:
> 
> > -----Original Message-----
> > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > Sent: Thursday, December 20, 2012 9:42 PM
> > To: R, Durgadoss
> > Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org;
> > hongbo.zhang@linaro.org; wni@nvidia.com
> > Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> > 
> > On Thu, Dec 20, 2012 at 07:52:03AM +0000, R, Durgadoss wrote:
> > > > On Tue, Dec 18, 2012 at 02:59:33PM +0530, Durgadoss R wrote:
> > > > > This patch adds a thermal_trip directory under
> > > > > /sys/class/thermal/zoneX. This directory contains
> > > > > the trip point values for sensors bound to this
> > > > > zone.
> > > >
> > > > Eeek, you just broke userspace tools that now can no longer see these
> > > > entries :(
> > > >
> > > > Why do you need to create a subdirectory?  As you found out, doing so
> > > > isn't the easiest, right?  That is on purpose.
> > >
> > > Yes, I observed the complexity.
> > >
> > > >
> > > > I really wouldn't recommend doing this at all, please stick within the
> > > > 'struct device' framework here, don't create new kobjects and hang sysfs
> > > > files off of them.
> > >
> > > But, we cannot put all _trip directly under ZoneX directory.
> > 
> > Why not?  What is preventing this?
> > 
> > > We can remove the thermal_trip directory, and put sensorY_trip under
> > > /sys/class/thermal/zoneX/.  But this sensorY_trip needs to be a
> > > directory which has four sysfs nodes named, active, passive, crit,
> > > hot.
> > >
> > > Rui, What do you think about this ?
> > >
> > > The only other way I see, is directly put
> > sensorY_trip_[active/passive/hot/crit]
> > > which will create way too many nodes, under /sys/class/thermal/zoneX/.
> > 
> > What is "too many"?  20000?  50000?  How many are we talking about here?
> 
> Not in 1000's though..
> 
> > What is the limiting factor that is preventing this from all going into
> > one directory?
> 
> We support a MAX of 12 sensors per zone today, which will lead to
> 12 * 4, 48 nodes under this directory named
> sensorY_trip_[active/passive/hot/crit], besides the other nodes.

That's fine, we can easily support that many files, have you tried this
already?

The main point is, if you use a kobject like you are, userspace tools
can't "see" these directories and files easily, if at all.  Try it out
with libudev yourself to verify it, the attributes will not show up as
owned to that device like you need them to be.

So put them all in one directory, we can handle 10's of thousands of
files quite easily, so 48 is trivial :)

thanks,

greg k-h
--
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 Dec. 20, 2012, 4:58 p.m. UTC | #6
> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Thursday, December 20, 2012 10:09 PM
> To: R, Durgadoss
> Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org;
> hongbo.zhang@linaro.org; wni@nvidia.com
> Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> 
> On Thu, Dec 20, 2012 at 04:25:32PM +0000, R, Durgadoss wrote:
> >
> > > -----Original Message-----
> > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > Sent: Thursday, December 20, 2012 9:42 PM
> > > To: R, Durgadoss
> > > Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > hongbo.zhang@linaro.org; wni@nvidia.com
> > > Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> > >
> > > On Thu, Dec 20, 2012 at 07:52:03AM +0000, R, Durgadoss wrote:
> > > > > On Tue, Dec 18, 2012 at 02:59:33PM +0530, Durgadoss R wrote:
> > > > > > This patch adds a thermal_trip directory under
> > > > > > /sys/class/thermal/zoneX. This directory contains
> > > > > > the trip point values for sensors bound to this
> > > > > > zone.
> > > > >
> > > > > Eeek, you just broke userspace tools that now can no longer see
> these
> > > > > entries :(
> > > > >
> > > > > Why do you need to create a subdirectory?  As you found out, doing
> so
> > > > > isn't the easiest, right?  That is on purpose.
> > > >
> > > > Yes, I observed the complexity.
> > > >
> > > > >
> > > > > I really wouldn't recommend doing this at all, please stick within the
> > > > > 'struct device' framework here, don't create new kobjects and hang
> sysfs
> > > > > files off of them.
> > > >
> > > > But, we cannot put all _trip directly under ZoneX directory.
> > >
> > > Why not?  What is preventing this?
> > >
> > > > We can remove the thermal_trip directory, and put sensorY_trip under
> > > > /sys/class/thermal/zoneX/.  But this sensorY_trip needs to be a
> > > > directory which has four sysfs nodes named, active, passive, crit,
> > > > hot.
> > > >
> > > > Rui, What do you think about this ?
> > > >
> > > > The only other way I see, is directly put
> > > sensorY_trip_[active/passive/hot/crit]
> > > > which will create way too many nodes, under
> /sys/class/thermal/zoneX/.
> > >
> > > What is "too many"?  20000?  50000?  How many are we talking about
> here?
> >
> > Not in 1000's though..
> >
> > > What is the limiting factor that is preventing this from all going into
> > > one directory?
> >
> > We support a MAX of 12 sensors per zone today, which will lead to
> > 12 * 4, 48 nodes under this directory named
> > sensorY_trip_[active/passive/hot/crit], besides the other nodes.
> 
> That's fine, we can easily support that many files, have you tried this
> already?

Yes, in fact, this is sort of what was the old implementation..
although with different sysfs nodes.

> 
> The main point is, if you use a kobject like you are, userspace tools
> can't "see" these directories and files easily, if at all.  Try it out
> with libudev yourself to verify it, the attributes will not show up as
> owned to that device like you need them to be.

I haven't used libudev exactly, but I realized this sort of thing,
when I was trying to catch UEvents on this device path.

I will give libudev a try..

> 
> So put them all in one directory, we can handle 10's of thousands of
> files quite easily, so 48 is trivial :)

Okay, Will make it this way :-)
Now I can see the implementation getting much simpler !!

Thank you Greg,
Durga
P.S: I should thank you for this file(samples/kobject/kobject-example.c) also,
from where I got how to get this implementation done :-)
--
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
Greg KH Dec. 20, 2012, 5:51 p.m. UTC | #7
On Thu, Dec 20, 2012 at 04:58:32PM +0000, R, Durgadoss wrote:
> > -----Original Message-----
> > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > Sent: Thursday, December 20, 2012 10:09 PM
> > To: R, Durgadoss
> > Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org;
> > hongbo.zhang@linaro.org; wni@nvidia.com
> > Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> > 
> > On Thu, Dec 20, 2012 at 04:25:32PM +0000, R, Durgadoss wrote:
> > >
> > > > -----Original Message-----
> > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > Sent: Thursday, December 20, 2012 9:42 PM
> > > > To: R, Durgadoss
> > > > Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > > hongbo.zhang@linaro.org; wni@nvidia.com
> > > > Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> > > >
> > > > On Thu, Dec 20, 2012 at 07:52:03AM +0000, R, Durgadoss wrote:
> > > > > > On Tue, Dec 18, 2012 at 02:59:33PM +0530, Durgadoss R wrote:
> > > > > > > This patch adds a thermal_trip directory under
> > > > > > > /sys/class/thermal/zoneX. This directory contains
> > > > > > > the trip point values for sensors bound to this
> > > > > > > zone.
> > > > > >
> > > > > > Eeek, you just broke userspace tools that now can no longer see
> > these
> > > > > > entries :(
> > > > > >
> > > > > > Why do you need to create a subdirectory?  As you found out, doing
> > so
> > > > > > isn't the easiest, right?  That is on purpose.
> > > > >
> > > > > Yes, I observed the complexity.
> > > > >
> > > > > >
> > > > > > I really wouldn't recommend doing this at all, please stick within the
> > > > > > 'struct device' framework here, don't create new kobjects and hang
> > sysfs
> > > > > > files off of them.
> > > > >
> > > > > But, we cannot put all _trip directly under ZoneX directory.
> > > >
> > > > Why not?  What is preventing this?
> > > >
> > > > > We can remove the thermal_trip directory, and put sensorY_trip under
> > > > > /sys/class/thermal/zoneX/.  But this sensorY_trip needs to be a
> > > > > directory which has four sysfs nodes named, active, passive, crit,
> > > > > hot.
> > > > >
> > > > > Rui, What do you think about this ?
> > > > >
> > > > > The only other way I see, is directly put
> > > > sensorY_trip_[active/passive/hot/crit]
> > > > > which will create way too many nodes, under
> > /sys/class/thermal/zoneX/.
> > > >
> > > > What is "too many"?  20000?  50000?  How many are we talking about
> > here?
> > >
> > > Not in 1000's though..
> > >
> > > > What is the limiting factor that is preventing this from all going into
> > > > one directory?
> > >
> > > We support a MAX of 12 sensors per zone today, which will lead to
> > > 12 * 4, 48 nodes under this directory named
> > > sensorY_trip_[active/passive/hot/crit], besides the other nodes.
> > 
> > That's fine, we can easily support that many files, have you tried this
> > already?
> 
> Yes, in fact, this is sort of what was the old implementation..
> although with different sysfs nodes.

What "old" implementation, one that is in-kernel?  Are you changing the
user interface here?

thanks,

greg k-h
--
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 Dec. 20, 2012, 6:12 p.m. UTC | #8
> -----Original Message-----
> From: Greg KH [mailto:gregkh@linuxfoundation.org]
> Sent: Thursday, December 20, 2012 11:21 PM
> To: R, Durgadoss
> Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org;
> hongbo.zhang@linaro.org; wni@nvidia.com
> Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> 
> On Thu, Dec 20, 2012 at 04:58:32PM +0000, R, Durgadoss wrote:
> > > -----Original Message-----
> > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > Sent: Thursday, December 20, 2012 10:09 PM
> > > To: R, Durgadoss
> > > Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-kernel@vger.kernel.org;
> > > hongbo.zhang@linaro.org; wni@nvidia.com
> > > Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> > >
> > > On Thu, Dec 20, 2012 at 04:25:32PM +0000, R, Durgadoss wrote:
> > > >
> > > > > -----Original Message-----
> > > > > From: Greg KH [mailto:gregkh@linuxfoundation.org]
> > > > > Sent: Thursday, December 20, 2012 9:42 PM
> > > > > To: R, Durgadoss
> > > > > Cc: Zhang, Rui; linux-pm@vger.kernel.org; linux-
> kernel@vger.kernel.org;
> > > > > hongbo.zhang@linaro.org; wni@nvidia.com
> > > > > Subject: Re: [PATCH 4/8] Thermal: Add Thermal_trip sysfs node
> > > > >
> > > > > On Thu, Dec 20, 2012 at 07:52:03AM +0000, R, Durgadoss wrote:
> > > > > > > On Tue, Dec 18, 2012 at 02:59:33PM +0530, Durgadoss R wrote:
> > > > > > > > This patch adds a thermal_trip directory under
> > > > > > > > /sys/class/thermal/zoneX. This directory contains
> > > > > > > > the trip point values for sensors bound to this
> > > > > > > > zone.
> > > > > > >
> > > > > > > Eeek, you just broke userspace tools that now can no longer see
> > > these
> > > > > > > entries :(
> > > > > > >
> > > > > > > Why do you need to create a subdirectory?  As you found out,
> doing
> > > so
> > > > > > > isn't the easiest, right?  That is on purpose.
> > > > > >
> > > > > > Yes, I observed the complexity.
> > > > > >
> > > > > > >
> > > > > > > I really wouldn't recommend doing this at all, please stick within
> the
> > > > > > > 'struct device' framework here, don't create new kobjects and
> hang
> > > sysfs
> > > > > > > files off of them.
> > > > > >
> > > > > > But, we cannot put all _trip directly under ZoneX directory.
> > > > >
> > > > > Why not?  What is preventing this?
> > > > >
> > > > > > We can remove the thermal_trip directory, and put sensorY_trip
> under
> > > > > > /sys/class/thermal/zoneX/.  But this sensorY_trip needs to be a
> > > > > > directory which has four sysfs nodes named, active, passive, crit,
> > > > > > hot.
> > > > > >
> > > > > > Rui, What do you think about this ?
> > > > > >
> > > > > > The only other way I see, is directly put
> > > > > sensorY_trip_[active/passive/hot/crit]
> > > > > > which will create way too many nodes, under
> > > /sys/class/thermal/zoneX/.
> > > > >
> > > > > What is "too many"?  20000?  50000?  How many are we talking about
> > > here?
> > > >
> > > > Not in 1000's though..
> > > >
> > > > > What is the limiting factor that is preventing this from all going into
> > > > > one directory?
> > > >
> > > > We support a MAX of 12 sensors per zone today, which will lead to
> > > > 12 * 4, 48 nodes under this directory named
> > > > sensorY_trip_[active/passive/hot/crit], besides the other nodes.
> > >
> > > That's fine, we can easily support that many files, have you tried this
> > > already?
> >
> > Yes, in fact, this is sort of what was the old implementation..
> > although with different sysfs nodes.
> 
> What "old" implementation, one that is in-kernel?  Are you changing the
> user interface here?

Sorry, I should have used better wordings ;(
[s/old/existing]
There are other sysfs nodes following the correct convention under
/sys/class/thermal/, which is what I was mentioning.

No, we are not changing the user interface, in these patches.

Thanks,
Durga
--
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
Hongbo Zhang Dec. 27, 2012, 7:01 a.m. UTC | #9
On 18 December 2012 17:29, Durgadoss R <durgadoss.r@intel.com> wrote:
> This patch adds a thermal_trip directory under
> /sys/class/thermal/zoneX. This directory contains
> the trip point values for sensors bound to this
> zone.
>
> Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
> ---
>  drivers/thermal/thermal_sys.c |  237 ++++++++++++++++++++++++++++++++++++++++-
>  include/linux/thermal.h       |   37 +++++++
>  2 files changed, 272 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index b39bf97..29ec073 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -448,6 +448,22 @@ static void thermal_zone_device_check(struct work_struct *work)
>         thermal_zone_device_update(tz);
>  }
>
> +static int get_sensor_indx_by_kobj(struct thermal_zone *tz, const char *name)
> +{
> +       int i, indx = -EINVAL;
> +
> +       mutex_lock(&sensor_list_lock);
> +       for (i = 0; i < tz->sensor_indx; i++) {
> +               if (!strnicmp(name, kobject_name(tz->kobj_trip[i]),
> +                       THERMAL_NAME_LENGTH)) {
> +                       indx = i;
> +                       break;
> +               }
> +       }
> +       mutex_unlock(&sensor_list_lock);
> +       return indx;
> +}
> +
>  static void remove_sensor_from_zone(struct thermal_zone *tz,
>                                 struct thermal_sensor *ts)
>  {
> @@ -459,9 +475,15 @@ static void remove_sensor_from_zone(struct thermal_zone *tz,
>
>         sysfs_remove_link(&tz->device.kobj, kobject_name(&ts->device.kobj));
>
> +       /* Delete this sensor's trip Kobject */
> +       kobject_del(tz->kobj_trip[indx]);
> +
>         /* Shift the entries in the tz->sensors array */
> -       for (j = indx; j < MAX_SENSORS_PER_ZONE - 1; j++)
> +       for (j = indx; j < MAX_SENSORS_PER_ZONE - 1; j++) {
>                 tz->sensors[j] = tz->sensors[j + 1];
> +               tz->sensor_trip[j] = tz->sensor_trip[j + 1];
> +               tz->kobj_trip[j] = tz->kobj_trip[j + 1];
> +       }
>
>         tz->sensor_indx--;
>  }
> @@ -875,6 +897,120 @@ policy_show(struct device *dev, struct device_attribute *devattr, char *buf)
>         return sprintf(buf, "%s\n", tz->governor->name);
>  }
>
> +static ssize_t
> +active_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
> +{
> +       int i, indx, ret = 0;
> +       struct thermal_zone *tz;
> +       struct device *dev;
> +
> +       /* In this function, for
> +        * /sys/class/thermal/zoneX/thermal_trip/sensorY:
> +        * attr                 points to sysfs node 'active'
> +        * kobj                 points to sensorY
> +        * kobj->parent         points to thermal_trip
> +        * kobj->parent->parent points to zoneX
> +        */
> +
> +       /* Get the zone pointer */
> +       dev = container_of(kobj->parent->parent, struct device, kobj);
> +       tz = to_zone(dev);
> +       if (!tz)
> +               return -EINVAL;
> +
> +       /*
> +        * We need this because in the sysfs tree, 'sensorY' is
> +        * not really the sensor pointer. It just has the name
> +        * 'sensorY'; whereas 'zoneX' is actually the zone pointer.
> +        * This means container_of(kobj, struct device, kobj) will not
> +        * provide the actual sensor pointer.
> +        */
> +       indx = get_sensor_indx_by_kobj(tz, kobject_name(kobj));
> +       if (indx < 0)
> +               return indx;
> +
> +       if (tz->sensor_trip[indx]->num_active_trips <= 0)
> +               return sprintf(buf, "<Not available>\n");
> +
> +       ret += sprintf(buf, "0x%x", tz->sensor_trip[indx]->active_trip_mask);
> +       for (i = 0; i < tz->sensor_trip[indx]->num_active_trips; i++) {
> +               ret += sprintf(buf + ret, " %d",
> +                       tz->sensor_trip[indx]->active_trips[i]);
> +       }
> +
> +       ret += sprintf(buf + ret, "\n");
> +       return ret;
> +}
> +
> +static ssize_t
> +ptrip_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
> +{
> +       int i, indx, ret = 0;
> +       struct thermal_zone *tz;
> +       struct device *dev;
> +
> +       /* Get the zone pointer */
> +       dev = container_of(kobj->parent->parent, struct device, kobj);
> +       tz = to_zone(dev);
> +       if (!tz)
> +               return -EINVAL;
> +
> +       indx = get_sensor_indx_by_kobj(tz, kobject_name(kobj));
> +       if (indx < 0)
> +               return indx;
> +
> +       if (tz->sensor_trip[indx]->num_passive_trips <= 0)
> +               return sprintf(buf, "<Not available>\n");
> +
> +       for (i = 0; i < tz->sensor_trip[indx]->num_passive_trips; i++) {
> +               ret += sprintf(buf + ret, "%d ",
> +                       tz->sensor_trip[indx]->passive_trips[i]);
> +       }
> +
> +       ret += sprintf(buf + ret, "\n");
> +       return ret;
> +}
> +
> +static ssize_t
> +hot_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
> +{
> +       int indx;
> +       struct thermal_zone *tz;
> +       struct device *dev;
> +
> +       /* Get the zone pointer */
> +       dev = container_of(kobj->parent->parent, struct device, kobj);
> +       tz = to_zone(dev);
> +       if (!tz)
> +               return -EINVAL;
> +
> +       indx = get_sensor_indx_by_kobj(tz, kobject_name(kobj));
> +       if (indx < 0)
> +               return indx;
> +
> +       return sprintf(buf, "%d\n", tz->sensor_trip[indx]->hot);
> +}
> +
> +static ssize_t
> +critical_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
> +{
> +       int indx;
> +       struct thermal_zone *tz;
> +       struct device *dev;
> +
> +       /* Get the zone pointer */
> +       dev = container_of(kobj->parent->parent, struct device, kobj);
> +       tz = to_zone(dev);
> +       if (!tz)
> +               return -EINVAL;
> +
> +       indx = get_sensor_indx_by_kobj(tz, kobject_name(kobj));
> +       if (indx < 0)
> +               return indx;
> +
> +       return sprintf(buf, "%d\n", tz->sensor_trip[indx]->crit);
> +}
> +
>  static DEVICE_ATTR(type, 0444, type_show, NULL);
>  static DEVICE_ATTR(temp, 0444, temp_show, NULL);
>  static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
> @@ -885,7 +1021,27 @@ static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show, policy_store);
>  static DEVICE_ATTR(sensor_name, 0444, sensor_name_show, NULL);
>  static DEVICE_ATTR(temp_input, 0444, sensor_temp_show, NULL);
>
> -static DEVICE_ATTR(zone_name, 0444, zone_name_show, NULL);
> +/* Thermal zone attributes */
> +static DEVICE_ATTR(zone_name, S_IRUGO, zone_name_show, NULL);
> +
> +/* Thermal trip attributes */
> +static struct kobj_attribute active_attr = __ATTR_RO(active);
> +/* TODO: rename this to passive while removing old code */
> +static struct kobj_attribute passive_attr = __ATTR_RO(ptrip);
> +static struct kobj_attribute hot_attr = __ATTR_RO(hot);
> +static struct kobj_attribute crit_attr = __ATTR_RO(critical);
> +
> +static struct attribute *trip_attrs[] = {
> +                       &active_attr.attr,
> +                       &passive_attr.attr,
> +                       &hot_attr.attr,
> +                       &crit_attr.attr,
> +                       NULL,
> +                       };
> +
> +static struct attribute_group trip_attr_group = {
> +                       .attrs = trip_attrs,
> +                       };
>
>  /* sys I/F for cooling device */
>  #define to_cooling_device(_dev)        \
> @@ -1770,12 +1926,19 @@ struct thermal_zone *create_thermal_zone(const char *name, void *devdata)
>         if (ret)
>                 goto exit_unregister;
>
> +       tz->kobj_thermal_trip = kobject_create_and_add("thermal_trip",
> +                                       &tz->device.kobj);
> +       if (!tz->kobj_thermal_trip)
> +               goto exit_name;
> +
>         /* Add this zone to the global list of thermal zones */
>         mutex_lock(&zone_list_lock);
>         list_add_tail(&tz->node, &thermal_zone_list);
>         mutex_unlock(&zone_list_lock);
>         return tz;
>
> +exit_name:
> +       device_remove_file(&tz->device, &dev_attr_zone_name);
>  exit_unregister:
>         device_unregister(&tz->device);
>  exit_idr:
> @@ -1789,6 +1952,7 @@ EXPORT_SYMBOL(create_thermal_zone);
>  void remove_thermal_zone(struct thermal_zone *tz)
>  {
>         struct thermal_zone *pos, *next;
> +       int i;
>         bool found = false;
>
>         if (!tz)
> @@ -1809,6 +1973,33 @@ void remove_thermal_zone(struct thermal_zone *tz)
>
>         device_remove_file(&tz->device, &dev_attr_zone_name);
>
> +       /* Just for ease of usage */
> +       i = tz->sensor_indx;
> +
> +       while (--i >= 0) {
> +               /* Remove /sys/class/thermal/zoneX/sensorY */
> +               sysfs_remove_link(&tz->device.kobj,
> +                               kobject_name(&tz->sensors[i]->device.kobj));
> +
> +               /* Remove /sys/class/thermal/zoneX/thermal_trip/sensorY */
> +               if (tz->kobj_trip[i]) {
> +                       sysfs_remove_group(tz->kobj_trip[i], &trip_attr_group);
> +                       kobject_del(tz->kobj_trip[i]);
> +               }
> +       }
> +
> +       /* Remove /sys/class/thermal/zoneX/thermal_trip */
> +       kobject_del(tz->kobj_thermal_trip);
> +
> +       /* Release the cdevs attached to this zone */
> +       i = tz->cdev_indx;
> +
> +       while (--i >= 0) {
> +               /* Remove /sys/class/thermal/zoneX/cooling_deviceY */
> +               sysfs_remove_link(&tz->device.kobj,
> +                               kobject_name(&tz->cdevs[i]->device.kobj));
> +       }
> +
>         release_idr(&thermal_zone_idr, &thermal_idr_lock, tz->id);
>         idr_destroy(&tz->idr);
>
> @@ -1920,6 +2111,48 @@ exit_zone:
>  }
>  EXPORT_SYMBOL(add_cdev_to_zone);
>
> +int add_sensor_trip_info(struct thermal_zone *tz, struct thermal_sensor *ts,
> +                       struct thermal_trip_point *trip)
> +{
> +       int indx, ret = -EINVAL;
> +
> +       if (!tz || !ts || !trip)
> +               return ret;
> +
> +       mutex_lock(&zone_list_lock);
> +
> +       GET_INDEX(tz, ts, indx, sensor);
> +       if (indx < 0)
> +               goto exit_indx;
> +
> +       /* Create kobj for /sys/class/thermal/zoneX/thermal_trip/sensorY */
> +       tz->kobj_trip[indx] = kobject_create_and_add(
> +                                       kobject_name(&ts->device.kobj),
> +                                       tz->kobj_thermal_trip);
> +       if (!tz->kobj_trip[indx]) {
> +               ret = -ENOMEM;
> +               goto exit_indx;
> +       }
> +
> +       ret = sysfs_create_group(tz->kobj_trip[indx], &trip_attr_group);
> +       if (ret) {
> +               dev_err(&tz->device, "sysfs_create_group failed:%d\n", ret);
> +               goto exit_kobj;
> +       }
> +
> +       tz->sensor_trip[indx] = trip;
> +       mutex_unlock(&zone_list_lock);
> +       return 0;
> +
> +exit_kobj:
> +       kobject_del(tz->kobj_trip[indx]);
> +       tz->kobj_trip[indx] = NULL;
> +exit_indx:
> +       mutex_unlock(&zone_list_lock);
> +       return ret;
> +}
> +EXPORT_SYMBOL(add_sensor_trip_info);
> +
>  /**
>   * thermal_sensor_register - register a new thermal sensor
>   * @name:      name of the thermal sensor
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index c4e45c7..8372f05 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -158,6 +158,30 @@ struct thermal_attr {
>         char name[THERMAL_NAME_LENGTH];
>  };
>
> +/*
> + * This structure defines the trip points for a sensor.
> + * The actual values for these trip points come from
> + * platform characterization. The thermal governors
> + * (either kernel or user space) may take appropriate
> + * actions when the sensors reach these trip points.
> + * See Documentation/thermal/sysfs-api2.txt for more details.
> + *
> + * As of now, For a particular sensor, we support:
> + * a) 1 hot trip point
> + * b) 1 critical trip point
> + * c) 'n' passive trip points
> + * d) 'm' active trip points
> + */
Durgadoss,
Currently the newly introduced governors don't treat passive/active
differently, what is the idea about this when you rebase governors to
new thermal zone/sensors? handle the passive/active differently or
eliminate the difference?

> +struct thermal_trip_point {
> +       int hot;
> +       int crit;
> +       int num_passive_trips;
> +       int *passive_trips;
> +       int num_active_trips;
> +       int *active_trips;
> +       int active_trip_mask;
> +};
> +
>  struct thermal_sensor {
>         char name[THERMAL_NAME_LENGTH];
>         int id;
> @@ -215,6 +239,16 @@ struct thermal_zone {
>         /* cdev level information */
>         int cdev_indx; /* index into 'cdevs' array */
>         struct thermal_cooling_device *cdevs[MAX_CDEVS_PER_ZONE];
> +
> +       /*
> +        * Thermal sensors trip information:
> +        * kobj_thermal_trip: /sys/class/thermal/zoneX/thermal_trip
> +        * kobj_trip: /sys/class/thermal/zoneX/thermal_trip/sensorY
> +        * sensor_trip: trip point information for each sensor
> +        */
> +       struct kobject *kobj_thermal_trip;
> +       struct kobject *kobj_trip[MAX_SENSORS_PER_ZONE];
> +       struct thermal_trip_point *sensor_trip[MAX_SENSORS_PER_ZONE];
>  };
>
>  /* Structure that holds thermal governor information */
> @@ -295,6 +329,9 @@ int add_sensor_to_zone(struct thermal_zone *, struct thermal_sensor *);
>
>  int add_cdev_to_zone(struct thermal_zone *, struct thermal_cooling_device *);
>
> +int add_sensor_trip_info(struct thermal_zone *, struct thermal_sensor *,
> +                       struct thermal_trip_point *);
> +
>  #ifdef CONFIG_NET
>  extern int thermal_generate_netlink_event(u32 orig, enum events event);
>  #else
> --
> 1.7.9.5
>
--
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/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index b39bf97..29ec073 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -448,6 +448,22 @@  static void thermal_zone_device_check(struct work_struct *work)
 	thermal_zone_device_update(tz);
 }
 
+static int get_sensor_indx_by_kobj(struct thermal_zone *tz, const char *name)
+{
+	int i, indx = -EINVAL;
+
+	mutex_lock(&sensor_list_lock);
+	for (i = 0; i < tz->sensor_indx; i++) {
+		if (!strnicmp(name, kobject_name(tz->kobj_trip[i]),
+			THERMAL_NAME_LENGTH)) {
+			indx = i;
+			break;
+		}
+	}
+	mutex_unlock(&sensor_list_lock);
+	return indx;
+}
+
 static void remove_sensor_from_zone(struct thermal_zone *tz,
 				struct thermal_sensor *ts)
 {
@@ -459,9 +475,15 @@  static void remove_sensor_from_zone(struct thermal_zone *tz,
 
 	sysfs_remove_link(&tz->device.kobj, kobject_name(&ts->device.kobj));
 
+	/* Delete this sensor's trip Kobject */
+	kobject_del(tz->kobj_trip[indx]);
+
 	/* Shift the entries in the tz->sensors array */
-	for (j = indx; j < MAX_SENSORS_PER_ZONE - 1; j++)
+	for (j = indx; j < MAX_SENSORS_PER_ZONE - 1; j++) {
 		tz->sensors[j] = tz->sensors[j + 1];
+		tz->sensor_trip[j] = tz->sensor_trip[j + 1];
+		tz->kobj_trip[j] = tz->kobj_trip[j + 1];
+	}
 
 	tz->sensor_indx--;
 }
@@ -875,6 +897,120 @@  policy_show(struct device *dev, struct device_attribute *devattr, char *buf)
 	return sprintf(buf, "%s\n", tz->governor->name);
 }
 
+static ssize_t
+active_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	int i, indx, ret = 0;
+	struct thermal_zone *tz;
+	struct device *dev;
+
+	/* In this function, for
+	 * /sys/class/thermal/zoneX/thermal_trip/sensorY:
+	 * attr			points to sysfs node 'active'
+	 * kobj			points to sensorY
+	 * kobj->parent		points to thermal_trip
+	 * kobj->parent->parent	points to zoneX
+	 */
+
+	/* Get the zone pointer */
+	dev = container_of(kobj->parent->parent, struct device, kobj);
+	tz = to_zone(dev);
+	if (!tz)
+		return -EINVAL;
+
+	/*
+	 * We need this because in the sysfs tree, 'sensorY' is
+	 * not really the sensor pointer. It just has the name
+	 * 'sensorY'; whereas 'zoneX' is actually the zone pointer.
+	 * This means container_of(kobj, struct device, kobj) will not
+	 * provide the actual sensor pointer.
+	 */
+	indx = get_sensor_indx_by_kobj(tz, kobject_name(kobj));
+	if (indx < 0)
+		return indx;
+
+	if (tz->sensor_trip[indx]->num_active_trips <= 0)
+		return sprintf(buf, "<Not available>\n");
+
+	ret += sprintf(buf, "0x%x", tz->sensor_trip[indx]->active_trip_mask);
+	for (i = 0; i < tz->sensor_trip[indx]->num_active_trips; i++) {
+		ret += sprintf(buf + ret, " %d",
+			tz->sensor_trip[indx]->active_trips[i]);
+	}
+
+	ret += sprintf(buf + ret, "\n");
+	return ret;
+}
+
+static ssize_t
+ptrip_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	int i, indx, ret = 0;
+	struct thermal_zone *tz;
+	struct device *dev;
+
+	/* Get the zone pointer */
+	dev = container_of(kobj->parent->parent, struct device, kobj);
+	tz = to_zone(dev);
+	if (!tz)
+		return -EINVAL;
+
+	indx = get_sensor_indx_by_kobj(tz, kobject_name(kobj));
+	if (indx < 0)
+		return indx;
+
+	if (tz->sensor_trip[indx]->num_passive_trips <= 0)
+		return sprintf(buf, "<Not available>\n");
+
+	for (i = 0; i < tz->sensor_trip[indx]->num_passive_trips; i++) {
+		ret += sprintf(buf + ret, "%d ",
+			tz->sensor_trip[indx]->passive_trips[i]);
+	}
+
+	ret += sprintf(buf + ret, "\n");
+	return ret;
+}
+
+static ssize_t
+hot_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	int indx;
+	struct thermal_zone *tz;
+	struct device *dev;
+
+	/* Get the zone pointer */
+	dev = container_of(kobj->parent->parent, struct device, kobj);
+	tz = to_zone(dev);
+	if (!tz)
+		return -EINVAL;
+
+	indx = get_sensor_indx_by_kobj(tz, kobject_name(kobj));
+	if (indx < 0)
+		return indx;
+
+	return sprintf(buf, "%d\n", tz->sensor_trip[indx]->hot);
+}
+
+static ssize_t
+critical_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	int indx;
+	struct thermal_zone *tz;
+	struct device *dev;
+
+	/* Get the zone pointer */
+	dev = container_of(kobj->parent->parent, struct device, kobj);
+	tz = to_zone(dev);
+	if (!tz)
+		return -EINVAL;
+
+	indx = get_sensor_indx_by_kobj(tz, kobject_name(kobj));
+	if (indx < 0)
+		return indx;
+
+	return sprintf(buf, "%d\n", tz->sensor_trip[indx]->crit);
+}
+
 static DEVICE_ATTR(type, 0444, type_show, NULL);
 static DEVICE_ATTR(temp, 0444, temp_show, NULL);
 static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
@@ -885,7 +1021,27 @@  static DEVICE_ATTR(policy, S_IRUGO | S_IWUSR, policy_show, policy_store);
 static DEVICE_ATTR(sensor_name, 0444, sensor_name_show, NULL);
 static DEVICE_ATTR(temp_input, 0444, sensor_temp_show, NULL);
 
-static DEVICE_ATTR(zone_name, 0444, zone_name_show, NULL);
+/* Thermal zone attributes */
+static DEVICE_ATTR(zone_name, S_IRUGO, zone_name_show, NULL);
+
+/* Thermal trip attributes */
+static struct kobj_attribute active_attr = __ATTR_RO(active);
+/* TODO: rename this to passive while removing old code */
+static struct kobj_attribute passive_attr = __ATTR_RO(ptrip);
+static struct kobj_attribute hot_attr = __ATTR_RO(hot);
+static struct kobj_attribute crit_attr = __ATTR_RO(critical);
+
+static struct attribute *trip_attrs[] = {
+			&active_attr.attr,
+			&passive_attr.attr,
+			&hot_attr.attr,
+			&crit_attr.attr,
+			NULL,
+			};
+
+static struct attribute_group trip_attr_group = {
+			.attrs = trip_attrs,
+			};
 
 /* sys I/F for cooling device */
 #define to_cooling_device(_dev)	\
@@ -1770,12 +1926,19 @@  struct thermal_zone *create_thermal_zone(const char *name, void *devdata)
 	if (ret)
 		goto exit_unregister;
 
+	tz->kobj_thermal_trip = kobject_create_and_add("thermal_trip",
+					&tz->device.kobj);
+	if (!tz->kobj_thermal_trip)
+		goto exit_name;
+
 	/* Add this zone to the global list of thermal zones */
 	mutex_lock(&zone_list_lock);
 	list_add_tail(&tz->node, &thermal_zone_list);
 	mutex_unlock(&zone_list_lock);
 	return tz;
 
+exit_name:
+	device_remove_file(&tz->device, &dev_attr_zone_name);
 exit_unregister:
 	device_unregister(&tz->device);
 exit_idr:
@@ -1789,6 +1952,7 @@  EXPORT_SYMBOL(create_thermal_zone);
 void remove_thermal_zone(struct thermal_zone *tz)
 {
 	struct thermal_zone *pos, *next;
+	int i;
 	bool found = false;
 
 	if (!tz)
@@ -1809,6 +1973,33 @@  void remove_thermal_zone(struct thermal_zone *tz)
 
 	device_remove_file(&tz->device, &dev_attr_zone_name);
 
+	/* Just for ease of usage */
+	i = tz->sensor_indx;
+
+	while (--i >= 0) {
+		/* Remove /sys/class/thermal/zoneX/sensorY */
+		sysfs_remove_link(&tz->device.kobj,
+				kobject_name(&tz->sensors[i]->device.kobj));
+
+		/* Remove /sys/class/thermal/zoneX/thermal_trip/sensorY */
+		if (tz->kobj_trip[i]) {
+			sysfs_remove_group(tz->kobj_trip[i], &trip_attr_group);
+			kobject_del(tz->kobj_trip[i]);
+		}
+	}
+
+	/* Remove /sys/class/thermal/zoneX/thermal_trip */
+	kobject_del(tz->kobj_thermal_trip);
+
+	/* Release the cdevs attached to this zone */
+	i = tz->cdev_indx;
+
+	while (--i >= 0) {
+		/* Remove /sys/class/thermal/zoneX/cooling_deviceY */
+		sysfs_remove_link(&tz->device.kobj,
+				kobject_name(&tz->cdevs[i]->device.kobj));
+	}
+
 	release_idr(&thermal_zone_idr, &thermal_idr_lock, tz->id);
 	idr_destroy(&tz->idr);
 
@@ -1920,6 +2111,48 @@  exit_zone:
 }
 EXPORT_SYMBOL(add_cdev_to_zone);
 
+int add_sensor_trip_info(struct thermal_zone *tz, struct thermal_sensor *ts,
+			struct thermal_trip_point *trip)
+{
+	int indx, ret = -EINVAL;
+
+	if (!tz || !ts || !trip)
+		return ret;
+
+	mutex_lock(&zone_list_lock);
+
+	GET_INDEX(tz, ts, indx, sensor);
+	if (indx < 0)
+		goto exit_indx;
+
+	/* Create kobj for /sys/class/thermal/zoneX/thermal_trip/sensorY */
+	tz->kobj_trip[indx] = kobject_create_and_add(
+					kobject_name(&ts->device.kobj),
+					tz->kobj_thermal_trip);
+	if (!tz->kobj_trip[indx]) {
+		ret = -ENOMEM;
+		goto exit_indx;
+	}
+
+	ret = sysfs_create_group(tz->kobj_trip[indx], &trip_attr_group);
+	if (ret) {
+		dev_err(&tz->device, "sysfs_create_group failed:%d\n", ret);
+		goto exit_kobj;
+	}
+
+	tz->sensor_trip[indx] = trip;
+	mutex_unlock(&zone_list_lock);
+	return 0;
+
+exit_kobj:
+	kobject_del(tz->kobj_trip[indx]);
+	tz->kobj_trip[indx] = NULL;
+exit_indx:
+	mutex_unlock(&zone_list_lock);
+	return ret;
+}
+EXPORT_SYMBOL(add_sensor_trip_info);
+
 /**
  * thermal_sensor_register - register a new thermal sensor
  * @name:	name of the thermal sensor
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index c4e45c7..8372f05 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -158,6 +158,30 @@  struct thermal_attr {
 	char name[THERMAL_NAME_LENGTH];
 };
 
+/*
+ * This structure defines the trip points for a sensor.
+ * The actual values for these trip points come from
+ * platform characterization. The thermal governors
+ * (either kernel or user space) may take appropriate
+ * actions when the sensors reach these trip points.
+ * See Documentation/thermal/sysfs-api2.txt for more details.
+ *
+ * As of now, For a particular sensor, we support:
+ * a) 1 hot trip point
+ * b) 1 critical trip point
+ * c) 'n' passive trip points
+ * d) 'm' active trip points
+ */
+struct thermal_trip_point {
+	int hot;
+	int crit;
+	int num_passive_trips;
+	int *passive_trips;
+	int num_active_trips;
+	int *active_trips;
+	int active_trip_mask;
+};
+
 struct thermal_sensor {
 	char name[THERMAL_NAME_LENGTH];
 	int id;
@@ -215,6 +239,16 @@  struct thermal_zone {
 	/* cdev level information */
 	int cdev_indx; /* index into 'cdevs' array */
 	struct thermal_cooling_device *cdevs[MAX_CDEVS_PER_ZONE];
+
+	/*
+	 * Thermal sensors trip information:
+	 * kobj_thermal_trip: /sys/class/thermal/zoneX/thermal_trip
+	 * kobj_trip: /sys/class/thermal/zoneX/thermal_trip/sensorY
+	 * sensor_trip: trip point information for each sensor
+	 */
+	struct kobject *kobj_thermal_trip;
+	struct kobject *kobj_trip[MAX_SENSORS_PER_ZONE];
+	struct thermal_trip_point *sensor_trip[MAX_SENSORS_PER_ZONE];
 };
 
 /* Structure that holds thermal governor information */
@@ -295,6 +329,9 @@  int add_sensor_to_zone(struct thermal_zone *, struct thermal_sensor *);
 
 int add_cdev_to_zone(struct thermal_zone *, struct thermal_cooling_device *);
 
+int add_sensor_trip_info(struct thermal_zone *, struct thermal_sensor *,
+			struct thermal_trip_point *);
+
 #ifdef CONFIG_NET
 extern int thermal_generate_netlink_event(u32 orig, enum events event);
 #else