summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorHyongbin Kim <hyongbink@nvidia.com>2013-08-21 12:22:27 +0900
committerGabby Lee <galee@nvidia.com>2013-08-23 04:58:59 -0700
commit51ac69e5b329f61d7c5ab4c37da4917e36ba256c (patch)
treea5f6d9e28630c2244454940310d5db7c3d35d86d /drivers
parent903518c6b37d3a425345e42173b20c07875385ff (diff)
power: max17048: sysedp throttle in low SOC
When low SOC, limit freq of cpu, gpu, emc by sysedp_lite. Bug 1316595 Change-Id: I112efb815d3c57731d7478bb2ab0589c10f72865 Signed-off-by: Hyongbin Kim <hyongbink@nvidia.com> Reviewed-on: http://git-master/r/264167 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Gabby Lee <galee@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/power/max17048_battery.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/power/max17048_battery.c b/drivers/power/max17048_battery.c
index 5c77020386c6..438efd753811 100644
--- a/drivers/power/max17048_battery.c
+++ b/drivers/power/max17048_battery.c
@@ -27,6 +27,7 @@
#include <linux/wakelock.h>
#include <linux/thermal.h>
#include <linux/platform_data/ina230.h>
+#include <linux/platform_data/tegra_edp.h>
#include <generated/mach-types.h>
#define MAX17048_VCELL 0x02
@@ -327,6 +328,27 @@ static void max17048_set_current_threshold(struct i2c_client *client)
}
}
+static void max17048_sysedp_throttle(struct i2c_client *client)
+{
+ struct max17048_chip *chip = i2c_get_clientdata(client);
+ int i;
+ unsigned int power = ULONG_MAX;
+
+ /* edp throttle by SOC */
+ /* sysedp_throttle_power array should be sorted in ascending order */
+ if (chip->pdata->sysedp_throttle) {
+ for (i = 0; i < chip->pdata->sysedp_throttle_num; i++) {
+ if ((chip->internal_soc <=
+ chip->pdata->sysedp_throttle_soc[i]) &&
+ chip->pdata->sysedp_throttle_power[i]) {
+ power = chip->pdata->sysedp_throttle_power[i];
+ break;
+ }
+ }
+ chip->pdata->sysedp_throttle(power);
+ }
+}
+
static uint16_t max17048_get_version(struct i2c_client *client)
{
return max17048_read_word(client, MAX17048_VER);
@@ -428,6 +450,7 @@ static void max17048_work(struct work_struct *work)
max17048_get_vcell(chip->client);
max17048_get_soc(chip->client);
max17048_set_current_threshold(chip->client);
+ max17048_sysedp_throttle(chip->client);
if (chip->soc != chip->lasttime_soc ||
chip->status != chip->lasttime_status) {
@@ -729,6 +752,7 @@ static irqreturn_t max17048_irq(int id, void *dev)
max17048_get_vcell(client);
max17048_get_soc(client);
max17048_set_current_threshold(client);
+ max17048_sysedp_throttle(client);
chip->lasttime_soc = chip->soc;
dev_info(&client->dev,
@@ -924,6 +948,40 @@ static struct max17048_platform_data *max17048_parse_dt(struct device *dev)
for (i = 0; i < pdata->current_threshold_num; i++)
pdata->current_threshold[i] = soc_array[i];
}
+
+ if ((!of_property_read_string(np, "sysedp_throttle", &str)) &&
+ (!strncmp(str, "sysedp_lite", strlen(str)))) {
+ pdata->sysedp_throttle = sysedp_lite_throttle;
+ } else {
+ pdata->sysedp_throttle = NULL;
+ }
+
+ ret = of_property_read_u32(np, "sysedp_throttle_num", &val);
+ if (ret < 0)
+ pdata->sysedp_throttle_num = 0;
+ else
+ pdata->sysedp_throttle_num = val;
+
+ if (pdata->sysedp_throttle_num > MAX17048_MAX_SOC_STEP)
+ pdata->sysedp_throttle_num = MAX17048_MAX_SOC_STEP;
+
+ if (pdata->sysedp_throttle != NULL && pdata->sysedp_throttle_num) {
+ ret = of_property_read_u32_array(np, "sysedp_throttle_soc",
+ soc_array, pdata->sysedp_throttle_num);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ for (i = 0; i < pdata->sysedp_throttle_num; i++)
+ pdata->sysedp_throttle_soc[i] = soc_array[i];
+
+ ret = of_property_read_u32_array(np, "sysedp_throttle_power",
+ soc_array, pdata->sysedp_throttle_num);
+ if (ret < 0)
+ return ERR_PTR(ret);
+
+ for (i = 0; i < pdata->sysedp_throttle_num; i++)
+ pdata->sysedp_throttle_power[i] = soc_array[i];
+ }
return pdata;
}
#else