From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758232AbcBXWbS (ORCPT ); Wed, 24 Feb 2016 17:31:18 -0500 Received: from mail-by2on0054.outbound.protection.outlook.com ([207.46.100.54]:45712 "EHLO na01-by2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753328AbcBXWbO (ORCPT ); Wed, 24 Feb 2016 17:31:14 -0500 Authentication-Results: spf=fail (sender IP is 66.35.236.227) smtp.mailfrom=opensource.altera.com; ettus.com; dkim=pass (signature was verified) header.d=altera.onmicrosoft.com;ettus.com; dmarc=none action=none header.from=opensource.altera.com; Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=opensource.altera.com; From: Alan Tull To: Rob Herring , Pantelis Antoniou CC: Frank Rowand , Grant Likely , , , Moritz Fischer , Pantelis Antoniou , Alan Tull , Dinh Nguyen , Alan Tull Subject: [PATCH] of: add pre-operation notifications Date: Wed, 24 Feb 2016 16:28:57 -0600 Message-ID: <1456352937-28311-1-git-send-email-atull@opensource.altera.com> X-Mailer: git-send-email 1.7.9.5 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [64.129.157.38] X-ClientProxiedBy: SN1PR0701CA0006.namprd07.prod.outlook.com (25.162.96.16) To BLUPR03MB1507.namprd03.prod.outlook.com (25.163.81.25) X-MS-Office365-Filtering-Correlation-Id: b5b30beb-c3e7-434b-77ea-08d33d6a3293 X-Microsoft-Exchange-Diagnostics-untrusted: 1;BLUPR03MB1507;2:W/7+mdVTfwceFlVizvUp/8goXvDmH9WCqGhHwsiLCUhdkGmKft3gWaYGDwXQM8Fv0pi9NzZQjrCRDzQxxF66TtRQ7CBXVCXjz31nfoiNLvgdD+OsVrHJyvP0EkE2O/bXhWNMZQH+BAQgZpLfy2VXpX40l4Cq/Cv6RWZm1rYTYMx2xADmqNP3Q90kskI11qxr;3:jcurOgkfXR7x6q0Q9AFnQwgSdke6KcZ6Be0uWdKyqVZ0Dov6QCKkZpOcHJ1geOfU0ZHMUpf1UxtAuXS14LXLebtXbvdMXiVlvnadg5iJDHPjVZ28kUdis//vwuTH1n/D;25:iUwTR/RVJVGG26Fmiaui6sI63U1OkkPc2ZL17/xy/YVoZn/QRB4TVjSzHTYA2ZssMyiV3DN7G3+Lm7B7TloHcHDnimD26Hz+qOBApPZwmDtzq64U3okXdOEzJn2SNyX1oZRGXBSh5XoAzLfvAEtccnNDpHkBywDuWCTHyCDD4ihsN+KHsVJ+VMkUR2Jbpwnmdu0UpmVLlA990UVx8g7O9+XGBwjAMhYvQvz64C6Vr7qYLhl7SthIeIpvn8YOtM12T84vMK0aXemazwJnroL2NJRUiPcTlWrhTZYbZ+dNj9Qm3qJDwHnIZ3JQZSFoxdpvd3wcPUySqgZkjGQiVRFzPw==;20:G1X+L+R+M5FtAgVCY+iBRp+mnChxkONJ+C4df10eiQJV3DfE2UTSKdW2MdCwv3phCybubLK/1Tzh8N0oTEiPYbRYey50u5mfxGmZbn9FVIAzZIZKEd9flIsjPJnxqjFe5tMV+QVEQx8/t4rq7Yabxhj+vtI+e6bRrjbrNWbxm+I= X-Microsoft-Antispam-Untrusted: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB1507; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:;UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046);SRVR:BLUPR03MB1507;BCL:0;PCL:0;RULEID:;SRVR:BLUPR03MB1507;BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(13018025)(8121501046)(13023025)(13024025)(13015025)(13017025)(3002001)(10201501046);SRVR:SN2PR03MB046;BCL:0;PCL:0;RULEID:;SRVR:SN2PR03MB046; X-Microsoft-Exchange-Diagnostics-untrusted: 1;BLUPR03MB1507;4:UT4DoV8K5C5NhS8Vmw2/H7hFbDaqj1fmg0J6vp63dnI1rePkICEnka7TmdkftFy7PvrTn5GFTjHupGYjBJvHj8+7ElRJweWFkGghtVC71yWZ9ntz79S/LeIM2pyO3NMgJoMJp4Qrizoh88UmAMC9kxIEUispy4GYVMY7thxhOxUZ3JLAQT7nAM24SKs/kHasIDFEpcmb3D8K2eOwR1LlNhJE1U5DXQ9f6dWdkzxcfXfCwkpbeainRy13KzUXl3wdd0H4YMDXVyubEFMFwrY0dKgmCJcnLpclkNYQgWy5muIoSnIHSw1wpo5vwYW4uQRgKbxsIJ8z8V5wYghhhPKyhaKbAzZCKk4YrjeRh0EOmabrUZ+YqLv8KtWvJ/weF8ig X-Forefront-PRVS: 08626BE3A5 X-Forefront-Antispam-Report-Untrusted: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(50466002)(2906002)(189998001)(5008740100001)(48376002)(4001430100002)(586003)(5001770100001)(3846002)(6116002)(122386002)(50226001)(575784001)(19580395003)(42186005)(4326007)(33646002)(1096002)(86362001)(5004730100002)(5890100001)(19580405001)(40100003)(53416004)(229853001)(15650500001)(66066001)(47776003)(5003940100001)(92566002)(5001960100002)(77096005)(50986999)(87976001)(107886002)(4720700001);DIR:OUT;SFP:1101;SCL:1;SRVR:BLUPR03MB1507;H:linuxheads99.altera.com;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics-untrusted: =?us-ascii?Q?1;BLUPR03MB1507;23:d2AZ06aM8/T78dRSD/nCK/ESMn5cIR/zC8opZ5zEs?= =?us-ascii?Q?Cr/G0PwG4Dsf8m6DUBBSzGYFVXQFPmziD44oJ4bQEQ9P9BROU0yNQ0+2lsd6?= =?us-ascii?Q?HH29S2VHYz6goNl1oR3ResmNwbn5L7BTj3CeGMt9n1VHp0RGjxDUnMKO49fT?= =?us-ascii?Q?F70l7KSyL9WMcLNQ99KvgoXr5xkNDjL+lwhoqMviC7h/V9/5Ym38dkn3LlcN?= =?us-ascii?Q?Rjycm0/98a5SdZLRoomVks8YTGD0orlC7xQdazIqKyER2Hh3qIwTyFpZKw5k?= =?us-ascii?Q?cd6MMSFD01ufBn+TYky205/dqV/uOXTzS04BLNBVxw3lJqgHnKdgi/sOIptk?= =?us-ascii?Q?QtkV7pWcra7W8UKqCYVC7YtVMsW3Shy63SFR0YHrWDR1sVVajj20Jx0OtKiF?= =?us-ascii?Q?ZQGzMhkGzWra9GM2ZA5QGJWEn4lO8mx5sW7SQBPET34J+RtiJ1taDxa69cMw?= =?us-ascii?Q?NXZ/RTvUOYF9u51b9qj5oRmcFZQjV+azjhAVeBVF2V1CaJKOzJpRKvflndr/?= =?us-ascii?Q?y2vKm6TpD49JBvp6yeGDU59ZfqVxZzGuMC8cECqzSgEsSoFFbJRL3xztxUqI?= =?us-ascii?Q?DXmZgdxbobp04ATgOJaeyvP6rmAwtY4Pqt2IoiUEzQFt+7/8cp6KMuGKyGGc?= =?us-ascii?Q?grkQEfTZ36jwxPHwAzrvb6+QCJra7WCLKP8QK2mmOimKynovDJZlumlLgmrT?= =?us-ascii?Q?Eedm7WsiyqipottW+ODmbBQOnmb5yOgfqFcyTx0QcvIf3A6iqqZy8EIyogTC?= =?us-ascii?Q?uwZ6tY1LdIwidolzdfkFhhKqxJwH2q1aGeKaR6rm7uotz2X+rYHOw0LoApDz?= =?us-ascii?Q?wEof2GFrI4t/UYqa/V3yluina1pPPNghfinowyXRYOk/aU6DrJ0Bibt5BurN?= =?us-ascii?Q?VFwiLehHrUtTJewyilr/0MOWMNq53Fp9E4+2rGnIIbQOU4qvx/+EEItwy6Lo?= =?us-ascii?Q?51nEiwLTa5x/b8sHnxbD9kYOHudSVF30MhSAaqhCrkYtvLwP7fH1tprNMI3m?= =?us-ascii?Q?i+1kkWcArSfm7qZhpk1UsXH228yKPYuhZ3w6OmndURKb4jir6rdp0nbC7jt6?= =?us-ascii?Q?iYxm6PlWvUX9p/UfJCJccmRTCw3?= X-Microsoft-Exchange-Diagnostics-untrusted: 1;BLUPR03MB1507;5:kT3bcg2XPBKhNpZjgfFltbk5rT/r9ReqY3XICParQP62YTSMjV7Qke2PcvwPZFTYcTagirPr7n1M61pGkTlVBfRRNGCtv+Y06oU8k8IWq5KEoD4hpAzCRLIshfU4IMnA/6fdevXXNGDR2gYXc/zlZQ==;24:K+cxJlfTFOr3RTASK3zj+XA7pqMqaFlkKcy3zjGM9EEr7rk5X/ZmdqxD8I9VlIHmyFLgI6g+52ext0xjzZIp4DLYKD8/PeXlJjJSW26YLEs=;20:6lfHX47wyExGGHSZ12dD8z/o0TJXhaDTlyaLDF1m40zvnH0SYgibwAcgM1ytnc6TmLvINp0rHacXyyYCPzTfpjpi7jNkgRCmIs0RxqqjWM7q3bD3vrb7Rxn6jfOAwpxtPJQX7KofSVwd+GvoQFyoDWs9RZgtHbE7uqVXExZtqN4= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR03MB1507 X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: BN1BFFO11FD047.protection.gbl X-Microsoft-Exchange-Diagnostics: 1;BN1BFFO11FD047;1:sbpHQ5YlbVszprwE309b3b3klGXpadQ5X4gZ1PDywdGzg1NL/vA7hJ042vu9DiKxg6tEf148TG3cdBzdpzGFeMQRBMB2X4Ap5YJ4YMnsn4ISGE8iRjDPMWlmngnAhLLLajxz8XPQARKkWRsZh53EmNTzp02FPalv670CP2im+/VKduDYM55hCCFZMoWjLQMzNoticJDyR2ZxEQru/ofawF7Fi2xTTGxQUF1w4hkKAWerr1iuMtEe33YPNkKo8wahnqBlm7kqs5GIlbiYlpdrSf8o8vzS4peR4N8tV+eCnif2vxSaykM7FZLyLdkYKmqj9OT99oCybqDQuNzs6MSz7yLDC1j9gTERZdu1r00I9B0Sp1UD7tN/mojmKjZPTQX4fCXLUbSKknH7CeuXWTRlQU2mLprGpeCcS1NWfMhUUaU= X-Forefront-Antispam-Report: CIP:66.35.236.227;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(2980300002)(1109001)(1110001)(339900001)(199003)(189002)(87936001)(53416004)(956001)(3720700001)(50986999)(16796002)(3846002)(6806005)(11100500001)(105606002)(189998001)(15650500001)(107886002)(1220700001)(4001430100002)(575784001)(5008740100001)(47776003)(1096002)(4326007)(2906002)(586003)(5004730100002)(5001960100002)(6116002)(33646002)(50466002)(122386002)(50226001)(229853001)(40100003)(85426001)(5003940100001)(106466001)(86362001)(77096005)(19580395003)(19580405001)(66066001)(5890100001)(48376002)(5001770100001)(92566002)(7099028)(4720700001);DIR:OUT;SFP:1101;SCL:1;SRVR:SN2PR03MB046;H:sj-itexedge03.altera.priv.altera.com;FPR:;SPF:Fail;MLV:sfv;A:0;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;SN2PR03MB046;2:D7Iw8NM7SPit+yZ37+0YlcKo9+QpHV+5yLKaVdcOXhk/4aaWNY9258CQ3wyHtV28NImoYW3bHr+G0I3X1+79PTc2JGKEu3HJKWeP+KfWQxJKASdrIcWWWPJ7TMec8Pktx7g2dEX8d71WSsJTZSLZWfWc5FTdxjT16BYTUxez5N3YP15j9ym8MZMbZZUBqXot;3:+x/rfcRMc8eXRaTyGsJvDI/a6v53twXYPfYiBPm9VEQovohHlF5JcRw+R7RmkK+QxXGbKGUIuCXEutOm1osphCNWx8vjUGtU/9y0JgF7F+d9iwT1QLPBpTssfADQ/uxYGR7OeStEXkd+Nfvx+6rsOlySdFlxFc6yg5kqqjg3pPRHnFZkPkAm0b89Qu4h1mwjcWbJHb0doZJdabQ1dzYWV4Cs2RwLOWVCHbKBPqVPP8yVvUsZL5aN7qYRNMO9L5qU;25:4lCf+ncXJb3bg5xJV7/rxsgd0ga5xij3iOJXdDObJwUr/Bxvpnc68ejLT8Ys/1IvFLoANsgBdkKKg/V0g6WvZuB4fZpMf8szmJWSVofuECZ2ueJ0PrfXov70XbFXbVQ0dtkhf5ZzedtXK1IDmSsCrU8vQvXYR02Wu0zvA4Y/04HvL8n1wlw35I3oU/zcp2Fho1kY9GI5ifLwft0zlTUaZ3p97waJuc4w+Hrzhno2MpOz039WSOScPjwxUNqWvejkXBvoywOIbifXTDFDKLqinhT9lolqgyJMn8oF0LUxz76Yr070ku3rAphCGr+6MN60fqAK9Cpda3qh6wczoDTqug==;20:npc9Iv9cfJ1p3gz5C66WxEP9JD6NZ+yT8BskIdhqGXtAoknO6S2xQmkimHh5e1Deu8fr/mQenhqhH6N0AxBsq/Wizgir1MNlJqaAJphR2VlTDJ/KGJn6Air9G7skA6cBfD516DdFnwHTZ8W2zPvvGVadO+vR9p2z79xGGgnLVPY= X-DkimResult-Test: Passed X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(3001016);SRVR:SN2PR03MB046; X-Microsoft-Exchange-Diagnostics: 1;SN2PR03MB046;4:pPybXPMLBDMcP6RXrJXna/AQ4tsMK7/OwRKsfoj/B/icQd2e4OO4skumURNArtXrl7qqZgq7fmXKWSfmjKWMRV/Nq+0BqN+Dkdd6/WkdcdezOCKN0+xka7f25eqAFosa501P0jVFYJdbk7cIHoE0+UYDhewW8hK8ZgIATj2FgsgaKJOhEiRtit5djuv+9uee2/g4T0Ouh7DOvXY8pQUdPixlHZLMwK08DilfSM+RnDSO9Ga163F5pK92/LpBTyaHISv9u6Is7QvflONS5dVYobVjA9VsvXRlWqmLewu7QFMc6Y0C69F6TB/peq7O0lCGjVfpG5luXdqQSy+/jhYumDHbFHJTHdsbP4kZDcmc0nxTEC6CRr3TPBiBnRApxSYEcvUE2PUqc9tppLSUrokwtSM6UOOfpcHIpDmFHeu2I1YAR5Iv/3Xb5YXuel+nLHwLv4qIkyY4AWNbH6mw7LRSfg== X-Forefront-PRVS: 08626BE3A5 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;SN2PR03MB046;23:CNimPaSWm+TLAUqXDmirnmjQsLSh+5tuUq1fvmksul?= =?us-ascii?Q?kSzGgxjFJwuUXONw+SDjv+daVzX61cvCsWt86jtiHt9q3UvFs4yznXhq4Em5?= =?us-ascii?Q?Nnc/nzbtAFDv3azXQ1jEk54nvv4ujcXzXf5BJImaaFAMbIDmomaggF4wQdSq?= =?us-ascii?Q?hvgP5TTp6jkIMMawgPP2HlRql3OSx3tSqutyttuz5kMMViIHUnOi0cJe5G6H?= =?us-ascii?Q?gjpOG9CXN4dSeUSlzTDwBpNJv0nJoiqSAi1sir4Y/hD3+3EuWZ8SMHtNo6HK?= =?us-ascii?Q?yQbtX/Lc7vB8sHSxkvvhBnfxs4HVXevFfJk6L4/pzV9SHTC8CtgBjkID8UPp?= =?us-ascii?Q?J10R10z5fnyTTe2XMJhFJh/w1Te73cSiTEJZRGuF1Ay8qxJQt2pLZ4OCp1mn?= =?us-ascii?Q?eeHcuw6jsrgSnNcU7dKyo669CZGsXYvAG5FbFGRdWkeROQnE7MhDyP2o06M9?= =?us-ascii?Q?uxU0e+xfc0+E3etSQ9Su41yBlzdx/Yguei8nW1HhR7GfMqWmj1KGNDp74Yp0?= =?us-ascii?Q?jCYuSPV8sD4VZ12rfXrgLdnyyb6TyQWIAcJpN3ORFzzi7haEH8C73MT5myi9?= =?us-ascii?Q?TkGcuLTzA8apR1MUaFXv5bQmiJFi6CpVkohfiv94F7JAUfenDmXRL0dzHWAL?= =?us-ascii?Q?vROYXw5T2tdvjFLE1B3k2dfKMrQTYpFgyb5rZQZoIMJes9Znx1DncQiNr+Cx?= =?us-ascii?Q?yYjlpQhFTDLJZl5MdrVl+GUI4PNDsMLeYIh405RcUUm2cDz6kLtmOI6H7PJ+?= =?us-ascii?Q?Vx6Gm9vMqUV9ktcrd3XIt9i90u7S6ZfWXvYZ0eUHLDCL/em1c/qZ66NREw06?= =?us-ascii?Q?uY0YIPYoRwCsHMqFocWe7413SiZv7Lxrcnf9ci4qtWTcOlLPSeBHV8Pc+t/p?= =?us-ascii?Q?vGrRGEmjmJFIhG8s2lyaeO22KUuufmX9PtQ+nT5Y1dtJs+IIlbBQc9+b/Yjc?= =?us-ascii?Q?Ee9WZ75t3iePYMU/51787szNQQW2GcvenCnQ+ryzc0ibjozBGucF2P4HDK/J?= =?us-ascii?Q?Z2npVQHtJDuzN2PxtBH8beRwgjBfS8XXSmp3nlPkiEjjtuzVQbNSe8ZX5xq+?= =?us-ascii?Q?p3WQ783LQY/lLrflPvoGsTnZEBNpW2emL5akCMOxwsEVHuoosLjcoPWdXPjB?= =?us-ascii?Q?oz1ub0zfmjklGXkz0CMB81JgLQQqWBG6wYGtq0Oj4PqLTNYX5oZ1ryHtinxr?= =?us-ascii?Q?Pjzx5eY1EpajUR/O/qbmC0/SYH9ofxws51Gkb9KntpelPyZPCm7QfV6pKCSR?= =?us-ascii?Q?pLJGpCVTnAdMs1mA3o1YCqKnvLEJzxbntFEF/0OzDioBOrWmhaX0aVslwJp5?= =?us-ascii?Q?ZHRcFJHi9L8WyTPNQlep8C9/sUtyZMZR/BM8V/T1JgEkvvgvlgG6hbuyiCmq?= =?us-ascii?Q?Unqw=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;SN2PR03MB046;5:1DIARFX5tGzCfNyAnmezFK42SNQz+BUClG7HKWSG/9h4hEWmYeW1f+W5JJRW5SA5crR/MUwOisCvQbtiBejNY1QwDvDfUd664mVPNxNBfjxQ5CH4zjEVRui+PiqvR8nuEqRFbxC5k7o92EaX8F1DCQ==;24:L8DPu0HlQVrL1GkZXOdKq92eU3psQIalcwaFOQslvYvNGR/mKvBEZsZBOVLtNdR3lK8yciRNPvIAAljVdes1jCfKv1fTDLDVkUivkVF3akU=;20:RVmhgznnExCx4eulrEjUS9/bffpmQ62YLVUYV0d/RIFPFEgz2CvocqIIpP3RYu9Y2LL5TDJEKEEfH3R4dqRd0RXtsydmh0EsURaheU67Up/Bedxn4c7rF9i+D0YG1C6496qStsXRxVfnZexgdTCD0zgptEv6fgAey8tpbJPuCtU= X-OriginatorOrg: opensource.altera.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Feb 2016 22:31:10.9980 (UTC) X-MS-Exchange-CrossTenant-Id: fbd72e03-d4a5-4110-adce-614d51f2077a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=fbd72e03-d4a5-4110-adce-614d51f2077a;Ip=[66.35.236.227];Helo=[sj-itexedge03.altera.priv.altera.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN2PR03MB046 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add pre-apply and pre-remove notifications. For pre-apply notifications that result from creating an overlay, include a device node to the overlay fragment in of_reconfig_data. If a pre-apply notifier return error, reject the changeset. Signed-off-by: Alan Tull --- drivers/of/base.c | 20 +++++++++++++ drivers/of/dynamic.c | 79 +++++++++++++++++++++++++++++++++++++++++++++----- drivers/of/overlay.c | 46 +++++++++++++++++++++++++---- include/linux/of.h | 7 +++++ 4 files changed, 138 insertions(+), 14 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 017dd94..6d170e0 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1719,6 +1719,12 @@ int of_add_property(struct device_node *np, struct property *prop) mutex_lock(&of_mutex); + rc = of_property_notify(OF_RECONFIG_PRE_ADD_PROPERTY, np, prop, NULL); + if (rc) { + mutex_unlock(&of_mutex); + return rc; + } + raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_add_property(np, prop); raw_spin_unlock_irqrestore(&devtree_lock, flags); @@ -1778,6 +1784,13 @@ int of_remove_property(struct device_node *np, struct property *prop) mutex_lock(&of_mutex); + rc = of_property_notify(OF_RECONFIG_PRE_REMOVE_PROPERTY, np, prop, + NULL); + if (rc) { + mutex_unlock(&of_mutex); + return rc; + } + raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_remove_property(np, prop); raw_spin_unlock_irqrestore(&devtree_lock, flags); @@ -1854,6 +1867,13 @@ int of_update_property(struct device_node *np, struct property *newprop) mutex_lock(&of_mutex); + rc = of_property_notify(OF_RECONFIG_PRE_UPDATE_PROPERTY, np, newprop, + oldprop); + if (rc) { + mutex_unlock(&of_mutex); + return rc; + } + raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_update_property(np, newprop, &oldprop); raw_spin_unlock_irqrestore(&devtree_lock, flags); diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index f0bf021..1ac9f49 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -85,6 +85,12 @@ const char *action_names[] = { [OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY", [OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY", [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY", + + [OF_RECONFIG_PRE_ATTACH_NODE] = "PRE_ATTACH_NODE", + [OF_RECONFIG_PRE_DETACH_NODE] = "PRE_DETACH_NODE", + [OF_RECONFIG_PRE_ADD_PROPERTY] = "PRE_ADD_PROPERTY", + [OF_RECONFIG_PRE_REMOVE_PROPERTY] = "PRE_REMOVE_PROPERTY", + [OF_RECONFIG_PRE_UPDATE_PROPERTY] = "PRE_UPDATE_PROPERTY", }; #endif @@ -97,12 +103,17 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) switch (action) { case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_DETACH_NODE: + case OF_RECONFIG_PRE_ATTACH_NODE: + case OF_RECONFIG_PRE_DETACH_NODE: pr_debug("of/notify %-15s %s\n", action_names[action], pr->dn->full_name); break; case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY: + case OF_RECONFIG_PRE_ADD_PROPERTY: + case OF_RECONFIG_PRE_REMOVE_PROPERTY: + case OF_RECONFIG_PRE_UPDATE_PROPERTY: pr_debug("of/notify %-15s %s:%s\n", action_names[action], pr->dn->full_name, pr->prop->name); break; @@ -141,6 +152,13 @@ int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data * prop = pr->prop; old_prop = pr->old_prop; break; + /* no state change during pre-apply notifications */ + case OF_RECONFIG_PRE_ATTACH_NODE: + case OF_RECONFIG_PRE_DETACH_NODE: + case OF_RECONFIG_PRE_ADD_PROPERTY: + case OF_RECONFIG_PRE_REMOVE_PROPERTY: + case OF_RECONFIG_PRE_UPDATE_PROPERTY: + return OF_RECONFIG_NO_CHANGE; default: return OF_RECONFIG_NO_CHANGE; } @@ -502,10 +520,31 @@ static void __of_changeset_entry_invert(struct of_changeset_entry *ce, } } -static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) +static unsigned long __of_changeset_entry_pre_action(unsigned long action) +{ + switch (action) { + case OF_RECONFIG_ATTACH_NODE: + return OF_RECONFIG_PRE_ATTACH_NODE; + case OF_RECONFIG_DETACH_NODE: + return OF_RECONFIG_PRE_DETACH_NODE; + case OF_RECONFIG_ADD_PROPERTY: + return OF_RECONFIG_PRE_ADD_PROPERTY; + case OF_RECONFIG_REMOVE_PROPERTY: + return OF_RECONFIG_PRE_REMOVE_PROPERTY; + case OF_RECONFIG_UPDATE_PROPERTY: + return OF_RECONFIG_PRE_UPDATE_PROPERTY; + } + + /* this should not happen */ + return action; +} + +static int __of_changeset_entry_notify(struct of_changeset_entry *ce, + bool revert, bool pre) { struct of_reconfig_data rd; struct of_changeset_entry ce_inverted; + unsigned long action; int ret; if (revert) { @@ -513,26 +552,38 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve ce = &ce_inverted; } - switch (ce->action) { + action = ce->action; + if (pre) + action = __of_changeset_entry_pre_action(action); + + switch (action) { case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_DETACH_NODE: + case OF_RECONFIG_PRE_DETACH_NODE: + case OF_RECONFIG_PRE_ATTACH_NODE: memset(&rd, 0, sizeof(rd)); rd.dn = ce->np; - ret = of_reconfig_notify(ce->action, &rd); + ret = of_reconfig_notify(action, &rd); break; case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY: - ret = of_property_notify(ce->action, ce->np, ce->prop, ce->old_prop); + case OF_RECONFIG_PRE_REMOVE_PROPERTY: + case OF_RECONFIG_PRE_ADD_PROPERTY: + case OF_RECONFIG_PRE_UPDATE_PROPERTY: + ret = of_property_notify(action, ce->np, ce->prop, + ce->old_prop); break; default: pr_err("%s: invalid devicetree changeset action: %i\n", __func__, - (int)ce->action); - return; + (int)action); + return -EINVAL; } if (ret) pr_err("%s: notifier error @%s\n", __func__, ce->np->full_name); + + return ret; } static int __of_changeset_entry_apply(struct of_changeset_entry *ce) @@ -687,7 +738,7 @@ int __of_changeset_apply(struct of_changeset *ocs) /* drop the global lock while emitting notifiers */ mutex_unlock(&of_mutex); list_for_each_entry(ce, &ocs->entries, node) - __of_changeset_entry_notify(ce, 0); + __of_changeset_entry_notify(ce, 0, 0); mutex_lock(&of_mutex); pr_debug("of_changeset: notifiers sent.\n"); @@ -708,8 +759,16 @@ int __of_changeset_apply(struct of_changeset *ocs) */ int of_changeset_apply(struct of_changeset *ocs) { + struct of_changeset_entry *ce; int ret; + pr_debug("of_changeset: pre-apply notifiers.\n"); + list_for_each_entry(ce, &ocs->entries, node) { + ret = __of_changeset_entry_notify(ce, 0, 1); + if (ret) + return ret; + } + mutex_lock(&of_mutex); ret = __of_changeset_apply(ocs); mutex_unlock(&of_mutex); @@ -723,6 +782,10 @@ int __of_changeset_revert(struct of_changeset *ocs) struct of_changeset_entry *ce; int ret; + pr_debug("of_changeset: emitting pre-revert notifiers.\n"); + list_for_each_entry_reverse(ce, &ocs->entries, node) + __of_changeset_entry_notify(ce, 1, 1); + pr_debug("of_changeset: reverting...\n"); list_for_each_entry_reverse(ce, &ocs->entries, node) { ret = __of_changeset_entry_revert(ce); @@ -738,7 +801,7 @@ int __of_changeset_revert(struct of_changeset *ocs) /* drop the global lock while emitting notifiers */ mutex_unlock(&of_mutex); list_for_each_entry_reverse(ce, &ocs->entries, node) - __of_changeset_entry_notify(ce, 1); + __of_changeset_entry_notify(ce, 1, 0); mutex_lock(&of_mutex); pr_debug("of_changeset: notifiers sent.\n"); diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 8225081..9d0c0d9 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -53,13 +53,30 @@ struct of_overlay { struct of_changeset cset; }; +static int of_overlay_notify(unsigned long action, struct device_node *np, + struct property *prop, struct property *old_prop, + struct device_node *overlay) +{ + struct of_reconfig_data rd; + + memset(&rd, 0, sizeof(rd)); + rd.dn = np; + rd.prop = prop; + rd.old_prop = old_prop; + rd.overlay = overlay; + return of_reconfig_notify(action, &rd); +} + static int of_overlay_apply_one(struct of_overlay *ov, - struct device_node *target, const struct device_node *overlay); + struct device_node *target, struct device_node *overlay); static int of_overlay_apply_single_property(struct of_overlay *ov, - struct device_node *target, struct property *prop) + struct device_node *target, struct property *prop, + struct device_node *overlay) { struct property *propn, *tprop; + unsigned long action; + int ret; /* NOTE: Multiple changes of single properties not supported */ tprop = of_find_property(target, prop->name, NULL); @@ -74,6 +91,15 @@ static int of_overlay_apply_single_property(struct of_overlay *ov, if (propn == NULL) return -ENOMEM; + if (!tprop) + action = OF_RECONFIG_PRE_ADD_PROPERTY; + else + action = OF_RECONFIG_PRE_UPDATE_PROPERTY; + + ret = of_overlay_notify(action, target, propn, tprop, overlay); + if (ret) + return ret; + /* not found? add */ if (tprop == NULL) return of_changeset_add_property(&ov->cset, target, propn); @@ -83,7 +109,8 @@ static int of_overlay_apply_single_property(struct of_overlay *ov, } static int of_overlay_apply_single_device_node(struct of_overlay *ov, - struct device_node *target, struct device_node *child) + struct device_node *target, struct device_node *child, + struct device_node *overlay) { const char *cname; struct device_node *tchild; @@ -108,6 +135,11 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, /* point to parent */ tchild->parent = target; + ret = of_overlay_notify(OF_RECONFIG_PRE_ATTACH_NODE, tchild, + NULL, NULL, overlay); + if (ret) + return ret; + ret = of_changeset_attach_node(&ov->cset, tchild); if (ret) return ret; @@ -128,14 +160,15 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, * by using the changeset. */ static int of_overlay_apply_one(struct of_overlay *ov, - struct device_node *target, const struct device_node *overlay) + struct device_node *target, struct device_node *overlay) { struct device_node *child; struct property *prop; int ret; for_each_property_of_node(overlay, prop) { - ret = of_overlay_apply_single_property(ov, target, prop); + ret = of_overlay_apply_single_property(ov, target, prop, + overlay); if (ret) { pr_err("%s: Failed to apply prop @%s/%s\n", __func__, target->full_name, prop->name); @@ -144,7 +177,8 @@ static int of_overlay_apply_one(struct of_overlay *ov, } for_each_child_of_node(overlay, child) { - ret = of_overlay_apply_single_device_node(ov, target, child); + ret = of_overlay_apply_single_device_node(ov, target, child, + overlay); if (ret != 0) { pr_err("%s: Failed to apply single node @%s/%s\n", __func__, target->full_name, diff --git a/include/linux/of.h b/include/linux/of.h index dd10626..c350a26 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -79,6 +79,7 @@ struct of_reconfig_data { struct device_node *dn; struct property *prop; struct property *old_prop; + struct device_node *overlay; /* only for pre-apply notify */ }; /* initialize a node */ @@ -350,6 +351,12 @@ extern int of_update_property(struct device_node *np, struct property *newprop); #define OF_RECONFIG_ADD_PROPERTY 0x0003 #define OF_RECONFIG_REMOVE_PROPERTY 0x0004 #define OF_RECONFIG_UPDATE_PROPERTY 0x0005 +#define OF_RECONFIG_PRE_ATTACH_NODE 0x0006 +#define OF_RECONFIG_PRE_DETACH_NODE 0x0007 +#define OF_RECONFIG_PRE_ADD_PROPERTY 0x0008 +#define OF_RECONFIG_PRE_REMOVE_PROPERTY 0x0009 +#define OF_RECONFIG_PRE_UPDATE_PROPERTY 0x000a + extern int of_attach_node(struct device_node *); extern int of_detach_node(struct device_node *); -- 1.7.9.5 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alan Tull Subject: [PATCH] of: add pre-operation notifications Date: Wed, 24 Feb 2016 16:28:57 -0600 Message-ID: <1456352937-28311-1-git-send-email-atull@opensource.altera.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Sender: devicetree-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: Rob Herring , Pantelis Antoniou Cc: Frank Rowand , Grant Likely , devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Moritz Fischer , Pantelis Antoniou , Alan Tull , Dinh Nguyen , Alan Tull List-Id: devicetree@vger.kernel.org Add pre-apply and pre-remove notifications. For pre-apply notifications that result from creating an overlay, include a device node to the overlay fragment in of_reconfig_data. If a pre-apply notifier return error, reject the changeset. Signed-off-by: Alan Tull --- drivers/of/base.c | 20 +++++++++++++ drivers/of/dynamic.c | 79 +++++++++++++++++++++++++++++++++++++++++++++----- drivers/of/overlay.c | 46 +++++++++++++++++++++++++---- include/linux/of.h | 7 +++++ 4 files changed, 138 insertions(+), 14 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index 017dd94..6d170e0 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1719,6 +1719,12 @@ int of_add_property(struct device_node *np, struct property *prop) mutex_lock(&of_mutex); + rc = of_property_notify(OF_RECONFIG_PRE_ADD_PROPERTY, np, prop, NULL); + if (rc) { + mutex_unlock(&of_mutex); + return rc; + } + raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_add_property(np, prop); raw_spin_unlock_irqrestore(&devtree_lock, flags); @@ -1778,6 +1784,13 @@ int of_remove_property(struct device_node *np, struct property *prop) mutex_lock(&of_mutex); + rc = of_property_notify(OF_RECONFIG_PRE_REMOVE_PROPERTY, np, prop, + NULL); + if (rc) { + mutex_unlock(&of_mutex); + return rc; + } + raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_remove_property(np, prop); raw_spin_unlock_irqrestore(&devtree_lock, flags); @@ -1854,6 +1867,13 @@ int of_update_property(struct device_node *np, struct property *newprop) mutex_lock(&of_mutex); + rc = of_property_notify(OF_RECONFIG_PRE_UPDATE_PROPERTY, np, newprop, + oldprop); + if (rc) { + mutex_unlock(&of_mutex); + return rc; + } + raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_update_property(np, newprop, &oldprop); raw_spin_unlock_irqrestore(&devtree_lock, flags); diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index f0bf021..1ac9f49 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -85,6 +85,12 @@ const char *action_names[] = { [OF_RECONFIG_ADD_PROPERTY] = "ADD_PROPERTY", [OF_RECONFIG_REMOVE_PROPERTY] = "REMOVE_PROPERTY", [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY", + + [OF_RECONFIG_PRE_ATTACH_NODE] = "PRE_ATTACH_NODE", + [OF_RECONFIG_PRE_DETACH_NODE] = "PRE_DETACH_NODE", + [OF_RECONFIG_PRE_ADD_PROPERTY] = "PRE_ADD_PROPERTY", + [OF_RECONFIG_PRE_REMOVE_PROPERTY] = "PRE_REMOVE_PROPERTY", + [OF_RECONFIG_PRE_UPDATE_PROPERTY] = "PRE_UPDATE_PROPERTY", }; #endif @@ -97,12 +103,17 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) switch (action) { case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_DETACH_NODE: + case OF_RECONFIG_PRE_ATTACH_NODE: + case OF_RECONFIG_PRE_DETACH_NODE: pr_debug("of/notify %-15s %s\n", action_names[action], pr->dn->full_name); break; case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY: + case OF_RECONFIG_PRE_ADD_PROPERTY: + case OF_RECONFIG_PRE_REMOVE_PROPERTY: + case OF_RECONFIG_PRE_UPDATE_PROPERTY: pr_debug("of/notify %-15s %s:%s\n", action_names[action], pr->dn->full_name, pr->prop->name); break; @@ -141,6 +152,13 @@ int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data * prop = pr->prop; old_prop = pr->old_prop; break; + /* no state change during pre-apply notifications */ + case OF_RECONFIG_PRE_ATTACH_NODE: + case OF_RECONFIG_PRE_DETACH_NODE: + case OF_RECONFIG_PRE_ADD_PROPERTY: + case OF_RECONFIG_PRE_REMOVE_PROPERTY: + case OF_RECONFIG_PRE_UPDATE_PROPERTY: + return OF_RECONFIG_NO_CHANGE; default: return OF_RECONFIG_NO_CHANGE; } @@ -502,10 +520,31 @@ static void __of_changeset_entry_invert(struct of_changeset_entry *ce, } } -static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool revert) +static unsigned long __of_changeset_entry_pre_action(unsigned long action) +{ + switch (action) { + case OF_RECONFIG_ATTACH_NODE: + return OF_RECONFIG_PRE_ATTACH_NODE; + case OF_RECONFIG_DETACH_NODE: + return OF_RECONFIG_PRE_DETACH_NODE; + case OF_RECONFIG_ADD_PROPERTY: + return OF_RECONFIG_PRE_ADD_PROPERTY; + case OF_RECONFIG_REMOVE_PROPERTY: + return OF_RECONFIG_PRE_REMOVE_PROPERTY; + case OF_RECONFIG_UPDATE_PROPERTY: + return OF_RECONFIG_PRE_UPDATE_PROPERTY; + } + + /* this should not happen */ + return action; +} + +static int __of_changeset_entry_notify(struct of_changeset_entry *ce, + bool revert, bool pre) { struct of_reconfig_data rd; struct of_changeset_entry ce_inverted; + unsigned long action; int ret; if (revert) { @@ -513,26 +552,38 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve ce = &ce_inverted; } - switch (ce->action) { + action = ce->action; + if (pre) + action = __of_changeset_entry_pre_action(action); + + switch (action) { case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_DETACH_NODE: + case OF_RECONFIG_PRE_DETACH_NODE: + case OF_RECONFIG_PRE_ATTACH_NODE: memset(&rd, 0, sizeof(rd)); rd.dn = ce->np; - ret = of_reconfig_notify(ce->action, &rd); + ret = of_reconfig_notify(action, &rd); break; case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY: - ret = of_property_notify(ce->action, ce->np, ce->prop, ce->old_prop); + case OF_RECONFIG_PRE_REMOVE_PROPERTY: + case OF_RECONFIG_PRE_ADD_PROPERTY: + case OF_RECONFIG_PRE_UPDATE_PROPERTY: + ret = of_property_notify(action, ce->np, ce->prop, + ce->old_prop); break; default: pr_err("%s: invalid devicetree changeset action: %i\n", __func__, - (int)ce->action); - return; + (int)action); + return -EINVAL; } if (ret) pr_err("%s: notifier error @%s\n", __func__, ce->np->full_name); + + return ret; } static int __of_changeset_entry_apply(struct of_changeset_entry *ce) @@ -687,7 +738,7 @@ int __of_changeset_apply(struct of_changeset *ocs) /* drop the global lock while emitting notifiers */ mutex_unlock(&of_mutex); list_for_each_entry(ce, &ocs->entries, node) - __of_changeset_entry_notify(ce, 0); + __of_changeset_entry_notify(ce, 0, 0); mutex_lock(&of_mutex); pr_debug("of_changeset: notifiers sent.\n"); @@ -708,8 +759,16 @@ int __of_changeset_apply(struct of_changeset *ocs) */ int of_changeset_apply(struct of_changeset *ocs) { + struct of_changeset_entry *ce; int ret; + pr_debug("of_changeset: pre-apply notifiers.\n"); + list_for_each_entry(ce, &ocs->entries, node) { + ret = __of_changeset_entry_notify(ce, 0, 1); + if (ret) + return ret; + } + mutex_lock(&of_mutex); ret = __of_changeset_apply(ocs); mutex_unlock(&of_mutex); @@ -723,6 +782,10 @@ int __of_changeset_revert(struct of_changeset *ocs) struct of_changeset_entry *ce; int ret; + pr_debug("of_changeset: emitting pre-revert notifiers.\n"); + list_for_each_entry_reverse(ce, &ocs->entries, node) + __of_changeset_entry_notify(ce, 1, 1); + pr_debug("of_changeset: reverting...\n"); list_for_each_entry_reverse(ce, &ocs->entries, node) { ret = __of_changeset_entry_revert(ce); @@ -738,7 +801,7 @@ int __of_changeset_revert(struct of_changeset *ocs) /* drop the global lock while emitting notifiers */ mutex_unlock(&of_mutex); list_for_each_entry_reverse(ce, &ocs->entries, node) - __of_changeset_entry_notify(ce, 1); + __of_changeset_entry_notify(ce, 1, 0); mutex_lock(&of_mutex); pr_debug("of_changeset: notifiers sent.\n"); diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 8225081..9d0c0d9 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -53,13 +53,30 @@ struct of_overlay { struct of_changeset cset; }; +static int of_overlay_notify(unsigned long action, struct device_node *np, + struct property *prop, struct property *old_prop, + struct device_node *overlay) +{ + struct of_reconfig_data rd; + + memset(&rd, 0, sizeof(rd)); + rd.dn = np; + rd.prop = prop; + rd.old_prop = old_prop; + rd.overlay = overlay; + return of_reconfig_notify(action, &rd); +} + static int of_overlay_apply_one(struct of_overlay *ov, - struct device_node *target, const struct device_node *overlay); + struct device_node *target, struct device_node *overlay); static int of_overlay_apply_single_property(struct of_overlay *ov, - struct device_node *target, struct property *prop) + struct device_node *target, struct property *prop, + struct device_node *overlay) { struct property *propn, *tprop; + unsigned long action; + int ret; /* NOTE: Multiple changes of single properties not supported */ tprop = of_find_property(target, prop->name, NULL); @@ -74,6 +91,15 @@ static int of_overlay_apply_single_property(struct of_overlay *ov, if (propn == NULL) return -ENOMEM; + if (!tprop) + action = OF_RECONFIG_PRE_ADD_PROPERTY; + else + action = OF_RECONFIG_PRE_UPDATE_PROPERTY; + + ret = of_overlay_notify(action, target, propn, tprop, overlay); + if (ret) + return ret; + /* not found? add */ if (tprop == NULL) return of_changeset_add_property(&ov->cset, target, propn); @@ -83,7 +109,8 @@ static int of_overlay_apply_single_property(struct of_overlay *ov, } static int of_overlay_apply_single_device_node(struct of_overlay *ov, - struct device_node *target, struct device_node *child) + struct device_node *target, struct device_node *child, + struct device_node *overlay) { const char *cname; struct device_node *tchild; @@ -108,6 +135,11 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, /* point to parent */ tchild->parent = target; + ret = of_overlay_notify(OF_RECONFIG_PRE_ATTACH_NODE, tchild, + NULL, NULL, overlay); + if (ret) + return ret; + ret = of_changeset_attach_node(&ov->cset, tchild); if (ret) return ret; @@ -128,14 +160,15 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, * by using the changeset. */ static int of_overlay_apply_one(struct of_overlay *ov, - struct device_node *target, const struct device_node *overlay) + struct device_node *target, struct device_node *overlay) { struct device_node *child; struct property *prop; int ret; for_each_property_of_node(overlay, prop) { - ret = of_overlay_apply_single_property(ov, target, prop); + ret = of_overlay_apply_single_property(ov, target, prop, + overlay); if (ret) { pr_err("%s: Failed to apply prop @%s/%s\n", __func__, target->full_name, prop->name); @@ -144,7 +177,8 @@ static int of_overlay_apply_one(struct of_overlay *ov, } for_each_child_of_node(overlay, child) { - ret = of_overlay_apply_single_device_node(ov, target, child); + ret = of_overlay_apply_single_device_node(ov, target, child, + overlay); if (ret != 0) { pr_err("%s: Failed to apply single node @%s/%s\n", __func__, target->full_name, diff --git a/include/linux/of.h b/include/linux/of.h index dd10626..c350a26 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -79,6 +79,7 @@ struct of_reconfig_data { struct device_node *dn; struct property *prop; struct property *old_prop; + struct device_node *overlay; /* only for pre-apply notify */ }; /* initialize a node */ @@ -350,6 +351,12 @@ extern int of_update_property(struct device_node *np, struct property *newprop); #define OF_RECONFIG_ADD_PROPERTY 0x0003 #define OF_RECONFIG_REMOVE_PROPERTY 0x0004 #define OF_RECONFIG_UPDATE_PROPERTY 0x0005 +#define OF_RECONFIG_PRE_ATTACH_NODE 0x0006 +#define OF_RECONFIG_PRE_DETACH_NODE 0x0007 +#define OF_RECONFIG_PRE_ADD_PROPERTY 0x0008 +#define OF_RECONFIG_PRE_REMOVE_PROPERTY 0x0009 +#define OF_RECONFIG_PRE_UPDATE_PROPERTY 0x000a + extern int of_attach_node(struct device_node *); extern int of_detach_node(struct device_node *); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html