示例#1
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;
}
示例#2
0
文件: hinic_hw_io.c 项目: Lyude/linux
/**
 * hinic_io_create_qps - Create Queue Pairs
 * @func_to_io: func to io channel that holds the IO components
 * @base_qpn: base qp number
 * @num_qps: number queue pairs to create
 * @sq_msix_entry: msix entries for sq
 * @rq_msix_entry: msix entries for rq
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_io_create_qps(struct hinic_func_to_io *func_to_io,
			u16 base_qpn, int num_qps,
			struct msix_entry *sq_msix_entries,
			struct msix_entry *rq_msix_entries)
{
	struct hinic_hwif *hwif = func_to_io->hwif;
	struct pci_dev *pdev = hwif->pdev;
	size_t qps_size, wq_size, db_size;
	void *ci_addr_base;
	int i, j, err;

	qps_size = num_qps * sizeof(*func_to_io->qps);
	func_to_io->qps = devm_kzalloc(&pdev->dev, qps_size, GFP_KERNEL);
	if (!func_to_io->qps)
		return -ENOMEM;

	wq_size = num_qps * sizeof(*func_to_io->sq_wq);
	func_to_io->sq_wq = devm_kzalloc(&pdev->dev, wq_size, GFP_KERNEL);
	if (!func_to_io->sq_wq) {
		err = -ENOMEM;
		goto err_sq_wq;
	}

	wq_size = num_qps * sizeof(*func_to_io->rq_wq);
	func_to_io->rq_wq = devm_kzalloc(&pdev->dev, wq_size, GFP_KERNEL);
	if (!func_to_io->rq_wq) {
		err = -ENOMEM;
		goto err_rq_wq;
	}

	db_size = num_qps * sizeof(*func_to_io->sq_db);
	func_to_io->sq_db = devm_kzalloc(&pdev->dev, db_size, GFP_KERNEL);
	if (!func_to_io->sq_db) {
		err = -ENOMEM;
		goto err_sq_db;
	}

	ci_addr_base = dma_zalloc_coherent(&pdev->dev, CI_TABLE_SIZE(num_qps),
					   &func_to_io->ci_dma_base,
					   GFP_KERNEL);
	if (!ci_addr_base) {
		dev_err(&pdev->dev, "Failed to allocate CI area\n");
		err = -ENOMEM;
		goto err_ci_base;
	}

	func_to_io->ci_addr_base = ci_addr_base;

	for (i = 0; i < num_qps; i++) {
		err = init_qp(func_to_io, &func_to_io->qps[i], i,
			      &sq_msix_entries[i], &rq_msix_entries[i]);
		if (err) {
			dev_err(&pdev->dev, "Failed to create QP %d\n", i);
			goto err_init_qp;
		}
	}

	err = write_qp_ctxts(func_to_io, base_qpn, num_qps);
	if (err) {
		dev_err(&pdev->dev, "Failed to init QP ctxts\n");
		goto err_write_qp_ctxts;
	}

	return 0;

err_write_qp_ctxts:
err_init_qp:
	for (j = 0; j < i; j++)
		destroy_qp(func_to_io, &func_to_io->qps[j]);

	dma_free_coherent(&pdev->dev, CI_TABLE_SIZE(num_qps),
			  func_to_io->ci_addr_base, func_to_io->ci_dma_base);

err_ci_base:
	devm_kfree(&pdev->dev, func_to_io->sq_db);

err_sq_db:
	devm_kfree(&pdev->dev, func_to_io->rq_wq);

err_rq_wq:
	devm_kfree(&pdev->dev, func_to_io->sq_wq);

err_sq_wq:
	devm_kfree(&pdev->dev, func_to_io->qps);
	return err;
}
static int mdss_dsi_get_dt_vreg_data(struct device *dev,
	struct dss_module_power *mp)
{
	int i = 0, rc = 0;
	u32 tmp = 0;
	struct device_node *of_node = NULL, *supply_node = NULL;

	if (!dev || !mp) {
		pr_err("%s: invalid input\n", __func__);
		rc = -EINVAL;
		return rc;
	}

	of_node = dev->of_node;

	mp->num_vreg = 0;
	for_each_child_of_node(of_node, supply_node) {
		if (!strncmp(supply_node->name, "qcom,platform-supply-entry",
						26))
			++mp->num_vreg;
	}
	if (mp->num_vreg == 0) {
		pr_debug("%s: no vreg\n", __func__);
		goto novreg;
	} else {
		pr_debug("%s: vreg found. count=%d\n", __func__, mp->num_vreg);
	}

	mp->vreg_config = devm_kzalloc(dev, sizeof(struct dss_vreg) *
		mp->num_vreg, GFP_KERNEL);
	if (!mp->vreg_config) {
		pr_err("%s: can't alloc vreg mem\n", __func__);
		rc = -ENOMEM;
		goto error;
	}

	for_each_child_of_node(of_node, supply_node) {
		if (!strncmp(supply_node->name, "qcom,platform-supply-entry",
						26)) {
			const char *st = NULL;
			/* vreg-name */
			rc = of_property_read_string(supply_node,
				"qcom,supply-name", &st);
			if (rc) {
				pr_err("%s: error reading name. rc=%d\n",
					__func__, rc);
				goto error;
			}
			snprintf(mp->vreg_config[i].vreg_name,
				ARRAY_SIZE((mp->vreg_config[i].vreg_name)),
				"%s", st);
			/* vreg-min-voltage */
			rc = of_property_read_u32(supply_node,
				"qcom,supply-min-voltage", &tmp);
			if (rc) {
				pr_err("%s: error reading min volt. rc=%d\n",
					__func__, rc);
				goto error;
			}
			mp->vreg_config[i].min_voltage = tmp;

			/* vreg-max-voltage */
			rc = of_property_read_u32(supply_node,
				"qcom,supply-max-voltage", &tmp);
			if (rc) {
				pr_err("%s: error reading max volt. rc=%d\n",
					__func__, rc);
				goto error;
			}
			mp->vreg_config[i].max_voltage = tmp;

			/* enable-load */
			rc = of_property_read_u32(supply_node,
				"qcom,supply-enable-load", &tmp);
			if (rc) {
				pr_err("%s: error reading enable load. rc=%d\n",
					__func__, rc);
				goto error;
			}
			mp->vreg_config[i].enable_load = tmp;

			/* disable-load */
			rc = of_property_read_u32(supply_node,
				"qcom,supply-disable-load", &tmp);
			if (rc) {
				pr_err("%s: error reading disable load. rc=%d\n",
					__func__, rc);
				goto error;
			}
			mp->vreg_config[i].disable_load = tmp;

			/* pre-sleep */
			rc = of_property_read_u32(supply_node,
				"qcom,supply-pre-on-sleep", &tmp);
			if (rc) {
				pr_debug("%s: error reading supply pre sleep value. rc=%d\n",
					__func__, rc);
			}
			mp->vreg_config[i].pre_on_sleep = (!rc ? tmp : 0);

			rc = of_property_read_u32(supply_node,
				"qcom,supply-pre-off-sleep", &tmp);
			if (rc) {
				pr_debug("%s: error reading supply pre sleep value. rc=%d\n",
					__func__, rc);
			}
			mp->vreg_config[i].pre_off_sleep = (!rc ? tmp : 0);

			/* post-sleep */
			rc = of_property_read_u32(supply_node,
				"qcom,supply-post-on-sleep", &tmp);
			if (rc) {
				pr_debug("%s: error reading supply post sleep value. rc=%d\n",
					__func__, rc);
			}
			mp->vreg_config[i].post_on_sleep = (!rc ? tmp : 0);

			rc = of_property_read_u32(supply_node,
				"qcom,supply-post-off-sleep", &tmp);
			if (rc) {
				pr_debug("%s: error reading supply post sleep value. rc=%d\n",
					__func__, rc);
			}
			mp->vreg_config[i].post_off_sleep = (!rc ? tmp : 0);

			pr_debug("%s: %s min=%d, max=%d, enable=%d, disable=%d, preonsleep=%d, postonsleep=%d, preoffsleep=%d, postoffsleep=%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].enable_load,
				mp->vreg_config[i].disable_load,
				mp->vreg_config[i].pre_on_sleep,
				mp->vreg_config[i].post_on_sleep,
				mp->vreg_config[i].pre_off_sleep,
				mp->vreg_config[i].post_off_sleep
				);
			++i;
		}
	}

	return rc;

error:
	if (mp->vreg_config) {
		devm_kfree(dev, mp->vreg_config);
		mp->vreg_config = NULL;
	}
novreg:
	mp->num_vreg = 0;

	return rc;
}
示例#4
0
static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
{
	int ret;
	struct clk_init_data init = {
		.flags = CLK_GET_RATE_NOCACHE,
		.num_parents = 0,
		.ops = &scmi_clk_ops,
		.name = sclk->info->name,
	};

	sclk->hw.init = &init;
	ret = devm_clk_hw_register(dev, &sclk->hw);
	if (!ret)
		clk_hw_set_rate_range(&sclk->hw, sclk->info->range.min_rate,
				      sclk->info->range.max_rate);
	return ret;
}

static int scmi_clocks_probe(struct scmi_device *sdev)
{
	int idx, count, err;
	struct clk_hw **hws;
	struct clk_hw_onecell_data *clk_data;
	struct device *dev = &sdev->dev;
	struct device_node *np = dev->of_node;
	const struct scmi_handle *handle = sdev->handle;

	if (!handle || !handle->clk_ops)
		return -ENODEV;

	count = handle->clk_ops->count_get(handle);
	if (count < 0) {
		dev_err(dev, "%s: invalid clock output count\n", np->name);
		return -EINVAL;
	}

	clk_data = devm_kzalloc(dev, sizeof(*clk_data) +
				sizeof(*clk_data->hws) * count, GFP_KERNEL);
	if (!clk_data)
		return -ENOMEM;

	clk_data->num = count;
	hws = clk_data->hws;

	for (idx = 0; idx < count; idx++) {
		struct scmi_clk *sclk;

		sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
		if (!sclk)
			return -ENOMEM;

		sclk->info = handle->clk_ops->info_get(handle, idx);
		if (!sclk->info) {
			dev_dbg(dev, "invalid clock info for idx %d\n", idx);
			continue;
		}

		sclk->id = idx;
		sclk->handle = handle;

		err = scmi_clk_ops_init(dev, sclk);
		if (err) {
			dev_err(dev, "failed to register clock %d\n", idx);
			devm_kfree(dev, sclk);
			hws[idx] = NULL;
		} else {
			dev_dbg(dev, "Registered clock:%s\n", sclk->info->name);
			hws[idx] = &sclk->hw;
		}
	}

	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
					   clk_data);
}
static int amlogic_pinctrl_parse_group(struct platform_device *pdev,
				   struct device_node *np, int idx,
				   const char **out_name)
{
	struct amlogic_pmx *d = platform_get_drvdata(pdev);
	struct amlogic_pin_group *g = d->soc->groups;
	struct property *prop;
	const char *propname = "amlogic,pins";
	const char *pinctrl_set = "amlogic,setmask";
	const char *pinctrl_clr = "amlogic,clrmask";
	const char *gpioname;
	int length,ret=0,i;
	u32 val;
	g=g+idx;
	g->name = np->name;
#if 0
/*read amlogic pins through num*/
	prop = of_find_property(np, propname, &length);
	if (!prop)
		return -EINVAL;
	g->num_pins = length / sizeof(u32);

	g->pins = devm_kzalloc(&pdev->dev, g->num_pins * sizeof(*g->pins),
			       GFP_KERNEL);
	if (!g->pins)
		return -ENOMEM;

	ret=of_property_read_u32_array(np, propname, g->pins, g->num_pins);
	if (ret)
			return -EINVAL;
#endif
/*read amlogic pins through name*/
	g->num_pins=of_property_count_strings(np, propname);
	if(g->num_pins>0){
		g->pins = devm_kzalloc(&pdev->dev, g->num_pins * sizeof(*g->pins),
				       GFP_KERNEL);
		if (!g->pins){
			ret= -ENOMEM;			
			dev_err(&pdev->dev, "malloc g->pins error\n");
			goto err;
		}
		for(i=0;i<g->num_pins;i++)
		{
			ret = of_property_read_string_index(np, propname,
							    i, &gpioname);
			if(ret<0){
				ret= -EINVAL;
				dev_err(&pdev->dev, "read %s error\n",propname);
				goto err;
			}
			ret=amlogic_gpio_name_map_num(gpioname);
			if(ret<0){
				ret= -EINVAL;
				dev_err(&pdev->dev, "%s change name to num  error\n",gpioname);
				goto err;
			}
			g->pins[i]=ret;
		}
	}
/*read amlogic set mask*/
	if(!of_property_read_u32(np, pinctrl_set, &val)){
		prop = of_find_property(np, pinctrl_set, &length);
		if (!prop){
			ret= -EINVAL;			
			dev_err(&pdev->dev, "read %s length error\n",pinctrl_set);
			goto err;
		}
		g->num_setmask=length / sizeof(u32);
		if(g->num_setmask%d->pinmux_cell){
			dev_err(&pdev->dev, "num_setmask error must be multiples of 2\n");
			g->num_setmask=(g->num_setmask/d->pinmux_cell)*d->pinmux_cell;
		}
		g->num_setmask=g->num_setmask/d->pinmux_cell;
		g->setmask= devm_kzalloc(&pdev->dev, g->num_setmask * sizeof(*g->setmask),
				       GFP_KERNEL);
		if (!g->setmask){
			ret= -ENOMEM;
			dev_err(&pdev->dev, "malloc g->setmask error\n");
			goto err;
		}

		ret=of_property_read_u32_array(np, pinctrl_set, (u32 *)(g->setmask), length / sizeof(u32));
		if (ret){
			ret= -EINVAL;		
			dev_err(&pdev->dev, "read %s data error\n",pinctrl_set);
			goto err;
		}
	}else{
		g->setmask=NULL;
		g->num_setmask=0;
	}
/*read clear mask*/
	if(!of_property_read_u32(np, pinctrl_clr, &val)){
		prop = of_find_property(np, pinctrl_clr, &length);
		if (!prop){
			dev_err(&pdev->dev, "read %s length error\n",pinctrl_clr);
			ret =-EINVAL;
			goto err;
		}
		g->num_clearmask=length / sizeof(u32);
		if(g->num_clearmask%d->pinmux_cell){
			dev_err(&pdev->dev, "num_setmask error must be multiples of 2\n");
			g->num_clearmask=(g->num_clearmask/d->pinmux_cell)*d->pinmux_cell;
		}
		g->num_clearmask=g->num_clearmask/d->pinmux_cell;
		g->clearmask= devm_kzalloc(&pdev->dev, g->num_clearmask * sizeof(*g->clearmask),
				       GFP_KERNEL);
		if (!g->clearmask){
			ret=-ENOMEM;		
			dev_err(&pdev->dev, "malloc g->clearmask error\n");
			goto err;
		}
		ret=of_property_read_u32_array(np, pinctrl_clr,(u32 *)( g->clearmask), length / sizeof(u32));
		if (ret){
			ret= -EINVAL;
			dev_err(&pdev->dev, "read %s data error\n",pinctrl_clr);
			goto err;
		}
	}
	else{
		g->clearmask=NULL;
		g->num_clearmask=0;
	}
	if (out_name)
		*out_name = g->name;
	return 0;
err:
	if(g->pins)
		devm_kfree(&pdev->dev,g->pins);
	if(g->setmask)
		devm_kfree(&pdev->dev,g->setmask);
	if(g->clearmask)
		devm_kfree(&pdev->dev,g->clearmask);
	return ret;
}
struct isci_orom *isci_request_oprom(struct pci_dev *pdev)
{
	void __iomem *oprom = pci_map_biosrom(pdev);
	struct isci_orom *rom = NULL;
	size_t len, i;
	int j;
	char oem_sig[4];
	struct isci_oem_hdr oem_hdr;
	u8 *tmp, sum;

	if (!oprom)
		return NULL;

	len = pci_biosrom_size(pdev);
	rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL);
	if (!rom) {
		dev_warn(&pdev->dev,
			 "Unable to allocate memory for orom\n");
		return NULL;
	}

	for (i = 0; i < len && rom; i += ISCI_OEM_SIG_SIZE) {
		memcpy_fromio(oem_sig, oprom + i, ISCI_OEM_SIG_SIZE);

		
		if (memcmp(oem_sig, ISCI_OEM_SIG, ISCI_OEM_SIG_SIZE) == 0) {
			size_t copy_len;

			memcpy_fromio(&oem_hdr, oprom + i, sizeof(oem_hdr));

			copy_len = min(oem_hdr.len - sizeof(oem_hdr),
				       sizeof(*rom));

			memcpy_fromio(rom,
				      oprom + i + sizeof(oem_hdr),
				      copy_len);

			
			tmp = (u8 *)&oem_hdr;
			for (j = 0, sum = 0; j < sizeof(oem_hdr); j++, tmp++)
				sum += *tmp;

			tmp = (u8 *)rom;
			for (j = 0; j < sizeof(*rom); j++, tmp++)
				sum += *tmp;

			if (sum != 0) {
				dev_warn(&pdev->dev,
					 "OEM table checksum failed\n");
				continue;
			}

			
			if (memcmp(rom->hdr.signature,
				   ISCI_ROM_SIG,
				   ISCI_ROM_SIG_SIZE) != 0)
				continue;

			dev_info(&pdev->dev,
				 "OEM parameter table found in OROM\n");
			break;
		}
	}

	if (i >= len) {
		dev_err(&pdev->dev, "oprom parse error\n");
		devm_kfree(&pdev->dev, rom);
		rom = NULL;
	}
	pci_unmap_biosrom(oprom);

	return rom;
}
static int rotator_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct rot_context *rot;
	struct exynos_drm_ippdrv *ippdrv;
	int ret;

	rot = devm_kzalloc(dev, sizeof(*rot), GFP_KERNEL);
	if (!rot) {
		dev_err(dev, "failed to allocate rot\n");
		return -ENOMEM;
	}

	rot->limit_tbl = (struct rot_limit_table *)
				platform_get_device_id(pdev)->driver_data;

	rot->regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	rot->regs = devm_request_and_ioremap(dev, rot->regs_res);
	if (!rot->regs) {
		dev_err(dev, "failed to map register\n");
		return -ENXIO;
	}

	rot->irq = platform_get_irq(pdev, 0);
	if (rot->irq < 0) {
		dev_err(dev, "failed to get irq\n");
		return rot->irq;
	}

	ret = request_threaded_irq(rot->irq, NULL, rotator_irq_handler,
			IRQF_ONESHOT, "drm_rotator", rot);
	if (ret < 0) {
		dev_err(dev, "failed to request irq\n");
		return ret;
	}

	rot->clock = devm_clk_get(dev, "rotator");
	if (IS_ERR_OR_NULL(rot->clock)) {
		dev_err(dev, "failed to get clock\n");
		ret = PTR_ERR(rot->clock);
		goto err_clk_get;
	}

	pm_runtime_enable(dev);

	ippdrv = &rot->ippdrv;
	ippdrv->dev = dev;
	ippdrv->ops[EXYNOS_DRM_OPS_SRC] = &rot_src_ops;
	ippdrv->ops[EXYNOS_DRM_OPS_DST] = &rot_dst_ops;
	ippdrv->check_property = rotator_ippdrv_check_property;
	ippdrv->start = rotator_ippdrv_start;
	ret = rotator_init_prop_list(ippdrv);
	if (ret < 0) {
		dev_err(dev, "failed to init property list.\n");
		goto err_ippdrv_register;
	}

	DRM_DEBUG_KMS("%s:ippdrv[0x%x]\n", __func__, (int)ippdrv);

	platform_set_drvdata(pdev, rot);

	ret = exynos_drm_ippdrv_register(ippdrv);
	if (ret < 0) {
		dev_err(dev, "failed to register drm rotator device\n");
		goto err_ippdrv_register;
	}

	dev_info(dev, "The exynos rotator is probed successfully\n");

	return 0;

err_ippdrv_register:
	devm_kfree(dev, ippdrv->prop_list);
	pm_runtime_disable(dev);
err_clk_get:
	free_irq(rot->irq, rot);
	return ret;
}
示例#8
0
int __devinit altera_gpio_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	int id, reg, ret;
	struct altera_gpio_chip *altera_gc = devm_kzalloc(&pdev->dev,
				sizeof(*altera_gc), GFP_KERNEL);
	if (altera_gc == NULL) {
		ret = -ENOMEM;
		pr_err("%s: registration failed with status %d\n",
			node->full_name, ret);
		return ret;
	}
	altera_gc->irq = 0;

	spin_lock_init(&altera_gc->gpio_lock);

	id = pdev->id;

	if (of_property_read_u32(node, "width", &reg))
		/*By default assume full GPIO controller*/
		altera_gc->mmchip.gc.ngpio = 32;
	else
		altera_gc->mmchip.gc.ngpio = reg;

	if (altera_gc->mmchip.gc.ngpio > 32) {
		pr_warn("%s: ngpio is greater than 32, defaulting to 32\n",
			node->full_name);
		altera_gc->mmchip.gc.ngpio = 32;
	}

	altera_gc->mmchip.gc.direction_input	= altera_gpio_direction_input;
	altera_gc->mmchip.gc.direction_output	= altera_gpio_direction_output;
	altera_gc->mmchip.gc.get		= altera_gpio_get;
	altera_gc->mmchip.gc.set		= altera_gpio_set;
	altera_gc->mmchip.gc.to_irq		= altera_gpio_to_irq;
	altera_gc->mmchip.gc.owner		= THIS_MODULE;

	ret = of_mm_gpiochip_add(node, &altera_gc->mmchip);
	if (ret)
		goto err;

	platform_set_drvdata(pdev, altera_gc);

	if (of_get_property(node, "interrupts", &reg) == NULL)
		goto skip_irq;
	altera_gc->hwirq = irq_of_parse_and_map(node, 0);

	if (altera_gc->hwirq == NO_IRQ)
		goto skip_irq;

	altera_gc->irq = irq_domain_add_linear(node, altera_gc->mmchip.gc.ngpio,
				&altera_gpio_irq_ops, altera_gc);

	if (!altera_gc->irq) {
		ret = -ENODEV;
		goto dispose_irq;
	}

	if (of_property_read_u32(node, "level_trigger", &reg)) {
		ret = -EINVAL;
		pr_err("%s: level_trigger value not set in device tree\n",
			node->full_name);
		goto teardown;
	}
	altera_gc->level_trigger = reg;

	irq_set_handler_data(altera_gc->hwirq, altera_gc);
	irq_set_chained_handler(altera_gc->hwirq, altera_gpio_irq_handler);

	return 0;

teardown:
	irq_domain_remove(altera_gc->irq);
dispose_irq:
	irq_dispose_mapping(altera_gc->hwirq);
	WARN_ON(gpiochip_remove(&altera_gc->mmchip.gc) < 0);

err:
	pr_err("%s: registration failed with status %d\n",
		node->full_name, ret);
	devm_kfree(&pdev->dev, altera_gc);

	return ret;
skip_irq:
	return 0;
}
struct esxxx_platform_data *es705_populate_dt_pdata(struct device *dev)
{
	struct esxxx_platform_data *pdata;

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
		dev_err(dev, "%s(): platform data allocation failed\n",
			__func__);
		goto err;
	}
	pdata->reset_gpio = of_get_named_gpio(dev->of_node,
					      "es705-reset-gpio", 0);
	if (pdata->reset_gpio < 0)
		of_property_read_u32(dev->of_node,
					"es705-reset-expander-gpio", &pdata->reset_gpio);
	if (pdata->reset_gpio < 0) {
		dev_err(dev, "%s(): get reset_gpio failed\n", __func__);
		goto alloc_err;
	}
	dev_dbg(dev, "%s(): reset gpio %d\n", __func__, pdata->reset_gpio);

	pdata->gpioa_gpio = of_get_named_gpio(dev->of_node,
					      "es705-gpioa-gpio", 0);
	if (pdata->gpioa_gpio < 0) {
		dev_err(dev, "%s(): get gpioa_gpio failed\n", __func__);
		goto alloc_err;
	}
	dev_dbg(dev, "%s(): gpioa gpio %d\n", __func__, pdata->gpioa_gpio);

	pdata->gpiob_gpio = of_get_named_gpio(dev->of_node,
					      "es705-gpiob-gpio", 0);
	if (pdata->gpiob_gpio < 0) {
		dev_err(dev, "%s(): get gpiob_gpio failed\n", __func__);
		goto alloc_err;
	}
	dev_dbg(dev, "%s(): gpiob gpio %d\n", __func__, pdata->gpiob_gpio);

	pdata->uart_tx_gpio = of_get_named_gpio(dev->of_node,
					     "es705-uart-tx", 0);
	if (pdata->uart_tx_gpio < 0) {
		dev_info(dev, "%s(): get uart_tx_gpio failed\n", __func__);
		pdata->uart_tx_gpio = -1;
	}
	dev_dbg(dev, "%s(): uart tx gpio %d\n", __func__, pdata->uart_tx_gpio);

	pdata->uart_rx_gpio = of_get_named_gpio(dev->of_node,
					     "es705-uart-rx", 0);
	if (pdata->uart_rx_gpio < 0) {
		dev_info(dev, "%s(): get uart_rx_gpio failed\n", __func__);
		pdata->uart_rx_gpio = -1;
	}
	dev_dbg(dev, "%s(): uart rx gpio %d\n", __func__, pdata->uart_rx_gpio);

	pdata->wakeup_gpio = of_get_named_gpio(dev->of_node,
					     "es705-wakeup-gpio", 0);
	if (pdata->wakeup_gpio < 0) {
		dev_info(dev, "%s(): get wakeup_gpio failed\n", __func__);
		pdata->wakeup_gpio = -1;
	}
	dev_dbg(dev, "%s(): wakeup gpio %d\n", __func__, pdata->wakeup_gpio);

	pdata->uart_gpio = of_get_named_gpio(dev->of_node,
					     "es705-uart-gpio", 0);
	if (pdata->uart_gpio < 0) {
		dev_info(dev, "%s(): get uart_gpio failed\n", __func__);
		pdata->uart_gpio = -1;
	}
	dev_dbg(dev, "%s(): uart gpio %d\n", __func__, pdata->uart_gpio);
	pdata->irq_base = gpio_to_irq(pdata->gpiob_gpio);

	return pdata;
alloc_err:
	devm_kfree(dev, pdata);
err:
	return NULL;
}
static struct device *msm_bus_device_init(
			struct msm_bus_node_device_type *pdata)
{
	struct device *bus_dev = NULL;
	struct msm_bus_node_device_type *bus_node = NULL;
	struct msm_bus_node_info_type *node_info = NULL;
	int ret = 0;

	bus_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
	if (!bus_dev) {
		MSM_BUS_ERR("%s:Device alloc failed\n", __func__);
		bus_dev = NULL;
		goto exit_device_init;
	}
	/**
	* Init here so we can use devm calls
	*/
	device_initialize(bus_dev);

	bus_node = devm_kzalloc(bus_dev,
			sizeof(struct msm_bus_node_device_type), GFP_KERNEL);
	if (!bus_node) {
		MSM_BUS_ERR("%s:Bus node alloc failed\n", __func__);
		kfree(bus_dev);
		bus_dev = NULL;
		goto exit_device_init;
	}

	node_info = devm_kzalloc(bus_dev,
			sizeof(struct msm_bus_node_info_type), GFP_KERNEL);
	if (!node_info) {
		MSM_BUS_ERR("%s:Bus node info alloc failed\n", __func__);
		devm_kfree(bus_dev, bus_node);
		kfree(bus_dev);
		bus_dev = NULL;
		goto exit_device_init;
	}

	bus_node->node_info = node_info;
	bus_node->ap_owned = pdata->ap_owned;
	bus_dev->platform_data = bus_node;

	if (msm_bus_copy_node_info(pdata, bus_dev) < 0) {
		devm_kfree(bus_dev, bus_node);
		devm_kfree(bus_dev, node_info);
		kfree(bus_dev);
		bus_dev = NULL;
		goto exit_device_init;
	}

	bus_dev->bus = &msm_bus_type;
	dev_set_name(bus_dev, bus_node->node_info->name);

	ret = device_add(bus_dev);
	if (ret < 0) {
		MSM_BUS_ERR("%s: Error registering device %d",
				__func__, pdata->node_info->id);
		devm_kfree(bus_dev, bus_node);
		devm_kfree(bus_dev, node_info->dev_connections);
		devm_kfree(bus_dev, node_info->connections);
		devm_kfree(bus_dev, node_info);
		kfree(bus_dev);
		bus_dev = NULL;
		goto exit_device_init;
	}

exit_device_init:
	return bus_dev;
}
static int msm_dai_slim_dev_probe(struct slim_device *sdev)
{
	int rc, i;
	u8 max_channels;
	u32 apps_ch_pipes;
	struct msm_dai_slim_drv_data *drv_data;
	struct device *dev = &sdev->dev;
	struct snd_soc_dai_driver *dai_drv;

	if (!dev->of_node ||
	    !dev->of_node->parent) {
		dev_err(dev,
			"%s: Invalid %s\n", __func__,
			(!dev->of_node) ? "of_node" : "parent_of_node");
		return -EINVAL;
	}

	rc = of_property_read_u32(dev->of_node->parent,
					 "qcom,apps-ch-pipes",
					 &apps_ch_pipes);
	if (rc) {
		dev_err(dev,
			"%s: Failed to lookup property %s in node %s, err = %d\n",
			__func__, "qcom,apps-ch-pipes",
			dev->of_node->parent->full_name, rc);
		goto err_ret;
	}

	max_channels = hweight_long(apps_ch_pipes);
	if (max_channels <= 0) {
		dev_err(dev,
			"%s: Invalid apps owned ports %d\n",
			__func__, max_channels);
		goto err_ret;
	}

	dev_dbg(dev, "%s: max channels = %u\n",
		__func__, max_channels);

	for (i = 0; i < ARRAY_SIZE(msm_slim_dais); i++) {
		dai_drv = &msm_slim_dais[i];
		dai_drv->capture.channels_max = max_channels;
		dai_drv->playback.channels_max = max_channels;
	}

	drv_data = devm_kzalloc(dev, sizeof(*drv_data),
				GFP_KERNEL);
	if (!drv_data) {
		dev_err(dev, "%s: dai driver struct alloc failed\n",
			__func__);
		rc = -ENOMEM;
		goto err_ret;
	}

	drv_data->sdev = sdev;
	drv_data->num_dais = NUM_SLIM_DAIS;

	rc = msm_dai_slim_populate_dai_data(dev, drv_data);
	if (rc) {
		dev_err(dev,
			"%s: failed to setup dai_data, err = %d\n",
			__func__, rc);
		goto err_populate_dai;
	}

	rc = snd_soc_register_component(&sdev->dev, &msm_dai_slim_component,
					msm_slim_dais, NUM_SLIM_DAIS);

	if (IS_ERR_VALUE(rc)) {
		dev_err(dev, "%s: failed to register DAI, err = %d\n",
			__func__, rc);
		goto err_reg_comp;
	}

	dev_set_drvdata(dev, drv_data);
	return rc;

err_reg_comp:
	msm_dai_slim_remove_dai_data(dev, drv_data);

err_populate_dai:
	devm_kfree(dev, drv_data);

err_ret:
	return rc;
}
static int msm_bus_copy_node_info(struct msm_bus_node_device_type *pdata,
				struct device *bus_dev)
{
	int ret = 0;
	struct msm_bus_node_info_type *node_info = NULL;
	struct msm_bus_node_info_type *pdata_node_info = NULL;
	struct msm_bus_node_device_type *bus_node = NULL;

	bus_node = bus_dev->platform_data;

	if (!bus_node || !pdata) {
		ret = -ENXIO;
		MSM_BUS_ERR("%s: Invalid pointers pdata %p, bus_node %p",
			__func__, pdata, bus_node);
		goto exit_copy_node_info;
	}

	node_info = bus_node->node_info;
	pdata_node_info = pdata->node_info;

	node_info->name = pdata_node_info->name;
	node_info->id =  pdata_node_info->id;
	node_info->bus_device_id = pdata_node_info->bus_device_id;
	node_info->mas_rpm_id = pdata_node_info->mas_rpm_id;
	node_info->slv_rpm_id = pdata_node_info->slv_rpm_id;
	node_info->num_connections = pdata_node_info->num_connections;
	node_info->num_qports = pdata_node_info->num_qports;
	node_info->buswidth = pdata_node_info->buswidth;
	node_info->virt_dev = pdata_node_info->virt_dev;
	node_info->is_fab_dev = pdata_node_info->is_fab_dev;
	node_info->qos_params.mode = pdata_node_info->qos_params.mode;
	node_info->qos_params.prio1 = pdata_node_info->qos_params.prio1;
	node_info->qos_params.prio0 = pdata_node_info->qos_params.prio0;
	node_info->qos_params.prio_lvl = pdata_node_info->qos_params.prio_lvl;
	node_info->qos_params.prio_rd = pdata_node_info->qos_params.prio_rd;
	node_info->qos_params.prio_wr = pdata_node_info->qos_params.prio_wr;
	node_info->qos_params.gp = pdata_node_info->qos_params.gp;
	node_info->qos_params.thmp = pdata_node_info->qos_params.thmp;
	node_info->qos_params.ws = pdata_node_info->qos_params.ws;

	node_info->dev_connections = devm_kzalloc(bus_dev,
			sizeof(struct device *) *
				pdata_node_info->num_connections,
			GFP_KERNEL);
	if (!node_info->dev_connections) {
		MSM_BUS_ERR("%s:Bus dev connections alloc failed\n", __func__);
		ret = -ENOMEM;
		goto exit_copy_node_info;
	}

	node_info->connections = devm_kzalloc(bus_dev,
			sizeof(int) * pdata_node_info->num_connections,
			GFP_KERNEL);
	if (!node_info->connections) {
		MSM_BUS_ERR("%s:Bus connections alloc failed\n", __func__);
		devm_kfree(bus_dev, node_info->dev_connections);
		ret = -ENOMEM;
		goto exit_copy_node_info;
	}

	memcpy(node_info->connections,
		pdata_node_info->connections,
		sizeof(int) * pdata_node_info->num_connections);

	node_info->qport = devm_kzalloc(bus_dev,
			sizeof(int) * pdata_node_info->num_qports,
			GFP_KERNEL);
	if (!node_info->qport) {
		MSM_BUS_ERR("%s:Bus qport allocation failed\n", __func__);
		devm_kfree(bus_dev, node_info->dev_connections);
		devm_kfree(bus_dev, node_info->connections);
		ret = -ENOMEM;
		goto exit_copy_node_info;
	}

	memcpy(node_info->qport,
		pdata_node_info->qport,
		sizeof(int) * pdata_node_info->num_qports);

exit_copy_node_info:
	return ret;
}
static int msm_bus_device_probe(struct platform_device *pdev)
{
	unsigned int i, ret;
	struct msm_bus_device_node_registration *pdata;

	/* If possible, get pdata from device-tree */
	if (pdev->dev.of_node)
		pdata = msm_bus_of_to_pdata(pdev);
	else {
		pdata = (struct msm_bus_device_node_registration *)pdev->
			dev.platform_data;
	}

	if (IS_ERR_OR_NULL(pdata)) {
		MSM_BUS_ERR("No platform data found");
		ret = -ENODATA;
		goto exit_device_probe;
	}

	for (i = 0; i < pdata->num_devices; i++) {
		struct device *node_dev = NULL;

		node_dev = msm_bus_device_init(&pdata->info[i]);

		if (!node_dev) {
			MSM_BUS_ERR("%s: Error during dev init for %d",
				__func__, pdata->info[i].node_info->id);
			ret = -ENXIO;
			goto exit_device_probe;
		}

		ret = msm_bus_init_clk(node_dev, &pdata->info[i]);
		/*Is this a fabric device ?*/
		if (pdata->info[i].node_info->is_fab_dev) {
			MSM_BUS_DBG("%s: %d is a fab", __func__,
						pdata->info[i].node_info->id);
			ret = msm_bus_fabric_init(node_dev, &pdata->info[i]);
			if (ret) {
				MSM_BUS_ERR("%s: Error intializing fab %d",
					__func__, pdata->info[i].node_info->id);
				goto exit_device_probe;
			}
		}
	}

	ret = bus_for_each_dev(&msm_bus_type, NULL, NULL,
						msm_bus_setup_dev_conn);
	if (ret) {
		MSM_BUS_ERR("%s: Error setting up dev connections", __func__);
		goto exit_device_probe;
	}

	ret = bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_dev_init_qos);
	if (ret) {
		MSM_BUS_ERR("%s: Error during qos init", __func__);
		goto exit_device_probe;
	}

	bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_node_debug);

	/* Register the arb layer ops */
	msm_bus_arb_setops_adhoc(&arb_ops);
	devm_kfree(&pdev->dev, pdata->info);
	devm_kfree(&pdev->dev, pdata);
exit_device_probe:
	return ret;
}
示例#14
0
int cros_ec_query_all(struct cros_ec_device *ec_dev)
{
	struct device *dev = ec_dev->dev;
	struct cros_ec_command *proto_msg;
	struct ec_response_get_protocol_info *proto_info;
	u32 ver_mask = 0;
	int ret;

	proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info),
			    GFP_KERNEL);
	if (!proto_msg)
		return -ENOMEM;

	/* First try sending with proto v3. */
	ec_dev->proto_version = 3;
	ret = cros_ec_host_command_proto_query(ec_dev, 0, proto_msg);

	if (ret == 0) {
		proto_info = (struct ec_response_get_protocol_info *)
			proto_msg->data;
		ec_dev->max_request = proto_info->max_request_packet_size -
			sizeof(struct ec_host_request);
		ec_dev->max_response = proto_info->max_response_packet_size -
			sizeof(struct ec_host_response);
		ec_dev->proto_version =
			min(EC_HOST_REQUEST_VERSION,
					fls(proto_info->protocol_versions) - 1);
		dev_dbg(ec_dev->dev,
			"using proto v%u\n",
			ec_dev->proto_version);

		ec_dev->din_size = ec_dev->max_response +
			sizeof(struct ec_host_response) +
			EC_MAX_RESPONSE_OVERHEAD;
		ec_dev->dout_size = ec_dev->max_request +
			sizeof(struct ec_host_request) +
			EC_MAX_REQUEST_OVERHEAD;

		/*
		 * Check for PD
		 */
		ret = cros_ec_host_command_proto_query(ec_dev, 1, proto_msg);

		if (ret) {
			dev_dbg(ec_dev->dev, "no PD chip found: %d\n", ret);
			ec_dev->max_passthru = 0;
		} else {
			dev_dbg(ec_dev->dev, "found PD chip\n");
			ec_dev->max_passthru =
				proto_info->max_request_packet_size -
				sizeof(struct ec_host_request);
		}
	} else {
		/* Try querying with a v2 hello message. */
		ec_dev->proto_version = 2;
		ret = cros_ec_host_command_proto_query_v2(ec_dev);

		if (ret == 0) {
			/* V2 hello succeeded. */
			dev_dbg(ec_dev->dev, "falling back to proto v2\n");

			ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
			ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
			ec_dev->max_passthru = 0;
			ec_dev->pkt_xfer = NULL;
			ec_dev->din_size = EC_PROTO2_MSG_BYTES;
			ec_dev->dout_size = EC_PROTO2_MSG_BYTES;
		} else {
			/*
			 * It's possible for a test to occur too early when
			 * the EC isn't listening. If this happens, we'll
			 * test later when the first command is run.
			 */
			ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN;
			dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret);
			goto exit;
		}
	}

	devm_kfree(dev, ec_dev->din);
	devm_kfree(dev, ec_dev->dout);

	ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
	if (!ec_dev->din) {
		ret = -ENOMEM;
		goto exit;
	}

	ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
	if (!ec_dev->dout) {
		devm_kfree(dev, ec_dev->din);
		ret = -ENOMEM;
		goto exit;
	}

	/* Probe if MKBP event is supported */
	ret = cros_ec_get_host_command_version_mask(ec_dev,
						    EC_CMD_GET_NEXT_EVENT,
						    &ver_mask);
	if (ret < 0 || ver_mask == 0)
		ec_dev->mkbp_event_supported = 0;
	else
		ec_dev->mkbp_event_supported = 1;

exit:
	kfree(proto_msg);
	return ret;
}
static struct msm_bus_fab_device_type *get_fab_device_info(
		struct device_node *dev_node,
		struct platform_device *pdev)
{
	struct msm_bus_fab_device_type *fab_dev;
	unsigned int ret;
	struct resource *res;
	const char *base_name;

	fab_dev = devm_kzalloc(&pdev->dev,
			sizeof(struct msm_bus_fab_device_type),
			GFP_KERNEL);
	if (!fab_dev) {
		dev_err(&pdev->dev,
			"Error: Unable to allocate memory for fab_dev\n");
		return NULL;
	}

	ret = of_property_read_string(dev_node, "qcom,base-name", &base_name);
	if (ret) {
		dev_err(&pdev->dev, "Error: Unable to get base address name\n");
		goto fab_dev_err;
	}

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, base_name);
	if (!res) {
		dev_err(&pdev->dev, "Error getting qos base addr %s\n",
								base_name);
		goto fab_dev_err;
	}
	fab_dev->pqos_base = res->start;
	fab_dev->qos_range = resource_size(res);
	fab_dev->bypass_qos_prg = of_property_read_bool(dev_node,
						"qcom,bypass-qos-prg");

	ret = of_property_read_u32(dev_node, "qcom,base-offset",
			&fab_dev->base_offset);
	if (ret)
		dev_dbg(&pdev->dev, "Bus base offset is missing\n");

	ret = of_property_read_u32(dev_node, "qcom,qos-off",
			&fab_dev->qos_off);
	if (ret)
		dev_dbg(&pdev->dev, "Bus qos off is missing\n");


	ret = of_property_read_u32(dev_node, "qcom,bus-type",
						&fab_dev->bus_type);
	if (ret) {
		dev_warn(&pdev->dev, "Bus type is missing\n");
		goto fab_dev_err;
	}

	ret = of_property_read_u32(dev_node, "qcom,qos-freq",
						&fab_dev->qos_freq);
	if (ret) {
		dev_dbg(&pdev->dev, "Bus qos freq is missing\n");
		fab_dev->qos_freq = DEFAULT_QOS_FREQ;
	}

	ret = of_property_read_u32(dev_node, "qcom,util-fact",
						&fab_dev->util_fact);
	if (ret) {
		dev_info(&pdev->dev, "Util-fact is missing, default to %d\n",
				DEFAULT_UTIL_FACT);
		fab_dev->util_fact = DEFAULT_UTIL_FACT;
	}

	ret = of_property_read_u32(dev_node, "qcom,vrail-comp",
						&fab_dev->vrail_comp);
	if (ret) {
		dev_info(&pdev->dev, "Vrail-comp is missing, default to %d\n",
				DEFAULT_VRAIL_COMP);
		fab_dev->vrail_comp = DEFAULT_VRAIL_COMP;
	}

	return fab_dev;

fab_dev_err:
	devm_kfree(&pdev->dev, fab_dev);
	fab_dev = 0;
	return NULL;
}
示例#16
0
static int ktd3102_backlight_probe(struct platform_device *pdev)
{
	struct backlight_device *bd;
	struct ktd3102_backlight_info *info;
	int ret;

	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
	if (unlikely(!info))
		return -ENOMEM;

	if (IS_ENABLED(CONFIG_OF)) {
		struct device_node *np = pdev->dev.of_node;
		struct device_node *brt_node;
		int arr[MAX_BRT_VALUE_IDX * 2], i;

		info->pin_ctrl = ktd3102_parse_dt_gpio(np, "bl-ctrl");
		if (info->pin_ctrl < 0) {
			pr_err("%s, failed to parse dt\n", __func__);
			return -EINVAL;
		}
		/* PWM pin isn't mandatory */
		info->pin_pwm = ktd3102_parse_dt_gpio(np, "bl-pwm");
		pr_info("%s: ctrl=%d, pwm=%d\n",
				__func__, info->pin_ctrl, info->pin_pwm);
	} else {
		if (unlikely(pdev->dev.platform_data == NULL)) {
			dev_err(&pdev->dev, "no platform data!\n");
			return -EINVAL;
		}
		/* TODO: fill info data */
	}

	ret = gpio_request(info->pin_ctrl, "BL_CTRL");
	if (unlikely(ret < 0)) {
		pr_err("%s, request gpio(%d) failed\n", __func__, info->pin_ctrl);
		goto err_bl_gpio_request;
	}

	ret = gpio_request(info->pin_pwm, "BL_PWM");
	if (unlikely(ret < 0)) {
		pr_err("%s, request gpio(%d) failed\n", __func__, info->pin_pwm);
		goto err_bl_gpio_request;
	}

	/* register gen backlight device */
	bd = gen_panel_backlight_device_register(pdev, info,
			&ktd3102_gen_backlight_ops, &info->prev_tune_level);
	if (!bd) {
		dev_err(&pdev->dev, "failed to register gen backlight\n");
		ret = -1;
		goto err_gen_bl_register;
	}

	pm_runtime_enable(&pdev->dev);
	platform_set_drvdata(pdev, bd);
	pm_runtime_get_sync(&pdev->dev);

	return 0;

err_gen_bl_register:
err_bl_gpio_request:
	devm_kfree(&pdev->dev, info);

	return ret;
}
示例#17
0
/**
 * dprc_scan_objects - Discover objects in a DPRC
 *
 * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
 * @total_irq_count: total number of IRQs needed by objects in the DPRC.
 *
 * Detects objects added and removed from a DPRC and synchronizes the
 * state of the Linux bus driver, MC by adding and removing
 * devices accordingly.
 * Two types of devices can be found in a DPRC: allocatable objects (e.g.,
 * dpbp, dpmcp) and non-allocatable devices (e.g., dprc, dpni).
 * All allocatable devices needed to be probed before all non-allocatable
 * devices, to ensure that device drivers for non-allocatable
 * devices can allocate any type of allocatable devices.
 * That is, we need to ensure that the corresponding resource pools are
 * populated before they can get allocation requests from probe callbacks
 * of the device drivers for the non-allocatable devices.
 */
int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
		      unsigned int *total_irq_count)
{
	int num_child_objects;
	int dprc_get_obj_failures;
	int error;
	unsigned int irq_count = mc_bus_dev->obj_desc.irq_count;
	struct dprc_obj_desc *child_obj_desc_array = NULL;

	error = dprc_get_obj_count(mc_bus_dev->mc_io,
				   0,
				   mc_bus_dev->mc_handle,
				   &num_child_objects);
	if (error < 0) {
		dev_err(&mc_bus_dev->dev, "dprc_get_obj_count() failed: %d\n",
			error);
		return error;
	}

	if (num_child_objects != 0) {
		int i;

		child_obj_desc_array =
		    devm_kmalloc_array(&mc_bus_dev->dev, num_child_objects,
				       sizeof(*child_obj_desc_array),
				       GFP_KERNEL);
		if (!child_obj_desc_array)
			return -ENOMEM;

		/*
		 * Discover objects currently present in the physical DPRC:
		 */
		dprc_get_obj_failures = 0;
		for (i = 0; i < num_child_objects; i++) {
			struct dprc_obj_desc *obj_desc =
			    &child_obj_desc_array[i];

			error = dprc_get_obj(mc_bus_dev->mc_io,
					     0,
					     mc_bus_dev->mc_handle,
					     i, obj_desc);
			if (error < 0) {
				dev_err(&mc_bus_dev->dev,
					"dprc_get_obj(i=%d) failed: %d\n",
					i, error);
				/*
				 * Mark the obj entry as "invalid", by using the
				 * empty string as obj type:
				 */
				obj_desc->type[0] = '\0';
				obj_desc->id = error;
				dprc_get_obj_failures++;
				continue;
			}

			/*
			 * add a quirk for all versions of dpsec < 4.0...none
			 * are coherent regardless of what the MC reports.
			 */
			if ((strcmp(obj_desc->type, "dpseci") == 0) &&
			    (obj_desc->ver_major < 4))
				obj_desc->flags |=
					DPRC_OBJ_FLAG_NO_MEM_SHAREABILITY;

			irq_count += obj_desc->irq_count;
			dev_dbg(&mc_bus_dev->dev,
				"Discovered object: type %s, id %d\n",
				obj_desc->type, obj_desc->id);
		}

		if (dprc_get_obj_failures != 0) {
			dev_err(&mc_bus_dev->dev,
				"%d out of %d devices could not be retrieved\n",
				dprc_get_obj_failures, num_child_objects);
		}
	}

	*total_irq_count = irq_count;
	dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
			    num_child_objects);

	dprc_add_new_devices(mc_bus_dev, child_obj_desc_array,
			     num_child_objects);

	if (child_obj_desc_array)
		devm_kfree(&mc_bus_dev->dev, child_obj_desc_array);

	return 0;
}
示例#18
0
static int ufshcd_populate_vreg(struct device *dev, const char *name,
		struct ufs_vreg **out_vreg)
{
	int ret = 0;
	char prop_name[MAX_PROP_SIZE];
	struct ufs_vreg *vreg = NULL;
	struct device_node *np = dev->of_node;

	if (!np) {
		dev_err(dev, "%s: non DT initialization\n", __func__);
		goto out;
	}

	snprintf(prop_name, MAX_PROP_SIZE, "%s-supply", name);
	if (!of_parse_phandle(np, prop_name, 0)) {
		dev_info(dev, "%s: Unable to find %s regulator, assuming enabled\n",
				__func__, prop_name);
		goto out;
	}

	vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
	if (!vreg)
		return -ENOMEM;

	vreg->name = kstrdup(name, GFP_KERNEL);

	/* if fixed regulator no need further initialization */
	snprintf(prop_name, MAX_PROP_SIZE, "%s-fixed-regulator", name);
	if (of_property_read_bool(np, prop_name))
		goto out;

	snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name);
	ret = of_property_read_u32(np, prop_name, &vreg->max_uA);
	if (ret) {
		dev_err(dev, "%s: unable to find %s err %d\n",
				__func__, prop_name, ret);
		goto out_free;
	}

	vreg->min_uA = 0;
	if (!strcmp(name, "vcc")) {
		if (of_property_read_bool(np, "vcc-supply-1p8")) {
			vreg->min_uV = UFS_VREG_VCC_1P8_MIN_UV;
			vreg->max_uV = UFS_VREG_VCC_1P8_MAX_UV;
		} else {
			vreg->min_uV = UFS_VREG_VCC_MIN_UV;
			vreg->max_uV = UFS_VREG_VCC_MAX_UV;
		}
	} else if (!strcmp(name, "vccq")) {
		vreg->min_uV = UFS_VREG_VCCQ_MIN_UV;
		vreg->max_uV = UFS_VREG_VCCQ_MAX_UV;
	} else if (!strcmp(name, "vccq2")) {
		vreg->min_uV = UFS_VREG_VCCQ2_MIN_UV;
		vreg->max_uV = UFS_VREG_VCCQ2_MAX_UV;
	}

	goto out;

out_free:
	devm_kfree(dev, vreg);
	vreg = NULL;
out:
	if (!ret)
		*out_vreg = vreg;
	return ret;
}
示例#19
0
static int isp_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct isp_k_private *isp_private = NULL;

	isp_private = devm_kzalloc(&pdev->dev, sizeof(*isp_private), GFP_KERNEL);
	if (!isp_private) {
		printk("isp_probe: isp_private is null error.\n");
		return -ENOMEM;
	}

	atomic_set(&isp_private->users, 0);
	isp_private->dn = pdev->dev.of_node;
	isp_private->clock = NULL;
	sema_init(&isp_private->device_lock, 1);
	sema_init(&isp_private->ioctl_lock, 1);
	ret = isp_block_buf_alloc(isp_private);
	if (ret) {
		ret = -ENOMEM;
		devm_kfree(&pdev->dev, isp_private);
		printk("isp_probe: no memory for isp_private, error.\n");
		return ret;
	}

	platform_set_drvdata(pdev, isp_private);
	s_isp_private = isp_private;
	ret = isp_lsc_buf_alloc(isp_private, ISP_LSC_BUF_SIZE);
	if (ret) {
		ret = -ENOMEM;
		isp_block_buf_free(isp_private);
		devm_kfree(&pdev->dev, isp_private);
		platform_set_drvdata(pdev, NULL);
		printk("isp_probe: no memory for isp lsc buf alloc, error.\n");
		return ret;
	}
	
	ret = isp_binging4awb_buf_alloc(isp_private, ISP_BING4AWB_SIZE);
	if (ret) {
		ret = -ENOMEM;
		isp_lsc_buf_free(isp_private);
		isp_block_buf_free(isp_private);
		devm_kfree(&pdev->dev, isp_private);
		platform_set_drvdata(pdev, NULL);
		printk("isp_probe: no memory for isp lsc buf alloc, error.\n");
		return ret;
	}

	ret = isp_yiq_antiflicker_buf_alloc(isp_private, ISP_YIQ_ANTIFLICKER_SIZE);
	if (ret) {
		ret = -ENOMEM;
		isp_binging4awb_buf_free(isp_private);
		isp_lsc_buf_free(isp_private);
		isp_block_buf_free(isp_private);
		devm_kfree(&pdev->dev, isp_private);
		platform_set_drvdata(pdev, NULL);
		printk("isp_probe: no memory for isp lsc buf alloc, error.\n");
		return ret;
	}

	ret = misc_register(&isp_dev);
	if (ret) {
		ret = -EACCES;
		isp_yiq_antiflicker_buf_free(isp_private);		
		isp_binging4awb_buf_free(isp_private);
		isp_lsc_buf_free(isp_private);
		isp_block_buf_free(isp_private);
		devm_kfree(&pdev->dev, isp_private);
		platform_set_drvdata(pdev, NULL);
		printk("isp_probe: misc_register error.\n");
	}

	parse_baseaddress(pdev->dev.of_node);
	printk("isp_probe: success.\n");

	return ret;
}
static int __devinit hall_sensor_probe(struct platform_device *pdev)
{
	struct hall_sensor_data *hsdata = pdev->dev.platform_data;
	struct input_dev *input_dev;
	int err = 0;

	if (pdev->dev.of_node) {
		hsdata = devm_kzalloc(&pdev->dev, sizeof(struct hall_sensor_data),
					GFP_KERNEL);
		if (!hsdata) {
			dev_err(&pdev->dev, "[Hall] Failed to allocate memory");
			return -ENOMEM;
		}

		err = hall_sensor_parse_dt(&pdev->dev, hsdata);
		if (err)
			goto err_free_mem;
	}

	if (!hsdata)
		return -EINVAL;

	hsdata->dev = &pdev->dev;

	input_dev = input_allocate_device();
	if (input_dev == NULL) {
		dev_err(&pdev->dev, "[Hall] Failed to allocate input device\n");
		goto err_free_mem;
	}

	input_dev->name = DRIVER_NAME;
	input_dev->dev.parent = &pdev->dev;
	input_dev->id.bustype = BUS_HOST;

	__set_bit(EV_KEY, input_dev->evbit);
	__set_bit(KEY_POWER, input_dev->keybit);

	spin_lock_init(&hsdata->lock);
	wake_lock_init(&hsdata->irq_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	hsdata->input_dev = input_dev;

	err = input_register_device(input_dev);
	if (err) {
		dev_err(&pdev->dev, "[Hall] Failed to register input device\n");
		goto err_free_input_dev;
	}

	/* GPIO irq */
	err = gpio_request(hsdata->irq_gpio, "hall-irq-gpio");
	if (err) {
		dev_err(&pdev->dev, "[Hall] Failed to request irq gpio\n");
		goto err_unregister_input;
	}

	err = gpio_direction_input(hsdata->irq_gpio);
	if (err) {
		dev_err(&pdev->dev, "[Hall] Unable to set direction for irq gpio %d\n",
				hsdata->irq_gpio);
		goto err_free_irq_gpio;
	}

	err = request_threaded_irq(hsdata->irq, NULL, hall_sensor_irq_handler,
								hsdata->irq_gpio_flags, DRIVER_NAME,
								hsdata);
	if (err) {
		dev_err(&pdev->dev, "[Hall] Failed to request irq %d\n", hsdata->irq);
		goto err_free_irq_gpio;
	}

	hsdata->sdev.print_state = switch_print_state;
	hsdata->sdev.name = SENSOR_NAME;
	hsdata->sdev.print_name = switch_print_name;
	err = switch_dev_register(&hsdata->sdev);
	if (err) {
		dev_err(&pdev->dev, "[Hall] Register switch device failed\n");
		goto err_free_irq;
	}

#if defined(CONFIG_FB)
	hsdata->fb_notif.notifier_call = hall_fb_notifier_callback;
	err = fb_register_client(&hsdata->fb_notif);
	if (err) {
		dev_err(&pdev->dev, "[Hall] Failed to register fb_notifier:%d\n", err);
		goto err_unregister_switch;
	}
#endif

	err = sysfs_create_group(&hsdata->sdev.dev->kobj, &hall_sensor_attr_group);
	if (err) {
		dev_err(&pdev->dev, "[Hall] Failed to create sysfs group:%d\n", err);
		goto err_unregister_fb;
	}

	dev_set_drvdata(&pdev->dev, hsdata);
	INIT_DELAYED_WORK(&hsdata->state_delay_work, hall_sensor_work);

	/* default enable wakeup feature */
	hsdata->wakeup_enable = true;
	device_init_wakeup(&pdev->dev, HALL_WAKEUP_ENABLE);
	enable_irq_wake(hsdata->irq);

	hsdev = hsdata;

	return 0;

err_unregister_fb:
	fb_unregister_client(&hsdata->fb_notif);
err_unregister_switch:
	switch_dev_unregister(&hsdata->sdev);
err_free_irq:
	free_irq(hsdata->irq, hsdata);
err_free_irq_gpio:
	if (gpio_is_valid(hsdata->irq_gpio))
		gpio_free(hsdata->irq_gpio);
err_unregister_input:
	input_unregister_device(hsdata->input_dev);
err_free_input_dev:
	if (input_dev)
		input_free_device(input_dev);
err_free_mem:
	devm_kfree(&pdev->dev, (void *)hsdata);
	return err;
}
static int __devinit mdss_dsi_ctrl_probe(struct platform_device *pdev)
{
	int rc = 0;
	u32 index;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	struct device_node *dsi_pan_node = NULL;
	char panel_cfg[MDSS_MAX_PANEL_LEN];
	struct resource *mdss_dsi_mres;
	const char *ctrl_name;
	bool cmd_cfg_cont_splash = true;

	if (!mdss_is_ready()) {
		pr_err("%s: MDP not probed yet!\n", __func__);
		return -EPROBE_DEFER;
	}

	if (!pdev->dev.of_node) {
		pr_err("DSI driver only supports device tree probe\n");
		return -ENOTSUPP;
	}

	ctrl_pdata = platform_get_drvdata(pdev);
	if (!ctrl_pdata) {
		ctrl_pdata = devm_kzalloc(&pdev->dev,
					  sizeof(struct mdss_dsi_ctrl_pdata),
					  GFP_KERNEL);
		if (!ctrl_pdata) {
			pr_err("%s: FAILED: cannot alloc dsi ctrl\n",
			       __func__);
			rc = -ENOMEM;
			goto error_no_mem;
		}
		platform_set_drvdata(pdev, ctrl_pdata);
	}

	ctrl_name = of_get_property(pdev->dev.of_node, "label", NULL);
	if (!ctrl_name)
		pr_info("%s:%d, DSI Ctrl name not specified\n",
			__func__, __LINE__);
	else
		pr_info("%s: DSI Ctrl name = %s\n",
			__func__, ctrl_name);

	rc = of_property_read_u32(pdev->dev.of_node,
				  "cell-index", &index);
	if (rc) {
		dev_err(&pdev->dev,
			"%s: Cell-index not specified, rc=%d\n",
			__func__, rc);
		goto error_no_mem;
	}

	if (index == 0)
		pdev->id = 1;
	else
		pdev->id = 2;

	mdss_dsi_mres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mdss_dsi_mres) {
		pr_err("%s:%d unable to get the MDSS resources",
		       __func__, __LINE__);
		rc = -ENOMEM;
		goto error_no_mem;
	}

	mdss_dsi_base = ioremap(mdss_dsi_mres->start,
				resource_size(mdss_dsi_mres));
	if (!mdss_dsi_base) {
		pr_err("%s:%d unable to remap dsi resources",
		       __func__, __LINE__);
		rc = -ENOMEM;
		goto error_no_mem;
	}

	rc = of_platform_populate(pdev->dev.of_node,
				  NULL, NULL, &pdev->dev);
	if (rc) {
		dev_err(&pdev->dev,
			"%s: failed to add child nodes, rc=%d\n",
			__func__, rc);
		goto error_ioremap;
	}

	/* Parse the regulator information */
	rc = mdss_dsi_get_dt_vreg_data(&pdev->dev,
				       &ctrl_pdata->power_data);
	if (rc) {
		pr_err("%s: failed to get vreg data from dt. rc=%d\n",
		       __func__, rc);
		goto error_vreg;
	}

	/* DSI panels can be different between controllers */
	rc = mdss_dsi_get_panel_cfg(panel_cfg);
	if (!rc)
		/* dsi panel cfg not present */
		pr_warn("%s:%d:dsi specific cfg not present\n",
			__func__, __LINE__);

	/* find panel device node */
	dsi_pan_node = mdss_dsi_find_panel_of_node(pdev, panel_cfg);
	if (!dsi_pan_node) {
		pr_err("%s: can't find panel node %s\n", __func__, panel_cfg);
		goto error_pan_node;
	}

	cmd_cfg_cont_splash = mdss_panel_get_boot_cfg() ? true : false;

    printk("[Display] cmd_cfg_cont_splash(%d) \n", cmd_cfg_cont_splash);	//ASUS_BSP: Louis +++

	rc = mdss_dsi_panel_init(dsi_pan_node, ctrl_pdata, cmd_cfg_cont_splash);
	if (rc) {
		pr_err("%s: dsi panel init failed\n", __func__);
		goto error_pan_node;
	}

	rc = dsi_panel_device_register(dsi_pan_node, ctrl_pdata);
	if (rc) {
		pr_err("%s: dsi panel dev reg failed\n", __func__);
		goto error_pan_node;
	}

	pr_debug("%s: Dsi Ctrl->%d initialized\n", __func__, index);
	return 0;

error_pan_node:
	of_node_put(dsi_pan_node);
error_vreg:
	mdss_dsi_put_dt_vreg_data(&pdev->dev, &ctrl_pdata->power_data);
error_ioremap:
	iounmap(mdss_dsi_base);
error_no_mem:
	devm_kfree(&pdev->dev, ctrl_pdata);

	return rc;
}
示例#22
0
static bool get_isdbt_dt_pdata(struct device *dev)
{
	dt_pdata = devm_kzalloc(dev, sizeof(struct isdbt_dt_platform_data), GFP_KERNEL);
	if (!dt_pdata) {
		DPRINTK("could not allocate memory for platform data\n");
		goto err;
	}

	if(dev->of_node)
	{
		dt_pdata->isdbt_pwr_en = of_get_named_gpio(dev->of_node, "isdbt_pwr_en", 0);
		if (dt_pdata->isdbt_pwr_en < 0) {
			DPRINTK("can not find the isdbt_pwr_en\n");
			goto alloc_err;
		}
		dt_pdata->isdbt_pwr_en2 = of_get_named_gpio(dev->of_node, "isdbt_pwr_en2", 0);
		if (dt_pdata->isdbt_pwr_en2 < 0) {
			DPRINTK("can not find the isdbt_pwr_en2\n");
			//goto alloc_err;
		}
		dt_pdata->isdbt_rst = of_get_named_gpio(dev->of_node, "isdbt_rst", 0);
		if (dt_pdata->isdbt_rst < 0) {
			DPRINTK("can not find the isdbt_rst\n");
			//goto alloc_err;
		}
		dt_pdata->isdbt_irq = of_get_named_gpio(dev->of_node, "isdbt_irq", 0);
		if (dt_pdata->isdbt_irq < 0) {
			DPRINTK("can not find the isdbt_irq\n");
			goto alloc_err;
		}
		dt_pdata->isdbt_spi_mosi = of_get_named_gpio(dev->of_node, "isdbt_spi_mosi", 0);
		if (dt_pdata->isdbt_spi_mosi < 0) {
			DPRINTK("can not find the isdbt_spi_mosi\n");
			goto alloc_err;
		}
		dt_pdata->isdbt_spi_miso = of_get_named_gpio(dev->of_node, "isdbt_spi_miso", 0);
		if (dt_pdata->isdbt_spi_miso < 0) {
			DPRINTK("can not find the isdbt_spi_miso\n");
			goto alloc_err;
		}
		dt_pdata->isdbt_spi_cs = of_get_named_gpio(dev->of_node, "isdbt_spi_cs", 0);
		if (dt_pdata->isdbt_spi_cs < 0) {
			DPRINTK("can not find the isdbt_spi_cs\n");
			goto alloc_err;
		}
		dt_pdata->isdbt_spi_clk = of_get_named_gpio(dev->of_node, "isdbt_spi_clk", 0);
		if (dt_pdata->isdbt_spi_clk < 0) {
			DPRINTK("can not find the isdbt_spi_clk\n");
			goto alloc_err;
		}
	}
	else {
		DPRINTK("could find device tree\n");
		dt_pdata->isdbt_pwr_en = convert_gpio(ISDBT_PWR_EN);
		dt_pdata->isdbt_pwr_en2 = convert_gpio(ISDBT_PWR_EN2);
		dt_pdata->isdbt_rst = convert_gpio(ISDBT_RST);
		dt_pdata->isdbt_irq = convert_gpio(ISDBT_INT);
		dt_pdata->isdbt_spi_mosi = convert_gpio(ISDBT_SPI_MOSI);
		dt_pdata->isdbt_spi_miso = convert_gpio(ISDBT_SPI_MISO);
		dt_pdata->isdbt_spi_cs = convert_gpio(ISDBT_SPI_CS);
		dt_pdata->isdbt_spi_clk = convert_gpio(ISDBT_SPI_CLK);
	}

	DPRINTK("[daromy] isdbt_pwr_en : %d\n", dt_pdata->isdbt_pwr_en);
	DPRINTK("[daromy] isdbt_pwr_en2 : %d\n", dt_pdata->isdbt_pwr_en2);
	DPRINTK("[daromy] isdbt_rst : %d\n", dt_pdata->isdbt_rst);
	DPRINTK("[daromy] isdbt_irq : %d\n", dt_pdata->isdbt_irq);
	DPRINTK("[daromy] isdbt_spi_mosi : %d\n", dt_pdata->isdbt_spi_mosi);
	DPRINTK("[daromy] isdbt_spi_miso : %d\n", dt_pdata->isdbt_spi_miso);
	DPRINTK("[daromy] isdbt_spi_cs : %d\n", dt_pdata->isdbt_spi_cs);
	DPRINTK("[daromy] isdbt_spi_clk : %d\n", dt_pdata->isdbt_spi_clk);
	
	return true;

alloc_err:
	devm_kfree(dev, dt_pdata);

err:
	return false;
}
示例#23
0
static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
{
	int rc = 0, i = 0;
	u32 index;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	struct device_node *dsi_pan_node = NULL;
	char panel_cfg[MDSS_MAX_PANEL_LEN];
	const char *ctrl_name;
	bool cmd_cfg_cont_splash = true;
	struct mdss_panel_cfg *pan_cfg = NULL;

	if (!mdss_is_ready()) {
		pr_err("%s: MDP not probed yet!\n", __func__);
		return -EPROBE_DEFER;
	}

	if (!pdev->dev.of_node) {
		pr_err("DSI driver only supports device tree probe\n");
		return -ENOTSUPP;
	}

	pan_cfg = mdss_panel_intf_type(MDSS_PANEL_INTF_HDMI);
	if (IS_ERR(pan_cfg)) {
		return PTR_ERR(pan_cfg);
	} else if (pan_cfg) {
		pr_debug("%s: HDMI is primary\n", __func__);
		return -ENODEV;
	}

	ctrl_pdata = platform_get_drvdata(pdev);
	if (!ctrl_pdata) {
		ctrl_pdata = devm_kzalloc(&pdev->dev,
					  sizeof(struct mdss_dsi_ctrl_pdata),
					  GFP_KERNEL);
		if (!ctrl_pdata) {
			pr_err("%s: FAILED: cannot alloc dsi ctrl\n",
			       __func__);
			rc = -ENOMEM;
			goto error_no_mem;
		}
		platform_set_drvdata(pdev, ctrl_pdata);
	}

	ctrl_name = of_get_property(pdev->dev.of_node, "label", NULL);
	if (!ctrl_name)
		pr_info("%s:%d, DSI Ctrl name not specified\n",
			__func__, __LINE__);
	else
		pr_info("%s: DSI Ctrl name = %s\n",
			__func__, ctrl_name);

	rc = of_property_read_u32(pdev->dev.of_node,
				  "cell-index", &index);
	if (rc) {
		dev_err(&pdev->dev,
			"%s: Cell-index not specified, rc=%d\n",
			__func__, rc);
		goto error_no_mem;
	}

	if (index == 0)
		pdev->id = 1;
	else
		pdev->id = 2;

	rc = of_platform_populate(pdev->dev.of_node,
				  NULL, NULL, &pdev->dev);
	if (rc) {
		dev_err(&pdev->dev,
			"%s: failed to add child nodes, rc=%d\n",
			__func__, rc);
		goto error_no_mem;
	}

	rc = mdss_dsi_pinctrl_init(pdev);
	if (rc)
		pr_warn("%s: failed to get pin resources\n", __func__);

	
	for (i = 0; i < DSI_MAX_PM; i++) {
		rc = mdss_dsi_get_dt_vreg_data(&pdev->dev,
			&ctrl_pdata->power_data[i], i);
		if (rc) {
			DEV_ERR("%s: '%s' get_dt_vreg_data failed.rc=%d\n",
				__func__, __mdss_dsi_pm_name(i), rc);
			goto error_vreg;
		}
	}

	
	rc = mdss_dsi_get_panel_cfg(panel_cfg);
	if (!rc)
		
		pr_warn("%s:%d:dsi specific cfg not present\n",
			__func__, __LINE__);

	
	dsi_pan_node = mdss_dsi_find_panel_of_node(pdev, panel_cfg);
	if (!dsi_pan_node) {
		pr_err("%s: can't find panel node %s\n", __func__, panel_cfg);
		goto error_pan_node;
	}

	cmd_cfg_cont_splash = mdss_panel_get_boot_cfg() ? true : false;

	rc = mdss_dsi_panel_init(dsi_pan_node, ctrl_pdata, cmd_cfg_cont_splash);
	if (rc) {
		pr_err("%s: dsi panel init failed\n", __func__);
		goto error_pan_node;
	}

	rc = dsi_panel_device_register(dsi_pan_node, ctrl_pdata);
	if (rc) {
		pr_err("%s: dsi panel dev reg failed\n", __func__);
		goto error_pan_node;
	}

	pr_debug("%s: Dsi Ctrl->%d initialized\n", __func__, index);
	return 0;

error_pan_node:
	of_node_put(dsi_pan_node);
error_vreg:
	for (; i >= 0; i--)
		mdss_dsi_put_dt_vreg_data(&pdev->dev,
			&ctrl_pdata->power_data[i]);
error_no_mem:
	devm_kfree(&pdev->dev, ctrl_pdata);

	return rc;
}
示例#24
0
static int ath6kl_hsic_probe(struct platform_device *pdev)
{
	struct ath6kl_platform_data *pdata = NULL;
	struct device *dev = &pdev->dev;
	int ret = 0;

	if (machine_is_apq8064_dma()) {
		/* todo */
	} else {

		ath6kl_bus_scale_pdata = msm_bus_cl_get_pdata(pdev);
		bus_perf_client =
			msm_bus_scale_register_client(
				ath6kl_bus_scale_pdata);
		msm_bus_scale_client_update_request(bus_perf_client, 4);

		pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);

		if (!pdata) {
			ath6kl_err("%s: Could not allocate memory for platform data\n",
				__func__);
			return -ENOMEM;
		}

		if (ath6kl_dt_parse_vreg_info(dev, &pdata->wifi_chip_pwd,
				"qca,wifi-chip-pwd") != 0) {
			ath6kl_err("%s: parse vreg info for %s error\n",
				"chip_pwd", __func__);
			goto err;
		}

		if (ath6kl_dt_parse_vreg_info(dev, &pdata->wifi_vddpa,
				"qca,wifi-vddpa") != 0) {
			ath6kl_err("%s: parse vreg info for %s error\n",
				"vddpa", __func__);
			goto err;
		}

		if (ath6kl_dt_parse_vreg_info(dev, &pdata->wifi_vddio,
				"qca,wifi-vddio") != 0) {
			ath6kl_err("%s: parse vreg info for %s error\n",
				"vddio", __func__);
			goto err;
		}

		pdata->pdev = pdev;
		platform_set_drvdata(pdev, pdata);
		gpdata = pdata;

		if (pdata->wifi_chip_pwd != NULL) {
			ret = ath6kl_platform_power(pdata, 1);

			if (ret == 0)
				ath6kl_hsic_bind(1);

			*platform_has_vreg = 1;
		}
	}

	return ret;

err:
	if (pdata != NULL)
		devm_kfree(dev, pdata);

	return -EINVAL;
}
static int uio_mvisp_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct uio_mvisp_dev *cdev;
	int ret = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "no memory resources given\n");
		return -ENODEV;
	}

	cdev = devm_kzalloc(&pdev->dev, sizeof(*cdev), GFP_KERNEL);
	if (!cdev) {
		dev_err(&pdev->dev, "uio_mvisp_dev: out of memory\n");
		return -ENOMEM;
	}

	cdev->clk = clk_get(&pdev->dev, "ISP-CLK");
	if (IS_ERR(cdev->clk)) {
		dev_err(&pdev->dev, "cannot get mvisp clock\n");
		ret = PTR_ERR(cdev->clk);
		goto err_clk;
	}

	cdev->reg_base = (void *)ioremap(res->start, res->end - res->start + 1);
	if (!cdev->reg_base) {
		dev_err(&pdev->dev, "can't remap register area\n");
		ret = -ENOMEM;
		goto err_reg_base;
	}

	platform_set_drvdata(pdev, cdev);

	cdev->uio_info.name = UIO_MVISP_NAME;
	cdev->uio_info.version = UIO_MVISP_VERSION;
	cdev->uio_info.mem[0].internal_addr = (void __iomem *)cdev->reg_base;
	cdev->uio_info.mem[0].addr = res->start;
	cdev->uio_info.mem[0].memtype = UIO_MEM_PHYS;
	cdev->uio_info.mem[0].size = res->end - res->start + 1;

	cdev->uio_info.priv = cdev;

	cdev->uio_info.open = mvisp_open;
	cdev->uio_info.release = mvisp_release;
	cdev->uio_info.ioctl = mvisp_ioctl;
	cdev->uio_info.mmap = NULL;

	mutex_init(&(cdev->mutex));
	cdev->filehandle_ins_num = 0;

	ret = uio_register_device(&pdev->dev, &cdev->uio_info);
	if (ret) {
		dev_err(&pdev->dev, "failed to register uio device\n");
		goto err_uio_register;
	}

	return 0;

err_uio_register:
	free_pages((unsigned long)cdev->uio_info.mem[1].internal_addr,
			get_order(VDEC_WORKING_BUFFER_SIZE));
err_reg_base:
	clk_put(cdev->clk);
err_clk:
	devm_kfree(&pdev->dev, cdev);

	return ret;
}
static struct msm_bus_node_info_type *get_node_info_data(
		struct device_node * const dev_node,
		struct platform_device * const pdev)
{
	struct msm_bus_node_info_type *node_info;
	unsigned int ret;
	int size;
	int i;
	struct device_node *con_node;
	struct device_node *bus_dev;

	node_info = devm_kzalloc(&pdev->dev,
			sizeof(struct msm_bus_node_info_type),
			GFP_KERNEL);
	if (!node_info) {
		dev_err(&pdev->dev,
			"Error: Unable to allocate memory for node_info\n");
		return NULL;
	}

	ret = of_property_read_u32(dev_node, "cell-id", &node_info->id);
	if (ret) {
		dev_warn(&pdev->dev, "Bus node is missing cell-id\n");
		goto node_info_err;
	}
	ret = of_property_read_string(dev_node, "label", &node_info->name);
	if (ret) {
		dev_warn(&pdev->dev, "Bus node is missing name\n");
		goto node_info_err;
	}
	node_info->qport = get_arr(pdev, dev_node, "qcom,qport",
			&node_info->num_qports);

	if (of_get_property(dev_node, "qcom,connections", &size)) {
		node_info->num_connections = size / sizeof(int);
		node_info->connections = devm_kzalloc(&pdev->dev, size,
				GFP_KERNEL);
	} else {
		node_info->num_connections = 0;
		node_info->connections = 0;
	}

	for (i = 0; i < node_info->num_connections; i++) {
		con_node = of_parse_phandle(dev_node, "qcom,connections", i);
		if (IS_ERR_OR_NULL(con_node))
			goto node_info_err;

		if (of_property_read_u32(con_node, "cell-id",
				&node_info->connections[i]))
			goto node_info_err;
		of_node_put(con_node);
	}

	if (of_get_property(dev_node, "qcom,blacklist", &size)) {
		node_info->num_blist = size/sizeof(u32);
		node_info->black_listed_connections = devm_kzalloc(&pdev->dev,
		size, GFP_KERNEL);
	} else {
		node_info->num_blist = 0;
		node_info->black_listed_connections = 0;
	}

	for (i = 0; i < node_info->num_blist; i++) {
		con_node = of_parse_phandle(dev_node, "qcom,blacklist", i);
		if (IS_ERR_OR_NULL(con_node))
			goto node_info_err;

		if (of_property_read_u32(con_node, "cell-id",
				&node_info->black_listed_connections[i]))
			goto node_info_err;
		of_node_put(con_node);
	}

	bus_dev = of_parse_phandle(dev_node, "qcom,bus-dev", 0);
	if (!IS_ERR_OR_NULL(bus_dev)) {
		if (of_property_read_u32(bus_dev, "cell-id",
			&node_info->bus_device_id)) {
			dev_err(&pdev->dev, "Can't find bus device. Node %d",
					node_info->id);
			goto node_info_err;
		}

		of_node_put(bus_dev);
	} else
		dev_dbg(&pdev->dev, "Can't find bdev phandle for %d",
					node_info->id);

	node_info->is_fab_dev = of_property_read_bool(dev_node, "qcom,fab-dev");
	node_info->virt_dev = of_property_read_bool(dev_node, "qcom,virt-dev");

	ret = of_property_read_u32(dev_node, "qcom,buswidth",
						&node_info->buswidth);
	if (ret) {
		dev_dbg(&pdev->dev, "Using default 8 bytes %d", node_info->id);
		node_info->buswidth = 8;
	}

	ret = of_property_read_u32(dev_node, "qcom,mas-rpm-id",
						&node_info->mas_rpm_id);
	if (ret) {
		dev_dbg(&pdev->dev, "mas rpm id is missing\n");
		node_info->mas_rpm_id = -1;
	}

	ret = of_property_read_u32(dev_node, "qcom,slv-rpm-id",
						&node_info->slv_rpm_id);
	if (ret) {
		dev_dbg(&pdev->dev, "slv rpm id is missing\n");
		node_info->slv_rpm_id = -1;
	}
	get_qos_params(dev_node, pdev, node_info);

	return node_info;

node_info_err:
	devm_kfree(&pdev->dev, node_info);
	node_info = 0;
	return NULL;
}
static int __devinit mdss_dsi_ctrl_probe(struct platform_device *pdev)
{
	int rc = 0;
	u32 index;
	struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
	struct device_node *dsi_pan_node = NULL;
	char panel_cfg[MDSS_MAX_PANEL_LEN];
	const char *ctrl_name;
	bool cmd_cfg_cont_splash = true;

	if (!mdss_is_ready()) {
		pr_err("%s: MDP not probed yet!\n", __func__);
		return -EPROBE_DEFER;
	}

	if (!pdev->dev.of_node) {
		pr_err("DSI driver only supports device tree probe\n");
		return -ENOTSUPP;
	}

	ctrl_pdata = platform_get_drvdata(pdev);
	if (!ctrl_pdata) {
		ctrl_pdata = devm_kzalloc(&pdev->dev,
					  sizeof(struct mdss_dsi_ctrl_pdata),
					  GFP_KERNEL);
		if (!ctrl_pdata) {
			pr_err("%s: FAILED: cannot alloc dsi ctrl\n",
			       __func__);
			rc = -ENOMEM;
			return rc;
		}
		ctrl_pdata->spec_pdata = devm_kzalloc(&pdev->dev,
			sizeof(struct mdss_panel_specific_pdata),
			GFP_KERNEL);
		if (!ctrl_pdata->spec_pdata) {
			pr_err("%s: FAILED: cannot alloc spec pdata\n",
				__func__);
			rc = -ENOMEM;
			goto error_no_mem;
		}
		platform_set_drvdata(pdev, ctrl_pdata);
	}

	ctrl_name = of_get_property(pdev->dev.of_node, "label", NULL);
	if (!ctrl_name)
		pr_info("%s:%d, DSI Ctrl name not specified\n",
			__func__, __LINE__);
	else
		pr_info("%s: DSI Ctrl name = %s\n",
			__func__, ctrl_name);

	rc = of_property_read_u32(pdev->dev.of_node,
				  "cell-index", &index);
	if (rc) {
		dev_err(&pdev->dev,
			"%s: Cell-index not specified, rc=%d\n",
			__func__, rc);
		goto error_no_mem;
	}

	if (index == 0)
		pdev->id = 1;
	else
		pdev->id = 2;

	rc = of_platform_populate(pdev->dev.of_node,
				  NULL, NULL, &pdev->dev);
	if (rc) {
		dev_err(&pdev->dev,
			"%s: failed to add child nodes, rc=%d\n",
			__func__, rc);
		goto error_no_mem;
	}

	/* Parse the regulator information */
	rc = mdss_dsi_get_dt_vreg_data(&pdev->dev,
				       &ctrl_pdata->power_data);
	if (rc) {
		pr_err("%s: failed to get vreg data from dt. rc=%d\n",
		       __func__, rc);
		goto error_vreg;
	}

	/* DSI panels can be different between controllers */
	rc = mdss_dsi_get_panel_cfg(panel_cfg);
	if (!rc)
		/* dsi panel cfg not present */
		pr_warn("%s:%d:dsi specific cfg not present\n",
			__func__, __LINE__);

	/* find panel device node */
	dsi_pan_node = mdss_dsi_find_panel_of_node(pdev, panel_cfg);
	if (!dsi_pan_node) {
		pr_err("%s: can't find panel node %s\n", __func__, panel_cfg);
		goto error_pan_node;
	}

	cmd_cfg_cont_splash = mdss_panel_get_boot_cfg() ? true : false;

	rc = mdss_dsi_panel_init(dsi_pan_node, ctrl_pdata, cmd_cfg_cont_splash);
	if (rc) {
		pr_err("%s: dsi panel init failed\n", __func__);
		goto error_pan_node;
	}

	rc = dsi_panel_device_register(dsi_pan_node, ctrl_pdata);
	if (rc) {
		pr_err("%s: dsi panel dev reg failed\n", __func__);
		goto error_pan_node;
	}

#ifdef CONFIG_FB_MSM_MDSS_SPECIFIC_PANEL
	if (ctrl_pdata->panel_data.panel_info.cont_splash_enabled &&
		ctrl_pdata->spec_pdata->pcc_data.pcc_sts & PCC_STS_UD) {
		ctrl_pdata->pcc_setup(&ctrl_pdata->panel_data);
		ctrl_pdata->spec_pdata->pcc_data.pcc_sts &= ~PCC_STS_UD;
	}
#endif	/* CONFIG_FB_MSM_MDSS_SPECIFIC_PANEL */

	pr_debug("%s: Dsi Ctrl->%d initialized\n", __func__, index);
	return 0;

error_pan_node:
	of_node_put(dsi_pan_node);
error_vreg:
	mdss_dsi_put_dt_vreg_data(&pdev->dev, &ctrl_pdata->power_data);
error_no_mem:
	devm_kfree(&pdev->dev, ctrl_pdata->spec_pdata);
	devm_kfree(&pdev->dev, ctrl_pdata);

	return rc;
}
static unsigned int get_bus_node_device_data(
		struct device_node * const dev_node,
		struct platform_device * const pdev,
		struct msm_bus_node_device_type * const node_device)
{
	node_device->node_info = get_node_info_data(dev_node, pdev);
	if (IS_ERR_OR_NULL(node_device->node_info)) {
		dev_err(&pdev->dev, "Error: Node info missing\n");
		return -ENODATA;
	}
	node_device->ap_owned = of_property_read_bool(dev_node,
							"qcom,ap-owned");

	if (node_device->node_info->is_fab_dev) {
		dev_err(&pdev->dev, "Dev %d\n", node_device->node_info->id);

		if (!node_device->node_info->virt_dev) {
			node_device->fabdev =
				get_fab_device_info(dev_node, pdev);
			if (IS_ERR_OR_NULL(node_device->fabdev)) {
				dev_err(&pdev->dev,
					"Error: Fabric device info missing\n");
				devm_kfree(&pdev->dev, node_device->node_info);
				return -ENODATA;
			}
		}
		node_device->clk[DUAL_CTX].clk = of_clk_get_by_name(dev_node,
							"bus_clk");

		if (IS_ERR_OR_NULL(node_device->clk[DUAL_CTX].clk))
			dev_err(&pdev->dev,
				"%s:Failed to get bus clk for bus%d ctx%d",
				__func__, node_device->node_info->id,
								DUAL_CTX);

		node_device->clk[ACTIVE_CTX].clk = of_clk_get_by_name(dev_node,
							"bus_a_clk");
		if (IS_ERR_OR_NULL(node_device->clk[ACTIVE_CTX].clk))
			dev_err(&pdev->dev,
				"Failed to get bus clk for bus%d ctx%d",
				 node_device->node_info->id, ACTIVE_CTX);

		node_device->qos_clk.clk = of_clk_get_by_name(dev_node,
							"bus_qos_clk");

		if (IS_ERR_OR_NULL(node_device->qos_clk.clk))
			dev_dbg(&pdev->dev,
				"%s:Failed to get bus qos clk for %d",
				__func__, node_device->node_info->id);

		if (msmbus_coresight_init_adhoc(pdev, dev_node))
			dev_warn(&pdev->dev,
				 "Coresight support absent for bus: %d\n",
				  node_device->node_info->id);
	} else {
		node_device->qos_clk.clk = of_clk_get_by_name(dev_node,
							"bus_qos_clk");

		if (IS_ERR_OR_NULL(node_device->qos_clk.clk))
			dev_dbg(&pdev->dev,
				"%s:Failed to get bus qos clk for mas%d",
				__func__, node_device->node_info->id);

		node_device->clk[DUAL_CTX].clk = of_clk_get_by_name(dev_node,
							"node_clk");

		if (IS_ERR_OR_NULL(node_device->clk[DUAL_CTX].clk))
			dev_dbg(&pdev->dev,
				"%s:Failed to get bus clk for bus%d ctx%d",
				__func__, node_device->node_info->id,
								DUAL_CTX);

	}
	return 0;
}
示例#29
0
static int pwm_backlight_probe(struct platform_device *pdev)
{
	struct backlight_properties props;
	struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
	struct backlight_device *bl;
	struct pwm_bl_data *pb;
	struct edp_manager *battery_manager = NULL;
	int ret;

	if (!data) {
		dev_err(&pdev->dev, "failed to find platform data\n");
		return -EINVAL;
	}

	if (data->init) {
		ret = data->init(&pdev->dev);
		if (ret < 0)
			return ret;
	}

	pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);
	if (!pb) {
		dev_err(&pdev->dev, "no memory for state\n");
		ret = -ENOMEM;
		goto err_alloc;
	}

	pb->period = data->pwm_period_ns;
	pb->notify = data->notify;
	pb->notify_after = data->notify_after;
	pb->check_fb = data->check_fb;
	pb->lth_brightness = data->lth_brightness *
		(data->pwm_period_ns / data->max_brightness);
	pb->dev = &pdev->dev;
	pb->display_init = data->init;
	pb->pwm_gpio = data->pwm_gpio;
	pb->edp_brightness_states = data->edp_brightness;

	pb->pwm = pwm_request(data->pwm_id, "backlight");
	if (IS_ERR(pb->pwm)) {
		dev_err(&pdev->dev, "unable to request PWM for backlight\n");
		ret = PTR_ERR(pb->pwm);
		goto err_alloc;
	} else
		dev_dbg(&pdev->dev, "got pwm for backlight\n");

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = data->max_brightness;

	if (gpio_is_valid(pb->pwm_gpio)) {
		ret = gpio_request(pb->pwm_gpio, "disp_bl");
		if (ret)
			dev_err(&pdev->dev, "backlight gpio request failed\n");
	}

	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
				       &pwm_backlight_ops, &props);
	if (IS_ERR(bl)) {
		dev_err(&pdev->dev, "failed to register backlight\n");
		ret = PTR_ERR(bl);
		goto err_bl;
	}

	pb->tegra_pwm_bl_edp_client = devm_kzalloc(&pdev->dev,
			sizeof(struct edp_client), GFP_KERNEL);
	if (IS_ERR_OR_NULL(pb->tegra_pwm_bl_edp_client)) {
		dev_err(&pdev->dev, "could not allocate edp client\n");
		return PTR_ERR(pb->tegra_pwm_bl_edp_client);
	}
	strncpy(pb->tegra_pwm_bl_edp_client->name,
			"backlight", EDP_NAME_LEN - 1);
	pb->tegra_pwm_bl_edp_client->name[EDP_NAME_LEN - 1] = '\0';
	pb->tegra_pwm_bl_edp_client->states = data->edp_states;
	pb->tegra_pwm_bl_edp_client->num_states = TEGRA_PWM_BL_EDP_NUM_STATES;
	pb->tegra_pwm_bl_edp_client->e0_index = TEGRA_PWM_BL_EDP_ZERO;
	pb->tegra_pwm_bl_edp_client->private_data = bl;
	pb->tegra_pwm_bl_edp_client->priority = EDP_MAX_PRIO + 2;
	pb->tegra_pwm_bl_edp_client->throttle = pwm_backlight_edpcb;
	pb->tegra_pwm_bl_edp_client->notify_promotion = pwm_backlight_edpcb;

	battery_manager = edp_get_manager("battery");
	if (!battery_manager) {
		dev_err(&pdev->dev, "unable to get edp manager\n");
	} else {
		ret = edp_register_client(battery_manager,
					pb->tegra_pwm_bl_edp_client);
		if (ret) {
			dev_err(&pdev->dev, "unable to register edp client\n");
		} else {
			ret = edp_update_client_request(
					pb->tegra_pwm_bl_edp_client,
						TEGRA_PWM_BL_EDP_ZERO, NULL);
			if (ret) {
				dev_err(&pdev->dev,
					"unable to set E0 EDP state\n");
				edp_unregister_client(
					pb->tegra_pwm_bl_edp_client);
			} else {
				goto edp_success;
			}
		}
	}

	devm_kfree(&pdev->dev, pb->tegra_pwm_bl_edp_client);
	pb->tegra_pwm_bl_edp_client = NULL;

edp_success:

	bl->props.brightness = data->dft_brightness;
	backlight_update_status(bl);

	if (gpio_is_valid(pb->pwm_gpio))
		gpio_free(pb->pwm_gpio);

	platform_set_drvdata(pdev, bl);
	return 0;

err_bl:
	pwm_free(pb->pwm);
err_alloc:
	if (data->exit)
		data->exit(&pdev->dev);
	return ret;
}
示例#30
0
static int __devinit mdss_dsi_ctrl_probe(struct platform_device *pdev)
{
    int rc = 0;
    u32 index;
    struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;

    if (pdev->dev.of_node) {
        struct resource *mdss_dsi_mres;
        const char *ctrl_name;

        ctrl_pdata = platform_get_drvdata(pdev);
        if (!ctrl_pdata) {
            ctrl_pdata = devm_kzalloc(&pdev->dev,
                                      sizeof(struct mdss_dsi_ctrl_pdata), GFP_KERNEL);
            if (!ctrl_pdata) {
                pr_err("%s: FAILED: cannot alloc dsi ctrl\n",
                       __func__);
                rc = -ENOMEM;
                goto error_no_mem;
            }
            platform_set_drvdata(pdev, ctrl_pdata);
        }

        ctrl_name = of_get_property(pdev->dev.of_node, "label", NULL);
        if (!ctrl_name)
            pr_info("%s:%d, DSI Ctrl name not specified\n",
                    __func__, __LINE__);
        else
            pr_info("%s: DSI Ctrl name = %s\n",
                    __func__, ctrl_name);

        rc = of_property_read_u32(pdev->dev.of_node,
                                  "cell-index", &index);
        if (rc) {
            dev_err(&pdev->dev,
                    "%s: Cell-index not specified, rc=%d\n",
                    __func__, rc);
            goto error_no_mem;
        }

        if (index == 0)
            pdev->id = 1;
        else
            pdev->id = 2;

        mdss_dsi_mres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!mdss_dsi_mres) {
            pr_err("%s:%d unable to get the MDSS resources",
                   __func__, __LINE__);
            rc = -ENOMEM;
            goto error_no_mem;
        }
        if (mdss_dsi_mres) {
            mdss_dsi_base = ioremap(mdss_dsi_mres->start,
                                    resource_size(mdss_dsi_mres));
            if (!mdss_dsi_base) {
                pr_err("%s:%d unable to remap dsi resources",
                       __func__, __LINE__);
                rc = -ENOMEM;
                goto error_no_mem;
            }
        }

        rc = of_platform_populate(pdev->dev.of_node,
                                  NULL, NULL, &pdev->dev);
        if (rc) {
            dev_err(&pdev->dev,
                    "%s: failed to add child nodes, rc=%d\n",
                    __func__, rc);
            goto error_ioremap;
        }

        /* Parse the regulator information */
        rc = mdss_dsi_get_dt_vreg_data(&pdev->dev,
                                       &ctrl_pdata->power_data);
        if (rc) {
            pr_err("%s: failed to get vreg data from dt. rc=%d\n",
                   __func__, rc);
            goto error_vreg;
        }

        pr_debug("%s: Dsi Ctrl->%d initialized\n", __func__, index);
    }

    return 0;

error_ioremap:
    iounmap(mdss_dsi_base);
error_no_mem:
    devm_kfree(&pdev->dev, ctrl_pdata);
error_vreg:
    mdss_dsi_put_dt_vreg_data(&pdev->dev, &ctrl_pdata->power_data);

    return rc;
}