static void __init cpg_mstp_clocks_init(struct device_node *np) { struct mstp_clock_group *group; const char *idxname; struct clk **clks; unsigned int i; group = kzalloc(sizeof(*group), GFP_KERNEL); clks = kmalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL); if (group == NULL || clks == NULL) { kfree(group); kfree(clks); pr_err("%s: failed to allocate group\n", __func__); return; } spin_lock_init(&group->lock); group->data.clks = clks; group->smstpcr = of_iomap(np, 0); group->mstpsr = of_iomap(np, 1); if (group->smstpcr == NULL) { pr_err("%s: failed to remap SMSTPCR\n", __func__); kfree(group); kfree(clks); return; } for (i = 0; i < MSTP_MAX_CLOCKS; ++i) clks[i] = ERR_PTR(-ENOENT); if (of_find_property(np, "clock-indices", &i)) idxname = "clock-indices"; else idxname = "renesas,clock-indices"; for (i = 0; i < MSTP_MAX_CLOCKS; ++i) { const char *parent_name; const char *name; u32 clkidx; int ret; /* Skip clocks with no name. */ ret = of_property_read_string_index(np, "clock-output-names", i, &name); if (ret < 0 || strlen(name) == 0) continue; parent_name = of_clk_get_parent_name(np, i); ret = of_property_read_u32_index(np, idxname, i, &clkidx); if (parent_name == NULL || ret < 0) break; if (clkidx >= MSTP_MAX_CLOCKS) { pr_err("%s: invalid clock %s %s index %u)\n", __func__, np->name, name, clkidx); continue; } clks[clkidx] = cpg_mstp_clock_register(name, parent_name, clkidx, group); if (!IS_ERR(clks[clkidx])) { group->data.clk_num = max(group->data.clk_num, clkidx + 1); /* * Register a clkdev to let board code retrieve the * clock by name and register aliases for non-DT * devices. * * FIXME: Remove this when all devices that require a * clock will be instantiated from DT. */ clk_register_clkdev(clks[clkidx], name, NULL); } else { pr_err("%s: failed to register %s %s clock (%ld)\n", __func__, np->name, name, PTR_ERR(clks[clkidx])); } } of_clk_add_provider(np, of_clk_src_onecell_get, &group->data); }
static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev) { struct device_node *dn = pdev->dev.of_node; struct brcmstb_gisb_arb_device *gdev; const struct of_device_id *of_id; struct resource *r; int err, timeout_irq, tea_irq; unsigned int num_masters, j = 0; int i, first, last; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); timeout_irq = platform_get_irq(pdev, 0); tea_irq = platform_get_irq(pdev, 1); gdev = devm_kzalloc(&pdev->dev, sizeof(*gdev), GFP_KERNEL); if (!gdev) return -ENOMEM; mutex_init(&gdev->lock); INIT_LIST_HEAD(&gdev->next); gdev->base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(gdev->base)) return PTR_ERR(gdev->base); of_id = of_match_node(brcmstb_gisb_arb_of_match, dn); if (!of_id) { pr_err("failed to look up compatible string\n"); return -EINVAL; } gdev->gisb_offsets = of_id->data; gdev->big_endian = of_device_is_big_endian(dn); err = devm_request_irq(&pdev->dev, timeout_irq, brcmstb_gisb_timeout_handler, 0, pdev->name, gdev); if (err < 0) return err; err = devm_request_irq(&pdev->dev, tea_irq, brcmstb_gisb_tea_handler, 0, pdev->name, gdev); if (err < 0) return err; /* If we do not have a valid mask, assume all masters are enabled */ if (of_property_read_u32(dn, "brcm,gisb-arb-master-mask", &gdev->valid_mask)) gdev->valid_mask = 0xffffffff; /* Proceed with reading the litteral names if we agree on the * number of masters */ num_masters = of_property_count_strings(dn, "brcm,gisb-arb-master-names"); if (hweight_long(gdev->valid_mask) == num_masters) { first = ffs(gdev->valid_mask) - 1; last = fls(gdev->valid_mask) - 1; for (i = first; i < last; i++) { if (!(gdev->valid_mask & BIT(i))) continue; of_property_read_string_index(dn, "brcm,gisb-arb-master-names", j, &gdev->master_names[i]); j++; } } err = sysfs_create_group(&pdev->dev.kobj, &gisb_arb_sysfs_attr_group); if (err) return err; platform_set_drvdata(pdev, gdev); list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list); #ifdef CONFIG_ARM hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0, "imprecise external abort"); #endif dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n", gdev->base, timeout_irq, tea_irq); return 0; }
static void of_gpiochip_add_pin_range(struct gpio_chip *chip) { struct device_node *np = chip->of_node; struct of_phandle_args pinspec; struct pinctrl_dev *pctldev; int index = 0, ret; const char *name; static const char group_names_propname[] = "gpio-ranges-group-names"; struct property *group_names; if (!np) return; group_names = of_find_property(np, group_names_propname, NULL); for (;; index++) { ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, index, &pinspec); if (ret) break; pctldev = of_pinctrl_get(pinspec.np); if (!pctldev) break; if (pinspec.args[2]) { if (group_names) { ret = of_property_read_string_index(np, group_names_propname, index, &name); if (strlen(name)) { pr_err("%s: Group name of numeric GPIO ranges must be the empty string.\n", np->full_name); break; } } /* npins != 0: linear range */ ret = gpiochip_add_pin_range(chip, pinctrl_dev_get_devname(pctldev), pinspec.args[0], pinspec.args[1], pinspec.args[2]); if (ret) break; } else { /* npins == 0: special range */ if (pinspec.args[1]) { pr_err("%s: Illegal gpio-range format.\n", np->full_name); break; } if (!group_names) { pr_err("%s: GPIO group range requested but no %s property.\n", np->full_name, group_names_propname); break; } ret = of_property_read_string_index(np, group_names_propname, index, &name); if (ret) break; if (!strlen(name)) { pr_err("%s: Group name of GPIO group range cannot be the empty string.\n", np->full_name); break; } ret = gpiochip_add_pingroup_range(chip, pctldev, pinspec.args[0], name); if (ret) break; } } }
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) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } 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) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } 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_gpio_req_tbl(struct device_node *of_node, struct msm_camera_gpio_conf *gconf, uint16_t *gpio_array, uint16_t gpio_array_size) { int rc = 0, i = 0; uint32_t count = 0; uint32_t *val_array = NULL; if (!of_get_property(of_node, "qcom,gpio-req-tbl-num", &count)) return 0; count /= sizeof(uint32_t); if (!count) { pr_err("%s qcom,gpio-req-tbl-num 0\n", __func__); return 0; } val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL); if (!val_array) { pr_err("%s failed %d\n", __func__, __LINE__); return -ENOMEM; } gconf->cam_gpio_req_tbl = kzalloc(sizeof(struct gpio) * count, GFP_KERNEL); if (!gconf->cam_gpio_req_tbl) { pr_err("%s failed %d\n", __func__, __LINE__); rc = -ENOMEM; goto ERROR1; } gconf->cam_gpio_req_tbl_size = count; rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-num", val_array, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } for (i = 0; i < count; i++) { if (val_array[i] >= gpio_array_size) { pr_err("%s gpio req tbl index %d invalid\n", __func__, val_array[i]); return -EINVAL; } gconf->cam_gpio_req_tbl[i].gpio = gpio_array[val_array[i]]; CDBG("%s cam_gpio_req_tbl[%d].gpio = %d\n", __func__, i, gconf->cam_gpio_req_tbl[i].gpio); } rc = of_property_read_u32_array(of_node, "qcom,gpio-req-tbl-flags", val_array, count); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } for (i = 0; i < count; i++) { gconf->cam_gpio_req_tbl[i].flags = val_array[i]; CDBG("%s cam_gpio_req_tbl[%d].flags = %ld\n", __func__, i, gconf->cam_gpio_req_tbl[i].flags); } for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "qcom,gpio-req-tbl-label", i, &gconf->cam_gpio_req_tbl[i].label); CDBG("%s cam_gpio_req_tbl[%d].label = %s\n", __func__, i, gconf->cam_gpio_req_tbl[i].label); if (rc < 0) { pr_err("%s failed %d\n", __func__, __LINE__); goto ERROR2; } } kfree(val_array); return rc; ERROR2: kfree(gconf->cam_gpio_req_tbl); ERROR1: kfree(val_array); gconf->cam_gpio_req_tbl_size = 0; return rc; }
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 if (!strcmp(seq_name, "sensor_gpio_vio")) ps[i].seq_val = SENSOR_GPIO_VIO; else if (!strcmp(seq_name, "sensor_gpio_vana")) ps[i].seq_val = SENSOR_GPIO_VANA; else if (!strcmp(seq_name, "sensor_gpio_vaf")) ps[i].seq_val = SENSOR_GPIO_VAF; 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; }
int msm_ispif_get_clk_info(struct ispif_device *ispif_dev, struct platform_device *pdev, struct msm_cam_clk_info *ahb_clk_info, struct msm_cam_clk_info *clk_info) { uint32_t count, num_ahb_clk = 0; const char *rate = NULL; int i, rc; 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; } for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "clock-names", i, &(clk_info[i].clk_name)); if (rc < 0) { pr_err("%s reading clock-name failed index %d\n", __func__, i); return rc; } rc = of_property_read_string_index(of_node, "qcom,clock-rates", i, &rate); CDBG("clock-names[%d] = %s, clk_rate = %s\n", i, clk_info[i].clk_name, rate); if (rc < 0) { pr_err("%s reading clock-rate failed index %d\n", __func__, i); return rc; } if (!strcmp(rate, "-1") || !strcmp(rate, "0")) clk_info[i].clk_rate = NO_SET_RATE; else if (!strcmp(rate, "-2")) clk_info[i].clk_rate = INIT_RATE; else rc = kstrtol(rate, 10, &clk_info[i].clk_rate); if (strnstr(clk_info[i].clk_name, "ahb", strlen(clk_info[i].clk_name))) { ahb_clk_info[num_ahb_clk].clk_name = clk_info[i].clk_name; ahb_clk_info[num_ahb_clk].clk_rate = clk_info[i].clk_rate; CDBG("clk_name[%d]= %s, clk_rate = %ld\n", num_ahb_clk, ahb_clk_info[num_ahb_clk].clk_name, ahb_clk_info[num_ahb_clk].clk_rate); num_ahb_clk++; } } CDBG("%s: num_ahb_clk %d num_clk %d\n", __func__, num_ahb_clk, count); ispif_dev->num_ahb_clk = num_ahb_clk; ispif_dev->num_clk = count; return 0; }
static int mdss_dsi_get_dt_vreg_data(struct device *dev, struct dss_module_power *mp) { int i, rc = 0; int dt_vreg_total = 0; u32 *val_array = NULL; struct device_node *of_node = NULL; if (!dev || !mp) { pr_err("%s: invalid input\n", __func__); rc = -EINVAL; goto error; } of_node = dev->of_node; mp->num_vreg = 0; dt_vreg_total = of_property_count_strings(of_node, "qcom,supply-names"); if (dt_vreg_total < 0) { pr_debug("%s: vreg not found. rc=%d\n", __func__, dt_vreg_total); rc = 0; goto error; } else { pr_debug("%s: vreg found. count=%d\n", __func__, dt_vreg_total); } if (dt_vreg_total > 0) { mp->num_vreg = dt_vreg_total; mp->vreg_config = devm_kzalloc(dev, sizeof(struct dss_vreg) * dt_vreg_total, GFP_KERNEL); if (!mp->vreg_config) { pr_err("%s: can't alloc vreg mem\n", __func__); goto error; } } else { pr_debug("%s: no vreg\n", __func__); return 0; } val_array = devm_kzalloc(dev, sizeof(u32) * dt_vreg_total, GFP_KERNEL); if (!val_array) { pr_err("%s: can't allocate vreg scratch mem\n", __func__); rc = -ENOMEM; goto error; } for (i = 0; i < dt_vreg_total; i++) { const char *st = NULL; /* vreg-name */ rc = of_property_read_string_index(of_node, "qcom,supply-names", i, &st); if (rc) { pr_err("%s: error reading name. i=%d, rc=%d\n", __func__, i, rc); goto error; } snprintf(mp->vreg_config[i].vreg_name, ARRAY_SIZE((mp->vreg_config[i].vreg_name)), "%s", st); /* vreg-min-voltage */ memset(val_array, 0, sizeof(u32) * dt_vreg_total); rc = of_property_read_u32_array(of_node, "qcom,supply-min-voltage-level", val_array, dt_vreg_total); if (rc) { pr_err("%s: error reading min volt. rc=%d\n", __func__, rc); goto error; } mp->vreg_config[i].min_voltage = val_array[i]; /* vreg-max-voltage */ memset(val_array, 0, sizeof(u32) * dt_vreg_total); rc = of_property_read_u32_array(of_node, "qcom,supply-max-voltage-level", val_array, dt_vreg_total); if (rc) { pr_err("%s: error reading max volt. rc=%d\n", __func__, rc); goto error; } mp->vreg_config[i].max_voltage = val_array[i]; /* vreg-peak-current*/ memset(val_array, 0, sizeof(u32) * dt_vreg_total); rc = of_property_read_u32_array(of_node, "qcom,supply-peak-current", val_array, dt_vreg_total); if (rc) { pr_err("%s: error reading peak current. rc=%d\n", __func__, rc); goto error; } mp->vreg_config[i].peak_current = val_array[i]; pr_debug("%s: %s min=%d, max=%d, pc=%d\n", __func__, mp->vreg_config[i].vreg_name, mp->vreg_config[i].min_voltage, mp->vreg_config[i].max_voltage, mp->vreg_config[i].peak_current); } devm_kfree(dev, val_array); return rc; error: if (mp->vreg_config) { devm_kfree(dev, mp->vreg_config); mp->vreg_config = NULL; } mp->num_vreg = 0; if (val_array) devm_kfree(dev, val_array); return rc; }
/********************************************************** * Function: charge_core_parse_dts * Discription: parse the module dts config value * Parameters: np:device_node * di:charge_core_info * return value: 0-sucess or others-fail **********************************************************/ static int charge_core_parse_dts(struct device_node* np, struct charge_core_info *di) { int ret = 0; int i = 0; int array_len = 0; int idata = 0; const char *chrg_data_string = NULL; /*ac charge current*/ ret = of_property_read_u32(np, "iin_ac", &(di->data.iin_ac)); if(ret) { hwlog_err("get iin_ac failed\n"); return -EINVAL; } hwlog_debug("iin_ac = %d\n",di->data.iin_ac); ret = of_property_read_u32(np, "ichg_ac", &(di->data.ichg_ac)); if(ret) { hwlog_err("get ichg_ac failed\n"); return -EINVAL; } hwlog_debug("ichg_ac = %d\n",di->data.ichg_ac); /*fcp charge current */ ret = of_property_read_u32(np,"iin_fcp",&(di->data.iin_fcp)); if(ret) { hwlog_info("get iin_fcp failed ,use iin_ac's value instead \n"); di->data.iin_fcp = di->data.iin_ac; } hwlog_debug("iin_fcp = %d\n",di->data.iin_fcp); ret = of_property_read_u32(np,"ichg_fcp",&(di->data.ichg_fcp)); if(ret) { hwlog_info("get ichg_fcp failed ,use ichg_ac's value instead \n"); di->data.ichg_fcp = di->data.ichg_ac; } hwlog_debug("ichg_fcp = %d\n",di->data.ichg_fcp); /*usb charge current*/ ret = of_property_read_u32(np, "iin_usb", &(di->data.iin_usb)); if(ret) { hwlog_err("get iin_usb failed\n"); return -EINVAL; } hwlog_debug("iin_usb = %d\n",di->data.iin_usb); ret = of_property_read_u32(np, "ichg_usb", &(di->data.ichg_usb)); if(ret) { hwlog_err("get ichg_usb failed\n"); return -EINVAL; } hwlog_debug("ichg_usb = %d\n",di->data.ichg_usb); /*nonstandard charge current*/ ret = of_property_read_u32(np, "iin_nonstd", &(di->data.iin_nonstd)); if(ret) { hwlog_err("get iin_nonstd failed\n"); return -EINVAL; } hwlog_debug("iin_nonstd = %d\n",di->data.iin_nonstd); ret = of_property_read_u32(np, "ichg_nonstd", &(di->data.ichg_nonstd)); if(ret) { hwlog_err("get ichg_nonstd failed\n"); return -EINVAL; } hwlog_debug("ichg_nonstd = %d\n",di->data.ichg_nonstd); /*Charging Downstream Port*/ ret = of_property_read_u32(np, "iin_bc_usb", &(di->data.iin_bc_usb)); if(ret) { hwlog_err("get iin_bc_usb failed\n"); return -EINVAL; } hwlog_debug("iin_bc_usb = %d\n",di->data.iin_bc_usb); ret = of_property_read_u32(np, "ichg_bc_usb", &(di->data.ichg_bc_usb)); if(ret) { hwlog_err("get ichg_bc_usb failed\n"); return -EINVAL; } hwlog_debug("ichg_bc_usb = %d\n",di->data.ichg_bc_usb); /*VR Charge current*/ ret = of_property_read_u32(np, "iin_vr", &(di->data.iin_vr)); if(ret) { hwlog_err("get iin_vr failed\n"); return -EINVAL; } hwlog_debug("iin_vr = %d\n",di->data.iin_vr); ret = of_property_read_u32(np, "ichg_vr", &(di->data.ichg_vr)); if(ret) { hwlog_err("get ichg_vr failed\n"); return -EINVAL; } hwlog_debug("ichg_vr = %d\n",di->data.ichg_vr); /*terminal current*/ ret = of_property_read_u32(np, "iterm", &(di->data.iterm)); if(ret) { hwlog_err("get iterm failed\n"); return -EINVAL; } hwlog_debug("iterm = %d\n",di->data.iterm); /*otg current*/ ret = of_property_read_u32(np, "otg_curr", &(di->data.otg_curr)); if(ret) { hwlog_err("get otg_curr failed\n"); return -EINVAL; } hwlog_debug("otg_curr = %d\n",di->data.otg_curr); /*segment para type*/ ret = of_property_read_u32(np, "segment_type", &(di->data.segment_type)); if(ret) { hwlog_err("get segment_type failed\n"); return -EINVAL; } /*TypeC High mode current*/ ret = of_property_read_u32(np, "typec_support", &(di->data.typec_support)); if(ret) { hwlog_err("get typec support flag!\n"); return -EINVAL; } hwlog_info("typec support flag = %d\n",di->data.typec_support); ret = of_property_read_u32(np, "iin_typech", &(di->data.iin_typech)); if(ret) { hwlog_err("get typec high mode ibus curr failed\n"); return -EINVAL; } hwlog_info("typec high mode ibus curr = %d\n",di->data.iin_typech); ret = of_property_read_u32(np, "ichg_typech", &(di->data.ichg_typech)); if(ret) { hwlog_err("get typec high mode ibat curr failed\n"); return -EINVAL; } hwlog_info("typec high mode ibat curr = %d\n",di->data.ichg_typech); //vdpm_para array_len = of_property_count_strings(np, "vdpm_para"); if ((array_len <= 0) || (array_len % VDPM_PARA_TOTAL != 0)) { hwlog_err("vdpm_para is invaild,please check vdpm_para number!!\n"); return -EINVAL; } if (array_len > VDPM_PARA_LEVEL * VDPM_PARA_TOTAL) { array_len = VDPM_PARA_LEVEL * VDPM_PARA_TOTAL; hwlog_err("vdpm_para is too long,use only front %d paras!!\n", array_len); return -EINVAL; } memset(di->vdpm_para, 0, VDPM_PARA_LEVEL * sizeof(struct charge_vdpm_data)); // data reset to 0 for (i = 0; i < array_len; i++) { ret = of_property_read_string_index(np, "vdpm_para", i, &chrg_data_string); if (ret) { hwlog_err("get vdpm_para failed\n"); return -EINVAL; } idata = simple_strtol(chrg_data_string, NULL, 10); switch (i % VDPM_PARA_TOTAL) { case VDPM_PARA_CAP_MIN: if ((idata < VDPM_CBAT_MIN) || (idata > VDPM_CBAT_MAX)) { hwlog_err("the vdpm_para cap_min is out of range!!\n"); return -EINVAL; } di->vdpm_para[ i/ (VDPM_PARA_TOTAL)].cap_min = idata; break; case VDPM_PARA_CAP_MAX: if((idata < VDPM_CBAT_MIN) || (idata > VDPM_CBAT_MAX)) { hwlog_err("the vdpm_para cap_max is out of range!!\n"); return -EINVAL; } di->vdpm_para[i / (VDPM_PARA_TOTAL)].cap_max = idata; break; case VDPM_PARA_DPM: if((idata < VDPM_VOLT_MIN) || (idata > VDPM_VOLT_MAX)) { hwlog_err("the vdpm_para vin_dpm is out of range!!\n"); return -EINVAL; } di->vdpm_para[i / (VDPM_PARA_TOTAL)].vin_dpm = idata; break; case VDPM_PARA_CAP_BACK: if((idata < 0) || (idata > VDPM_CAP_DETA)) { hwlog_err("the vdpm_para cap_back is out of range!!\n"); return -EINVAL; } di->vdpm_para[i / (VDPM_PARA_TOTAL)].cap_back = idata; break; default: hwlog_err("get vdpm_para failed\n"); } hwlog_debug("di->vdpm_para[%d][%d] = %d\n", i / (VDPM_PARA_TOTAL), i % (VDPM_PARA_TOTAL), idata); } /* inductance_para */ memset(di->inductance_para, 0, INDUCTANCE_PARA_LEVEL * sizeof(struct charge_inductance_data)); // data reset to 0 array_len = of_property_count_strings(np, "inductance_para"); if ((array_len <= 0) || (array_len % INDUCTANCE_PARA_TOTAL != 0)) { hwlog_err("inductance_para is invaild,please check inductance_para number!!\n"); return -EINVAL; } if (array_len > INDUCTANCE_PARA_LEVEL * INDUCTANCE_PARA_TOTAL) { array_len = INDUCTANCE_PARA_LEVEL * INDUCTANCE_PARA_TOTAL; hwlog_err("inductance_para is too long,use only front %d paras!!\n", array_len); return -EINVAL; } for(i = 0; i < array_len ; i++) { ret = of_property_read_string_index(np, "inductance_para", i, &chrg_data_string); if (ret) { hwlog_err("get inductance_para failed\n"); return -EINVAL; } idata = simple_strtol(chrg_data_string, NULL, 10); switch (i % INDUCTANCE_PARA_TOTAL) { case INDUCTANCE_PARA_CAP_MIN: if ((idata < INDUCTANCE_CBAT_MIN) || (idata > INDUCTANCE_CBAT_MAX)) { hwlog_err("the inductance_para cap_min is out of range!!\n"); return -EINVAL; } di->inductance_para[ i/ (INDUCTANCE_PARA_TOTAL)].cap_min = idata; break; case INDUCTANCE_PARA_CAP_MAX: if ((idata < INDUCTANCE_CBAT_MIN) || (idata > INDUCTANCE_CBAT_MAX)) { hwlog_err("the inductance_para cap_max is out of range!!\n"); return -EINVAL; } di->inductance_para[i / (INDUCTANCE_PARA_TOTAL)].cap_max = idata; break; case INDUCTANCE_PARA_IIN: if ((idata < INDUCTANCE_IIN_MIN) || (idata > INDUCTANCE_IIN_MAX)) { hwlog_err("the inductance_para iin is out of range!!\n"); return -EINVAL; } di->inductance_para[i / (INDUCTANCE_PARA_TOTAL)].iin_inductance= idata; break; case INDUCTANCE_PARA_CAP_BACK: if ((idata < 0) || (idata > INDUCTANCE_CAP_DETA)) { hwlog_err("the inductance_para cap_back is out of range!!\n"); return -EINVAL; } di->inductance_para[i / (INDUCTANCE_PARA_TOTAL)].cap_back = idata; break; default: hwlog_err("get vdpm_para failed\n"); } hwlog_info("di->inductance_para[%d][%d] = %d\n", i / (INDUCTANCE_PARA_TOTAL), i % (INDUCTANCE_PARA_TOTAL), idata); } if(strstr(saved_command_line, "androidboot.swtype=factory") && (!is_hisi_battery_exist())) { di->data.iin_ac = CHARGE_CURRENT_2000_MA; di->data.ichg_ac = CHARGE_CURRENT_1900_MA; di->data.iin_bc_usb = CHARGE_CURRENT_2000_MA; di->data.ichg_bc_usb = CHARGE_CURRENT_1900_MA; hwlog_info("factory version,iin_ac = %d mA,ichg_ac %d mA,iin_bc_usb = %d mA,ichg_bc_usb = %d mA\n", di->data.iin_ac,di->data.ichg_ac,di->data.iin_bc_usb,di->data.ichg_bc_usb); } di->data.iin_max = di->data.iin_ac < di->data.iin_fcp ? di->data.iin_fcp :di->data.iin_ac; di->data.ichg_max = di->data.ichg_ac < di->data.ichg_fcp ? di->data.ichg_fcp :di->data.ichg_ac; hwlog_info("iin_max = %d mA,ichg_max %d mA\n",di->data.iin_max,di->data.ichg_max); return 0; }
static void __init zynq_periph_clk_setup(struct device_node *np) { struct zynq_periph_clk *periph; const char *parent_names[3]; struct clk_init_data init; int clk_num = 0, err; const char *name; struct clk *clk; u32 reg; int i; err = of_property_read_u32(np, "reg", ®); if (WARN_ON(err)) return; periph = kzalloc(sizeof(*periph), GFP_KERNEL); if (WARN_ON(!periph)) return; periph->clk_ctrl = slcr_base + reg; spin_lock_init(&periph->clkact_lock); init.name = np->name; init.ops = &zynq_periph_clk_ops; for (i = 0; i < ARRAY_SIZE(parent_names); i++) parent_names[i] = of_clk_get_parent_name(np, i); init.parent_names = parent_names; init.num_parents = ARRAY_SIZE(parent_names); periph->hw.init = &init; clk = clk_register(NULL, &periph->hw); if (WARN_ON(IS_ERR(clk))) return; err = of_clk_add_provider(np, of_clk_src_simple_get, clk); if (WARN_ON(err)) return; err = of_property_read_string_index(np, "clock-output-names", 0, &name); if (WARN_ON(err)) return; periph->gates[0] = clk_register_gate(NULL, name, np->name, 0, periph->clk_ctrl, 0, 0, &periph->clkact_lock); if (WARN_ON(IS_ERR(periph->gates[0]))) return; clk_num++; /* some periph clks have 2 downstream gates */ err = of_property_read_string_index(np, "clock-output-names", 1, &name); if (err != -ENODATA) { periph->gates[1] = clk_register_gate(NULL, name, np->name, 0, periph->clk_ctrl, 1, 0, &periph->clkact_lock); if (WARN_ON(IS_ERR(periph->gates[1]))) return; clk_num++; } periph->onecell_data.clks = periph->gates; periph->onecell_data.clk_num = clk_num; err = of_clk_add_provider(np, of_clk_src_onecell_get, &periph->onecell_data); if (WARN_ON(err)) return; }
static int msm_csid_get_clk_info(struct csid_device *csid_dev, struct platform_device *pdev) { uint32_t count; uint32_t cnt = 0; int i, rc; int ii = 0; uint32_t rates[CSID_NUM_CLK_MAX]; const char *clock_name; struct device_node *of_node; of_node = pdev->dev.of_node; count = of_property_count_strings(of_node, "qcom,clock-names"); csid_dev->num_clk = count; CDBG("%s: count = %d\n", __func__, count); if (count == 0) { pr_err("%s: no clocks found in device tree, count=%d", __func__, count); return -EINVAL; } if (count > CSID_NUM_CLK_MAX) { pr_err("%s: invalid count=%d, max is %d\n", __func__, count, CSID_NUM_CLK_MAX); return -EINVAL; } if (csid_dev->hw_dts_version == CSID_VERSION_V22) { cnt = count; count = 0; CDBG("%s: cnt = %d\n", __func__, cnt); if (cnt == 0) { pr_err("%s: no clocks found in device tree, cnt=%d", __func__, cnt); return -EINVAL; } if (cnt > CSID_NUM_CLK_MAX) { pr_err("%s: invalid cnt=%d, max is %d\n", __func__, cnt, CSID_NUM_CLK_MAX); return -EINVAL; } for (i = 0; i < cnt; i++) { count++; rc = of_property_read_string_index(of_node, "qcom,clock-names", i, &clock_name); CDBG("%s: clock_names[%d] = %s\n", __func__, i, clock_name); if (rc < 0) { pr_err("%s:%d, failed\n", __func__, __LINE__); return rc; } if (strcmp(clock_name, "csi_phy_src_clk") == 0) break; } csid_dev->num_clk = count; } for (i = 0; i < count; i++) { rc = of_property_read_string_index(of_node, "qcom,clock-names", i, &(csid_clk_info[i].clk_name)); CDBG("%s: clock-names[%d] = %s\n", __func__, i, csid_clk_info[i].clk_name); if (rc < 0) { pr_err("%s:%d, failed\n", __func__, __LINE__); return rc; } } rc = of_property_read_u32_array(of_node, "qcom,clock-rates", rates, count); if (rc < 0) { pr_err("%s:%d, failed", __func__, __LINE__); return rc; } for (i = 0; i < count; i++) { csid_clk_info[i].clk_rate = (rates[i] == 0) ? -1 : rates[i]; CDBG("%s: clk_rate[%d] = %ld\n", __func__, i, csid_clk_info[i].clk_rate); } if (csid_dev->hw_dts_version == CSID_VERSION_V22) { csid_dev->num_clk_src_info = cnt - count; CDBG("%s: count = %d\n", __func__, (cnt - count)); for (i = count; i < cnt; i++) { ii++; rc = of_property_read_string_index(of_node, "qcom,clock-names", i, &(csid_clk_src_info[ii].clk_name)); CDBG("%s: clock-names[%d] = %s\n", __func__, ii, csid_clk_src_info[ii].clk_name); if (rc < 0) { pr_err("%s:%d, failed\n", __func__, __LINE__); return rc; } } ii = 0; rc = of_property_read_u32_array(of_node, "qcom,clock-rates", rates, cnt); if (rc < 0) { pr_err("%s:%d, failed", __func__, __LINE__); return rc; } for (i = count; i < cnt; i++) { ii++; csid_clk_src_info[ii].clk_rate = rates[i]; CDBG("%s: clk_rate[%d] = %ld\n", __func__, ii, csid_clk_src_info[ii].clk_rate); } } return 0; }
static void __init zynq_clk_setup(struct device_node *np) { int i; u32 tmp; int ret; struct clk *clk; char *clk_name; const char *clk_output_name[clk_max]; const char *cpu_parents[4]; const char *periph_parents[4]; const char *swdt_ext_clk_mux_parents[2]; const char *can_mio_mux_parents[NUM_MIO_PINS]; pr_info("Zynq clock init\n"); /* get clock output names from DT */ for (i = 0; i < clk_max; i++) { if (of_property_read_string_index(np, "clock-output-names", i, &clk_output_name[i])) { pr_err("%s: clock output name not in DT\n", __func__); BUG(); } } cpu_parents[0] = clk_output_name[armpll]; cpu_parents[1] = clk_output_name[armpll]; cpu_parents[2] = clk_output_name[ddrpll]; cpu_parents[3] = clk_output_name[iopll]; periph_parents[0] = clk_output_name[iopll]; periph_parents[1] = clk_output_name[iopll]; periph_parents[2] = clk_output_name[armpll]; periph_parents[3] = clk_output_name[ddrpll]; /* ps_clk */ ret = of_property_read_u32(np, "ps-clk-frequency", &tmp); if (ret) { pr_warn("ps_clk frequency not specified, using 33 MHz.\n"); tmp = 33333333; } ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, CLK_IS_ROOT, tmp); /* PLLs */ clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL, SLCR_PLL_STATUS, 0, &armpll_lock); clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll], armpll_parents, 2, 0, SLCR_ARMPLL_CTRL, 4, 1, 0, &armpll_lock); clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL, SLCR_PLL_STATUS, 1, &ddrpll_lock); clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll], ddrpll_parents, 2, 0, SLCR_DDRPLL_CTRL, 4, 1, 0, &ddrpll_lock); clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL, SLCR_PLL_STATUS, 2, &iopll_lock); clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll], iopll_parents, 2, 0, SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock); /* CPU clocks */ tmp = readl(SLCR_621_TRUE) & 1; clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 0, SLCR_ARM_CLK_CTRL, 4, 2, 0, &armclk_lock); clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0, SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &armclk_lock); clks[cpu_6or4x] = clk_register_gate(NULL, clk_output_name[cpu_6or4x], "cpu_div", CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, 24, 0, &armclk_lock); clk = clk_register_fixed_factor(NULL, "cpu_3or2x_div", "cpu_div", 0, 1, 2); clks[cpu_3or2x] = clk_register_gate(NULL, clk_output_name[cpu_3or2x], "cpu_3or2x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, 25, 0, &armclk_lock); clk = clk_register_fixed_factor(NULL, "cpu_2x_div", "cpu_div", 0, 1, 2 + tmp); clks[cpu_2x] = clk_register_gate(NULL, clk_output_name[cpu_2x], "cpu_2x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, 26, 0, &armclk_lock); clk = clk_register_fixed_factor(NULL, "cpu_1x_div", "cpu_div", 0, 1, 4 + 2 * tmp); clks[cpu_1x] = clk_register_gate(NULL, clk_output_name[cpu_1x], "cpu_1x_div", CLK_IGNORE_UNUSED, SLCR_ARM_CLK_CTRL, 27, 0, &armclk_lock); /* Timers */ swdt_ext_clk_mux_parents[0] = clk_output_name[cpu_1x]; for (i = 0; i < ARRAY_SIZE(swdt_ext_clk_input_names); i++) { int idx = of_property_match_string(np, "clock-names", swdt_ext_clk_input_names[i]); if (idx >= 0) swdt_ext_clk_mux_parents[i + 1] = of_clk_get_parent_name(np, idx); else swdt_ext_clk_mux_parents[i + 1] = dummy_nm; } clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt], swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT, SLCR_SWDT_CLK_SEL, 0, 1, 0, &gem0clk_lock); /* DDR clocks */ clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0, SLCR_DDR_CLK_CTRL, 26, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock); clks[ddr2x] = clk_register_gate(NULL, clk_output_name[ddr2x], "ddr2x_div", 0, SLCR_DDR_CLK_CTRL, 1, 0, &ddrclk_lock); clk_prepare_enable(clks[ddr2x]); clk = clk_register_divider(NULL, "ddr3x_div", "ddrpll", 0, SLCR_DDR_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &ddrclk_lock); clks[ddr3x] = clk_register_gate(NULL, clk_output_name[ddr3x], "ddr3x_div", 0, SLCR_DDR_CLK_CTRL, 0, 0, &ddrclk_lock); clk_prepare_enable(clks[ddr3x]); clk = clk_register_divider(NULL, "dci_div0", "ddrpll", 0, SLCR_DCI_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &dciclk_lock); clk = clk_register_divider(NULL, "dci_div1", "dci_div0", CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &dciclk_lock); clks[dci] = clk_register_gate(NULL, clk_output_name[dci], "dci_div1", CLK_SET_RATE_PARENT, SLCR_DCI_CLK_CTRL, 0, 0, &dciclk_lock); clk_prepare_enable(clks[dci]); /* Peripheral clocks */ for (i = fclk0; i <= fclk3; i++) zynq_clk_register_fclk(i, clk_output_name[i], SLCR_FPGA0_CLK_CTRL + 0x10 * (i - fclk0), periph_parents); zynq_clk_register_periph_clk(lqspi, 0, clk_output_name[lqspi], NULL, SLCR_LQSPI_CLK_CTRL, periph_parents, 0); zynq_clk_register_periph_clk(smc, 0, clk_output_name[smc], NULL, SLCR_SMC_CLK_CTRL, periph_parents, 0); zynq_clk_register_periph_clk(pcap, 0, clk_output_name[pcap], NULL, SLCR_PCAP_CLK_CTRL, periph_parents, 0); zynq_clk_register_periph_clk(sdio0, sdio1, clk_output_name[sdio0], clk_output_name[sdio1], SLCR_SDIO_CLK_CTRL, periph_parents, 1); zynq_clk_register_periph_clk(uart0, uart1, clk_output_name[uart0], clk_output_name[uart1], SLCR_UART_CLK_CTRL, periph_parents, 1); zynq_clk_register_periph_clk(spi0, spi1, clk_output_name[spi0], clk_output_name[spi1], SLCR_SPI_CLK_CTRL, periph_parents, 1); for (i = 0; i < ARRAY_SIZE(gem0_emio_input_names); i++) { int idx = of_property_match_string(np, "clock-names", gem0_emio_input_names[i]); if (idx >= 0) gem0_mux_parents[i + 1] = of_clk_get_parent_name(np, idx); } clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, 0, SLCR_GEM0_CLK_CTRL, 4, 2, 0, &gem0clk_lock); clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0, SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock); clk = clk_register_divider(NULL, "gem0_div1", "gem0_div0", CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock); clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, 0, SLCR_GEM0_CLK_CTRL, 6, 1, 0, &gem0clk_lock); clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0], "gem0_emio_mux", CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock); for (i = 0; i < ARRAY_SIZE(gem1_emio_input_names); i++) { int idx = of_property_match_string(np, "clock-names", gem1_emio_input_names[i]); if (idx >= 0) gem1_mux_parents[i + 1] = of_clk_get_parent_name(np, idx); } clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, 0, SLCR_GEM1_CLK_CTRL, 4, 2, 0, &gem1clk_lock); clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0, SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock); clk = clk_register_divider(NULL, "gem1_div1", "gem1_div0", CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock); clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, 0, SLCR_GEM1_CLK_CTRL, 6, 1, 0, &gem1clk_lock); clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1], "gem1_emio_mux", CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock); tmp = strlen("mio_clk_00x"); clk_name = kmalloc(tmp, GFP_KERNEL); for (i = 0; i < NUM_MIO_PINS; i++) { int idx; snprintf(clk_name, tmp, "mio_clk_%2.2d", i); idx = of_property_match_string(np, "clock-names", clk_name); if (idx >= 0) can_mio_mux_parents[i] = of_clk_get_parent_name(np, idx); else can_mio_mux_parents[i] = dummy_nm; } kfree(clk_name); clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, 0, SLCR_CAN_CLK_CTRL, 4, 2, 0, &canclk_lock); clk = clk_register_divider(NULL, "can_div0", "can_mux", 0, SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &canclk_lock); clk = clk_register_divider(NULL, "can_div1", "can_div0", CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &canclk_lock); clk = clk_register_gate(NULL, "can0_gate", "can_div1", CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 0, 0, &canclk_lock); clk = clk_register_gate(NULL, "can1_gate", "can_div1", CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0, &canclk_lock); clk = clk_register_mux(NULL, "can0_mio_mux", can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, &canmioclk_lock); clk = clk_register_mux(NULL, "can1_mio_mux", can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, SLCR_CAN_MIOCLK_CTRL, 16, 6, 0, &canmioclk_lock); clks[can0] = clk_register_mux(NULL, clk_output_name[can0], can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, &canmioclk_lock); clks[can1] = clk_register_mux(NULL, clk_output_name[can1], can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, SLCR_CAN_MIOCLK_CTRL, 22, 1, 0, &canmioclk_lock); for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) { int idx = of_property_match_string(np, "clock-names", dbgtrc_emio_input_names[i]); if (idx >= 0) dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np, idx); } clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, 0, SLCR_DBG_CLK_CTRL, 4, 2, 0, &dbgclk_lock); clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0, SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock); clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, 0, SLCR_DBG_CLK_CTRL, 6, 1, 0, &dbgclk_lock); clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc], "dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL, 0, 0, &dbgclk_lock); clks[dbg_apb] = clk_register_gate(NULL, clk_output_name[dbg_apb], clk_output_name[cpu_1x], 0, SLCR_DBG_CLK_CTRL, 1, 0, &dbgclk_lock); /* One gated clock for all APER clocks. */ clks[dma] = clk_register_gate(NULL, clk_output_name[dma], clk_output_name[cpu_2x], 0, SLCR_APER_CLK_CTRL, 0, 0, &aperclk_lock); clks[usb0_aper] = clk_register_gate(NULL, clk_output_name[usb0_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 2, 0, &aperclk_lock); clks[usb1_aper] = clk_register_gate(NULL, clk_output_name[usb1_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 3, 0, &aperclk_lock); clks[gem0_aper] = clk_register_gate(NULL, clk_output_name[gem0_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 6, 0, &aperclk_lock); clks[gem1_aper] = clk_register_gate(NULL, clk_output_name[gem1_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 7, 0, &aperclk_lock); clks[sdio0_aper] = clk_register_gate(NULL, clk_output_name[sdio0_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 10, 0, &aperclk_lock); clks[sdio1_aper] = clk_register_gate(NULL, clk_output_name[sdio1_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 11, 0, &aperclk_lock); clks[spi0_aper] = clk_register_gate(NULL, clk_output_name[spi0_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 14, 0, &aperclk_lock); clks[spi1_aper] = clk_register_gate(NULL, clk_output_name[spi1_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 15, 0, &aperclk_lock); clks[can0_aper] = clk_register_gate(NULL, clk_output_name[can0_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 16, 0, &aperclk_lock); clks[can1_aper] = clk_register_gate(NULL, clk_output_name[can1_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 17, 0, &aperclk_lock); clks[i2c0_aper] = clk_register_gate(NULL, clk_output_name[i2c0_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 18, 0, &aperclk_lock); clks[i2c1_aper] = clk_register_gate(NULL, clk_output_name[i2c1_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 19, 0, &aperclk_lock); clks[uart0_aper] = clk_register_gate(NULL, clk_output_name[uart0_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 20, 0, &aperclk_lock); clks[uart1_aper] = clk_register_gate(NULL, clk_output_name[uart1_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 21, 0, &aperclk_lock); clks[gpio_aper] = clk_register_gate(NULL, clk_output_name[gpio_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 22, 0, &aperclk_lock); clks[lqspi_aper] = clk_register_gate(NULL, clk_output_name[lqspi_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 23, 0, &aperclk_lock); clks[smc_aper] = clk_register_gate(NULL, clk_output_name[smc_aper], clk_output_name[cpu_1x], 0, SLCR_APER_CLK_CTRL, 24, 0, &aperclk_lock); for (i = 0; i < ARRAY_SIZE(clks); i++) { if (IS_ERR(clks[i])) { pr_err("Zynq clk %d: register failed with %ld\n", i, PTR_ERR(clks[i])); BUG(); } } clk_data.clks = clks; clk_data.clk_num = ARRAY_SIZE(clks); of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); }
static void __init st_of_clkgena_divmux_setup(struct device_node *np) { const struct of_device_id *match; const struct clkgena_divmux_data *data; struct clk_onecell_data *clk_data; void __iomem *reg; const char **parents; int num_parents = 0, i; match = of_match_node(clkgena_divmux_of_match, np); if (WARN_ON(!match)) return; data = match->data; reg = clkgen_get_register_base(np); if (!reg) return; parents = clkgen_mux_get_parents(np, &num_parents); if (IS_ERR(parents)) goto err_parents; clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); if (!clk_data) goto err_alloc; clk_data->clk_num = data->num_outputs; clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), GFP_KERNEL); if (!clk_data->clks) goto err_alloc_clks; for (i = 0; i < clk_data->clk_num; i++) { struct clk *clk; const char *clk_name; if (of_property_read_string_index(np, "clock-output-names", i, &clk_name)) break; /* * If we read an empty clock name then the output is unused */ if (*clk_name == '\0') continue; clk = clk_register_genamux(clk_name, parents, num_parents, reg, data, i); if (IS_ERR(clk)) goto err; clk_data->clks[i] = clk; } kfree(parents); of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); return; err: kfree(clk_data->clks); err_alloc_clks: kfree(clk_data); err_alloc: kfree(parents); err_parents: iounmap(reg); }