lkml.org 
[lkml]   [2014]   [Apr]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 6/8] OF: i2c: Add overlay bus handler
    Date
    Add the bus handler registration needed for performing overlays
    containing i2c devices.

    Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
    ---
    drivers/i2c/i2c-core.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++-
    1 file changed, 86 insertions(+), 1 deletion(-)

    diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
    index aee3b99..017fb03 100644
    --- a/drivers/i2c/i2c-core.c
    +++ b/drivers/i2c/i2c-core.c
    @@ -1082,10 +1082,89 @@ struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
    return i2c_verify_adapter(dev);
    }
    EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
    +
    +#ifdef CONFIG_OF_OVERLAY
    +static int i2c_handler_create(struct of_overlay_device_entry *de,
    + int revert)
    +{
    + struct device_node *dn;
    + struct i2c_adapter *adap;
    + struct i2c_client *client;
    +
    + if (!de || !de->np)
    + return -ENOTSUPP;
    +
    + dn = de->np;
    +
    + adap = of_find_i2c_adapter_by_node(dn->parent);
    + if (adap == NULL)
    + return -ENOTSUPP;
    +
    + client = of_i2c_register_device(adap, dn);
    + put_device(&adap->dev);
    +
    + if (client == NULL) {
    + pr_err("%s: failed to create i2c client device "
    + "for '%s'\n",
    + __func__, dn->full_name);
    + /* of_i2c_device_create tosses the real error code */
    + return -EINVAL;
    + }
    +
    + return 0;
    +}
    +
    +static int i2c_handler_remove(struct of_overlay_device_entry *de,
    + int revert)
    +{
    + struct device_node *dn;
    + struct i2c_client *client;
    +
    + if (!de || !de->np)
    + return -ENOTSUPP;
    +
    + dn = de->np;
    +
    + client = of_find_i2c_device_by_node(dn);
    + if (client == NULL)
    + return -ENOTSUPP;
    +
    + /* unregister takes one ref away */
    + i2c_unregister_device(client);
    +
    + /* and put the reference of the find */
    + put_device(&client->dev);
    +
    + return 0;
    +}
    +
    +static const struct of_overlay_handler_ops i2c_handler_ops = {
    + .create = i2c_handler_create,
    + .remove = i2c_handler_remove,
    +};
    +
    +static struct of_overlay_handler i2c_handler = {
    + .name = "i2c",
    + .ops = &i2c_handler_ops,
    +};
    +
    +static int __init i2c_bus_handler_register(void)
    +{
    + return of_overlay_handler_register(&i2c_handler);
    +}
    +#endif
    +
    #else
    static void of_i2c_register_devices(struct i2c_adapter *adap) { }
    #endif /* CONFIG_OF */

    +#if !defined(CONFIG_OF) || !defined(CONFIG_OF_OVERLAY)
    +static inline int i2c_bus_handler_register(void)
    +{
    + return 0;
    +}
    +#endif
    +
    /* ACPI support code */

    #if IS_ENABLED(CONFIG_ACPI)
    @@ -1677,8 +1756,14 @@ static int __init i2c_init(void)
    retval = i2c_add_driver(&dummy_driver);
    if (retval)
    goto class_err;
    - return 0;

    + retval = i2c_bus_handler_register();
    + if (retval)
    + goto bus_handler_err;
    +
    + return 0;
    +bus_handler_err:
    + i2c_del_driver(&dummy_driver);
    class_err:
    #ifdef CONFIG_I2C_COMPAT
    class_compat_unregister(i2c_adapter_compat_class);
    --
    1.7.12


    \
     
     \ /
      Last update: 2014-04-04 15:01    [W:3.431 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site