Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make bq2415x uevent reporting more robust #13

Open
wants to merge 2 commits into
base: maemo-6.6.y
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 32 additions & 10 deletions drivers/power/supply/bq2415x_charger.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
/* timeout for resetting chip timer */
#define BQ2415X_TIMER_TIMEOUT 10

/* input source detection interval. insanely long! */
#define BQ2415X_DETECTION_INTERVAL 9

#define BQ2415X_REG_STATUS 0x00
#define BQ2415X_REG_CONTROL 0x01
#define BQ2415X_REG_VOLTAGE 0x02
Expand Down Expand Up @@ -160,7 +163,8 @@ struct bq2415x_device {
struct bq2415x_platform_data init_data;
struct power_supply *charger;
struct power_supply_desc charger_desc;
struct delayed_work work;
struct delayed_work timer_work;
struct delayed_work refresh_work;
struct device_node *notify_node;
struct notifier_block nb;
enum bq2415x_mode reported_mode;/* mode reported by hook function */
Expand Down Expand Up @@ -841,7 +845,14 @@ static int bq2415x_notifier_call(struct notifier_block *nb,
if (bq->automode < 1)
return NOTIFY_OK;

schedule_delayed_work(&bq->work, 0);
/*
* Sometimes the chip takes more than 5s to update its internal state.
* Therefore schedule a late refresh of reported supply properties.
*/
cancel_delayed_work(&bq->refresh_work);
schedule_delayed_work(&bq->refresh_work, BQ2415X_DETECTION_INTERVAL * HZ);

schedule_delayed_work(&bq->timer_work, 0);

return NOTIFY_OK;
}
Expand All @@ -861,11 +872,11 @@ static void bq2415x_set_autotimer(struct bq2415x_device *bq, int state)
bq->autotimer = state;

if (state) {
schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ);
schedule_delayed_work(&bq->timer_work, BQ2415X_TIMER_TIMEOUT * HZ);
bq2415x_exec_command(bq, BQ2415X_TIMER_RESET);
bq->timer_error = NULL;
} else {
cancel_delayed_work_sync(&bq->work);
cancel_delayed_work_sync(&bq->timer_work);
}

mutex_unlock(&bq2415x_timer_mutex);
Expand All @@ -884,10 +895,10 @@ static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg)
}

/* delayed work function for auto resetting chip timer */
static void bq2415x_timer_work(struct work_struct *work)
static void bq2415x_timer_work(struct work_struct *timer_work)
{
struct bq2415x_device *bq = container_of(work, struct bq2415x_device,
work.work);
struct bq2415x_device *bq = container_of(timer_work, struct bq2415x_device,
timer_work.work);
int ret;
int error;
int boost;
Expand Down Expand Up @@ -984,9 +995,18 @@ static void bq2415x_timer_work(struct work_struct *work)
}
}

schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ);
schedule_delayed_work(&bq->timer_work, BQ2415X_TIMER_TIMEOUT * HZ);
}

/* delayed work function for refreshing properties on input source detection */
static void bq2415x_refresh_work(struct work_struct *refresh_work)
{
struct bq2415x_device *bq = container_of(refresh_work, struct bq2415x_device,
refresh_work.work);
power_supply_changed(bq->charger);
}


/**** power supply interface code ****/

static enum power_supply_property bq2415x_power_supply_props[] = {
Expand Down Expand Up @@ -1040,7 +1060,8 @@ static void bq2415x_power_supply_exit(struct bq2415x_device *bq)
bq->autotimer = 0;
if (bq->automode > 0)
bq->automode = 0;
cancel_delayed_work_sync(&bq->work);
cancel_delayed_work_sync(&bq->timer_work);
cancel_delayed_work_sync(&bq->refresh_work);
power_supply_unregister(bq->charger);
kfree(bq->model);
}
Expand Down Expand Up @@ -1686,7 +1707,8 @@ static int bq2415x_probe(struct i2c_client *client)
}
}

INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work);
INIT_DELAYED_WORK(&bq->timer_work, bq2415x_timer_work);
INIT_DELAYED_WORK(&bq->refresh_work, bq2415x_refresh_work);
bq2415x_set_autotimer(bq, 1);

dev_info(bq->dev, "driver registered\n");
Expand Down