diff options
Diffstat (limited to 'drivers/extcon/extcon.c')
-rw-r--r-- | drivers/extcon/extcon.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index e7a9561a826d..e1c71359b605 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -167,6 +167,16 @@ static const struct __extcon_info { .id = EXTCON_DISP_HMD, .name = "HMD", }, + [EXTCON_DISP_CVBS] = { + .type = EXTCON_TYPE_DISP, + .id = EXTCON_DISP_CVBS, + .name = "CVBS", + }, + [EXTCON_DISP_EDP] = { + .type = EXTCON_TYPE_DISP, + .id = EXTCON_DISP_EDP, + .name = "EDP", + }, /* Miscellaneous external connector */ [EXTCON_DOCK] = { @@ -247,7 +257,7 @@ static int find_cable_index_by_id(struct extcon_dev *edev, const unsigned int id { int i; - /* Find the the index of extcon cable in edev->supported_cable */ + /* Find the index of extcon cable in edev->supported_cable */ for (i = 0; i < edev->max_supported; i++) { if (edev->supported_cable[i] == id) return i; @@ -399,6 +409,7 @@ static ssize_t cable_state_show(struct device *dev, /** * extcon_sync() - Synchronize the state for an external connector. * @edev: the extcon device + * @id: the unique id indicating an external connector * * Note that this function send a notification in order to synchronize * the state and property of an external connector. @@ -576,19 +587,7 @@ EXPORT_SYMBOL_GPL(extcon_set_state); */ int extcon_set_state_sync(struct extcon_dev *edev, unsigned int id, bool state) { - int ret, index; - unsigned long flags; - - index = find_cable_index_by_id(edev, id); - if (index < 0) - return index; - - /* Check whether the external connector's state is changed. */ - spin_lock_irqsave(&edev->lock, flags); - ret = is_extcon_changed(edev, index, state); - spin_unlock_irqrestore(&edev->lock, flags); - if (!ret) - return 0; + int ret; ret = extcon_set_state(edev, id, state); if (ret < 0) @@ -748,6 +747,9 @@ EXPORT_SYMBOL_GPL(extcon_set_property); /** * extcon_set_property_sync() - Set property of an external connector with sync. + * @edev: the extcon device + * @id: the unique id indicating an external connector + * @prop: the property id indicating an extcon property * @prop_val: the pointer including the new value of extcon property * * Note that when setting the property value of external connector, @@ -863,6 +865,8 @@ EXPORT_SYMBOL_GPL(extcon_set_property_capability); * @extcon_name: the extcon name provided with extcon_dev_register() * * Return the pointer of extcon device if success or ERR_PTR(err) if fail. + * NOTE: This function returns -EPROBE_DEFER so it may only be called from + * probe() functions. */ struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) { @@ -876,7 +880,7 @@ struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) if (!strcmp(sd->name, extcon_name)) goto out; } - sd = NULL; + sd = ERR_PTR(-EPROBE_DEFER); out: mutex_unlock(&extcon_dev_list_lock); return sd; @@ -1230,19 +1234,14 @@ int extcon_dev_register(struct extcon_dev *edev) edev->dev.type = &edev->extcon_dev_type; } - ret = device_register(&edev->dev); - if (ret) { - put_device(&edev->dev); - goto err_dev; - } - spin_lock_init(&edev->lock); - edev->nh = devm_kcalloc(&edev->dev, edev->max_supported, - sizeof(*edev->nh), GFP_KERNEL); - if (!edev->nh) { - ret = -ENOMEM; - device_unregister(&edev->dev); - goto err_dev; + if (edev->max_supported) { + edev->nh = kcalloc(edev->max_supported, sizeof(*edev->nh), + GFP_KERNEL); + if (!edev->nh) { + ret = -ENOMEM; + goto err_alloc_nh; + } } for (index = 0; index < edev->max_supported; index++) @@ -1253,6 +1252,12 @@ int extcon_dev_register(struct extcon_dev *edev) dev_set_drvdata(&edev->dev, edev); edev->state = 0; + ret = device_register(&edev->dev); + if (ret) { + put_device(&edev->dev); + goto err_dev; + } + mutex_lock(&extcon_dev_list_lock); list_add(&edev->entry, &extcon_dev_list); mutex_unlock(&extcon_dev_list_lock); @@ -1261,6 +1266,9 @@ int extcon_dev_register(struct extcon_dev *edev) err_dev: if (edev->max_supported) + kfree(edev->nh); +err_alloc_nh: + if (edev->max_supported) kfree(edev->extcon_dev_type.groups); err_alloc_groups: if (edev->max_supported && edev->mutually_exclusive) { @@ -1320,6 +1328,7 @@ void extcon_dev_unregister(struct extcon_dev *edev) if (edev->max_supported) { kfree(edev->extcon_dev_type.groups); kfree(edev->cables); + kfree(edev->nh); } put_device(&edev->dev); |