static int bdata_get_property(struct power_supply *psy,
			      enum power_supply_property psp,
			      union power_supply_propval *val)
{
	int rc = 0;
	struct data_info *di = container_of(psy, struct data_info, bdata_ps);

	dev_dbg(di->dev, "%s() enter. psp=%d\n", __func__, psp);

	if (!atomic_read(&di->got_bdata))
		return -EBUSY;

	MUTEX_LOCK(&di->lock);

	switch (psp) {
	case POWER_SUPPLY_PROP_TECHNOLOGY:
#ifdef DEBUG_FS
		if (di->technology_debug.active) {
			enum battery_technology tech;
			tech = (enum battery_technology)
				di->technology_debug.value;
			di->technology = get_technology(tech);
		}
#endif /* DEBUG_FS */
		val->intval = di->technology;
		break;

	case POWER_SUPPLY_PROP_TEMP:
		/* Temperature in tenths of degree Celsius */
		val->intval = di->temp_celsius * 10;
#ifdef DEBUG_FS
		if (di->temperature_debug.active)
			val->intval = di->temperature_debug.value * 10;
#endif /* DEBUG_FS */
		break;

	case POWER_SUPPLY_PROP_TEMP_AMBIENT:
		/* Ambient temperature in tenths of degree Celsius */
		val->intval = di->temp_celsius_amb * 10;
#ifdef DEBUG_FS
		if (di->temperature_amb_debug.active)
			val->intval = di->temperature_amb_debug.value * 10;
#endif /* DEBUG_FS */
		break;

	default:
		rc = -EINVAL;
		break;

	}
	MUTEX_UNLOCK(&di->lock);

	dev_dbg(di->dev, "%s() exit. psp=%d val=%d rc=%d\n",
		__func__, psp, val->intval, rc);

	return rc;
}
static int bdata_get_property(struct power_supply *psy,
			      enum power_supply_property psp,
			      union power_supply_propval *val)
{
	int rc = 0;
	struct data_info *di = container_of(psy, struct data_info, bdata_ps);

	MUTEX_LOCK(&di->lock);

	switch (psp) {
	case POWER_SUPPLY_PROP_TECHNOLOGY:
	{
		enum battery_technology tech = di->bdata.technology;
#ifdef DEBUG_FS
		if (di->technology_debug.active)
			tech = (enum battery_technology)
				di->technology_debug.value;
#endif
		val->intval = get_technology(tech);
		break;
	}
	case POWER_SUPPLY_PROP_CAPACITY:
		if (di->use_fuelgauge)
			val->intval = di->bdata.cap_percent;
		else
			rc = -EINVAL;
		break;
	case POWER_SUPPLY_PROP_TEMP:
		/* Temperature in tenths of degree Celsius */
		val->intval = di->bdata.temp_celsius * 10;
#ifdef DEBUG_FS
		if (di->temperature_debug.active)
			val->intval = di->temperature_debug.value * 10;
#endif
		break;
	case POWER_SUPPLY_PROP_TEMP_AMBIENT:
		/* Ambient temperature in tenths of degree Celsius */
		val->intval = di->bdata.temp_celsius_amb * 10;
#ifdef DEBUG_FS
		if (di->temperature_amb_debug.active)
			val->intval = di->temperature_amb_debug.value * 10;
#endif
		break;
	default:
		rc = -EINVAL;
		break;

	}

	MUTEX_UNLOCK(&di->lock);

	return rc;
}
static void semc_battery_timer_worker(struct work_struct *work)
{
	enum battery_technology tech;
	int tech_old = 0;
	int temp_old = 0;
	int amb_old = 0;
	u8 got = 0;
	struct data_info *di =
		container_of(work, struct data_info, timer_work);

	if (atomic_cmpxchg(&di->suspend_lock, 0, 1))
		return;

	if (get_batt_therm_resistance(di, &resistance) >= 0) {
		tech = get_battery_type(resistance);
		MUTEX_LOCK(&di->lock);
		tech_old = di->technology;
		temp_old = di->temp_celsius;
		di->technology = get_technology(tech);
		di->temp_celsius = get_battery_temperature(resistance);
		MUTEX_UNLOCK(&di->lock);
		got |= 0x01;
	}
	if (get_battery_temperature_ambient(&ambient_temp) >= 0) {
		MUTEX_LOCK(&di->lock);
		amb_old = di->temp_celsius_amb;
		di->temp_celsius_amb = ambient_temp;
		MUTEX_UNLOCK(&di->lock);
		got |= 0x02;
	}
	atomic_set(&di->suspend_lock, 0);

	if (((got & 0x01) &&
	(di->technology != tech_old || di->temp_celsius != temp_old)) ||
	((got & 0x02) && di->temp_celsius_amb != amb_old))
		power_supply_changed(&di->bdata_ps);

	if (got & 0x03)
		atomic_set(&di->got_bdata, 1);

	dev_dbg(di->dev, "%s() got=%d tech=%d batt_temp=%d ambient_temp=%d\n",
		__func__,
		got, di->technology, di->temp_celsius, di->temp_celsius_amb);

	semc_battery_timer_start(di);
}