Esempio n. 1
0
static int __devinit qpnp_regulator_probe(struct spmi_device *spmi)
{
	struct qpnp_regulator_platform_data *pdata;
	struct qpnp_regulator *vreg;
	struct regulator_desc *rdesc;
	struct qpnp_regulator_platform_data of_pdata;
	struct regulator_init_data *init_data;
	char *reg_name;
	int rc;
	bool is_dt;

	vreg = kzalloc(sizeof(struct qpnp_regulator), GFP_KERNEL);
	if (!vreg) {
		dev_err(&spmi->dev, "%s: Can't allocate qpnp_regulator\n",
			__func__);
		return -ENOMEM;
	}

	is_dt = of_match_device(spmi_match_table, &spmi->dev);

	/* Check if device tree is in use. */
	if (is_dt) {
		init_data = of_get_regulator_init_data(&spmi->dev,
						       spmi->dev.of_node);
		if (!init_data) {
			dev_err(&spmi->dev, "%s: unable to allocate memory\n",
					__func__);
			kfree(vreg);
			return -ENOMEM;
		}
		memset(&of_pdata, 0,
			sizeof(struct qpnp_regulator_platform_data));
		memcpy(&of_pdata.init_data, init_data,
			sizeof(struct regulator_init_data));

		if (of_get_property(spmi->dev.of_node, "parent-supply", NULL))
			of_pdata.init_data.supply_regulator = "parent";

		rc = qpnp_regulator_get_dt_config(spmi, &of_pdata);
		if (rc) {
			dev_err(&spmi->dev, "%s: DT parsing failed, rc=%d\n",
					__func__, rc);
			kfree(vreg);
			return -ENOMEM;
		}

		pdata = &of_pdata;
	} else {
		pdata = spmi->dev.platform_data;
	}

	if (pdata == NULL) {
		dev_err(&spmi->dev, "%s: no platform data specified\n",
			__func__);
		kfree(vreg);
		return -EINVAL;
	}

	vreg->spmi_dev		= spmi;
	vreg->prev_write_count	= -1;
	vreg->write_count	= 0;
	vreg->base_addr		= pdata->base_addr;
	vreg->enable_time	= pdata->enable_time;
	vreg->system_load	= pdata->system_load;
	vreg->ocp_enable	= pdata->ocp_enable;
	vreg->ocp_enable_time	= pdata->ocp_enable_time;

	rdesc			= &vreg->rdesc;
	rdesc->id		= spmi->ctrl->nr;
	rdesc->owner		= THIS_MODULE;
	rdesc->type		= REGULATOR_VOLTAGE;

	reg_name = kzalloc(strnlen(pdata->init_data.constraints.name,
				MAX_NAME_LEN) + 1, GFP_KERNEL);
	if (!reg_name) {
		dev_err(&spmi->dev, "%s: Can't allocate regulator name\n",
			__func__);
		kfree(vreg);
		return -ENOMEM;
	}
	strlcpy(reg_name, pdata->init_data.constraints.name,
		strnlen(pdata->init_data.constraints.name, MAX_NAME_LEN) + 1);
	rdesc->name = reg_name;

	dev_set_drvdata(&spmi->dev, vreg);

	rc = qpnp_regulator_match(vreg);
	if (rc) {
		vreg_err(vreg, "regulator type unknown, rc=%d\n", rc);
		goto bail;
	}

	if (is_dt && rdesc->ops) {
		/* Fill in ops and mode masks when using device tree. */
		if (rdesc->ops->enable)
			pdata->init_data.constraints.valid_ops_mask
				|= REGULATOR_CHANGE_STATUS;
		if (rdesc->ops->get_voltage)
			pdata->init_data.constraints.valid_ops_mask
				|= REGULATOR_CHANGE_VOLTAGE;
		if (rdesc->ops->get_mode) {
			pdata->init_data.constraints.valid_ops_mask
				|= REGULATOR_CHANGE_MODE
				| REGULATOR_CHANGE_DRMS;
			pdata->init_data.constraints.valid_modes_mask
				= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE;
		}
	}

	rc = qpnp_regulator_init_registers(vreg, pdata);
	if (rc) {
		vreg_err(vreg, "common initialization failed, rc=%d\n", rc);
		goto bail;
	}

	vreg->rdev = regulator_register(rdesc, &spmi->dev,
			&(pdata->init_data), vreg, spmi->dev.of_node);
	if (IS_ERR(vreg->rdev)) {
		rc = PTR_ERR(vreg->rdev);
		vreg_err(vreg, "regulator_register failed, rc=%d\n", rc);
		goto bail;
	}

	qpnp_vreg_show_state(vreg->rdev, QPNP_REGULATOR_ACTION_INIT);

	return 0;

bail:
	if (rc)
		vreg_err(vreg, "probe failed, rc=%d\n", rc);

	kfree(vreg->rdesc.name);
	kfree(vreg);

	return rc;
}
static int __devinit qpnp_regulator_probe(struct spmi_device *spmi)
{
	struct qpnp_regulator_platform_data *pdata;
	struct qpnp_regulator *vreg;
	struct regulator_desc *rdesc;
	struct qpnp_regulator_platform_data of_pdata;
	struct regulator_init_data *init_data;
	char *reg_name;
	int rc;
	bool is_dt;

	vreg = kzalloc(sizeof(struct qpnp_regulator), GFP_KERNEL);
	if (!vreg) {
		dev_err(&spmi->dev, "%s: Can't allocate qpnp_regulator\n",
			__func__);
		return -ENOMEM;
	}

	is_dt = of_match_device(spmi_match_table, &spmi->dev);

	
	if (is_dt) {
		init_data = of_get_regulator_init_data(&spmi->dev,
						       spmi->dev.of_node);
		if (!init_data) {
			dev_err(&spmi->dev, "%s: unable to allocate memory\n",
					__func__);
			kfree(vreg);
			return -ENOMEM;
		}
		memset(&of_pdata, 0,
			sizeof(struct qpnp_regulator_platform_data));
		memcpy(&of_pdata.init_data, init_data,
			sizeof(struct regulator_init_data));

		if (of_get_property(spmi->dev.of_node, "parent-supply", NULL))
			of_pdata.init_data.supply_regulator = "parent";

		rc = qpnp_regulator_get_dt_config(spmi, &of_pdata);
		if (rc) {
			dev_err(&spmi->dev, "%s: DT parsing failed, rc=%d\n",
					__func__, rc);
			kfree(vreg);
			return -ENOMEM;
		}

		pdata = &of_pdata;
	} else {
		pdata = spmi->dev.platform_data;
	}

	if (pdata == NULL) {
		dev_err(&spmi->dev, "%s: no platform data specified\n",
			__func__);
		kfree(vreg);
		return -EINVAL;
	}

	vreg->spmi_dev		= spmi;
	vreg->prev_write_count	= -1;
	vreg->write_count	= 0;
	vreg->base_addr		= pdata->base_addr;
	vreg->enable_time	= pdata->enable_time;
	vreg->system_load	= pdata->system_load;
	vreg->ocp_enable	= pdata->ocp_enable;
	vreg->ocp_irq		= pdata->ocp_irq;
	vreg->ocp_max_retries	= pdata->ocp_max_retries;
	vreg->ocp_retry_delay_ms = pdata->ocp_retry_delay_ms;

	if (vreg->ocp_max_retries == 0)
		vreg->ocp_max_retries = QPNP_VS_OCP_DEFAULT_MAX_RETRIES;
	if (vreg->ocp_retry_delay_ms == 0)
		vreg->ocp_retry_delay_ms = QPNP_VS_OCP_DEFAULT_RETRY_DELAY_MS;

	rdesc			= &vreg->rdesc;
	rdesc->id		= spmi->ctrl->nr;
	rdesc->owner		= THIS_MODULE;
	rdesc->type		= REGULATOR_VOLTAGE;

	reg_name = kzalloc(strnlen(pdata->init_data.constraints.name,
				MAX_NAME_LEN) + 1, GFP_KERNEL);
	if (!reg_name) {
		dev_err(&spmi->dev, "%s: Can't allocate regulator name\n",
			__func__);
		kfree(vreg);
		return -ENOMEM;
	}
	strlcpy(reg_name, pdata->init_data.constraints.name,
		strnlen(pdata->init_data.constraints.name, MAX_NAME_LEN) + 1);
	rdesc->name = reg_name;

	dev_set_drvdata(&spmi->dev, vreg);

	rc = qpnp_regulator_match(vreg);
	if (rc) {
		vreg_err(vreg, "regulator type unknown, rc=%d\n", rc);
		goto bail;
	}

	if (is_dt && rdesc->ops) {
		
		if (rdesc->ops->enable)
			pdata->init_data.constraints.valid_ops_mask
				|= REGULATOR_CHANGE_STATUS;
		if (rdesc->ops->get_voltage)
			pdata->init_data.constraints.valid_ops_mask
				|= REGULATOR_CHANGE_VOLTAGE;
		if (rdesc->ops->get_mode) {
			pdata->init_data.constraints.valid_ops_mask
				|= REGULATOR_CHANGE_MODE
				| REGULATOR_CHANGE_DRMS;
			pdata->init_data.constraints.valid_modes_mask
				= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE;
		}
	}

	rc = qpnp_regulator_init_registers(vreg, pdata);
	if (rc) {
		vreg_err(vreg, "common initialization failed, rc=%d\n", rc);
		goto bail;
	}

	if (vreg->logical_type != QPNP_REGULATOR_LOGICAL_TYPE_VS)
		vreg->ocp_irq = 0;

	if (vreg->ocp_irq) {
		rc = devm_request_irq(&spmi->dev, vreg->ocp_irq,
			qpnp_regulator_vs_ocp_isr, IRQF_TRIGGER_RISING, "ocp",
			vreg);
		if (rc < 0) {
			vreg_err(vreg, "failed to request irq %d, rc=%d\n",
				vreg->ocp_irq, rc);
			goto bail;
		}

		INIT_DELAYED_WORK(&vreg->ocp_work, qpnp_regulator_vs_ocp_work);
	}

	vreg->rdev = regulator_register(rdesc, &spmi->dev,
			&(pdata->init_data), vreg, spmi->dev.of_node);
	if (IS_ERR(vreg->rdev)) {
		rc = PTR_ERR(vreg->rdev);
		if (rc != -EPROBE_DEFER)
			vreg_err(vreg, "regulator_register failed, rc=%d\n",
				rc);
		goto cancel_ocp_work;
	}

	qpnp_vreg_show_state(vreg->rdev, QPNP_REGULATOR_ACTION_INIT);

	return 0;

cancel_ocp_work:
	if (vreg->ocp_irq)
		cancel_delayed_work_sync(&vreg->ocp_work);
bail:
	if (rc && rc != -EPROBE_DEFER)
		vreg_err(vreg, "probe failed, rc=%d\n", rc);

	kfree(vreg->rdesc.name);
	kfree(vreg);

	return rc;
}