diff options
Diffstat (limited to 'meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-thermal-emc1403-driver.patch')
-rw-r--r-- | meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-thermal-emc1403-driver.patch | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-thermal-emc1403-driver.patch b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-thermal-emc1403-driver.patch new file mode 100644 index 000000000..667db0207 --- /dev/null +++ b/meta/recipes-kernel/linux/linux-netbook-2.6.33.2/linux-2.6.34-moorestown-thermal-emc1403-driver.patch @@ -0,0 +1,285 @@ +From e11104658a3b8eabbb4eb74b38645a4f114b745d Mon Sep 17 00:00:00 2001 +From: Kalhan Trisal <kalhan.trisal@intel.com> +Date: Fri, 4 Sep 2009 18:10:52 -0400 +Subject: [PATCH 075/104] Thermal patch for emc1403 driver + +Thermal driver will handle event generation even if alert handler is called multiple time due to GPE->GPIO changes. The IRQ has become now shared and the handler will be called on every event as shared with other devices also. + +Signed-off-by: Kalhan Trisal <kalhan.trisal@intel.com> +--- + drivers/hwmon/Kconfig | 2 +- + drivers/hwmon/emc1403.c | 128 +++++++++++++++++++++-------------------------- + 2 files changed, 58 insertions(+), 72 deletions(-) + +diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig +index 55637c3..c8fefbc 100644 +--- a/drivers/hwmon/Kconfig ++++ b/drivers/hwmon/Kconfig +@@ -55,7 +55,7 @@ config SENSORS_LIS331DL + + config SENSORS_EMC1403 + tristate "SMSC EMC1403 Thermal" +- depends on I2C_MRST && GPE && GPIO_MAX7315 && MSTWN_POWER_MGMT ++ depends on I2C + help + If you say yes here you get support for the SMSC Devices + EMC1403 temperature monitoring chip. +diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c +index 45cf5d0..75e3b15 100644 +--- a/drivers/hwmon/emc1403.c ++++ b/drivers/hwmon/emc1403.c +@@ -44,8 +44,7 @@ MODULE_LICENSE("GPL v2"); + /* To support the interrupt mechanism for moorestown interrupt flag is added + * If the flag is not enabled it support generic emc1403 chip */ + +-#if defined(CONFIG_GPIO_LNWPMIC) && defined(CONFIG_GPIO_MAX7315) \ +- && defined(CONFIG_MSTWN_POWER_MGMT) ++#if defined(CONFIG_GPIO_LANGWELL_PMIC) && defined(CONFIG_MSTWN_POWER_MGMT) + #define MOORESTOWN_INTERRUPT_ENABLE + #endif + +@@ -335,40 +334,6 @@ static ssize_t store_power_state(struct device *dev, + return count; + } + +-static ssize_t show_mode(struct device *dev, +- struct device_attribute *attr, char *buf) +-{ +- struct i2c_client *client = to_i2c_client(dev); +- int ret_val; +- +- ret_val = i2c_read_current_data(client, 0x03); +- ret_val = ret_val & 0x80; +- if (ret_val == 0x80) +- ret_val = 1; +- return sprintf(buf, "%x", ret_val); +-} +- +-static ssize_t store_mode(struct device *dev, +- struct device_attribute *attr, const char *buf, size_t count) +-{ +- struct i2c_client *client = to_i2c_client(dev); +- unsigned long val = 0; +- char curr_val; +- +- if (strict_strtoul(buf, 10, &val)) +- return -EINVAL; +- +- curr_val = i2c_read_current_data(client, 0x03); +- if (val == INTERRUPT_MODE_ENABLE) +- curr_val = curr_val & 0x7F; +- else if (val == INTERRUPT_MODE_DISABLE) +- curr_val = curr_val | 0x80; +- else +- return -EINVAL; +- i2c_write_current_data(client, 0x03, curr_val); +- return count; +-} +- + static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, + show_temp_auto_offset, store_temp_auto_offset, 0, 1); + static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, +@@ -398,7 +363,6 @@ static DEVICE_ATTR(status, S_IRUGO, show_status_reg, NULL); + + static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, + show_power_state, store_power_state); +-static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, show_mode, store_mode); + + static struct attribute *mid_att_thermal[] = { + &sensor_dev_attr_temp1_min.dev_attr.attr, +@@ -416,7 +380,6 @@ static struct attribute *mid_att_thermal[] = { + &dev_attr_hyster.attr, + &dev_attr_status.attr, + &dev_attr_power_state.attr, +- &dev_attr_mode.attr, + NULL + }; + +@@ -449,102 +412,124 @@ static irqreturn_t alert_interrupt_handler(int id, void *dev) + return IRQ_HANDLED; + } + ++ + /* when the device raise the interrupt we mask the interrupt + * bit for that device as the status register is R-C + * so that till thermal governor doesnot take action we need + * not to send continuous events */ + + static int interrupt_status(struct i2c_client *client, u8 diode_reg_val, +- u8 *status, u8 event) ++ u8 *mask_status, u8 event, u8 *status) + { +- u8 crit_st = 0, set_mask = 0; ++ u8 crit_st = 0, set_mask = 0, event_status = 0; + + set_mask = i2c_read_current_data(client, 0x1F); + if (diode_reg_val & THM_CHAN_TEMP[3]) { +- set_mask = (set_mask | 0x02); +- crit_st = (crit_st | 2); ++ if (set_mask & TEMP2) ++ event_status = event_status | TEMP2; ++ else ++ set_mask = set_mask | 0x02; ++ crit_st = crit_st | 2; + } + if (diode_reg_val & THM_CHAN_TEMP[2]) { +- set_mask = (set_mask | 0x04); +- crit_st = (crit_st | 4); ++ if (set_mask & TEMP3) ++ event_status = event_status | TEMP3; ++ else ++ set_mask = set_mask | 0x04; ++ crit_st = crit_st | 4; + } + if (diode_reg_val & THM_CHAN_TEMP[4]) { +- set_mask = (set_mask | 0x01); +- crit_st = (crit_st | 1); ++ if (set_mask & TEMP1) ++ event_status = event_status | TEMP1; ++ else ++ set_mask = set_mask | 0x01; ++ crit_st = crit_st | 1; + } + if (event == ALERT_EVENT) +- i2c_smbus_write_byte_data(client, 0x1F, set_mask); +- *status = crit_st; ++ i2c_smbus_write_byte_data(client, 0x1f, set_mask); ++ *mask_status = crit_st; ++ *status = event_status; + return 0; + } + + static void ospm_event(int event_id, int sensor_id, int curr_temp) + { + if (event_id == THERM_EVENT) { +- printk(KERN_ALERT "emc1403: Sensor Id = %d crit event \ ++ printk(KERN_ALERT "emc1403: sensor id = %d crit event \ + temp = %d \n", sensor_id, curr_temp); + ospm_generate_netlink_event(sensor_id, + OSPM_EVENT_THERMAL_CRITICAL); + } + if (event_id == HIGH_EVENT) { +- printk(KERN_ALERT "emc1403: Sensor Id = %d AUX1 event \ ++ printk(KERN_ALERT "emc1403: sensor id = %d aux1 event \ + temp = %d \n", sensor_id, curr_temp); + ospm_generate_netlink_event(sensor_id, + OSPM_EVENT_THERMAL_AUX1); + } + if (event_id == LOW_EVENT) { +- printk(KERN_ALERT "emc1403: Sensor Id = %d AUX0 event \ ++ printk(KERN_ALERT "emc1403: sensor id = %d aux0 event \ + temp = %d \n", sensor_id, curr_temp); + ospm_generate_netlink_event(sensor_id, + OSPM_EVENT_THERMAL_AUX0); + } + if (event_id == FAULT_EVENT) { +- printk(KERN_ALERT "emc1403: Sensor Id = %d Fault event \ ++ printk(KERN_ALERT "emc1403: sensor id = %d fault event \ + temp = %d \n", sensor_id, curr_temp); + ospm_generate_netlink_event(sensor_id, + OSPM_EVENT_THERMAL_DEV_FAULT); + } + } + +-static void send_event(struct i2c_client *client, int status, int event_id) ++static void send_event(struct i2c_client *client, int status, u8 mask_event, ++ int event_id) + { + int ret_val; + + if (status & TEMP1) { +- ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[0]); +- ospm_event(event_id, TEMP_DEV_ID1, ret_val); ++ if (!(TEMP1 & mask_event)) { ++ ret_val = i2c_read_current_data(client, ++ THM_REG_CURR_TEMP[0]); ++ ospm_event(event_id, TEMP_DEV_ID1, ret_val); ++ } + } + if (status & TEMP2) { +- ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[1]); +- ospm_event(event_id, TEMP_DEV_ID2, ret_val); ++ if (!(TEMP2 & mask_event)) { ++ ret_val = i2c_read_current_data(client, ++ THM_REG_CURR_TEMP[1]); ++ ospm_event(event_id, TEMP_DEV_ID2, ret_val); ++ } + } + if (status & TEMP3) { +- ret_val = i2c_read_current_data(client, THM_REG_CURR_TEMP[2]); +- ospm_event(event_id, TEMP_DEV_ID3, ret_val); ++ if (!(TEMP3 & mask_event)) { ++ ret_val = i2c_read_current_data(client, ++ THM_REG_CURR_TEMP[2]); ++ ospm_event(event_id, TEMP_DEV_ID3, ret_val); ++ } + } + } + + static void therm_handle_intrpt(struct work_struct *work) + { +- u8 status, reg_val; ++ u8 status, reg_val, mask_status; + struct thermal_data *data = container_of(work, + struct thermal_data, therm_handler); + + /* check if therm_module_info is initialized */ + if (!data) + return; +- /* Which DIODE has raised the interrupt 0x1B +- internal/External1/External2 */ ++ /* which diode has raised the interrupt 0x1b ++ internal/external1/external2 */ + reg_val = i2c_smbus_read_byte_data(data->client, + THM_STAT_REG_TEMP[0]); +- interrupt_status(data->client, reg_val, &status, THERM_EVENT); +- send_event(data->client, status, THERM_EVENT); ++ interrupt_status(data->client, reg_val, &status, THERM_EVENT, ++ &mask_status); ++ send_event(data->client, status, 0, THERM_EVENT); + } + + static void alert_handle_intrpt(struct work_struct *work) + { + int sta_reg_val, reg_val; +- u8 status; ++ u8 status, mask_status; + struct thermal_data *data = container_of(work, + struct thermal_data, alert_handler); + if (!data) +@@ -557,25 +542,26 @@ static void alert_handle_intrpt(struct work_struct *work) + internal/External1/External2 */ + sta_reg_val = i2c_smbus_read_byte_data(data->client, + THM_STAT_REG_TEMP[1]); ++ /*chek if the mask is already enabled then donot send the event again*/ + interrupt_status(data->client, sta_reg_val, &status, +- ALERT_EVENT); +- send_event(data->client, status, HIGH_EVENT); ++ ALERT_EVENT, &mask_status); ++ send_event(data->client, status, mask_status, HIGH_EVENT); + } + /* Low status bit is set */ + if (reg_val & THM_CHAN_TEMP[1]) { + sta_reg_val = i2c_smbus_read_byte_data(data->client, + THM_STAT_REG_TEMP[2]); + interrupt_status(data->client, sta_reg_val, &status, +- ALERT_EVENT); +- send_event(data->client, status, LOW_EVENT); ++ ALERT_EVENT, &mask_status); ++ send_event(data->client, status, mask_status, LOW_EVENT); + } + /* Fault status bit is set */ + if (reg_val & THM_CHAN_TEMP[2]) { + sta_reg_val = i2c_smbus_read_byte_data(data->client, + THM_STAT_REG_TEMP[3]); + interrupt_status(data->client, sta_reg_val, &status, +- ALERT_EVENT); +- send_event(data->client, status, FAULT_EVENT); ++ ALERT_EVENT, &mask_status); ++ send_event(data->client, status, mask_status, FAULT_EVENT); + } + } + #endif +-- +1.6.2.5 + |