Skip to content

Commit

Permalink
usb: common: usb-conn-gpio: fix NULL pointer dereference of charger
Browse files Browse the repository at this point in the history
When power on system with OTG cable, IDDIG's interrupt arises before
the charger registration, it will cause a NULL pointer dereference,
fix the issue by registering the power supply before requesting
IDDIG/VBUS irq.

Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Link: https://lore.kernel.org/r/1621406386-18838-1-git-send-email-chunfeng.yun@mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Chunfeng Yun authored and gregkh committed May 21, 2021
1 parent c63fef4 commit 8802879
Showing 1 changed file with 26 additions and 18 deletions.
44 changes: 26 additions & 18 deletions drivers/usb/common/usb-conn-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,32 @@ static int usb_charger_get_property(struct power_supply *psy,
return 0;
}

static int usb_conn_probe(struct platform_device *pdev)
static int usb_conn_psy_register(struct usb_conn_info *info)
{
struct device *dev = &pdev->dev;
struct power_supply_desc *desc;
struct usb_conn_info *info;
struct device *dev = info->dev;
struct power_supply_desc *desc = &info->desc;
struct power_supply_config cfg = {
.of_node = dev->of_node,
};

desc->name = "usb-charger";
desc->properties = usb_charger_properties;
desc->num_properties = ARRAY_SIZE(usb_charger_properties);
desc->get_property = usb_charger_get_property;
desc->type = POWER_SUPPLY_TYPE_USB;
cfg.drv_data = info;

info->charger = devm_power_supply_register(dev, desc, &cfg);
if (IS_ERR(info->charger))
dev_err(dev, "Unable to register charger\n");

return PTR_ERR_OR_ZERO(info->charger);
}

static int usb_conn_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct usb_conn_info *info;
bool need_vbus = true;
int ret = 0;

Expand Down Expand Up @@ -218,6 +236,10 @@ static int usb_conn_probe(struct platform_device *pdev)
return PTR_ERR(info->role_sw);
}

ret = usb_conn_psy_register(info);
if (ret)
goto put_role_sw;

if (info->id_gpiod) {
info->id_irq = gpiod_to_irq(info->id_gpiod);
if (info->id_irq < 0) {
Expand Down Expand Up @@ -252,20 +274,6 @@ static int usb_conn_probe(struct platform_device *pdev)
}
}

desc = &info->desc;
desc->name = "usb-charger";
desc->properties = usb_charger_properties;
desc->num_properties = ARRAY_SIZE(usb_charger_properties);
desc->get_property = usb_charger_get_property;
desc->type = POWER_SUPPLY_TYPE_USB;
cfg.drv_data = info;

info->charger = devm_power_supply_register(dev, desc, &cfg);
if (IS_ERR(info->charger)) {
dev_err(dev, "Unable to register charger\n");
return PTR_ERR(info->charger);
}

platform_set_drvdata(pdev, info);

/* Perform initial detection */
Expand Down

0 comments on commit 8802879

Please sign in to comment.