Skip to content

Commit

Permalink
Merge remote-tracking branch 'chanwoo-extcon/ib-extcon-powersupply-4.…
Browse files Browse the repository at this point in the history
…8' into psy-next
  • Loading branch information
sre committed Jun 28, 2016
2 parents 2e05b51 + 830ae44 commit 411ef2b
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 258 deletions.
201 changes: 24 additions & 177 deletions drivers/extcon/extcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,38 +127,6 @@ static int find_cable_index_by_id(struct extcon_dev *edev, const unsigned int id
return -EINVAL;
}

static int find_cable_id_by_name(struct extcon_dev *edev, const char *name)
{
int id = -EINVAL;
int i = 0;

/* Find the id of extcon cable */
while (extcon_name[i]) {
if (!strncmp(extcon_name[i], name, CABLE_NAME_MAX)) {
id = i;
break;
}
i++;
}

return id;
}

static int find_cable_index_by_name(struct extcon_dev *edev, const char *name)
{
int id;

if (edev->max_supported == 0)
return -EINVAL;

/* Find the the number of extcon cable */
id = find_cable_id_by_name(edev, name);
if (id < 0)
return id;

return find_cable_index_by_id(edev, id);
}

static bool is_extcon_changed(u32 prev, u32 new, int idx, bool *attached)
{
if (((prev >> idx) & 0x1) != ((new >> idx) & 0x1)) {
Expand Down Expand Up @@ -373,25 +341,6 @@ int extcon_get_cable_state_(struct extcon_dev *edev, const unsigned int id)
}
EXPORT_SYMBOL_GPL(extcon_get_cable_state_);

/**
* extcon_get_cable_state() - Get the status of a specific cable.
* @edev: the extcon device that has the cable.
* @cable_name: cable name.
*
* Note that this is slower than extcon_get_cable_state_.
*/
int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name)
{
int id;

id = find_cable_id_by_name(edev, cable_name);
if (id < 0)
return id;

return extcon_get_cable_state_(edev, id);
}
EXPORT_SYMBOL_GPL(extcon_get_cable_state);

/**
* extcon_set_cable_state_() - Set the status of a specific cable.
* @edev: the extcon device that has the cable.
Expand Down Expand Up @@ -421,28 +370,6 @@ int extcon_set_cable_state_(struct extcon_dev *edev, unsigned int id,
}
EXPORT_SYMBOL_GPL(extcon_set_cable_state_);

/**
* extcon_set_cable_state() - Set the status of a specific cable.
* @edev: the extcon device that has the cable.
* @cable_name: cable name.
* @cable_state: the new cable status. The default semantics is
* true: attached / false: detached.
*
* Note that this is slower than extcon_set_cable_state_.
*/
int extcon_set_cable_state(struct extcon_dev *edev,
const char *cable_name, bool cable_state)
{
int id;

id = find_cable_id_by_name(edev, cable_name);
if (id < 0)
return id;

return extcon_set_cable_state_(edev, id, cable_state);
}
EXPORT_SYMBOL_GPL(extcon_set_cable_state);

/**
* extcon_get_extcon_dev() - Get the extcon device instance from the name
* @extcon_name: The extcon name provided with extcon_dev_register()
Expand All @@ -466,105 +393,6 @@ struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)
}
EXPORT_SYMBOL_GPL(extcon_get_extcon_dev);

/**
* extcon_register_interest() - Register a notifier for a state change of a
* specific cable, not an entier set of cables of a
* extcon device.
* @obj: an empty extcon_specific_cable_nb object to be returned.
* @extcon_name: the name of extcon device.
* if NULL, extcon_register_interest will register
* every cable with the target cable_name given.
* @cable_name: the target cable name.
* @nb: the notifier block to get notified.
*
* Provide an empty extcon_specific_cable_nb. extcon_register_interest() sets
* the struct for you.
*
* extcon_register_interest is a helper function for those who want to get
* notification for a single specific cable's status change. If a user wants
* to get notification for any changes of all cables of a extcon device,
* he/she should use the general extcon_register_notifier().
*
* Note that the second parameter given to the callback of nb (val) is
* "old_state", not the current state. The current state can be retrieved
* by looking at the third pameter (edev pointer)'s state value.
*/
int extcon_register_interest(struct extcon_specific_cable_nb *obj,
const char *extcon_name, const char *cable_name,
struct notifier_block *nb)
{
unsigned long flags;
int ret;

if (!obj || !cable_name || !nb)
return -EINVAL;

if (extcon_name) {
obj->edev = extcon_get_extcon_dev(extcon_name);
if (!obj->edev)
return -ENODEV;

obj->cable_index = find_cable_index_by_name(obj->edev,
cable_name);
if (obj->cable_index < 0)
return obj->cable_index;

obj->user_nb = nb;

spin_lock_irqsave(&obj->edev->lock, flags);
ret = raw_notifier_chain_register(
&obj->edev->nh[obj->cable_index],
obj->user_nb);
spin_unlock_irqrestore(&obj->edev->lock, flags);
} else {
struct class_dev_iter iter;
struct extcon_dev *extd;
struct device *dev;

if (!extcon_class)
return -ENODEV;
class_dev_iter_init(&iter, extcon_class, NULL, NULL);
while ((dev = class_dev_iter_next(&iter))) {
extd = dev_get_drvdata(dev);

if (find_cable_index_by_name(extd, cable_name) < 0)
continue;

class_dev_iter_exit(&iter);
return extcon_register_interest(obj, extd->name,
cable_name, nb);
}

ret = -ENODEV;
}

return ret;
}
EXPORT_SYMBOL_GPL(extcon_register_interest);

/**
* extcon_unregister_interest() - Unregister the notifier registered by
* extcon_register_interest().
* @obj: the extcon_specific_cable_nb object returned by
* extcon_register_interest().
*/
int extcon_unregister_interest(struct extcon_specific_cable_nb *obj)
{
unsigned long flags;
int ret;

if (!obj)
return -EINVAL;

spin_lock_irqsave(&obj->edev->lock, flags);
ret = raw_notifier_chain_unregister(
&obj->edev->nh[obj->cable_index], obj->user_nb);
spin_unlock_irqrestore(&obj->edev->lock, flags);

return ret;
}
EXPORT_SYMBOL_GPL(extcon_unregister_interest);

/**
* extcon_register_notifier() - Register a notifiee to get notified by
* any attach status changes from the extcon.
Expand All @@ -582,14 +410,33 @@ int extcon_register_notifier(struct extcon_dev *edev, unsigned int id,
unsigned long flags;
int ret, idx;

if (!edev || !nb)
if (!nb)
return -EINVAL;

idx = find_cable_index_by_id(edev, id);
if (edev) {
idx = find_cable_index_by_id(edev, id);

spin_lock_irqsave(&edev->lock, flags);
ret = raw_notifier_chain_register(&edev->nh[idx], nb);
spin_unlock_irqrestore(&edev->lock, flags);
spin_lock_irqsave(&edev->lock, flags);
ret = raw_notifier_chain_register(&edev->nh[idx], nb);
spin_unlock_irqrestore(&edev->lock, flags);
} else {
struct extcon_dev *extd;

mutex_lock(&extcon_dev_list_lock);
list_for_each_entry(extd, &extcon_dev_list, entry) {
idx = find_cable_index_by_id(extd, id);
if (idx >= 0)
break;
}
mutex_unlock(&extcon_dev_list_lock);

if (idx >= 0) {
edev = extd;
return extcon_register_notifier(extd, id, nb);
} else {
ret = -ENODEV;
}
}

return ret;
}
Expand Down
77 changes: 53 additions & 24 deletions drivers/power/axp288_charger.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,6 @@

#define AXP288_EXTCON_DEV_NAME "axp288_extcon"

#define AXP288_EXTCON_SLOW_CHARGER "SLOW-CHARGER"
#define AXP288_EXTCON_DOWNSTREAM_CHARGER "CHARGE-DOWNSTREAM"
#define AXP288_EXTCON_FAST_CHARGER "FAST-CHARGER"

enum {
VBUS_OV_IRQ = 0,
CHARGE_DONE_IRQ,
Expand All @@ -158,7 +154,7 @@ struct axp288_chrg_info {
/* OTG/Host mode */
struct {
struct work_struct work;
struct extcon_specific_cable_nb cable;
struct extcon_dev *cable;
struct notifier_block id_nb;
bool id_short;
} otg;
Expand Down Expand Up @@ -586,17 +582,15 @@ static void axp288_charger_extcon_evt_worker(struct work_struct *work)
bool old_connected = info->cable.connected;

/* Determine cable/charger type */
if (extcon_get_cable_state(edev, AXP288_EXTCON_SLOW_CHARGER) > 0) {
if (extcon_get_cable_state_(edev, EXTCON_CHG_USB_SDP) > 0) {
dev_dbg(&info->pdev->dev, "USB SDP charger is connected");
info->cable.connected = true;
info->cable.chg_type = POWER_SUPPLY_TYPE_USB;
} else if (extcon_get_cable_state(edev,
AXP288_EXTCON_DOWNSTREAM_CHARGER) > 0) {
} else if (extcon_get_cable_state_(edev, EXTCON_CHG_USB_CDP) > 0) {
dev_dbg(&info->pdev->dev, "USB CDP charger is connected");
info->cable.connected = true;
info->cable.chg_type = POWER_SUPPLY_TYPE_USB_CDP;
} else if (extcon_get_cable_state(edev,
AXP288_EXTCON_FAST_CHARGER) > 0) {
} else if (extcon_get_cable_state_(edev, EXTCON_CHG_USB_DCP) > 0) {
dev_dbg(&info->pdev->dev, "USB DCP charger is connected");
info->cable.connected = true;
info->cable.chg_type = POWER_SUPPLY_TYPE_USB_DCP;
Expand Down Expand Up @@ -692,8 +686,8 @@ static int axp288_charger_handle_otg_evt(struct notifier_block *nb,
{
struct axp288_chrg_info *info =
container_of(nb, struct axp288_chrg_info, otg.id_nb);
struct extcon_dev *edev = param;
int usb_host = extcon_get_cable_state(edev, "USB-Host");
struct extcon_dev *edev = info->otg.cable;
int usb_host = extcon_get_cable_state_(edev, EXTCON_USB_HOST);

dev_dbg(&info->pdev->dev, "external connector USB-Host is %s\n",
usb_host ? "attached" : "detached");
Expand Down Expand Up @@ -848,10 +842,33 @@ static int axp288_charger_probe(struct platform_device *pdev)
/* Register for extcon notification */
INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker);
info->cable.nb.notifier_call = axp288_charger_handle_cable_evt;
ret = extcon_register_notifier(info->cable.edev, EXTCON_NONE, &info->cable.nb);
ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_SDP,
&info->cable.nb);
if (ret) {
dev_err(&info->pdev->dev,
"failed to register extcon notifier for SDP %d\n", ret);
return ret;
}

ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_CDP,
&info->cable.nb);
if (ret) {
dev_err(&info->pdev->dev,
"failed to register extcon notifier for CDP %d\n", ret);
extcon_unregister_notifier(info->cable.edev,
EXTCON_CHG_USB_SDP, &info->cable.nb);
return ret;
}

ret = extcon_register_notifier(info->cable.edev, EXTCON_CHG_USB_DCP,
&info->cable.nb);
if (ret) {
dev_err(&info->pdev->dev,
"failed to register extcon notifier %d\n", ret);
"failed to register extcon notifier for DCP %d\n", ret);
extcon_unregister_notifier(info->cable.edev,
EXTCON_CHG_USB_SDP, &info->cable.nb);
extcon_unregister_notifier(info->cable.edev,
EXTCON_CHG_USB_CDP, &info->cable.nb);
return ret;
}

Expand All @@ -871,14 +888,14 @@ static int axp288_charger_probe(struct platform_device *pdev)
/* Register for OTG notification */
INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker);
info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt;
ret = extcon_register_interest(&info->otg.cable, NULL, "USB-Host",
ret = extcon_register_notifier(info->otg.cable, EXTCON_USB_HOST,
&info->otg.id_nb);
if (ret)
dev_warn(&pdev->dev, "failed to register otg notifier\n");

if (info->otg.cable.edev)
info->otg.id_short = extcon_get_cable_state(
info->otg.cable.edev, "USB-Host");
if (info->otg.cable)
info->otg.id_short = extcon_get_cable_state_(
info->otg.cable, EXTCON_USB_HOST);

/* Register charger interrupts */
for (i = 0; i < CHRG_INTR_END; i++) {
Expand All @@ -905,22 +922,34 @@ static int axp288_charger_probe(struct platform_device *pdev)
return 0;

intr_reg_failed:
if (info->otg.cable.edev)
extcon_unregister_interest(&info->otg.cable);
if (info->otg.cable)
extcon_unregister_notifier(info->otg.cable, EXTCON_USB_HOST,
&info->otg.id_nb);
power_supply_unregister(info->psy_usb);
psy_reg_failed:
extcon_unregister_notifier(info->cable.edev, EXTCON_NONE, &info->cable.nb);
extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP,
&info->cable.nb);
extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP,
&info->cable.nb);
extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_DCP,
&info->cable.nb);
return ret;
}

static int axp288_charger_remove(struct platform_device *pdev)
{
struct axp288_chrg_info *info = dev_get_drvdata(&pdev->dev);

if (info->otg.cable.edev)
extcon_unregister_interest(&info->otg.cable);
if (info->otg.cable)
extcon_unregister_notifier(info->otg.cable, EXTCON_USB_HOST,
&info->otg.id_nb);

extcon_unregister_notifier(info->cable.edev, EXTCON_NONE, &info->cable.nb);
extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_SDP,
&info->cable.nb);
extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_CDP,
&info->cable.nb);
extcon_unregister_notifier(info->cable.edev, EXTCON_CHG_USB_DCP,
&info->cable.nb);
power_supply_unregister(info->psy_usb);

return 0;
Expand Down
Loading

0 comments on commit 411ef2b

Please sign in to comment.