int get_sony_hw(void) { int ret = 0; struct device_node *dt_root; int i, j, count = 0; const char *dt_space_no = NULL; if (_sony_hw != HW_UNKNOWN) return _sony_hw; dt_root = of_find_node_by_path("/"); count = of_property_count_strings(dt_root, "somc,space-no"); if (count <= 0) return HW_UNKNOWN; for (i = 0; i < count; i++) { ret = of_property_read_string_index(dt_root, "somc,space-no", i, &dt_space_no); if (ret < 0) continue; for (j = 0; j < ARRAY_SIZE(sony_hw_map); j++) { if (!strcmp(dt_space_no, sony_hw_map[j].space_no)) { _sony_hw = sony_hw_map[j].hw; break; }; }; }; return _sony_hw; }
static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config, struct pinctrl_map **map, unsigned *num_maps) { struct sirfsoc_pmx *spmx = pinctrl_dev_get_drvdata(pctldev); struct device_node *np; struct property *prop; const char *function, *group; int ret, index = 0, count = 0; /* calculate number of maps required */ for_each_child_of_node(np_config, np) { ret = of_property_read_string(np, "sirf,function", &function); if (ret < 0) { of_node_put(np); return ret; } ret = of_property_count_strings(np, "sirf,pins"); if (ret < 0) { of_node_put(np); return ret; } count += ret; }
static int scpi_clk_add(struct device *dev, struct device_node *np, const struct of_device_id *match) { struct clk **clks; int idx, count; struct scpi_clk_data *clk_data; count = of_property_count_strings(np, "clock-output-names"); if (count < 0) { dev_err(dev, "%s: invalid clock output count\n", np->name); return -EINVAL; } clk_data = devm_kmalloc(dev, sizeof(*clk_data), GFP_KERNEL); if (!clk_data) return -ENOMEM; clk_data->clk_num = count; clk_data->clk = devm_kcalloc(dev, count, sizeof(*clk_data->clk), GFP_KERNEL); if (!clk_data->clk) return -ENOMEM; clks = devm_kcalloc(dev, count, sizeof(*clks), GFP_KERNEL); if (!clks) return -ENOMEM; for (idx = 0; idx < count; idx++) { struct scpi_clk *sclk; const char *name; u32 val; sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL); if (!sclk) return -ENOMEM; if (of_property_read_string_index(np, "clock-output-names", idx, &name)) { dev_err(dev, "invalid clock name @ %s\n", np->name); return -EINVAL; } if (of_property_read_u32_index(np, "clock-indices", idx, &val)) { dev_err(dev, "invalid clock index @ %s\n", np->name); return -EINVAL; } sclk->id = val; clks[idx] = scpi_clk_ops_init(dev, match, sclk, name); if (IS_ERR_OR_NULL(clks[idx])) dev_err(dev, "failed to register clock '%s'\n", name); else dev_dbg(dev, "Registered clock '%s'\n", name); clk_data->clk[idx] = sclk; } return of_clk_add_provider(np, scpi_of_clk_src_get, clk_data); }
static int of_get_qcom_regulator_init_data(struct device *dev, struct regulator_init_data **init_data) { struct device_node *node = dev->of_node; struct regulator_consumer_supply *consumer_supplies; int i, rc, num_consumer_supplies, array_len; array_len = of_property_count_strings(node, consumer_supply_prop_name); if (array_len > 0) { if (array_len & 1) { dev_err(dev, "error: %s device node property value " "contains an odd number of elements: %d\n", consumer_supply_prop_name, array_len); return -EINVAL; } num_consumer_supplies = array_len / 2; consumer_supplies = devm_kzalloc(dev, sizeof(struct regulator_consumer_supply) * num_consumer_supplies, GFP_KERNEL); if (consumer_supplies == NULL) { dev_err(dev, "devm_kzalloc failed\n"); return -ENOMEM; } for (i = 0; i < num_consumer_supplies; i++) { rc = of_property_read_string_index(node, consumer_supply_prop_name, i * 2, &consumer_supplies[i].supply); if (rc) { dev_err(dev, "of_property_read_string_index " "failed, rc=%d\n", rc); devm_kfree(dev, consumer_supplies); return rc; } rc = of_property_read_string_index(node, consumer_supply_prop_name, (i * 2) + 1, &consumer_supplies[i].dev_name); if (rc) { dev_err(dev, "of_property_read_string_index " "failed, rc=%d\n", rc); devm_kfree(dev, consumer_supplies); return rc; } if (strnlen(consumer_supplies[i].dev_name, MAX_DEV_NAME_LEN) == 0) consumer_supplies[i].dev_name = NULL; } (*init_data)->consumer_supplies = consumer_supplies; (*init_data)->num_consumer_supplies = num_consumer_supplies; } return 0; }
static int nokia_modem_gpio_probe(struct device *dev) { struct device_node *np = dev->of_node; struct nokia_modem_device *modem = dev_get_drvdata(dev); int gpio_count, gpio_name_count, i, err; gpio_count = of_gpio_count(np); if (gpio_count < 0) { dev_err(dev, "missing gpios: %d\n", gpio_count); return gpio_count; } gpio_name_count = of_property_count_strings(np, "gpio-names"); if (gpio_count != gpio_name_count) { dev_err(dev, "number of gpios does not equal number of gpio names\n"); return -EINVAL; } modem->gpios = devm_kzalloc(dev, gpio_count * sizeof(struct nokia_modem_gpio), GFP_KERNEL); if (!modem->gpios) { dev_err(dev, "Could not allocate memory for gpios\n"); return -ENOMEM; } modem->gpio_amount = gpio_count; for (i = 0; i < gpio_count; i++) { modem->gpios[i].gpio = devm_gpiod_get_index(dev, NULL, i); if (IS_ERR(modem->gpios[i].gpio)) { dev_err(dev, "Could not get gpio %d\n", i); return PTR_ERR(modem->gpios[i].gpio); } err = of_property_read_string_index(np, "gpio-names", i, &(modem->gpios[i].name)); if (err) { dev_err(dev, "Could not get gpio name %d\n", i); return err; } err = gpiod_direction_output(modem->gpios[i].gpio, 0); if (err) return err; err = gpiod_export(modem->gpios[i].gpio, 0); if (err) return err; err = gpiod_export_link(dev, modem->gpios[i].name, modem->gpios[i].gpio); if (err) return err; } return 0; }
/** * omap_device_build_from_dt - build an omap_device with multiple hwmods * @pdev_name: name of the platform_device driver to use * @pdev_id: this platform_device's connection ID * @oh: ptr to the single omap_hwmod that backs this omap_device * @pdata: platform_data ptr to associate with the platform_device * @pdata_len: amount of memory pointed to by @pdata * * Function for building an omap_device already registered from device-tree * * Returns 0 or PTR_ERR() on error. */ static int omap_device_build_from_dt(struct platform_device *pdev) { struct omap_hwmod **hwmods; struct omap_device *od; struct omap_hwmod *oh; struct device_node *node = pdev->dev.of_node; const char *oh_name; int oh_cnt, i, ret = 0; oh_cnt = of_property_count_strings(node, "ti,hwmods"); if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) { dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); return -ENODEV; } hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); if (!hwmods) { ret = -ENOMEM; goto odbfd_exit; } for (i = 0; i < oh_cnt; i++) { of_property_read_string_index(node, "ti,hwmods", i, &oh_name); oh = omap_hwmod_lookup(oh_name); if (!oh) { dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n", oh_name); ret = -EINVAL; goto odbfd_exit1; } hwmods[i] = oh; } od = omap_device_alloc(pdev, hwmods, oh_cnt); if (!od) { dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", oh_name); ret = PTR_ERR(od); goto odbfd_exit1; } /* Fix up missing resource names */ for (i = 0; i < pdev->num_resources; i++) { struct resource *r = &pdev->resource[i]; if (r->name == NULL) r->name = dev_name(&pdev->dev); } if (of_get_property(node, "ti,no_idle_on_suspend", NULL)) omap_device_disable_idle_on_suspend(pdev); pdev->dev.pm_domain = &omap_device_pm_domain; odbfd_exit1: kfree(hwmods); odbfd_exit: return ret; }
static int mitigate_inrush_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; int i, retval; struct subsystem *subsys; struct inrush_driver_data *drv_data; retval = of_property_count_strings(np, "qcom,dependent-subsystems"); if (IS_ERR_VALUE(retval)) { dev_err(dev, "Failed to get dependent subsystems\n"); return -EINVAL; } drv_data = kzalloc((retval * sizeof(struct subsystem) + sizeof(struct inrush_driver_data)), GFP_KERNEL); if (!drv_data) return -ENOMEM; drv_data->subsystems = (void *)drv_data + sizeof(struct inrush_driver_data); drv_data->subsys_count = retval; for (i = 0; i < drv_data->subsys_count; i++) { subsys = &drv_data->subsystems[i]; subsys->drv_data = drv_data; of_property_read_string_index(np, "qcom,dependent-subsystems", i, &subsys->name); subsys->nb.notifier_call = mitigate_inrush_notifier_cb; subsys->notif_handle = subsys_notif_register_notifier(subsys->name, &subsys->nb); if (IS_ERR(subsys->notif_handle)) { dev_err(dev, "Notifier registration failed for %s\n", subsys->name); retval = PTR_ERR(subsys->notif_handle); goto err_subsys_notif; } } drv_data->vreg = devm_regulator_get(dev, "vdd"); if (IS_ERR(drv_data->vreg)) { dev_err(dev, "Failed to get regulator\n"); return PTR_ERR(drv_data->vreg); } return 0; err_subsys_notif: for (i = 0; i < drv_data->subsys_count; i++) { subsys = &drv_data->subsystems[i]; subsys_notif_unregister_notifier(subsys->notif_handle, &subsys->nb); } kfree(drv_data); return retval; }
int msm_ispif_get_ahb_clk_info(struct ispif_device *ispif_dev, struct platform_device *pdev, struct msm_cam_clk_info *ahb_clk_info) { uint32_t count, num_ahb_clk = 0; int i, rc; uint32_t rates[ISPIF_CLK_INFO_MAX]; struct device_node *of_node; of_node = pdev->dev.of_node; count = of_property_count_strings(of_node, "clock-names"); CDBG("count = %d\n", count); if (count == 0) { pr_err("no clocks found in device tree, count=%d", count); return 0; } if (count > ISPIF_CLK_INFO_MAX) { pr_err("invalid count=%d, max is %d\n", count, ISPIF_CLK_INFO_MAX); return -EINVAL; } rc = of_property_read_u32_array(of_node, "qcom,clock-rates", rates, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); return rc; } for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "clock-names", i, &(ahb_clk_info[num_ahb_clk].clk_name)); CDBG("clock-names[%d] = %s\n", i, ahb_clk_info[i].clk_name); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); return rc; } if (strnstr(ahb_clk_info[num_ahb_clk].clk_name, "ahb", sizeof(ahb_clk_info[num_ahb_clk].clk_name))) { ahb_clk_info[num_ahb_clk].clk_rate = (rates[i] == 0) ? (long)-1 : rates[i]; CDBG("clk_rate[%d] = %ld\n", i, ahb_clk_info[i].clk_rate); num_ahb_clk++; } } ispif_dev->num_ahb_clk = num_ahb_clk; return 0; }
static struct mmi_factory_info *mmi_parse_of(struct platform_device *pdev) { struct mmi_factory_info *info; int gpio_count; struct device_node *np = pdev->dev.of_node; int i; enum of_gpio_flags flags; if (!np) { dev_err(&pdev->dev, "No OF DT node found.\n"); return NULL; } gpio_count = of_gpio_count(np); if (!gpio_count) { dev_err(&pdev->dev, "No GPIOS defined.\n"); return NULL; } /* Make sure number of GPIOs defined matches the supplied number of * GPIO name strings. */ if (gpio_count != of_property_count_strings(np, "gpio-names")) { dev_err(&pdev->dev, "GPIO info and name mismatch\n"); return NULL; } info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) return NULL; info->list = devm_kzalloc(&pdev->dev, sizeof(struct gpio) * gpio_count, GFP_KERNEL); if (!info->list) return NULL; info->num_gpios = gpio_count; for (i = 0; i < gpio_count; i++) { info->list[i].gpio = of_get_gpio_flags(np, i, &flags); info->list[i].flags = flags; of_property_read_string_index(np, "gpio-names", i, &info->list[i].label); dev_dbg(&pdev->dev, "GPIO: %d FLAGS: %ld LABEL: %s\n", info->list[i].gpio, info->list[i].flags, info->list[i].label); } return info; }
/** * of_dma_request_slave_channel - Get the DMA slave channel * @np: device node to get DMA request from * @name: name of desired channel * * Returns pointer to appropriate DMA channel on success or an error pointer. */ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, const char *name) { struct of_phandle_args dma_spec; struct of_dma *ofdma; struct dma_chan *chan; int count, i; int ret_no_channel = -ENODEV; if (!np || !name) { pr_err("%s: not enough information provided\n", __func__); return ERR_PTR(-ENODEV); } /* Silently fail if there is not even the "dmas" property */ if (!of_find_property(np, "dmas", NULL)) return ERR_PTR(-ENODEV); count = of_property_count_strings(np, "dma-names"); if (count < 0) { pr_err("%s: dma-names property of node '%s' missing or empty\n", __func__, np->full_name); return ERR_PTR(-ENODEV); } for (i = 0; i < count; i++) { if (of_dma_match_channel(np, name, i, &dma_spec)) continue; mutex_lock(&of_dma_lock); ofdma = of_dma_find_controller(&dma_spec); if (ofdma) { chan = ofdma->of_dma_xlate(&dma_spec, ofdma); } else { ret_no_channel = -EPROBE_DEFER; chan = NULL; } mutex_unlock(&of_dma_lock); of_node_put(dma_spec.np); if (chan) return chan; } return ERR_PTR(ret_no_channel); }
static int msm_jpeg_get_clk_info(struct msm_jpeg_device *jpeg_dev, struct platform_device *pdev) { uint32_t count; int i, rc; uint32_t rates[JPEG_CLK_INFO_MAX]; struct device_node *of_node; of_node = pdev->dev.of_node; count = of_property_count_strings(of_node, "clock-names"); JPEG_DBG("count = %d\n", count); if (count == 0) { pr_err("no clocks found in device tree, count=%d", count); return 0; } if (count > JPEG_CLK_INFO_MAX) { pr_err("invalid count=%d, max is %d\n", count, JPEG_CLK_INFO_MAX); return -EINVAL; } for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "clock-names", i, &(jpeg_8x_clk_info[i].clk_name)); JPEG_DBG("clock-names[%d] = %s\n", i, jpeg_8x_clk_info[i].clk_name); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); return rc; } } rc = of_property_read_u32_array(of_node, "qcom,clock-rates", rates, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); return rc; } for (i = 0; i < count; i++) { jpeg_8x_clk_info[i].clk_rate = (rates[i] == 0) ? -1 : rates[i]; JPEG_DBG("clk_rate[%d] = %ld\n", i, jpeg_8x_clk_info[i].clk_rate); } jpeg_dev->num_clk = count; return 0; }
/** * fwnode_property_read_string_array - return string array property of a node * @fwnode: Firmware node to get the property of * @propname: Name of the property * @val: The values are stored here or %NULL to return the number of values * @nval: Size of the @val array * * Read an string list property @propname from the given firmware node and store * them to @val if found. * * Return: number of values if @val was %NULL, * %0 if the property was found (success), * %-EINVAL if given arguments are not valid, * %-ENODATA if the property does not have a value, * %-EPROTO if the property is not an array of strings, * %-EOVERFLOW if the size of the property is not as expected, * %-ENXIO if no suitable firmware interface is present. */ int fwnode_property_read_string_array(struct fwnode_handle *fwnode, const char *propname, const char **val, size_t nval) { if (is_of_node(fwnode)) return val ? of_property_read_string_array(to_of_node(fwnode), propname, val, nval) : of_property_count_strings(to_of_node(fwnode), propname); else if (is_acpi_node(fwnode)) return acpi_dev_prop_read(to_acpi_node(fwnode), propname, DEV_PROP_STRING, val, nval); return pset_prop_read_array(to_pset(fwnode), propname, DEV_PROP_STRING, val, nval); }
int axidma_of_num_channels(struct platform_device *pdev) { int num_dmas, num_dma_names; struct device_node *driver_node; // Get the device tree node for the driver driver_node = pdev->dev.of_node; // Check that the device tree node has the 'dmas' and 'dma-names' properties if (of_find_property(driver_node, "dma-names", NULL) == NULL) { axidma_node_err(driver_node, "Property 'dma-names' is missing.\n"); return -EINVAL; } else if (of_find_property(driver_node, "dmas", NULL) == NULL) { axidma_node_err(driver_node, "Property 'dmas' is missing.\n"); return -EINVAL; } // Get the length of the properties, and make sure they are not empty num_dma_names = of_property_count_strings(driver_node, "dma-names"); if (num_dma_names < 0) { axidma_node_err(driver_node, "Unable to get the 'dma-names' property " "length.\n"); return -EINVAL; } else if (num_dma_names == 0) { axidma_node_err(driver_node, "'dma-names' property is empty.\n"); return -EINVAL; } num_dmas = of_count_phandle_with_args(driver_node, "dmas", "#dma-cells"); if (num_dmas < 0) { axidma_node_err(driver_node, "Unable to get the 'dmas' property " "length.\n"); return -EINVAL; } else if (num_dmas == 0) { axidma_node_err(driver_node, "'dmas' property is empty.\n"); return -EINVAL; } // Check that the number of entries in each property matches if (num_dma_names != num_dmas) { axidma_node_err(driver_node, "Length of 'dma-names' and 'dmas' " "properties differ.\n"); return -EINVAL; } return num_dma_names; }
static int of_get_eq_pdata(struct tas57xx_platform_data *pdata, struct device_node* p_node) { int i, ret = 0, length = 0; const char *str = NULL; char *regs = NULL; prob_priv.num_eq = of_property_count_strings(p_node,"eq_name"); if(prob_priv.num_eq <= 0){ printk("no of eq_name config\n"); ret = -ENODEV; goto exit; } pdata->num_eq_cfgs = prob_priv.num_eq; prob_priv.eq_configs = kzalloc(prob_priv.num_eq * sizeof(struct tas57xx_eq_cfg), GFP_KERNEL); for(i = 0; i < prob_priv.num_eq; i++){ ret = of_property_read_string_index(p_node, "eq_name", i , &str); if(of_find_property(p_node, "eq_table", &length) == NULL){ printk("%s fail to get of eq_table\n", __func__); goto exit1; } regs = kzalloc(length * sizeof(char *), GFP_KERNEL); if (!regs) { printk("ERROR, NO enough mem for eq_table!\n"); return -ENOMEM; } ret = of_property_read_u8_array(p_node, "eq_table", regs, length); strncpy(prob_priv.eq_configs[i].name, str, NAME_SIZE); prob_priv.eq_configs[i].regs = regs; } pdata->eq_cfgs = prob_priv.eq_configs; return 0; exit1: kfree(prob_priv.eq_configs); exit: return ret; }
static int of_read_clocks(struct device *dev, struct clk ***clks_ref, const char *propname) { int clk_count, i, len; struct clk **clks; if (!of_find_property(dev->of_node, propname, &len)) return 0; clk_count = of_property_count_strings(dev->of_node, propname); if (IS_ERR_VALUE(clk_count)) { dev_err(dev, "Failed to get clock names\n"); return -EINVAL; } clks = devm_kzalloc(dev, sizeof(struct clk *) * clk_count, GFP_KERNEL); if (!clks) return -ENOMEM; for (i = 0; i < clk_count; i++) { const char *clock_name; of_property_read_string_index(dev->of_node, propname, i, &clock_name); clks[i] = devm_clk_get(dev, clock_name); if (IS_ERR(clks[i])) { int rc = PTR_ERR(clks[i]); if (rc != -EPROBE_DEFER) dev_err(dev, "Failed to get %s clock\n", clock_name); return rc; } /* Make sure rate-settable clocks' rates are set */ if (clk_get_rate(clks[i]) == 0) clk_set_rate(clks[i], clk_round_rate(clks[i], XO_FREQ)); } *clks_ref = clks; return clk_count; }
/** * of_dma_request_slave_channel - Get the DMA slave channel * @np: device node to get DMA request from * @name: name of desired channel * * Returns pointer to appropriate dma channel on success or NULL on error. */ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, const char *name) { struct of_phandle_args dma_spec; struct of_dma *ofdma; struct dma_chan *chan; int count, i; if (!np || !name) { pr_err("%s: not enough information provided\n", __func__); return NULL; } count = of_property_count_strings(np, "dma-names"); if (count < 0) { pr_err("%s: dma-names property missing or empty\n", __func__); return NULL; } for (i = 0; i < count; i++) { if (of_dma_match_channel(np, name, i, &dma_spec)) continue; mutex_lock(&of_dma_lock); ofdma = of_dma_find_controller(&dma_spec); if (ofdma) chan = ofdma->of_dma_xlate(&dma_spec, ofdma); else chan = NULL; mutex_unlock(&of_dma_lock); of_node_put(dma_spec.np); if (chan) return chan; } return NULL; }
static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode, const char *propname, const char **val, size_t nval) { if (is_of_node(fwnode)) return val ? of_property_read_string_array(to_of_node(fwnode), propname, val, nval) : of_property_count_strings(to_of_node(fwnode), propname); else if (is_acpi_node(fwnode)) return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING, val, nval); else if (is_pset_node(fwnode)) return val ? pset_prop_read_string_array(to_pset_node(fwnode), propname, val, nval) : pset_prop_count_elems_of_size(to_pset_node(fwnode), propname, sizeof(const char *)); return -ENXIO; }
static void siw_touch_of_array(struct device *dev, void *np, void *string, const char **name, int *cnt) { int i; int ret = 0; (*cnt) = 0; ret = of_property_count_strings(np, string); if (ret < 0) { t_dev_warn(dev, "of count : %s not found\n", (char *)string); return; } (*cnt) = ret; t_dev_dbg_of(dev, "of count : %s, %d\n", (char *)string, (*cnt)); for (i = 0; i < (*cnt); i++) { ret = of_property_read_string_index(np, string, i, (const char **)&name[i]); if (!ret) { t_dev_info(dev, "of string[%d/%d] : %s\n", i+1, (*cnt), name[i]); } } }
static void __init lpc18xx_ccu_init(struct device_node *np) { struct lpc18xx_branch_clk_data *clk_data; void __iomem *reg_base; int i, ret; reg_base = of_iomap(np, 0); if (!reg_base) { pr_warn("%s: failed to map address range\n", __func__); return; } clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); if (!clk_data) return; clk_data->num = of_property_count_strings(np, "clock-names"); clk_data->name = kcalloc(clk_data->num, sizeof(char *), GFP_KERNEL); if (!clk_data->name) { kfree(clk_data); return; } for (i = 0; i < clk_data->num; i++) { ret = of_property_read_string_index(np, "clock-names", i, &clk_data->name[i]); if (ret) { pr_warn("%s: failed to get clock name at idx %d\n", __func__, i); continue; } lpc18xx_ccu_register_branch_clks(reg_base, clk_data->name[i]); } of_clk_add_provider(np, lpc18xx_ccu_branch_clk_get, clk_data); }
static void __init of_selftest_property_string(void) { const char *strings[4]; struct device_node *np; int rc; pr_info("start\n"); np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); if (!np) { pr_err("No testcase data in device tree\n"); return; } rc = of_property_match_string(np, "phandle-list-names", "first"); selftest(rc == 0, "first expected:0 got:%i\n", rc); rc = of_property_match_string(np, "phandle-list-names", "second"); selftest(rc == 1, "second expected:0 got:%i\n", rc); rc = of_property_match_string(np, "phandle-list-names", "third"); selftest(rc == 2, "third expected:0 got:%i\n", rc); rc = of_property_match_string(np, "phandle-list-names", "fourth"); selftest(rc == -ENODATA, "unmatched string; rc=%i\n", rc); rc = of_property_match_string(np, "missing-property", "blah"); selftest(rc == -EINVAL, "missing property; rc=%i\n", rc); rc = of_property_match_string(np, "empty-property", "blah"); selftest(rc == -ENODATA, "empty property; rc=%i\n", rc); rc = of_property_match_string(np, "unterminated-string", "blah"); selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc); /* of_property_count_strings() tests */ rc = of_property_count_strings(np, "string-property"); selftest(rc == 1, "Incorrect string count; rc=%i\n", rc); rc = of_property_count_strings(np, "phandle-list-names"); selftest(rc == 3, "Incorrect string count; rc=%i\n", rc); rc = of_property_count_strings(np, "unterminated-string"); selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc); rc = of_property_count_strings(np, "unterminated-string-list"); selftest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc); /* of_property_read_string_index() tests */ rc = of_property_read_string_index(np, "string-property", 0, strings); selftest(rc == 0 && !strcmp(strings[0], "foobar"), "of_property_read_string_index() failure; rc=%i\n", rc); strings[0] = NULL; rc = of_property_read_string_index(np, "string-property", 1, strings); selftest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc); rc = of_property_read_string_index(np, "phandle-list-names", 0, strings); selftest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc); rc = of_property_read_string_index(np, "phandle-list-names", 1, strings); selftest(rc == 0 && !strcmp(strings[0], "second"), "of_property_read_string_index() failure; rc=%i\n", rc); rc = of_property_read_string_index(np, "phandle-list-names", 2, strings); selftest(rc == 0 && !strcmp(strings[0], "third"), "of_property_read_string_index() failure; rc=%i\n", rc); strings[0] = NULL; rc = of_property_read_string_index(np, "phandle-list-names", 3, strings); selftest(rc == -ENODATA && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc); strings[0] = NULL; rc = of_property_read_string_index(np, "unterminated-string", 0, strings); selftest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc); rc = of_property_read_string_index(np, "unterminated-string-list", 0, strings); selftest(rc == 0 && !strcmp(strings[0], "first"), "of_property_read_string_index() failure; rc=%i\n", rc); strings[0] = NULL; rc = of_property_read_string_index(np, "unterminated-string-list", 2, strings); /* should fail */ selftest(rc == -EILSEQ && strings[0] == NULL, "of_property_read_string_index() failure; rc=%i\n", rc); strings[1] = NULL; /* of_property_read_string_array() tests */ rc = of_property_read_string_array(np, "string-property", strings, 4); selftest(rc == 1, "Incorrect string count; rc=%i\n", rc); rc = of_property_read_string_array(np, "phandle-list-names", strings, 4); selftest(rc == 3, "Incorrect string count; rc=%i\n", rc); rc = of_property_read_string_array(np, "unterminated-string", strings, 4); selftest(rc == -EILSEQ, "unterminated string; rc=%i\n", rc); /* -- An incorrectly formed string should cause a failure */ rc = of_property_read_string_array(np, "unterminated-string-list", strings, 4); selftest(rc == -EILSEQ, "unterminated string array; rc=%i\n", rc); /* -- parsing the correctly formed strings should still work: */ strings[2] = NULL; rc = of_property_read_string_array(np, "unterminated-string-list", strings, 2); selftest(rc == 2 && strings[2] == NULL, "of_property_read_string_array() failure; rc=%i\n", rc); strings[1] = NULL; rc = of_property_read_string_array(np, "phandle-list-names", strings, 1); selftest(rc == 1 && strings[1] == NULL, "Overwrote end of string array; rc=%i, str='%s'\n", rc, strings[1]); }
static int gdsc_probe(struct platform_device *pdev) { static atomic_t gdsc_count = ATOMIC_INIT(-1); struct regulator_config reg_config = {}; struct regulator_init_data *init_data; struct resource *res; struct gdsc *sc; uint32_t regval; bool retain_mem, retain_periph, support_hw_trigger; int i, ret; sc = devm_kzalloc(&pdev->dev, sizeof(struct gdsc), GFP_KERNEL); if (sc == NULL) return -ENOMEM; init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); if (init_data == NULL) return -ENOMEM; if (of_get_property(pdev->dev.of_node, "parent-supply", NULL)) init_data->supply_regulator = "parent"; ret = of_property_read_string(pdev->dev.of_node, "regulator-name", &sc->rdesc.name); if (ret) return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) return -EINVAL; sc->gdscr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (sc->gdscr == NULL) return -ENOMEM; sc->clock_count = of_property_count_strings(pdev->dev.of_node, "clock-names"); if (sc->clock_count == -EINVAL) { sc->clock_count = 0; } else if (IS_ERR_VALUE(sc->clock_count)) { dev_err(&pdev->dev, "Failed to get clock names\n"); return -EINVAL; } sc->clocks = devm_kzalloc(&pdev->dev, sizeof(struct clk *) * sc->clock_count, GFP_KERNEL); if (!sc->clocks) return -ENOMEM; sc->root_en = of_property_read_bool(pdev->dev.of_node, "qcom,enable-root-clk"); for (i = 0; i < sc->clock_count; i++) { const char *clock_name; of_property_read_string_index(pdev->dev.of_node, "clock-names", i, &clock_name); sc->clocks[i] = devm_clk_get(&pdev->dev, clock_name); if (IS_ERR(sc->clocks[i])) { int rc = PTR_ERR(sc->clocks[i]); if (rc != -EPROBE_DEFER) dev_err(&pdev->dev, "Failed to get %s\n", clock_name); return rc; } } sc->rdesc.id = atomic_inc_return(&gdsc_count); sc->rdesc.ops = &gdsc_ops; sc->rdesc.type = REGULATOR_VOLTAGE; sc->rdesc.owner = THIS_MODULE; platform_set_drvdata(pdev, sc); /* * Disable HW trigger: collapse/restore occur based on registers writes. * Disable SW override: Use hardware state-machine for sequencing. */ regval = readl_relaxed(sc->gdscr); regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK); /* Configure wait time between states. */ regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK); regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL; writel_relaxed(regval, sc->gdscr); retain_mem = of_property_read_bool(pdev->dev.of_node, "qcom,retain-mem"); sc->toggle_mem = !retain_mem; retain_periph = of_property_read_bool(pdev->dev.of_node, "qcom,retain-periph"); sc->toggle_periph = !retain_periph; sc->toggle_logic = !of_property_read_bool(pdev->dev.of_node, "qcom,skip-logic-collapse"); support_hw_trigger = of_property_read_bool(pdev->dev.of_node, "qcom,support-hw-trigger"); if (support_hw_trigger) { init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE; init_data->constraints.valid_modes_mask |= REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST; } if (!sc->toggle_logic) { regval &= ~SW_COLLAPSE_MASK; writel_relaxed(regval, sc->gdscr); ret = readl_tight_poll_timeout(sc->gdscr, regval, regval & PWR_ON_MASK, TIMEOUT_US); if (ret) { dev_err(&pdev->dev, "%s enable timed out: 0x%x\n", sc->rdesc.name, regval); return ret; } } for (i = 0; i < sc->clock_count; i++) { if (retain_mem || (regval & PWR_ON_MASK)) clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_MEM); else clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_MEM); if (retain_periph || (regval & PWR_ON_MASK)) clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_PERIPH); else clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH); } reg_config.dev = &pdev->dev; reg_config.init_data = init_data; reg_config.driver_data = sc; reg_config.of_node = pdev->dev.of_node; sc->rdev = regulator_register(&sc->rdesc, ®_config); if (IS_ERR(sc->rdev)) { dev_err(&pdev->dev, "regulator_register(\"%s\") failed.\n", sc->rdesc.name); return PTR_ERR(sc->rdev); } return 0; }
/** * omap_device_build_from_dt - build an omap_device with multiple hwmods * @pdev_name: name of the platform_device driver to use * @pdev_id: this platform_device's connection ID * @oh: ptr to the single omap_hwmod that backs this omap_device * @pdata: platform_data ptr to associate with the platform_device * @pdata_len: amount of memory pointed to by @pdata * * Function for building an omap_device already registered from device-tree * * Returns 0 or PTR_ERR() on error. */ static int omap_device_build_from_dt(struct platform_device *pdev) { struct omap_hwmod **hwmods; struct omap_device *od; struct omap_hwmod *oh; struct device_node *node = pdev->dev.of_node; const char *oh_name, *rst_name; int oh_cnt, dstr_cnt, i, ret = 0; bool device_active = false; oh_cnt = of_property_count_strings(node, "ti,hwmods"); if (oh_cnt <= 0) { dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); return -ENODEV; } hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); if (!hwmods) { ret = -ENOMEM; goto odbfd_exit; } for (i = 0; i < oh_cnt; i++) { of_property_read_string_index(node, "ti,hwmods", i, &oh_name); oh = omap_hwmod_lookup(oh_name); if (!oh) { dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n", oh_name); ret = -EINVAL; goto odbfd_exit1; } hwmods[i] = oh; if (oh->flags & HWMOD_INIT_NO_IDLE) device_active = true; } od = omap_device_alloc(pdev, hwmods, oh_cnt); if (IS_ERR(od)) { dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", oh_name); ret = PTR_ERR(od); goto odbfd_exit1; } /* Fix up missing resource names */ for (i = 0; i < pdev->num_resources; i++) { struct resource *r = &pdev->resource[i]; if (r->name == NULL) r->name = dev_name(&pdev->dev); } pdev->dev.pm_domain = &omap_device_pm_domain; if (device_active) { omap_device_enable(pdev); pm_runtime_set_active(&pdev->dev); } dstr_cnt = of_property_count_strings(node, "ti,deassert-hard-reset"); if (dstr_cnt > 0) { for (i = 0; i < dstr_cnt; i += 2) { of_property_read_string_index( node, "ti,deassert-hard-reset", i, &oh_name); of_property_read_string_index( node, "ti,deassert-hard-reset", i+1, &rst_name); oh = omap_hwmod_lookup(oh_name); if (!oh) { dev_warn(&pdev->dev, "Cannot parse deassert property for '%s'\n", oh_name); break; } omap_hwmod_deassert_hardreset(oh, rst_name); } } odbfd_exit1: kfree(hwmods); odbfd_exit: /* if data/we are at fault.. load up a fail handler */ if (ret) pdev->dev.pm_domain = &omap_device_fail_pm_domain; return ret; }
static int __init dra7xx_pcie_probe(struct platform_device *pdev) { u32 reg; int ret; int irq; int i; int phy_count; struct phy **phy; void __iomem *base; struct resource *res; struct dra7xx_pcie *dra7xx; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; char name[10]; int gpio_sel; enum of_gpio_flags flags; unsigned long gpio_flags; dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); if (!dra7xx) return -ENOMEM; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(dev, "missing IRQ resource\n"); return -EINVAL; } ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler, IRQF_SHARED, "dra7xx-pcie-main", dra7xx); if (ret) { dev_err(dev, "failed to request irq\n"); return ret; } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf"); base = devm_ioremap_nocache(dev, res->start, resource_size(res)); if (!base) return -ENOMEM; phy_count = of_property_count_strings(np, "phy-names"); if (phy_count < 0) { dev_err(dev, "unable to find the strings\n"); return phy_count; } phy = devm_kzalloc(dev, sizeof(*phy) * phy_count, GFP_KERNEL); if (!phy) return -ENOMEM; for (i = 0; i < phy_count; i++) { snprintf(name, sizeof(name), "pcie-phy%d", i); phy[i] = devm_phy_get(dev, name); if (IS_ERR(phy[i])) return PTR_ERR(phy[i]); ret = phy_init(phy[i]); if (ret < 0) goto err_phy; ret = phy_power_on(phy[i]); if (ret < 0) { phy_exit(phy[i]); goto err_phy; } } dra7xx->base = base; dra7xx->phy = phy; dra7xx->dev = dev; dra7xx->phy_count = phy_count; pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "pm_runtime_get_sync failed\n"); goto err_get_sync; } gpio_sel = of_get_gpio_flags(dev->of_node, 0, &flags); if (gpio_is_valid(gpio_sel)) { gpio_flags = (flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH; ret = devm_gpio_request_one(dev, gpio_sel, gpio_flags, "pcie_reset"); if (ret) { dev_err(&pdev->dev, "gpio%d request failed, ret %d\n", gpio_sel, ret); goto err_gpio; } } else if (gpio_sel == -EPROBE_DEFER) { ret = -EPROBE_DEFER; goto err_gpio; } reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD); reg &= ~LTSSM_EN; dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); platform_set_drvdata(pdev, dra7xx); ret = dra7xx_add_pcie_port(dra7xx, pdev); if (ret < 0) goto err_gpio; return 0; err_gpio: pm_runtime_put(dev); err_get_sync: pm_runtime_disable(dev); err_phy: while (--i >= 0) { phy_power_off(phy[i]); phy_exit(phy[i]); } return ret; }
void __init opal_sys_param_init(void) { struct device_node *sysparam; struct param_attr *attr; u32 *id, *size; int count, i; u8 *perm; if (!opal_kobj) { pr_warn("SYSPARAM: opal kobject is not available\n"); goto out; } sysparam_kobj = kobject_create_and_add("sysparams", opal_kobj); if (!sysparam_kobj) { pr_err("SYSPARAM: Failed to create sysparam kobject\n"); goto out; } /* Allocate big enough buffer for any get/set transactions */ param_data_buf = kzalloc(MAX_PARAM_DATA_LEN, GFP_KERNEL); if (!param_data_buf) { pr_err("SYSPARAM: Failed to allocate memory for param data " "buf\n"); goto out_kobj_put; } sysparam = of_find_node_by_path("/ibm,opal/sysparams"); if (!sysparam) { pr_err("SYSPARAM: Opal sysparam node not found\n"); goto out_param_buf; } if (!of_device_is_compatible(sysparam, "ibm,opal-sysparams")) { pr_err("SYSPARAM: Opal sysparam node not compatible\n"); goto out_node_put; } /* Number of parameters exposed through DT */ count = of_property_count_strings(sysparam, "param-name"); if (count < 0) { pr_err("SYSPARAM: No string found of property param-name in " "the node %s\n", sysparam->name); goto out_node_put; } id = kzalloc(sizeof(*id) * count, GFP_KERNEL); if (!id) { pr_err("SYSPARAM: Failed to allocate memory to read parameter " "id\n"); goto out_node_put; } size = kzalloc(sizeof(*size) * count, GFP_KERNEL); if (!size) { pr_err("SYSPARAM: Failed to allocate memory to read parameter " "size\n"); goto out_free_id; } perm = kzalloc(sizeof(*perm) * count, GFP_KERNEL); if (!perm) { pr_err("SYSPARAM: Failed to allocate memory to read supported " "action on the parameter"); goto out_free_size; } if (of_property_read_u32_array(sysparam, "param-id", id, count)) { pr_err("SYSPARAM: Missing property param-id in the DT\n"); goto out_free_perm; } if (of_property_read_u32_array(sysparam, "param-len", size, count)) { pr_err("SYSPARAM: Missing propery param-len in the DT\n"); goto out_free_perm; } if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) { pr_err("SYSPARAM: Missing propery param-perm in the DT\n"); goto out_free_perm; } attr = kzalloc(sizeof(*attr) * count, GFP_KERNEL); if (!attr) { pr_err("SYSPARAM: Failed to allocate memory for parameter " "attributes\n"); goto out_free_perm; } /* For each of the parameters, populate the parameter attributes */ for (i = 0; i < count; i++) { sysfs_attr_init(&attr[i].kobj_attr.attr); attr[i].param_id = id[i]; attr[i].param_size = size[i]; if (of_property_read_string_index(sysparam, "param-name", i, &attr[i].kobj_attr.attr.name)) continue; /* If the parameter is read-only or read-write */ switch (perm[i] & 3) { case OPAL_SYSPARAM_READ: attr[i].kobj_attr.attr.mode = S_IRUGO; break; case OPAL_SYSPARAM_WRITE: attr[i].kobj_attr.attr.mode = S_IWUGO; break; case OPAL_SYSPARAM_RW: attr[i].kobj_attr.attr.mode = S_IRUGO | S_IWUGO; break; default: break; } attr[i].kobj_attr.show = sys_param_show; attr[i].kobj_attr.store = sys_param_store; if (sysfs_create_file(sysparam_kobj, &attr[i].kobj_attr.attr)) { pr_err("SYSPARAM: Failed to create sysfs file %s\n", attr[i].kobj_attr.attr.name); goto out_free_attr; } } kfree(perm); kfree(size); kfree(id); of_node_put(sysparam); return; out_free_attr: kfree(attr); out_free_perm: kfree(perm); out_free_size: kfree(size); out_free_id: kfree(id); out_node_put: of_node_put(sysparam); out_param_buf: kfree(param_data_buf); out_kobj_put: kobject_put(sysparam_kobj); out: return; }
int msm_camera_get_dt_power_setting_data(struct device_node *of_node, struct camera_vreg_t *cam_vreg, int num_vreg, struct msm_camera_power_ctrl_t *power_info) { int rc = 0, i, j; int count = 0; const char *seq_name = NULL; uint32_t *array = NULL; struct msm_sensor_power_setting *ps; struct msm_sensor_power_setting *power_setting; uint16_t *power_setting_size, size = 0; bool need_reverse = 0; if (!power_info) return -EINVAL; power_setting = power_info->power_setting; power_setting_size = &power_info->power_setting_size; count = of_property_count_strings(of_node, "qcom,cam-power-seq-type"); *power_setting_size = count; CDBG("%s qcom,cam-power-seq-type count %d\n", __func__, count); if (count <= 0) return 0; ps = kzalloc(sizeof(*ps) * count, GFP_KERNEL); if (!ps) { pr_err("%s failed %d\n", __func__, __LINE__); return -ENOMEM; } power_setting = ps; power_info->power_setting = ps; for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "qcom,cam-power-seq-type", i, &seq_name); CDBG("%s seq_name[%d] = %s\n", __func__, i, seq_name); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR1; } if (!strcmp(seq_name, "sensor_vreg")) { ps[i].seq_type = SENSOR_VREG; CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__, i, ps[i].seq_type); } else if (!strcmp(seq_name, "sensor_gpio")) { ps[i].seq_type = SENSOR_GPIO; CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__, i, ps[i].seq_type); } else if (!strcmp(seq_name, "sensor_clk")) { ps[i].seq_type = SENSOR_CLK; CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__, i, ps[i].seq_type); } else if (!strcmp(seq_name, "sensor_i2c_mux")) { ps[i].seq_type = SENSOR_I2C_MUX; CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__, i, ps[i].seq_type); } else { CDBG("%s: unrecognized seq-type\n", __func__); rc = -EILSEQ; goto ERROR1; } } for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "qcom,cam-power-seq-val", i, &seq_name); CDBG("%s seq_name[%d] = %s\n", __func__, i, seq_name); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR1; } switch (ps[i].seq_type) { case SENSOR_VREG: for (j = 0; j < num_vreg; j++) { if (!strcmp(seq_name, cam_vreg[j].reg_name)) break; } if (j < num_vreg) ps[i].seq_val = j; else rc = -EILSEQ; break; case SENSOR_GPIO: if (!strcmp(seq_name, "sensor_gpio_reset")) ps[i].seq_val = SENSOR_GPIO_RESET; else if (!strcmp(seq_name, "sensor_gpio_standby")) ps[i].seq_val = SENSOR_GPIO_STANDBY; else if (!strcmp(seq_name, "sensor_gpio_vdig")) ps[i].seq_val = SENSOR_GPIO_VDIG; else rc = -EILSEQ; break; case SENSOR_CLK: if (!strcmp(seq_name, "sensor_cam_mclk")) ps[i].seq_val = SENSOR_CAM_MCLK; else if (!strcmp(seq_name, "sensor_cam_clk")) ps[i].seq_val = SENSOR_CAM_CLK; else rc = -EILSEQ; break; case SENSOR_I2C_MUX: if (!strcmp(seq_name, "none")) ps[i].seq_val = 0; else rc = -EILSEQ; break; default: rc = -EILSEQ; break; } if (rc < 0) { CDBG("%s: unrecognized seq-val\n", __func__); goto ERROR1; } } array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL); if (!array) { pr_err("%s failed %d\n", __func__, __LINE__); rc = -ENOMEM; goto ERROR1; } rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-cfg-val", array, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } for (i = 0; i < count; i++) { if (ps[i].seq_type == SENSOR_GPIO) { if (array[i] == 0) ps[i].config_val = GPIO_OUT_LOW; else if (array[i] == 1) ps[i].config_val = GPIO_OUT_HIGH; } else { ps[i].config_val = array[i]; } CDBG("%s power_setting[%d].config_val = %ld\n", __func__, i, ps[i].config_val); } rc = of_property_read_u32_array(of_node, "qcom,cam-power-seq-delay", array, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } for (i = 0; i < count; i++) { ps[i].delay = array[i]; CDBG("%s power_setting[%d].delay = %d\n", __func__, i, ps[i].delay); } kfree(array); size = *power_setting_size; if (NULL != ps && 0 != size) need_reverse = 1; power_info->power_down_setting = kzalloc(sizeof(*ps) * size, GFP_KERNEL); if (!power_info->power_down_setting) { pr_err("%s failed %d\n", __func__, __LINE__); rc = -ENOMEM; goto ERROR1; } memcpy(power_info->power_down_setting, ps, sizeof(*ps) * size); power_info->power_down_setting_size = size; if (need_reverse) { int c, end = size - 1; struct msm_sensor_power_setting power_down_setting_t; for (c = 0; c < size/2; c++) { power_down_setting_t = power_info->power_down_setting[c]; power_info->power_down_setting[c] = power_info->power_down_setting[end]; power_info->power_down_setting[end] = power_down_setting_t; end--; } } return rc; ERROR2: kfree(array); ERROR1: kfree(ps); power_setting_size = 0; return rc; }
/* * This function reads the following from dtsi file * 1. All gpio sets * 2. All combinations of gpio sets * 3. Pinctrl handles to gpio sets * * Returns error if there is * 1. Problem reading from dtsi file * 2. Memory allocation failure */ int msm_gpioset_initialize(enum pinctrl_client client, struct device *dev) { struct pinctrl *pinctrl; const char *gpioset_names = "qcom,msm-gpios"; const char *gpioset_combinations = "qcom,pinctrl-names"; const char *gpioset_names_str = NULL; const char *gpioset_comb_str = NULL; int num_strings = 0; int ret = 0; int i = 0; pr_debug("%s\n", __func__); pinctrl = devm_pinctrl_get(dev); if (IS_ERR(pinctrl)) { pr_err("%s: Unable to get pinctrl handle\n", __func__); return -EINVAL; } pinctrl_info[client].pinctrl = pinctrl; /* Reading of gpio sets */ num_strings = of_property_count_strings(dev->of_node, gpioset_names); if (num_strings < 0) { dev_err(dev, "%s: missing %s in dt node or length is incorrect\n", __func__, gpioset_names); goto err; } gpioset_info[client].gpiosets_max = num_strings; gpioset_info[client].gpiosets = devm_kzalloc(dev, gpioset_info[client].gpiosets_max * sizeof(char *), GFP_KERNEL); if (!gpioset_info[client].gpiosets) { dev_err(dev, "Can't allocate memory for gpio set names\n"); ret = -ENOMEM; goto err; } for (i = 0; i < num_strings; i++) { ret = of_property_read_string_index(dev->of_node, gpioset_names, i, &gpioset_names_str); gpioset_info[client].gpiosets[i] = devm_kzalloc(dev, (strlen(gpioset_names_str) + 1), GFP_KERNEL); if (!gpioset_info[client].gpiosets[i]) { dev_err(dev, "%s: Can't allocate gpiosets[%d] data\n", __func__, i); ret = -ENOMEM; goto err; } strlcpy(gpioset_info[client].gpiosets[i], gpioset_names_str, strlen(gpioset_names_str)+1); gpioset_names_str = NULL; } num_strings = 0; /* Allocating memory for gpio set counter */ gpioset_info[client].gpioset_state = devm_kzalloc(dev, gpioset_info[client].gpiosets_max * sizeof(uint8_t), GFP_KERNEL); if (!gpioset_info[client].gpioset_state) { dev_err(dev, "Can't allocate memory for gpio set counter\n"); ret = -ENOMEM; goto err; } /* Reading of all combinations of gpio sets */ num_strings = of_property_count_strings(dev->of_node, gpioset_combinations); if (num_strings < 0) { dev_err(dev, "%s: missing %s in dt node or length is incorrect\n", __func__, gpioset_combinations); goto err; } gpioset_info[client].gpiosets_comb_max = num_strings; gpioset_info[client].gpiosets_comb_names = devm_kzalloc(dev, num_strings * sizeof(char *), GFP_KERNEL); if (!gpioset_info[client].gpiosets_comb_names) { dev_err(dev, "Can't allocate gpio set combination names data\n"); ret = -ENOMEM; goto err; } for (i = 0; i < gpioset_info[client].gpiosets_comb_max; i++) { ret = of_property_read_string_index(dev->of_node, gpioset_combinations, i, &gpioset_comb_str); gpioset_info[client].gpiosets_comb_names[i] = devm_kzalloc(dev, (strlen(gpioset_comb_str) + 1), GFP_KERNEL); if (!gpioset_info[client].gpiosets_comb_names[i]) { dev_err(dev, "%s: Can't allocate combinations[%d] data\n", __func__, i); ret = -ENOMEM; goto err; } strlcpy(gpioset_info[client].gpiosets_comb_names[i], gpioset_comb_str, strlen(gpioset_comb_str)+1); pr_debug("%s: GPIO configuration %s\n", __func__, gpioset_info[client].gpiosets_comb_names[i]); gpioset_comb_str = NULL; } /* Allocating memory for handles to pinctrl states */ pinctrl_info[client].cdc_lines = devm_kzalloc(dev, num_strings * sizeof(char *), GFP_KERNEL); if (!pinctrl_info[client].cdc_lines) { dev_err(dev, "Can't allocate pinctrl_info.cdc_lines data\n"); ret = -ENOMEM; goto err; } /* Get pinctrl handles for gpio sets in dtsi file */ for (i = 0; i < num_strings; i++) { pinctrl_info[client].cdc_lines[i] = pinctrl_lookup_state( pinctrl, (const char *)gpioset_info[client]. gpiosets_comb_names[i]); if (IS_ERR(pinctrl_info[client].cdc_lines[i])) pr_err("%s: Unable to get pinctrl handle for %s\n", __func__, gpioset_info[client]. gpiosets_comb_names[i]); } goto success; err: /* Free up memory allocated for gpio set combinations */ for (i = 0; i < gpioset_info[client].gpiosets_max; i++) { if (NULL != gpioset_info[client].gpiosets[i]) devm_kfree(dev, gpioset_info[client].gpiosets[i]); } if (NULL != gpioset_info[client].gpiosets) devm_kfree(dev, gpioset_info[client].gpiosets); /* Free up memory allocated for gpio set combinations */ for (i = 0; i < gpioset_info[client].gpiosets_comb_max; i++) { if (NULL != gpioset_info[client].gpiosets_comb_names[i]) devm_kfree(dev, gpioset_info[client].gpiosets_comb_names[i]); } if (NULL != gpioset_info[client].gpiosets_comb_names) devm_kfree(dev, gpioset_info[client].gpiosets_comb_names); /* Free up memory allocated for handles to pinctrl states */ if (NULL != pinctrl_info[client].cdc_lines) devm_kfree(dev, pinctrl_info[client].cdc_lines); /* Free up memory allocated for counter of gpio sets */ if (NULL != gpioset_info[client].gpioset_state) devm_kfree(dev, gpioset_info[client].gpioset_state); success: return ret; }
static int __devinit gdsc_probe(struct platform_device *pdev) { static atomic_t gdsc_count = ATOMIC_INIT(-1); struct regulator_init_data *init_data; struct resource *res; struct gdsc *sc; uint32_t regval; bool retain_mem, retain_periph; int i, ret; #ifdef CONFIG_MACH_LGE int use_lge_workaround = 0; /* default: all not applied */ #endif sc = devm_kzalloc(&pdev->dev, sizeof(struct gdsc), GFP_KERNEL); if (sc == NULL) return -ENOMEM; init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); if (init_data == NULL) return -ENOMEM; if (of_get_property(pdev->dev.of_node, "parent-supply", NULL)) init_data->supply_regulator = "parent"; ret = of_property_read_string(pdev->dev.of_node, "regulator-name", &sc->rdesc.name); if (ret) return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) return -EINVAL; sc->gdscr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (sc->gdscr == NULL) return -ENOMEM; sc->clock_count = of_property_count_strings(pdev->dev.of_node, "qcom,clock-names"); if (sc->clock_count == -EINVAL) { sc->clock_count = 0; } else if (IS_ERR_VALUE(sc->clock_count)) { dev_err(&pdev->dev, "Failed to get clock names\n"); return -EINVAL; } sc->clocks = devm_kzalloc(&pdev->dev, sizeof(struct clk *) * sc->clock_count, GFP_KERNEL); if (!sc->clocks) return -ENOMEM; for (i = 0; i < sc->clock_count; i++) { const char *clock_name; of_property_read_string_index(pdev->dev.of_node, "qcom,clock-names", i, &clock_name); sc->clocks[i] = devm_clk_get(&pdev->dev, clock_name); if (IS_ERR(sc->clocks[i])) { int rc = PTR_ERR(sc->clocks[i]); if (rc != -EPROBE_DEFER) dev_err(&pdev->dev, "Failed to get %s\n", clock_name); return rc; } } #ifdef CONFIG_MACH_LGE of_property_read_u32(pdev->dev.of_node, "lge,use_workaround", &use_lge_workaround); sc->use_lge_workaround = !(!use_lge_workaround); #endif sc->rdesc.id = atomic_inc_return(&gdsc_count); sc->rdesc.ops = &gdsc_ops; sc->rdesc.type = REGULATOR_VOLTAGE; sc->rdesc.owner = THIS_MODULE; platform_set_drvdata(pdev, sc); /* * Disable HW trigger: collapse/restore occur based on registers writes. * Disable SW override: Use hardware state-machine for sequencing. */ regval = readl_relaxed(sc->gdscr); regval &= ~(HW_CONTROL_MASK | SW_OVERRIDE_MASK); /* Configure wait time between states. */ regval &= ~(EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK); regval |= EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL; writel_relaxed(regval, sc->gdscr); retain_mem = of_property_read_bool(pdev->dev.of_node, "qcom,retain-mem"); retain_periph = of_property_read_bool(pdev->dev.of_node, "qcom,retain-periph"); for (i = 0; i < sc->clock_count; i++) { if (retain_mem || (regval & PWR_ON_MASK)) clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_MEM); else clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_MEM); if (retain_periph || (regval & PWR_ON_MASK)) clk_set_flags(sc->clocks[i], CLKFLAG_RETAIN_PERIPH); else clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH); } sc->toggle_mem = !retain_mem; sc->toggle_periph = !retain_periph; sc->toggle_logic = !of_property_read_bool(pdev->dev.of_node, "qcom,skip-logic-collapse"); if (!sc->toggle_logic) { #ifdef CONFIG_MACH_LGE /* LGE workaround is not used if a device is good pdn revision */ if (lge_get_board_revno() >= use_lge_workaround) { regval &= ~SW_COLLAPSE_MASK; writel_relaxed(regval, sc->gdscr); ret = readl_tight_poll_timeout(sc->gdscr, regval, regval & PWR_ON_MASK, TIMEOUT_US); if (ret) { dev_err(&pdev->dev, "%s enable timed out\n", sc->rdesc.name); return ret; } } else { pr_info("%s: %s is enabled only at first by lge workaround\n", __func__, sc->rdesc.name); ret = lge_gdsc_enable(sc); if (ret) { dev_err(&pdev->dev, "%s enable timed out\n", sc->rdesc.name); return ret; } } #else /* qmc */ regval &= ~SW_COLLAPSE_MASK; writel_relaxed(regval, sc->gdscr); ret = readl_tight_poll_timeout(sc->gdscr, regval, regval & PWR_ON_MASK, TIMEOUT_US); if (ret) { dev_err(&pdev->dev, "%s enable timed out\n", sc->rdesc.name); return ret; } #endif } sc->rdev = regulator_register(&sc->rdesc, &pdev->dev, init_data, sc, pdev->dev.of_node); if (IS_ERR(sc->rdev)) { dev_err(&pdev->dev, "regulator_register(\"%s\") failed.\n", sc->rdesc.name); return PTR_ERR(sc->rdev); } return 0; }
static int power_sysfs_parse_dt(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; int arr_num, ret, i; arr_cnt = of_property_count_strings(node, "sysfs,node") / 3; if (arr_cnt > 0) pr_info("%s : Total sysfs node is %d\n", __func__, arr_cnt); else { pr_err("%s : ERROR sysfs node isn't exist\n", __func__); return 0; } arr = kzalloc(arr_cnt * sizeof(struct power_sysfs_array), GFP_KERNEL); if (arr != NULL) { for (arr_num = 0, i = 0; arr_num < arr_cnt; arr_num++) { ret = of_property_read_string_index(node, "sysfs,node", i++, &arr[arr_num].group); if (ret) { pr_err("%s : ERROR get %ith group\n", __func__, arr_num); goto err_get_array; } ret = of_property_read_string_index(node, "sysfs,node", i++, &arr[arr_num].user_node); if (ret) { pr_err("%s : ERROR get %ith user_node\n", __func__, arr_num); goto err_get_array; } ret = of_property_read_string_index(node, "sysfs,node", i++, &arr[arr_num].kernel_node); if (ret) { pr_err("%s : ERROR get %ith kernel_node\n", __func__, arr_num); goto err_get_array; } else if (check_mandatory_path(arr_num)) { if (!strcmp(arr[arr_num].kernel_node, "NULL")) { pr_err("%s : ERROR get mandatory path %s\n", __func__, arr[arr_num].user_node); goto err_get_array; } pr_info("%s : %s path is mandatory \n", __func__, arr[arr_num].user_node); } } } else { pr_err("%s : ERROR get sysfs array\n", __func__); return -1; } /* debug */ for (arr_num = 0; arr_num < arr_cnt; arr_num++) pr_err("%s : get %dth node is %s, %s, %s\n", __func__, arr_num, arr[arr_num].group, arr[arr_num].user_node, arr[arr_num].kernel_node); return 0; err_get_array: kzfree(arr); return -1; }
int msm_camera_get_dt_vreg_data(struct device_node *of_node, struct camera_vreg_t **cam_vreg, int *num_vreg) { int rc = 0, i = 0; uint32_t count = 0; uint32_t *vreg_array = NULL; struct camera_vreg_t *vreg = NULL; count = of_property_count_strings(of_node, "qcom,cam-vreg-name"); CDBG("%s qcom,cam-vreg-name count %d\n", __func__, count); if (!count) return 0; vreg = kzalloc(sizeof(*vreg) * count, GFP_KERNEL); if (!vreg) { pr_err("%s failed %d\n", __func__, __LINE__); return -ENOMEM; } *cam_vreg = vreg; *num_vreg = count; for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "qcom,cam-vreg-name", i, &vreg[i].reg_name); CDBG("%s reg_name[%d] = %s\n", __func__, i, vreg[i].reg_name); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR1; } } vreg_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL); if (!vreg_array) { pr_err("%s failed %d\n", __func__, __LINE__); rc = -ENOMEM; goto ERROR1; } rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-type", vreg_array, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } for (i = 0; i < count; i++) { vreg[i].type = vreg_array[i]; CDBG("%s cam_vreg[%d].type = %d\n", __func__, i, vreg[i].type); } rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-min-voltage", vreg_array, count); if (rc == 0) { for (i = 0; i < count; i++) { vreg[i].min_voltage = vreg_array[i]; CDBG("%s cam_vreg[%d].min_voltage = %d\n", __func__, i, vreg[i].min_voltage); } } rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-max-voltage", vreg_array, count); if (rc == 0) { for (i = 0; i < count; i++) { vreg[i].max_voltage = vreg_array[i]; CDBG("%s cam_vreg[%d].max_voltage = %d\n", __func__, i, vreg[i].max_voltage); } } rc = of_property_read_u32_array(of_node, "qcom,cam-vreg-op-mode", vreg_array, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } for (i = 0; i < count; i++) { vreg[i].op_mode = vreg_array[i]; CDBG("%s cam_vreg[%d].op_mode = %d\n", __func__, i, vreg[i].op_mode); } kfree(vreg_array); return rc; ERROR2: kfree(vreg_array); ERROR1: kfree(vreg); *num_vreg = 0; return rc; }
int msm_camera_get_dt_power_off_setting_data(struct device_node *of_node, struct camera_vreg_t *cam_vreg, int num_vreg, struct msm_sensor_power_setting **power_setting, uint16_t *power_setting_size) { int rc = 0, i, j; int count = 0; const char *seq_name = NULL; uint32_t *array = NULL; struct msm_sensor_power_setting *ps; if (!power_setting || !power_setting_size) return -EINVAL; count = of_property_count_strings(of_node, "qcom,cam-power-off-seq-type"); *power_setting_size = count; CDBG("%s qcom,cam-power-off-seq-type count %d\n", __func__, count); if (count <= 0) return 0; ps = kzalloc(sizeof(*ps) * count, GFP_KERNEL); if (!ps) { pr_err("%s failed %d\n", __func__, __LINE__); return -ENOMEM; } *power_setting = ps; for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "qcom,cam-power-off-seq-type", i, &seq_name); CDBG("%s seq_name[%d] = %s\n", __func__, i, seq_name); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR1; } if (!strcmp(seq_name, "sensor_vreg")) { ps[i].seq_type = SENSOR_VREG; CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__, i, ps[i].seq_type); } else if (!strcmp(seq_name, "sensor_gpio")) { ps[i].seq_type = SENSOR_GPIO; CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__, i, ps[i].seq_type); } else if (!strcmp(seq_name, "sensor_clk")) { ps[i].seq_type = SENSOR_CLK; CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__, i, ps[i].seq_type); } else if (!strcmp(seq_name, "sensor_i2c_mux")) { ps[i].seq_type = SENSOR_I2C_MUX; CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__, i, ps[i].seq_type); #if defined(CONFIG_MACH_MONTBLANC) || defined(CONFIG_MACH_VIKALCU) } else if (!strcmp(seq_name, "sensor_additional_ldo")) { ps[i].seq_type = SENSOR_ADDITIONAL_LDO; CDBG("%s:%d seq_type[%d] %d\n", __func__, __LINE__, i, ps[i].seq_type); #endif } else { CDBG("%s: unrecognized seq-type\n", __func__); rc = -EILSEQ; goto ERROR1; } } for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "qcom,cam-power-off-seq-val", i, &seq_name); CDBG("%s seq_name[%d] = %s\n", __func__, i, seq_name); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR1; } switch (ps[i].seq_type) { case SENSOR_VREG: for (j = 0; j < num_vreg; j++) { if (!strcmp(seq_name, cam_vreg[j].reg_name)) break; } if (j < num_vreg) ps[i].seq_val = j; else rc = -EILSEQ; break; #if defined(CONFIG_MACH_MONTBLANC) case SENSOR_ADDITIONAL_LDO: #endif case SENSOR_GPIO: if (!strcmp(seq_name, "sensor_gpio_reset")) ps[i].seq_val = SENSOR_GPIO_RESET; else if (!strcmp(seq_name, "sensor_gpio_standby")) ps[i].seq_val = SENSOR_GPIO_STANDBY; else if (!strcmp(seq_name, "sensor_gpio_ext_vana_power")) ps[i].seq_val = SENSOR_GPIO_EXT_VANA_POWER; else if (!strcmp(seq_name, "sensor_gpio_ext_vio_power")) ps[i].seq_val = SENSOR_GPIO_EXT_VIO_POWER; else if (!strcmp(seq_name, "sensor_gpio_ext_vcore_power")) ps[i].seq_val = SENSOR_GPIO_EXT_VCORE_POWER; else rc = -EILSEQ; break; case SENSOR_CLK: if (!strcmp(seq_name, "sensor_cam_mclk")) ps[i].seq_val = SENSOR_CAM_MCLK; else if (!strcmp(seq_name, "sensor_cam_clk")) ps[i].seq_val = SENSOR_CAM_CLK; else rc = -EILSEQ; break; case SENSOR_I2C_MUX: if (!strcmp(seq_name, "none")) ps[i].seq_val = 0; else rc = -EILSEQ; break; default: rc = -EILSEQ; break; } if (rc < 0) { CDBG("%s: unrecognized seq-val\n", __func__); goto ERROR1; } } array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL); if (!array) { pr_err("%s failed %d\n", __func__, __LINE__); rc = -ENOMEM; goto ERROR1; } rc = of_property_read_u32_array(of_node, "qcom,cam-power-off-seq-cfg-val", array, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } for (i = 0; i < count; i++) { if (ps[i].seq_type == SENSOR_GPIO) { if (array[i] == 0) ps[i].config_val = GPIO_OUT_LOW; else if (array[i] == 1) ps[i].config_val = GPIO_OUT_HIGH; } else { ps[i].config_val = array[i]; } CDBG("%s power_setting[%d].config_val = %ld\n", __func__, i, ps[i].config_val); } rc = of_property_read_u32_array(of_node, "qcom,cam-power-off-seq-delay", array, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } for (i = 0; i < count; i++) { ps[i].delay = array[i]; CDBG("%s power_setting[%d].delay = %d\n", __func__, i, ps[i].delay); } kfree(array); return rc; ERROR2: kfree(array); ERROR1: kfree(ps); power_setting_size = 0; return rc; }