From patchwork Tue Feb 1 06:56:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: durgadoss.r@intel.com X-Patchwork-Id: 521981 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p117dIij012070 for ; Tue, 1 Feb 2011 07:39:30 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751288Ab1BAG43 (ORCPT ); Tue, 1 Feb 2011 01:56:29 -0500 Received: from mga02.intel.com ([134.134.136.20]:60940 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750859Ab1BAG42 convert rfc822-to-8bit (ORCPT ); Tue, 1 Feb 2011 01:56:28 -0500 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 31 Jan 2011 22:56:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.60,408,1291622400"; d="scan'208";a="702674814" Received: from pgsmsx603.gar.corp.intel.com ([10.221.43.87]) by orsmga001.jf.intel.com with ESMTP; 31 Jan 2011 22:56:26 -0800 Received: from bgsmsx502.gar.corp.intel.com (10.223.4.248) by pgsmsx603.gar.corp.intel.com (10.221.43.87) with Microsoft SMTP Server (TLS) id 8.2.254.0; Tue, 1 Feb 2011 14:56:21 +0800 Received: from bgsmsx502.gar.corp.intel.com ([10.223.4.248]) by bgsmsx502.gar.corp.intel.com ([10.223.4.248]) with mapi; Tue, 1 Feb 2011 12:26:20 +0530 From: "R, Durgadoss" To: "Zhang, Rui" , Thomas Renninger , Henrique de Moraes Holschuh , Len Brown CC: "linux-acpi@vger.kernel.org" Date: Tue, 1 Feb 2011 12:26:19 +0530 Subject: Patch[1/1]:Adding_Netlink_Support_to_ThermalFramework Thread-Topic: Patch[1/1]:Adding_Netlink_Support_to_ThermalFramework Thread-Index: AcvB3SD4vLCqDve2TW+k2QVdi1di5g== Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 01 Feb 2011 07:39:30 +0000 (UTC) diff --git a/Documentation/thermal/thermal_netlink.txt b/Documentation/thermal/thermal_netlink.txt new file mode 100644 index 0000000..92e0900 --- /dev/null +++ b/Documentation/thermal/thermal_netlink.txt @@ -0,0 +1,45 @@ +Event Notification Support +========================== + +0. Introduction +--------------- +The generic thermal sysfs provides a set of interfaces for thermal zone +devices (sensors) and thermal cooling devices (fan, processor...) to register +with the thermal management solution and to be a part of it. + +The framework includes a simple notification mechanism, in the form of a +netlink event. Netlink socket initialization is done during the _init_ +of the framework. Drivers which intend to use the notification mechanism +must register with the thermal framework. Once registered, they will be +assigned an unique id. They can call thermal_netlink_event() to send +netlink events. + +This thermal_netlink_event function takes two arguments: + 1.Originator id + 2.Event Type + +The originator should be one of the devices added in the thermal_devices +enum in the thermal.h. Likewise, the list of events have also been added +as an enum in thermal.h. + +1. Events: +---------- +The following are the list of events that the notification mechanism supports: +1.THERMAL_WARN +2.THERMAL_EMERG +3.THERMAL_CRIT +4.THERMAL_CT_AUX0 + The coretemp module supports two thresholds for thermal management, + through IA32_THERM_INTERRUPT register. One of these thresholds is + lower than the current temperature and the other higher. When the CPU + temperature sensor crosses the programmed lower threshold, THERMAL_CT_AUX0 + event is generated. +5.THERMAL_CT_AUX1 + This event is generated when the CPU temperature Sensor crosses the + programmed higher threshold limit. +6.THERMAL_PT_AUX0 + This is similar to the THERMAL_CT_AUX0, except that it is generated by + the package temperature sensor. +7.THERMAL_PT_AUX1 + This is similar to the THERMAL_CT_AUX1, except that it is generated by + the package temperature sensor. diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index bf7c687..7085794 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -22,3 +22,10 @@ config THERMAL_HWMON requires a 2.10.7/3.0.2 or later lm-sensors userspace. Say Y if your user-space is new enough. + +config THERMAL_NETLINK + tristate "Netlink Interface to Notify Thermal Events" + depends on THERMAL && NET + help + Say Y here, if you want the thermal events to be notified via + netlink events. diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 31108a0..9ee8380 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_THERMAL) += thermal_sys.o +obj-$(CONFIG_THERMAL_NETLINK) += thermal_netlink.o diff --git a/drivers/thermal/thermal_netlink.c b/drivers/thermal/thermal_netlink.c new file mode 100644 index 0000000..1678a13 --- /dev/null +++ b/drivers/thermal/thermal_netlink.c @@ -0,0 +1,95 @@ +#include +#include + +static unsigned int thermal_event_seqnum; + +static struct genl_family thermal_event_genl_family = { + .id = GENL_ID_GENERATE, + .name = THERMAL_GENL_FAMILY_NAME, + .version = THERMAL_GENL_VERSION, + .maxattr = THERMAL_GENL_ATTR_MAX, +}; + +static struct genl_multicast_group thermal_event_mcgrp = { + .name = THERMAL_GENL_MCAST_GROUP_NAME, +}; + +int thermal_netlink_event(enum thermal_devices orig, enum thermal_events event) +{ + struct sk_buff *skb; + struct nlattr *attr; + struct thermal_genl_event *thermal_event; + void *msg_header; + int size; + int result; + + /* allocate memory */ + size = nla_total_size(sizeof(struct thermal_genl_event)) + \ + nla_total_size(0); + + skb = genlmsg_new(size, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + + /* add the genetlink message header */ + msg_header = genlmsg_put(skb, 0, thermal_event_seqnum++, + &thermal_event_genl_family, 0, + THERMAL_GENL_CMD_EVENT); + if (!msg_header) { + nlmsg_free(skb); + return -ENOMEM; + } + + /* fill the data */ + attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, \ + sizeof(struct thermal_genl_event)); + + if (!attr) { + nlmsg_free(skb); + return -EINVAL; + } + + thermal_event = nla_data(attr); + if (!thermal_event) { + nlmsg_free(skb); + return -EINVAL; + } + + memset(thermal_event, 0, sizeof(struct thermal_genl_event)); + + thermal_event->device = orig; + thermal_event->event = event; + + /* send multicast genetlink message */ + result = genlmsg_end(skb, msg_header); + if (result < 0) { + nlmsg_free(skb); + return result; + } + + return genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC); +} + +static int __init thermal_netlink_init(void) +{ + int result; + + result = genl_register_family(&thermal_event_genl_family); + if (result) + return result; + + result = genl_register_mc_group(&thermal_event_genl_family, + &thermal_event_mcgrp); + if (result) + genl_unregister_family(&thermal_event_genl_family); + return result; +} + +static void __exit thermal_netlink_exit(void) +{ + genl_unregister_family(&thermal_event_genl_family); +} + +subsys_initcall(thermal_netlink_init); +module_exit(thermal_netlink_exit); + diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 1de8b9e..bd79d18 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -147,4 +147,58 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *, void *, *); void thermal_cooling_device_unregister(struct thermal_cooling_device *); +#ifdef CONFIG_NET + +/* Add Netlink Notification Support Elements */ +#define THERMAL_GENL_FAMILY_NAME "thermal_event" +#define THERMAL_GENL_VERSION 0x01 +#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_group" + +enum thermal_events { + /* generic thermal events */ + THERMAL_WARN, + THERMAL_EMERG, + THERMAL_CRIT, + /* coretemp thermal events */ + THERMAL_CT_AUX0, + THERMAL_CT_AUX1, + /* pkgtemp thermal events */ + THERMAL_PT_AUX0, + THERMAL_PT_AUX1, + /* Add other events, if any */ +}; + +enum thermal_devices { + /* For multi-core CPUs */ + THERMAL_CPU_CORE0 = 0, + THERMAL_GPU = 32, + THERMAL_BATTERY, + /* Add other devices, if any */ +}; + +struct thermal_genl_event { + enum thermal_devices device; + enum thermal_events event; +}; + +/* attributes of thermal_genl_family */ +enum { + THERMAL_GENL_ATTR_UNSPEC, + THERMAL_GENL_ATTR_EVENT, + __THERMAL_GENL_ATTR_MAX, +}; +#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1) + +/* commands supported by the thermal_genl_family */ +enum { + THERMAL_GENL_CMD_UNSPEC, + THERMAL_GENL_CMD_EVENT, + __THERMAL_GENL_CMD_MAX, +}; +#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1) + +int thermal_netlink_event(enum thermal_devices, enum thermal_events); + +#endif /* CONFIG_NET */ + #endif /* __THERMAL_H__ */