summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonghwa Lee <jonghwa3.lee@samsung.com>2014-10-24 06:26:56 (GMT)
committerChanho Park <chanho61.park@samsung.com>2014-11-18 03:01:06 (GMT)
commit6e4eda7a74f43adbae691bd756ea86516cbf0c0e (patch)
tree265691c81c45cfb91cf2d043ac3deb39cabf251b
parent8586a86fd4eb3e0a264ac200f8f0df6910dd58a9 (diff)
downloadlinux-3.10-6e4eda7a74f43adbae691bd756ea86516cbf0c0e.zip
linux-3.10-6e4eda7a74f43adbae691bd756ea86516cbf0c0e.tar.gz
linux-3.10-6e4eda7a74f43adbae691bd756ea86516cbf0c0e.tar.bz2
power: charger-manager: Support to change polling rate in runtime.
Add 'polling_ms' sysfs node to change charger-manager's monitoring rate in runtime. It can set only bigger than 2 jiffies (for 200 HZ system it is 10 msecs.) as it's allowed for minimum poling rate in previous. It resets poller and re-configure polling rate based on new input if next polling time is far enough. Otherwise, it just waits expiration of timer and new polling rate will affects the next scheduling. Change-Id: I6a9a07b96db2554e2ec047224df818dcc4ab1a17 Signed-off-by: Jonghwa Lee <jonghwa3.lee@samsung.com>
-rw-r--r--drivers/power/charger-manager.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c
index 7f2a57f..f9a654d 100644
--- a/drivers/power/charger-manager.c
+++ b/drivers/power/charger-manager.c
@@ -959,6 +959,63 @@ static ssize_t charger_externally_control_store(struct device *dev,
return count;
}
+static ssize_t show_polling_ms(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct charger_manager *cm;
+ ssize_t len;
+
+ list_for_each_entry(cm, &cm_list, entry)
+ if (cm->charger_psy.dev == dev)
+ break;
+
+ if (cm->charger_psy.dev != dev)
+ return -EINVAL;
+
+ len = sprintf(buf, "%d\n", cm->desc->polling_interval_ms);
+
+ return len;
+}
+
+static ssize_t store_polling_ms(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct charger_manager *cm;
+ int polling_ms;
+ int ret;
+
+ ret = sscanf(buf, "%d", &polling_ms);
+ if (ret < 0 )
+ return -EINVAL;
+
+ if (polling_ms < CM_JIFFIES_SMALL * MSEC_PER_SEC / HZ)
+ return -EINVAL;
+
+ list_for_each_entry(cm, &cm_list, entry)
+ if (cm->charger_psy.dev == dev)
+ break;
+
+ if (cm->charger_psy.dev != dev)
+ return -ENODEV;
+
+ cm->desc->polling_interval_ms = polling_ms;
+
+ pr_info("Polling interval's changed to %u ms.\n",
+ cm->desc->polling_interval_ms);
+
+ if (next_polling - jiffies >
+ msecs_to_jiffies(cm->desc->polling_interval_ms)) {
+ pr_info("Reset poller now... \n");
+ cancel_delayed_work(&cm_monitor_work);
+ schedule_work(&setup_polling);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(polling_ms, 0644, show_polling_ms, store_polling_ms);
+
/**
* charger_manager_register_sysfs - Register sysfs entry for each charger
* @cm: the Charger Manager representing the battery.
@@ -982,6 +1039,11 @@ static int charger_manager_register_sysfs(struct charger_manager *cm)
int ret = 0;
int i;
+ /* Create polling_ms sysfs node */
+ ret = device_create_file(cm->charger_psy.dev, &dev_attr_polling_ms);
+ if (ret)
+ pr_err("Failed to create poling_ms sysfs node (%d)\n", ret);
+
/* Create sysfs entry to control charger(regulator) */
for (i = 0; i < desc->num_charger_regulators; i++) {
charger = &desc->charger_regulators[i];