aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 12:58:09 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 12:58:09 -0500
commit16e024f30ce96ef5fa651e2914e19d175a924cab (patch)
treed68106151a0b36e22625d7af7b23081a48c92e87 /drivers/of
parentc36e0501ee91d7616a188efbf9714b1fce150032 (diff)
parent376bddd34433065aeb9b9a140870537feecf90ef (diff)
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull powerpc update from Benjamin Herrenschmidt: "The main highlight is probably some base POWER8 support. There's more to come such as transactional memory support but that will wait for the next one. Overall it's pretty quiet, or rather I've been pretty poor at picking things up from patchwork and reviewing them this time around and Kumar no better on the FSL side it seems..." * 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (73 commits) powerpc+of: Rename and fix OF reconfig notifier error inject module powerpc: mpc5200: Add a3m071 board support powerpc/512x: don't compile any platform DIU code if the DIU is not enabled powerpc/mpc52xx: use module_platform_driver macro powerpc+of: Export of_reconfig_notifier_[register,unregister] powerpc/dma/raidengine: add raidengine device powerpc/iommu/fsl: Add PAMU bypass enable register to ccsr_guts struct powerpc/mpc85xx: Change spin table to cached memory powerpc/fsl-pci: Add PCI controller ATMU PM support powerpc/86xx: fsl_pcibios_fixup_bus requires CONFIG_PCI drivers/virt: the Freescale hypervisor driver doesn't need to check MSR[GS] powerpc/85xx: p1022ds: Use NULL instead of 0 for pointers powerpc: Disable relocation on exceptions when kexecing powerpc: Enable relocation on during exceptions at boot powerpc: Move get_longbusy_msecs into hvcall.h and remove duplicate function powerpc: Add wrappers to enable/disable relocation on exceptions powerpc: Add set_mode hcall powerpc: Setup relocation on exceptions for bare metal systems powerpc: Move initial mfspr LPCR out of __init_LPCR powerpc: Add relocation on exception vector handlers ...
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/base.c142
1 files changed, 127 insertions, 15 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index be846408dbc1..db8d211a0d05 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1114,13 +1114,36 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
1114} 1114}
1115EXPORT_SYMBOL(of_parse_phandle_with_args); 1115EXPORT_SYMBOL(of_parse_phandle_with_args);
1116 1116
1117#if defined(CONFIG_OF_DYNAMIC)
1118static int of_property_notify(int action, struct device_node *np,
1119 struct property *prop)
1120{
1121 struct of_prop_reconfig pr;
1122
1123 pr.dn = np;
1124 pr.prop = prop;
1125 return of_reconfig_notify(action, &pr);
1126}
1127#else
1128static int of_property_notify(int action, struct device_node *np,
1129 struct property *prop)
1130{
1131 return 0;
1132}
1133#endif
1134
1117/** 1135/**
1118 * prom_add_property - Add a property to a node 1136 * of_add_property - Add a property to a node
1119 */ 1137 */
1120int prom_add_property(struct device_node *np, struct property *prop) 1138int of_add_property(struct device_node *np, struct property *prop)
1121{ 1139{
1122 struct property **next; 1140 struct property **next;
1123 unsigned long flags; 1141 unsigned long flags;
1142 int rc;
1143
1144 rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
1145 if (rc)
1146 return rc;
1124 1147
1125 prop->next = NULL; 1148 prop->next = NULL;
1126 write_lock_irqsave(&devtree_lock, flags); 1149 write_lock_irqsave(&devtree_lock, flags);
@@ -1146,18 +1169,23 @@ int prom_add_property(struct device_node *np, struct property *prop)
1146} 1169}
1147 1170
1148/** 1171/**
1149 * prom_remove_property - Remove a property from a node. 1172 * of_remove_property - Remove a property from a node.
1150 * 1173 *
1151 * Note that we don't actually remove it, since we have given out 1174 * Note that we don't actually remove it, since we have given out
1152 * who-knows-how-many pointers to the data using get-property. 1175 * who-knows-how-many pointers to the data using get-property.
1153 * Instead we just move the property to the "dead properties" 1176 * Instead we just move the property to the "dead properties"
1154 * list, so it won't be found any more. 1177 * list, so it won't be found any more.
1155 */ 1178 */
1156int prom_remove_property(struct device_node *np, struct property *prop) 1179int of_remove_property(struct device_node *np, struct property *prop)
1157{ 1180{
1158 struct property **next; 1181 struct property **next;
1159 unsigned long flags; 1182 unsigned long flags;
1160 int found = 0; 1183 int found = 0;
1184 int rc;
1185
1186 rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
1187 if (rc)
1188 return rc;
1161 1189
1162 write_lock_irqsave(&devtree_lock, flags); 1190 write_lock_irqsave(&devtree_lock, flags);
1163 next = &np->properties; 1191 next = &np->properties;
@@ -1187,7 +1215,7 @@ int prom_remove_property(struct device_node *np, struct property *prop)
1187} 1215}
1188 1216
1189/* 1217/*
1190 * prom_update_property - Update a property in a node, if the property does 1218 * of_update_property - Update a property in a node, if the property does
1191 * not exist, add it. 1219 * not exist, add it.
1192 * 1220 *
1193 * Note that we don't actually remove it, since we have given out 1221 * Note that we don't actually remove it, since we have given out
@@ -1195,19 +1223,22 @@ int prom_remove_property(struct device_node *np, struct property *prop)
1195 * Instead we just move the property to the "dead properties" list, 1223 * Instead we just move the property to the "dead properties" list,
1196 * and add the new property to the property list 1224 * and add the new property to the property list
1197 */ 1225 */
1198int prom_update_property(struct device_node *np, 1226int of_update_property(struct device_node *np, struct property *newprop)
1199 struct property *newprop)
1200{ 1227{
1201 struct property **next, *oldprop; 1228 struct property **next, *oldprop;
1202 unsigned long flags; 1229 unsigned long flags;
1203 int found = 0; 1230 int rc, found = 0;
1231
1232 rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
1233 if (rc)
1234 return rc;
1204 1235
1205 if (!newprop->name) 1236 if (!newprop->name)
1206 return -EINVAL; 1237 return -EINVAL;
1207 1238
1208 oldprop = of_find_property(np, newprop->name, NULL); 1239 oldprop = of_find_property(np, newprop->name, NULL);
1209 if (!oldprop) 1240 if (!oldprop)
1210 return prom_add_property(np, newprop); 1241 return of_add_property(np, newprop);
1211 1242
1212 write_lock_irqsave(&devtree_lock, flags); 1243 write_lock_irqsave(&devtree_lock, flags);
1213 next = &np->properties; 1244 next = &np->properties;
@@ -1246,12 +1277,55 @@ int prom_update_property(struct device_node *np,
1246 * device tree nodes. 1277 * device tree nodes.
1247 */ 1278 */
1248 1279
1280static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
1281
1282int of_reconfig_notifier_register(struct notifier_block *nb)
1283{
1284 return blocking_notifier_chain_register(&of_reconfig_chain, nb);
1285}
1286EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
1287
1288int of_reconfig_notifier_unregister(struct notifier_block *nb)
1289{
1290 return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
1291}
1292EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
1293
1294int of_reconfig_notify(unsigned long action, void *p)
1295{
1296 int rc;
1297
1298 rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
1299 return notifier_to_errno(rc);
1300}
1301
1302#ifdef CONFIG_PROC_DEVICETREE
1303static void of_add_proc_dt_entry(struct device_node *dn)
1304{
1305 struct proc_dir_entry *ent;
1306
1307 ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
1308 if (ent)
1309 proc_device_tree_add_node(dn, ent);
1310}
1311#else
1312static void of_add_proc_dt_entry(struct device_node *dn)
1313{
1314 return;
1315}
1316#endif
1317
1249/** 1318/**
1250 * of_attach_node - Plug a device node into the tree and global list. 1319 * of_attach_node - Plug a device node into the tree and global list.
1251 */ 1320 */
1252void of_attach_node(struct device_node *np) 1321int of_attach_node(struct device_node *np)
1253{ 1322{
1254 unsigned long flags; 1323 unsigned long flags;
1324 int rc;
1325
1326 rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
1327 if (rc)
1328 return rc;
1255 1329
1256 write_lock_irqsave(&devtree_lock, flags); 1330 write_lock_irqsave(&devtree_lock, flags);
1257 np->sibling = np->parent->child; 1331 np->sibling = np->parent->child;
@@ -1259,24 +1333,61 @@ void of_attach_node(struct device_node *np)
1259 np->parent->child = np; 1333 np->parent->child = np;
1260 of_allnodes = np; 1334 of_allnodes = np;
1261 write_unlock_irqrestore(&devtree_lock, flags); 1335 write_unlock_irqrestore(&devtree_lock, flags);
1336
1337 of_add_proc_dt_entry(np);
1338 return 0;
1262} 1339}
1263 1340
1341#ifdef CONFIG_PROC_DEVICETREE
1342static void of_remove_proc_dt_entry(struct device_node *dn)
1343{
1344 struct device_node *parent = dn->parent;
1345 struct property *prop = dn->properties;
1346
1347 while (prop) {
1348 remove_proc_entry(prop->name, dn->pde);
1349 prop = prop->next;
1350 }
1351
1352 if (dn->pde)
1353 remove_proc_entry(dn->pde->name, parent->pde);
1354}
1355#else
1356static void of_remove_proc_dt_entry(struct device_node *dn)
1357{
1358 return;
1359}
1360#endif
1361
1264/** 1362/**
1265 * of_detach_node - "Unplug" a node from the device tree. 1363 * of_detach_node - "Unplug" a node from the device tree.
1266 * 1364 *
1267 * The caller must hold a reference to the node. The memory associated with 1365 * The caller must hold a reference to the node. The memory associated with
1268 * the node is not freed until its refcount goes to zero. 1366 * the node is not freed until its refcount goes to zero.
1269 */ 1367 */
1270void of_detach_node(struct device_node *np) 1368int of_detach_node(struct device_node *np)
1271{ 1369{
1272 struct device_node *parent; 1370 struct device_node *parent;
1273 unsigned long flags; 1371 unsigned long flags;
1372 int rc = 0;
1373
1374 rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
1375 if (rc)
1376 return rc;
1274 1377
1275 write_lock_irqsave(&devtree_lock, flags); 1378 write_lock_irqsave(&devtree_lock, flags);
1276 1379
1380 if (of_node_check_flag(np, OF_DETACHED)) {
1381 /* someone already detached it */
1382 write_unlock_irqrestore(&devtree_lock, flags);
1383 return rc;
1384 }
1385
1277 parent = np->parent; 1386 parent = np->parent;
1278 if (!parent) 1387 if (!parent) {
1279 goto out_unlock; 1388 write_unlock_irqrestore(&devtree_lock, flags);
1389 return rc;
1390 }
1280 1391
1281 if (of_allnodes == np) 1392 if (of_allnodes == np)
1282 of_allnodes = np->allnext; 1393 of_allnodes = np->allnext;
@@ -1301,9 +1412,10 @@ void of_detach_node(struct device_node *np)
1301 } 1412 }
1302 1413
1303 of_node_set_flag(np, OF_DETACHED); 1414 of_node_set_flag(np, OF_DETACHED);
1304
1305out_unlock:
1306 write_unlock_irqrestore(&devtree_lock, flags); 1415 write_unlock_irqrestore(&devtree_lock, flags);
1416
1417 of_remove_proc_dt_entry(np);
1418 return rc;
1307} 1419}
1308#endif /* defined(CONFIG_OF_DYNAMIC) */ 1420#endif /* defined(CONFIG_OF_DYNAMIC) */
1309 1421