summaryrefslogtreecommitdiff
path: root/drivers/w1
diff options
context:
space:
mode:
authorLily Zhang <r58066@freescale.com>2010-09-25 09:37:00 +0800
committerAlan Tull <r80115@freescale.com>2010-09-25 09:53:59 -0500
commit1a0d1a8bc4b1e39ab25488ed0e28f0e39eb71982 (patch)
treec637fb3e321bfe6f4e0e529e8cd8d7c0394ca7b7 /drivers/w1
parent27d19e5176a0b235a610d9de564f424d484c4f9b (diff)
ENGR00131906-1 split w1_ds2438 driver as two drivers
The kernel commit "5f487cd34" changes the function power_supply_register. When calling power_supply_register into ds2438_add_slave, it causes slave->master->mutex dead lock. This patch splits w1_ds2438 driver as w1_ds2438 (w1 slave) driver and ds2438_battery driver to avoid dead lock in driver initialization. Signed-off-by: Lily Zhang <r58066@freescale.com>
Diffstat (limited to 'drivers/w1')
-rw-r--r--drivers/w1/slaves/Kconfig1
-rw-r--r--drivers/w1/slaves/w1_ds2438.c537
-rw-r--r--drivers/w1/slaves/w1_ds2438.h6
3 files changed, 85 insertions, 459 deletions
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig
index ad77126801f5..58f3e64e600a 100644
--- a/drivers/w1/slaves/Kconfig
+++ b/drivers/w1/slaves/Kconfig
@@ -46,6 +46,7 @@ config W1_SLAVE_DS2433
config W1_SLAVE_DS2438
tristate "Smart Battery Monitor (DS2438)"
+ depends on W1
help
Say Y here if you want to use a 1-wire
Smart Battery Monitor family device (DS2438).
diff --git a/drivers/w1/slaves/w1_ds2438.c b/drivers/w1/slaves/w1_ds2438.c
index 251ca0e7f914..4212117d9424 100644
--- a/drivers/w1/slaves/w1_ds2438.c
+++ b/drivers/w1/slaves/w1_ds2438.c
@@ -14,411 +14,20 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
-#include <linux/moduleparam.h>
#include <linux/device.h>
-#include <linux/jiffies.h>
-#include <linux/workqueue.h>
-#include <linux/pm.h>
#include <linux/platform_device.h>
-#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/slab.h>
-#include <linux/delay.h>
#include <linux/err.h>
#include <linux/idr.h>
-#include <linux/power_supply.h>
#include "../w1.h"
#include "../w1_int.h"
#include "../w1_family.h"
#include "w1_ds2438.h"
-struct ds2438_device_info {
- /* DS2438 data, valid after calling ds2438_battery_read_status() */
- unsigned long update_time; /* jiffies when data read */
- char raw[DS2438_PAGE_SIZE]; /* raw DS2438 data */
- int voltage_uV;
- int current_uA;
- int accum_current_uAh;
- int temp_C;
- int charge_status;
- u8 init:1;
- u8 setup:1;
- u8 calibrate:1;
- u8 input_src:1;
- u8 ee_flg:1;
- u8 resv_bit:3;
- u8 threshold:8;
- u16 resv_bytes;
- u32 senser;
-
- struct power_supply bat;
- struct device *w1_dev;
- struct ds2438_ops ops;
- struct workqueue_struct *monitor_wqueue;
- struct delayed_work monitor_work;
-};
-
-#define DS2438_SENSER 25
-#define to_ds2438_device_info(x) container_of((x), struct ds2438_device_info, \
- bat);
-
-
-static enum power_supply_property ds2438_battery_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CURRENT_NOW,
- POWER_SUPPLY_PROP_TEMP,
- POWER_SUPPLY_PROP_CHARGE_NOW,
-};
-
-static char ds2438_sensers_title[] = "DS2438 senserin thousands of resister:";
-static unsigned int cache_time = 1000;
-module_param(cache_time, uint, 0644);
-MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
-
-static ssize_t ds2438_show_input(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct power_supply *psy = dev_get_drvdata(dev);
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
-
- return sprintf(buf, "%s\n", di->input_src ? "1:VDD" : "0:VAD");
-}
-
-static ssize_t ds2438_show_senser(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int len;
- struct power_supply *psy = dev_get_drvdata(dev);
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
-
- len = sprintf(buf, "%s\n", ds2438_sensers_title);
- len += sprintf(buf + len, "%d\n", di->senser);
- return len;
-}
-
-static ssize_t ds2438_show_ee(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct power_supply *psy = dev_get_drvdata(dev);
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
-
- return sprintf(buf, "%d\n", di->ee_flg);
-}
-
-static ssize_t ds2438_show_threshold(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct power_supply *psy = dev_get_drvdata(dev);
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
-
- return sprintf(buf, "%d\n", di->threshold);
-}
-
-static ssize_t ds2438_set_input(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t count)
-{
- struct power_supply *psy = dev_get_drvdata(dev);
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
- di->input_src = !!simple_strtoul(buf, NULL, 0);
- return count;
-}
-
-static ssize_t ds2438_set_senser(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t count)
-{
- u32 resister;
- struct power_supply *psy = dev_get_drvdata(dev);
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
- resister = simple_strtoul(buf, NULL, 0);
- if (resister)
- di->senser = resister;
- return count;
-}
-
-static ssize_t ds2438_set_ee(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct power_supply *psy = dev_get_drvdata(dev);
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
-
- di->ee_flg = !!simple_strtoul(buf, NULL, 0);
- di->setup = 1;
- return count;
-}
-
-static ssize_t ds2438_set_threshold(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int threshold;
- struct power_supply *psy = dev_get_drvdata(dev);
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
-
- threshold = simple_strtoul(buf, NULL, 0);
- if (threshold < 256) {
- di->threshold = threshold;
- di->setup = 1;
- return count;
- }
- return -EINVAL;
-}
-
-static ssize_t ds2438_set_calibrate(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct power_supply *psy = dev_get_drvdata(dev);
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
-
- di->calibrate = !!simple_strtoul(buf, NULL, 0);
- return count;
-}
-
-static struct device_attribute ds2438_dev_attr[] = {
- __ATTR(input_src, 0664, ds2438_show_input, ds2438_set_input),
- __ATTR(senser, 0664, ds2438_show_senser, ds2438_set_senser),
- __ATTR(ee_flg, 0664, ds2438_show_ee, ds2438_set_ee),
- __ATTR(threshold, 0664, ds2438_show_threshold, ds2438_set_threshold),
- __ATTR(calibrate, 0220, NULL, ds2438_set_calibrate),
-};
-
-static void ds2438_setup(struct ds2438_device_info *di)
-{
- di->ops.load_sram(di->w1_dev, PAGE0_CONTROL);
- di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- if (di->init && di->setup) {
- if (di->ee_flg)
- di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_EE;
- else
- di->raw[PAGE0_STAT_CTRL] &= ~DS2438_CTRL_EE;
- if (di->input_src)
- di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_AD;
- else
- di->raw[PAGE0_STAT_CTRL] &= ~DS2438_CTRL_AD;
- di->raw[PAGE0_THRESHOLD] = di->threshold;
- } else {
- di->ee_flg = !!(di->raw[PAGE0_STAT_CTRL] & DS2438_CTRL_EE);
- di->input_src = !!(di->raw[PAGE0_STAT_CTRL] & DS2438_CTRL_AD);
- di->threshold = di->raw[PAGE0_THRESHOLD];
- di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_IAD | DS2438_CTRL_CA;
- }
- di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL);
- if (!di->init) {
- di->calibrate = 1;
- di->init = 1;
- }
- di->setup = 0;
-}
-
-static void ds2438_calibrate(struct ds2438_device_info *di)
-{
- int current_raw;
- /* disable ICA */
- di->ops.load_sram(di->w1_dev, PAGE0_CONTROL);
- di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- di->raw[PAGE0_STAT_CTRL] &= ~DS2438_CTRL_IAD;
- di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL);
-
- /* Zero offset */
- di->ops.load_sram(di->w1_dev, PAGE1_ETM);
- di->ops.read_page(di->w1_dev, PAGE1_ETM, di->raw);
- ds2438_writew(di->raw + PAGE1_OFFSET_LSB, 0);
- di->ops.drain_sram(di->w1_dev, PAGE1_ETM_BYTE0);
-
- /* enable ICA & read current */
- di->ops.load_sram(di->w1_dev, PAGE0_CONTROL);
- di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_IAD;
- di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL);
- /*wait current convert about 36HZ */
- mdelay(30);
- /* disable ICA */
- di->ops.load_sram(di->w1_dev, PAGE0_CONTROL);
- di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- di->raw[PAGE0_STAT_CTRL] &= ~DS2438_CTRL_IAD;
- di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL);
- /* read current value */
- current_raw = ds2438_readw(di->raw + PAGE0_CURRENT_LSB);
- /* write offset by current value */
- di->ops.load_sram(di->w1_dev, PAGE1_ETM);
- di->ops.read_page(di->w1_dev, PAGE1_ETM, di->raw);
- ds2438_writew(di->raw + PAGE1_OFFSET_LSB, current_raw << 8);
- di->ops.write_page(di->w1_dev, PAGE1_ETM, di->raw);
- di->ops.drain_sram(di->w1_dev, PAGE1_ETM);
-
- /*enable ICA again */
- di->ops.load_sram(di->w1_dev, PAGE0_CONTROL);
- di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_IAD;
- di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL);
- di->calibrate = 0;
-}
-
-/*
- * power supply temperture is in tenths of degree.
- */
-static inline int ds2438_get_temp(u16 raw)
-{
- int degree, s;
- s = !!(raw & 0x8000);
-
- if (s)
- raw = ((~raw & 0x7FFF) + 1);
- degree = ((raw >> 8) * 10) + (((raw & 0xFF) * 5) + 63) / 128;
- return s ? -degree : degree;
-}
-
-/*
- * power supply current is in uA.
- */
-static inline int ds2438_get_current(u32 senser, u16 raw)
-{
- int s, current_uA;
- s = !!(raw & 0xFC00);
- /* (x * 1000 * 1000)uA / (4096 * (Rsens / 1000)) */
- raw &= 0x3FF;
- current_uA = raw * 125 * 125 * 125;
- current_uA /= (senser << 3);
- return s ? -current_uA : current_uA;
-}
-
-/*
- * power supply current is in uAh.
- */
-static inline int ds2438_get_ica(u32 senser, u8 raw)
-{
- int charge_uAh;
- /* (x * 1000 * 1000)uA / (2048 * (Rsens / 1000)) */
- charge_uAh = (raw * 125 * 125 * 125) >> 4;
- charge_uAh /= (senser << 4);
- return charge_uAh;
-}
-
-static int ds2438_battery_update_page1(struct ds2438_device_info *di)
-{
- int ica_raw;
- di->ops.load_sram(di->w1_dev, PAGE1_ETM);
- di->ops.read_page(di->w1_dev, PAGE1_ETM, di->raw);
- ica_raw = di->raw[PAGE1_ICA];
- di->accum_current_uAh = ds2438_get_ica(di->senser, ica_raw);
- return 0;
-}
-
-static int ds2438_battery_read_status(struct ds2438_device_info *di)
-{
- u8 status;
- int temp_raw, voltage_raw, current_raw;
-
- if (!(di->init) || di->setup)
- ds2438_setup(di);
-
- if (di->calibrate)
- ds2438_calibrate(di);
-
- if (di->update_time && time_before(jiffies, di->update_time +
- msecs_to_jiffies(cache_time)))
- return 0;
-
- di->ops.load_sram(di->w1_dev, PAGE0_CONTROL);
- di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw);
- status = di->raw[PAGE0_STAT_CTRL];
- temp_raw = ds2438_readw(di->raw + PAGE0_TEMP_LSB);
- voltage_raw = ds2438_readw(di->raw + PAGE0_VOLTAGE_LSB);
- current_raw = ds2438_readw(di->raw + PAGE0_CURRENT_LSB);
- di->temp_C = ds2438_get_temp(temp_raw);
- di->voltage_uV = voltage_raw * 10000;
- di->current_uA = ds2438_get_current(di->senser, current_raw);
-
- ds2438_battery_update_page1(di);
-
- if (!(status & DS2438_STAT_TB))
- di->ops.command(di->w1_dev, DS2438_CONVERT_TEMP, 0);
- if (!(status & DS2438_STAT_ADB))
- di->ops.command(di->w1_dev, DS2438_CONVERT_VOLT, 0);
- di->update_time = jiffies;
- return 0;
-}
-
-static void ds2438_battery_update_status(struct ds2438_device_info *di)
-{
- int old_charge_status = di->charge_status;
-
- ds2438_battery_read_status(di);
-
- if (di->charge_status != old_charge_status)
- power_supply_changed(&di->bat);
-}
-
-static void ds2438_battery_work(struct work_struct *work)
-{
- struct ds2438_device_info *di = container_of(work,
- struct ds2438_device_info,
- monitor_work.work);
- const int interval = HZ * 60;
-
- dev_dbg(di->w1_dev, "%s\n", __func__);
-
- ds2438_battery_update_status(di);
- queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval);
-}
-
-static void ds2438_battery_external_power_changed(struct power_supply *psy)
-{
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
-
- dev_dbg(di->w1_dev, "%s\n", __func__);
-
- cancel_delayed_work(&di->monitor_work);
- queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ / 10);
-}
-
-static int ds2438_battery_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct ds2438_device_info *di = to_ds2438_device_info(psy);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- val->intval = di->charge_status;
- return 0;
- default:
- break;
- }
-
- ds2438_battery_read_status(di);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = di->voltage_uV;
- break;
- case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = di->current_uA;
- break;
- case POWER_SUPPLY_PROP_TEMP:
- val->intval = di->temp_C;
- break;
- case POWER_SUPPLY_PROP_CHARGE_NOW:
- val->intval = di->accum_current_uAh;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
/* W1 slave DS2438 famliy operations */
-static int ds2438_read_page(struct device *dev, u8 page, u8 *buf)
+int w1_ds2438_read_page(struct device *dev, u8 page, u8 *buf)
{
struct w1_slave *slave = container_of(dev, struct w1_slave, dev);
if ((page >= DS2438_PAGE_NUM) || (buf == NULL))
@@ -433,8 +42,9 @@ static int ds2438_read_page(struct device *dev, u8 page, u8 *buf)
mutex_unlock(&slave->master->mutex);
return 0;
}
+EXPORT_SYMBOL(w1_ds2438_read_page);
-static int ds2438_write_page(struct device *dev, u8 page, u8 *buf)
+int w1_ds2438_write_page(struct device *dev, u8 page, u8 *buf)
{
struct w1_slave *slave = container_of(dev, struct w1_slave, dev);
if ((page >= DS2438_PAGE_NUM) || (buf == NULL))
@@ -449,8 +59,9 @@ static int ds2438_write_page(struct device *dev, u8 page, u8 *buf)
mutex_unlock(&slave->master->mutex);
return 0;
}
+EXPORT_SYMBOL(w1_ds2438_write_page);
-static int ds2438_command(struct device *dev, u8 command, u8 data)
+int w1_ds2438_command(struct device *dev, u8 command, u8 data)
{
struct w1_slave *slave = container_of(dev, struct w1_slave, dev);
@@ -466,94 +77,100 @@ static int ds2438_command(struct device *dev, u8 command, u8 data)
mutex_unlock(&slave->master->mutex);
return 0;
}
+EXPORT_SYMBOL(w1_ds2438_command);
-static int ds2438_drain_sram(struct device *dev, u8 page)
+int w1_ds2438_drain_sram(struct device *dev, u8 page)
{
- return ds2438_command(dev, DS2438_COPY_SCRATCHPAD, page);
+ return w1_ds2438_command(dev, DS2438_COPY_SCRATCHPAD, page);
}
+EXPORT_SYMBOL(w1_ds2438_drain_sram);
-static int ds2438_load_sram(struct device *dev, u8 page)
+int w1_ds2438_load_sram(struct device *dev, u8 page)
{
- return ds2438_command(dev, DS2438_RECALL_MEMORY, page);
+ return w1_ds2438_command(dev, DS2438_RECALL_MEMORY, page);
}
+EXPORT_SYMBOL(w1_ds2438_load_sram);
-static inline void ds2438_defaut_ops(struct ds2438_ops *ops)
-{
- ops->read_page = ds2438_read_page;
- ops->write_page = ds2438_write_page;
- ops->drain_sram = ds2438_drain_sram;
- ops->load_sram = ds2438_load_sram;
- ops->command = ds2438_command;
-}
+static DEFINE_IDR(bat_idr);
+static DEFINE_MUTEX(bat_idr_lock);
-static int ds2438_add_slave(struct w1_slave *slave)
+static int new_bat_id(void)
{
- int i, retval = 0;
- struct ds2438_device_info *di;
+ int ret;
- di = kzalloc(sizeof(*di), GFP_KERNEL);
- if (!di) {
- retval = -ENOMEM;
- goto di_alloc_failed;
- }
+ while (1) {
+ int id;
- di->w1_dev = &slave->dev;
- di->bat.name = dev_name(&slave->dev);
- di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
- di->bat.properties = ds2438_battery_props;
- di->bat.num_properties = ARRAY_SIZE(ds2438_battery_props);
- di->bat.get_property = ds2438_battery_get_property;
- di->bat.external_power_changed = ds2438_battery_external_power_changed;
- ds2438_defaut_ops(&di->ops);
- di->senser = DS2438_SENSER;
- di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
-
- retval = power_supply_register(&slave->dev, &di->bat);
- if (retval) {
- dev_err(&slave->dev, "failed to register battery\n");
- goto batt_failed;
- }
+ ret = idr_pre_get(&bat_idr, GFP_KERNEL);
+ if (ret == 0)
+ return -ENOMEM;
- for (i = 0; i < ARRAY_SIZE(ds2438_dev_attr); i++) {
- if (device_create_file(di->bat.dev, ds2438_dev_attr + i)) {
- printk(KERN_ERR "Customize attribute file fail!\n");
+ mutex_lock(&bat_idr_lock);
+ ret = idr_get_new(&bat_idr, NULL, &id);
+ mutex_unlock(&bat_idr_lock);
+
+ if (ret == 0) {
+ ret = id & MAX_ID_MASK;
+ break;
+ } else if (ret == -EAGAIN) {
+ continue;
+ } else {
break;
}
}
- if (i != ARRAY_SIZE(ds2438_dev_attr)) {
- for (; i >= 0; i++)
- device_remove_file(di->bat.dev, ds2438_dev_attr + i);
- goto workqueue_failed;
+ return ret;
+}
+
+static void release_bat_id(int id)
+{
+ mutex_lock(&bat_idr_lock);
+ idr_remove(&bat_idr, id);
+ mutex_unlock(&bat_idr_lock);
+}
+
+static int ds2438_add_slave(struct w1_slave *slave)
+{
+ int ret;
+ int id;
+ struct platform_device *pdev;
+
+ id = new_bat_id();
+ if (id < 0) {
+ ret = id;
+ goto noid;
}
- INIT_DELAYED_WORK(&di->monitor_work, ds2438_battery_work);
- di->monitor_wqueue = create_singlethread_workqueue(dev_name(&slave->dev));
- if (!di->monitor_wqueue) {
- retval = -ESRCH;
- goto workqueue_failed;
+
+ pdev = platform_device_alloc(DS2438_DEV_NAME, id);
+ if (!pdev) {
+ ret = -ENOMEM;
+ goto pdev_alloc_failed;
}
- dev_set_drvdata(&slave->dev, di);
- queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ / 2);
-
- goto success;
-
- workqueue_failed:
- power_supply_unregister(&di->bat);
- batt_failed:
- kfree(di);
- di_alloc_failed:
- success:
- return retval;
+ pdev->dev.parent = &slave->dev;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto pdev_add_failed;
+
+ dev_set_drvdata(&slave->dev, pdev);
+ goto success;
+
+pdev_add_failed:
+ platform_device_unregister(pdev);
+pdev_alloc_failed:
+ release_bat_id(id);
+noid:
+success:
+ return ret;
}
static void ds2438_remove_slave(struct w1_slave *slave)
{
- struct ds2438_device_info *di = dev_get_drvdata(&slave->dev);
+ struct platform_device *pdev = dev_get_drvdata(&slave->dev);
+ int id = pdev->id;
- cancel_rearming_delayed_workqueue(di->monitor_wqueue,
- &di->monitor_work);
- destroy_workqueue(di->monitor_wqueue);
- power_supply_unregister(&di->bat);
+ platform_device_unregister(pdev);
+ release_bat_id(id);
}
static struct w1_family_ops w1_ds2438_fops = {
@@ -569,12 +186,14 @@ static struct w1_family w1_family_ds2438 = {
static int __init w1_ds2438_init(void)
{
pr_info("1-wire driver for the DS2438 smart battery monitor\n");
+ idr_init(&bat_idr);
return w1_register_family(&w1_family_ds2438);
}
static void __exit w1_ds2438_fini(void)
{
w1_unregister_family(&w1_family_ds2438);
+ idr_destroy(&bat_idr);
}
module_init(w1_ds2438_init);
diff --git a/drivers/w1/slaves/w1_ds2438.h b/drivers/w1/slaves/w1_ds2438.h
index 40d48f25cc10..b9fb73cafea4 100644
--- a/drivers/w1/slaves/w1_ds2438.h
+++ b/drivers/w1/slaves/w1_ds2438.h
@@ -116,4 +116,10 @@ static inline void ds2438_writew(u8 *raw, u16 data)
*raw++ = data & 0xFF;
*raw = (data >> 8) & 0xFF;
}
+
+extern int w1_ds2438_read_page(struct device *dev, u8 page, u8 *buf);
+extern int w1_ds2438_write_page(struct device *dev, u8 page, u8 *buf);
+extern int w1_ds2438_command(struct device *dev, u8 command, u8 data);
+extern int w1_ds2438_drain_sram(struct device *dev, u8 page);
+extern int w1_ds2438_load_sram(struct device *dev, u8 page);
#endif /* __W1_DS2438_H__ */