1*dfa76060SDavid S. Miller /* prom_common.c: OF device tree support common code. 2*dfa76060SDavid S. Miller * 3*dfa76060SDavid S. Miller * Paul Mackerras August 1996. 4*dfa76060SDavid S. Miller * Copyright (C) 1996-2005 Paul Mackerras. 5*dfa76060SDavid S. Miller * 6*dfa76060SDavid S. Miller * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. 7*dfa76060SDavid S. Miller * {engebret|bergner}@us.ibm.com 8*dfa76060SDavid S. Miller * 9*dfa76060SDavid S. Miller * Adapted for sparc by David S. Miller davem@davemloft.net 10*dfa76060SDavid S. Miller * 11*dfa76060SDavid S. Miller * This program is free software; you can redistribute it and/or 12*dfa76060SDavid S. Miller * modify it under the terms of the GNU General Public License 13*dfa76060SDavid S. Miller * as published by the Free Software Foundation; either version 14*dfa76060SDavid S. Miller * 2 of the License, or (at your option) any later version. 15*dfa76060SDavid S. Miller */ 16*dfa76060SDavid S. Miller 17*dfa76060SDavid S. Miller #include <linux/kernel.h> 18*dfa76060SDavid S. Miller #include <linux/module.h> 19*dfa76060SDavid S. Miller #include <linux/errno.h> 20*dfa76060SDavid S. Miller #include <linux/mutex.h> 21*dfa76060SDavid S. Miller #include <linux/slab.h> 22*dfa76060SDavid S. Miller #include <linux/of.h> 23*dfa76060SDavid S. Miller #include <asm/prom.h> 24*dfa76060SDavid S. Miller #include <asm/oplib.h> 25*dfa76060SDavid S. Miller 26*dfa76060SDavid S. Miller #include "prom.h" 27*dfa76060SDavid S. Miller 28*dfa76060SDavid S. Miller struct device_node *of_find_node_by_phandle(phandle handle) 29*dfa76060SDavid S. Miller { 30*dfa76060SDavid S. Miller struct device_node *np; 31*dfa76060SDavid S. Miller 32*dfa76060SDavid S. Miller for (np = allnodes; np; np = np->allnext) 33*dfa76060SDavid S. Miller if (np->node == handle) 34*dfa76060SDavid S. Miller break; 35*dfa76060SDavid S. Miller 36*dfa76060SDavid S. Miller return np; 37*dfa76060SDavid S. Miller } 38*dfa76060SDavid S. Miller EXPORT_SYMBOL(of_find_node_by_phandle); 39*dfa76060SDavid S. Miller 40*dfa76060SDavid S. Miller int of_getintprop_default(struct device_node *np, const char *name, int def) 41*dfa76060SDavid S. Miller { 42*dfa76060SDavid S. Miller struct property *prop; 43*dfa76060SDavid S. Miller int len; 44*dfa76060SDavid S. Miller 45*dfa76060SDavid S. Miller prop = of_find_property(np, name, &len); 46*dfa76060SDavid S. Miller if (!prop || len != 4) 47*dfa76060SDavid S. Miller return def; 48*dfa76060SDavid S. Miller 49*dfa76060SDavid S. Miller return *(int *) prop->value; 50*dfa76060SDavid S. Miller } 51*dfa76060SDavid S. Miller EXPORT_SYMBOL(of_getintprop_default); 52*dfa76060SDavid S. Miller 53*dfa76060SDavid S. Miller DEFINE_MUTEX(of_set_property_mutex); 54*dfa76060SDavid S. Miller EXPORT_SYMBOL(of_set_property_mutex); 55*dfa76060SDavid S. Miller 56*dfa76060SDavid S. Miller int of_set_property(struct device_node *dp, const char *name, void *val, int len) 57*dfa76060SDavid S. Miller { 58*dfa76060SDavid S. Miller struct property **prevp; 59*dfa76060SDavid S. Miller void *new_val; 60*dfa76060SDavid S. Miller int err; 61*dfa76060SDavid S. Miller 62*dfa76060SDavid S. Miller new_val = kmalloc(len, GFP_KERNEL); 63*dfa76060SDavid S. Miller if (!new_val) 64*dfa76060SDavid S. Miller return -ENOMEM; 65*dfa76060SDavid S. Miller 66*dfa76060SDavid S. Miller memcpy(new_val, val, len); 67*dfa76060SDavid S. Miller 68*dfa76060SDavid S. Miller err = -ENODEV; 69*dfa76060SDavid S. Miller 70*dfa76060SDavid S. Miller write_lock(&devtree_lock); 71*dfa76060SDavid S. Miller prevp = &dp->properties; 72*dfa76060SDavid S. Miller while (*prevp) { 73*dfa76060SDavid S. Miller struct property *prop = *prevp; 74*dfa76060SDavid S. Miller 75*dfa76060SDavid S. Miller if (!strcasecmp(prop->name, name)) { 76*dfa76060SDavid S. Miller void *old_val = prop->value; 77*dfa76060SDavid S. Miller int ret; 78*dfa76060SDavid S. Miller 79*dfa76060SDavid S. Miller mutex_lock(&of_set_property_mutex); 80*dfa76060SDavid S. Miller ret = prom_setprop(dp->node, name, val, len); 81*dfa76060SDavid S. Miller mutex_unlock(&of_set_property_mutex); 82*dfa76060SDavid S. Miller 83*dfa76060SDavid S. Miller err = -EINVAL; 84*dfa76060SDavid S. Miller if (ret >= 0) { 85*dfa76060SDavid S. Miller prop->value = new_val; 86*dfa76060SDavid S. Miller prop->length = len; 87*dfa76060SDavid S. Miller 88*dfa76060SDavid S. Miller if (OF_IS_DYNAMIC(prop)) 89*dfa76060SDavid S. Miller kfree(old_val); 90*dfa76060SDavid S. Miller 91*dfa76060SDavid S. Miller OF_MARK_DYNAMIC(prop); 92*dfa76060SDavid S. Miller 93*dfa76060SDavid S. Miller err = 0; 94*dfa76060SDavid S. Miller } 95*dfa76060SDavid S. Miller break; 96*dfa76060SDavid S. Miller } 97*dfa76060SDavid S. Miller prevp = &(*prevp)->next; 98*dfa76060SDavid S. Miller } 99*dfa76060SDavid S. Miller write_unlock(&devtree_lock); 100*dfa76060SDavid S. Miller 101*dfa76060SDavid S. Miller /* XXX Upate procfs if necessary... */ 102*dfa76060SDavid S. Miller 103*dfa76060SDavid S. Miller return err; 104*dfa76060SDavid S. Miller } 105*dfa76060SDavid S. Miller EXPORT_SYMBOL(of_set_property); 106*dfa76060SDavid S. Miller 107*dfa76060SDavid S. Miller int of_find_in_proplist(const char *list, const char *match, int len) 108*dfa76060SDavid S. Miller { 109*dfa76060SDavid S. Miller while (len > 0) { 110*dfa76060SDavid S. Miller int l; 111*dfa76060SDavid S. Miller 112*dfa76060SDavid S. Miller if (!strcmp(list, match)) 113*dfa76060SDavid S. Miller return 1; 114*dfa76060SDavid S. Miller l = strlen(list) + 1; 115*dfa76060SDavid S. Miller list += l; 116*dfa76060SDavid S. Miller len -= l; 117*dfa76060SDavid S. Miller } 118*dfa76060SDavid S. Miller return 0; 119*dfa76060SDavid S. Miller } 120*dfa76060SDavid S. Miller EXPORT_SYMBOL(of_find_in_proplist); 121*dfa76060SDavid S. Miller 122