static int update_dt_node(u32 phandle, s32 scope) { struct update_props_workarea *upwa; struct device_node *dn; struct property *prop = NULL; int i, rc, rtas_rc; char *prop_data; char *rtas_buf; int update_properties_token; u32 vd; update_properties_token = rtas_token("ibm,update-properties"); if (update_properties_token == RTAS_UNKNOWN_SERVICE) return -EINVAL; rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); if (!rtas_buf) return -ENOMEM; dn = of_find_node_by_phandle(phandle); if (!dn) { kfree(rtas_buf); return -ENOENT; } upwa = (struct update_props_workarea *)&rtas_buf[0]; upwa->phandle = phandle; do { rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf, scope); if (rtas_rc < 0) break; prop_data = rtas_buf + sizeof(*upwa); /* On the first call to ibm,update-properties for a node the * the first property value descriptor contains an empty * property name, the property value length encoded as u32, * and the property value is the node path being updated. */ if (*prop_data == 0) { prop_data++; vd = *(u32 *)prop_data; prop_data += vd + sizeof(vd); upwa->nprops--; } for (i = 0; i < upwa->nprops; i++) { char *prop_name; prop_name = prop_data; prop_data += strlen(prop_name) + 1; vd = *(u32 *)prop_data; prop_data += sizeof(vd); switch (vd) { case 0x00000000: /* name only property, nothing to do */ break; case 0x80000000: prop = of_find_property(dn, prop_name, NULL); of_remove_property(dn, prop); prop = NULL; break; default: rc = update_dt_property(dn, &prop, prop_name, vd, prop_data); if (rc) { printk(KERN_ERR "Could not update %s" " property\n", prop_name); } prop_data += vd; } } } while (rtas_rc == 1); of_node_put(dn); kfree(rtas_buf); return 0; }
static void disable_serial_gpio(void) { struct device_node *np_tx, *np_rx, *np_tx_def, *np_rx_def; struct property *pp; static u32 pin_func_val; static struct property pin_func = { .name = "qcom,pin-func", .value = &pin_func_val, .length = sizeof(pin_func_val), }; static struct property output_low = { .name = "output-low", .value = NULL, .length = 0, }; static struct property bias_disable = { .name = "bias-disable", .value = NULL, .length = 0, }; np_tx = of_find_node_by_path( "/soc/pinctrl@fd510000/msm_gpio_4"); if (!np_tx) { pr_err("couldn't find msm_gpio_4 node\n"); return; } np_rx = of_find_node_by_path( "/soc/pinctrl@fd510000/msm_gpio_5"); if (!np_rx) { pr_err("couldn't find msm_gpio_5 node\n"); goto err0; } of_update_property(np_tx, &pin_func); of_update_property(np_rx, &pin_func); np_tx_def = of_find_node_by_name(np_tx, "default"); if (!np_tx_def) { pr_err("couldn't find msm_gpio_4_def node\n"); goto err1; } np_rx_def = of_find_node_by_name(np_rx, "default"); if (!np_rx_def) { pr_err("couldn't find msm_gpio_5_def node\n"); goto err2; } of_add_property(np_tx_def, &output_low); pp = of_find_property(np_rx_def, "bias-pull-up", NULL); if (pp) { of_remove_property(np_rx_def, pp); of_add_property(np_rx_def, &bias_disable); } of_add_property(np_rx_def, &output_low); of_node_put(np_rx_def); err2: of_node_put(np_tx_def); err1: of_node_put(np_rx); err0: of_node_put(np_tx); return; } static int __init init_console_setup(void) { if (need_serial_console) { pr_info("Adding %s%d as preferred console\n", CONSOLE_NAME, CONSOLE_IX); add_preferred_console(CONSOLE_NAME, CONSOLE_IX, CONSOLE_OPTIONS); } else { struct device_node *np; static struct property serial_con_status = { .name = "status", .value = "disabled", .length = sizeof("disabled"), }; np = of_find_node_by_path("/soc/serial@f991e000"); if (!np) { pr_err("couldn't find /soc/serial@f991e000 node\n"); return -EINVAL; } pr_info("disabling %s node", np->full_name); of_update_property(np, &serial_con_status); of_node_put(np); disable_serial_gpio(); } return 0; } early_initcall(init_console_setup);