From patchwork Mon Nov 24 22:33:40 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Likely X-Patchwork-Id: 414133 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 67563140170 for ; Tue, 25 Nov 2014 09:35:51 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750813AbaKXWfC (ORCPT ); Mon, 24 Nov 2014 17:35:02 -0500 Received: from mail-wg0-f46.google.com ([74.125.82.46]:35136 "EHLO mail-wg0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751362AbaKXWeP (ORCPT ); Mon, 24 Nov 2014 17:34:15 -0500 Received: by mail-wg0-f46.google.com with SMTP id x12so13711282wgg.33 for ; Mon, 24 Nov 2014 14:34:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=TL+Dwn8a4wjpjMtjDcz3FEPpzQRFF/vRt1EPC+fI3Fs=; b=JFiaUkqVbk1+ITr3Ek4zrf8KR0L5AzvXD2/LEFa2PJAuy0fWoFUOqxd7w16LenUfmd T2mfz8AYT5MQX/0a7gU3X5E3MUgH8T1Q0L+5Ul6IA1b0EE+c/wkGmbSf2cdb6gbdSJQV +LjG+4H05lGNPyML8dp3HG5uZHis7pUHrM0jRGw2gzEMmPUAJDn3pcinf94G0e6qQNwZ igOsgbteXNmz9RTXnSLWNuI3I675TCaJorSMeYdMQQ6NBe0BRqXBFcMoQd5+KHomazJJ +SxWWQEGfG40RGBLd2VYMxOsDREsMrnDBRoNssqeX1Yax6/Mg3pRoEzwg8MEERwyio+g f0Ow== X-Gm-Message-State: ALoCoQnkYzAPhebvKgduRRF9qz8xvDb3bZuZCDGboX8mm6uUvGSoqU2nrbjmErjhdTvsl5OvJtIm X-Received: by 10.180.218.39 with SMTP id pd7mr4791264wic.21.1416868454171; Mon, 24 Nov 2014 14:34:14 -0800 (PST) Received: from trevor.secretlab.ca (host86-166-84-117.range86-166.btcentralplus.com. [86.166.84.117]) by mx.google.com with ESMTPSA id ef6sm38921wic.1.2014.11.24.14.34.10 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Nov 2014 14:34:12 -0800 (PST) Received: by trevor.secretlab.ca (Postfix, from userid 1000) id E49F9C44216; Mon, 24 Nov 2014 22:33:45 +0000 (GMT) From: Grant Likely To: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Pantelis Antoniou Cc: Rob Herring , Mark Brown , Wolfram Sang , Grant Likely , linux-i2c@vger.kernel.org Subject: [PATCH v2 12/14] i2c/of: Add OF_RECONFIG notifier handler Date: Mon, 24 Nov 2014 22:33:40 +0000 Message-Id: <1416868422-22103-13-git-send-email-grant.likely@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1416868422-22103-1-git-send-email-grant.likely@linaro.org> References: <1416868422-22103-1-git-send-email-grant.likely@linaro.org> Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org From: Pantelis Antoniou CONFIG_OF_DYNAMIC enables runtime changes to the device tree which in turn may trigger addition or removal of devices from Linux. Add an OF_RECONFIG notifier handler to receive tree change events and to creating or destroy i2c devices as required. Signed-off-by: Pantelis Antoniou [grant.likely: clean up #ifdefs and drop unneeded error handling] Signed-off-by: Grant Likely Cc: Wolfram Sang Cc: Rob Herring Cc: linux-i2c@vger.kernel.org Reviewed-by: Wolfram Sang --- drivers/i2c/i2c-core.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 15ba6185dba5..d8afd3f28ca4 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1951,6 +1951,52 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) } EXPORT_SYMBOL(i2c_clients_command); +#if IS_ENABLED(CONFIG_OF_DYNAMIC) +static int of_i2c_notify(struct notifier_block *nb, unsigned long action, + void *arg) +{ + struct of_reconfig_data *rd = arg; + struct i2c_adapter *adap; + struct i2c_client *client; + + switch (of_reconfig_get_state_change(action, rd)) { + case OF_RECONFIG_CHANGE_ADD: + adap = of_find_i2c_adapter_by_node(rd->dn->parent); + if (adap == NULL) + return NOTIFY_OK; /* not for us */ + + client = of_i2c_register_device(adap, rd->dn); + put_device(&adap->dev); + + if (IS_ERR(client)) { + pr_err("%s: failed to create for '%s'\n", + __func__, rd->dn->full_name); + return notifier_from_errno(PTR_ERR(client)); + } + break; + case OF_RECONFIG_CHANGE_REMOVE: + /* find our device by node */ + client = of_find_i2c_device_by_node(rd->dn); + if (client == NULL) + return NOTIFY_OK; /* no? not meant for us */ + + /* unregister takes one ref away */ + i2c_unregister_device(client); + + /* and put the reference of the find */ + put_device(&client->dev); + break; + } + + return NOTIFY_OK; +} +static struct notifier_block i2c_of_notifier = { + .notifier_call = of_i2c_notify, +}; +#else +extern struct notifier_block i2c_of_notifier; +#endif /* CONFIG_OF_DYNAMIC */ + static int __init i2c_init(void) { int retval; @@ -1968,6 +2014,10 @@ static int __init i2c_init(void) retval = i2c_add_driver(&dummy_driver); if (retval) goto class_err; + + if (IS_ENABLED(CONFIG_OF_DYNAMIC)) + WARN_ON(of_reconfig_notifier_register(&i2c_of_notifier)); + return 0; class_err: @@ -1981,6 +2031,8 @@ bus_err: static void __exit i2c_exit(void) { + if (IS_ENABLED(CONFIG_OF_DYNAMIC)) + WARN_ON(of_reconfig_notifier_unregister(&i2c_of_notifier)); i2c_del_driver(&dummy_driver); #ifdef CONFIG_I2C_COMPAT class_compat_unregister(i2c_adapter_compat_class);