Ejemplo n.º 1
0
/**
 * macio_pci_add_devices - Adds sub-devices of mac-io to the device tree
 * @chip: pointer to the macio_chip holding the devices
 * 
 * This function will do the job of extracting devices from the
 * Open Firmware device tree, build macio_dev structures and add
 * them to the Linux device tree.
 * 
 * For now, childs of media-bay are added now as well. This will
 * change rsn though.
 */
static void macio_pci_add_devices(struct macio_chip *chip)
{
	struct device_node *np, *pnode;
	struct macio_dev *rdev, *mdev, *mbdev = NULL, *sdev = NULL;
	struct device *parent = NULL;
	struct resource *root_res = &iomem_resource;
	
	/* Add a node for the macio bus itself */
#ifdef CONFIG_PCI
	if (chip->lbus.pdev) {
		parent = &chip->lbus.pdev->dev;
		root_res = &chip->lbus.pdev->resource[0];
	}
#endif
	pnode = of_node_get(chip->of_node);
	if (pnode == NULL)
		return;

	/* Add macio itself to hierarchy */
	rdev = macio_add_one_device(chip, parent, pnode, NULL, root_res);
	if (rdev == NULL)
		return;
	root_res = &rdev->resource[0];

	/* First scan 1st level */
	for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) {
		if (macio_skip_device(np))
			continue;
		of_node_get(np);
		mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL,
					    root_res);
		if (mdev == NULL)
			of_node_put(np);
		else if (strncmp(np->name, "media-bay", 9) == 0)
			mbdev = mdev;
		else if (strncmp(np->name, "escc", 4) == 0)
			sdev = mdev;
	}

	/* Add media bay devices if any */
	if (mbdev)
		for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np))
			     != NULL;) {
			if (macio_skip_device(np))
				continue;
			of_node_get(np);
			if (macio_add_one_device(chip, &mbdev->ofdev.dev, np,
						 mbdev,  root_res) == NULL)
				of_node_put(np);
		}

	/* Add serial ports if any */
	if (sdev) {
		for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np))
			     != NULL;) {
			if (macio_skip_device(np))
				continue;
			of_node_get(np);
			if (macio_add_one_device(chip, &sdev->ofdev.dev, np,
						 NULL, root_res) == NULL)
				of_node_put(np);
		}
	}
}
Ejemplo n.º 2
0
static void __init pseries_mpic_init_IRQ(void)
{
	struct device_node *np, *old, *cascade = NULL;
        const unsigned int *addrp;
	unsigned long intack = 0;
	const unsigned int *opprop;
	unsigned long openpic_addr = 0;
	unsigned int cascade_irq;
	int naddr, n, i, opplen;
	struct mpic *mpic;

	np = of_find_node_by_path("/");
	naddr = of_n_addr_cells(np);
	opprop = of_get_property(np, "platform-open-pic", &opplen);
	if (opprop != 0) {
		openpic_addr = of_read_number(opprop, naddr);
		printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
	}
	of_node_put(np);

	BUG_ON(openpic_addr == 0);

	/* Setup the openpic driver */
	mpic = mpic_alloc(pSeries_mpic_node, openpic_addr,
			  MPIC_PRIMARY,
			  16, 250, /* isu size, irq count */
			  " MPIC     ");
	BUG_ON(mpic == NULL);

	/* Add ISUs */
	opplen /= sizeof(u32);
	for (n = 0, i = naddr; i < opplen; i += naddr, n++) {
		unsigned long isuaddr = of_read_number(opprop + i, naddr);
		mpic_assign_isu(mpic, n, isuaddr);
	}

	/* All ISUs are setup, complete initialization */
	mpic_init(mpic);

	/* Look for cascade */
	for_each_node_by_type(np, "interrupt-controller")
		if (of_device_is_compatible(np, "chrp,iic")) {
			cascade = np;
			break;
		}
	if (cascade == NULL)
		return;

	cascade_irq = irq_of_parse_and_map(cascade, 0);
	if (cascade_irq == NO_IRQ) {
		printk(KERN_ERR "mpic: failed to map cascade interrupt");
		return;
	}

	/* Check ACK type */
	for (old = of_node_get(cascade); old != NULL ; old = np) {
		np = of_get_parent(old);
		of_node_put(old);
		if (np == NULL)
			break;
		if (strcmp(np->name, "pci") != 0)
			continue;
		addrp = of_get_property(np, "8259-interrupt-acknowledge",
					    NULL);
		if (addrp == NULL)
			continue;
		naddr = of_n_addr_cells(np);
		intack = addrp[naddr-1];
		if (naddr > 1)
			intack |= ((unsigned long)addrp[naddr-2]) << 32;
	}
	if (intack)
		printk(KERN_DEBUG "mpic: PCI 8259 intack at 0x%016lx\n",
		       intack);
	i8259_init(cascade, intack);
	of_node_put(cascade);
	set_irq_chained_handler(cascade_irq, pseries_8259_cascade);
}
Ejemplo n.º 3
0
static int arizona_ldo1_probe(struct platform_device *pdev)
{
	struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
	const struct regulator_desc *desc;
	struct regulator_config config = { };
	struct arizona_ldo1 *ldo1;
	int ret;

	arizona->external_dcvdd = false;

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

	ldo1->arizona = arizona;

	/*
	 * Since the chip usually supplies itself we provide some
	 * default init_data for it.  This will be overridden with
	 * platform data if provided.
	 */
	switch (arizona->type) {
	case WM5102:
	case WM8997:
		desc = &arizona_ldo1_hc;
		ldo1->init_data = arizona_ldo1_dvfs;
		break;
	default:
		desc = &arizona_ldo1;
		ldo1->init_data = arizona_ldo1_default;
		break;
	}

	ldo1->init_data.consumer_supplies = &ldo1->supply;
	ldo1->supply.supply = "DCVDD";
	ldo1->supply.dev_name = dev_name(arizona->dev);

	config.dev = arizona->dev;
	config.driver_data = ldo1;
	config.regmap = arizona->regmap;

	if (IS_ENABLED(CONFIG_OF)) {
		if (!dev_get_platdata(arizona->dev)) {
			ret = arizona_ldo1_of_get_pdata(arizona, &config);
			if (ret < 0)
				return ret;
		}
	}

	config.ena_gpio = arizona->pdata.ldoena;

	if (arizona->pdata.ldo1)
		config.init_data = arizona->pdata.ldo1;
	else
		config.init_data = &ldo1->init_data;

	/*
	 * LDO1 can only be used to supply DCVDD so if it has no
	 * consumers then DCVDD is supplied externally.
	 */
	if (config.init_data->num_consumer_supplies == 0)
		arizona->external_dcvdd = true;

	ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config);
	if (IS_ERR(ldo1->regulator)) {
		ret = PTR_ERR(ldo1->regulator);
		dev_err(arizona->dev, "Failed to register LDO1 supply: %d\n",
			ret);
		return ret;
	}

	of_node_put(config.of_node);

	platform_set_drvdata(pdev, ldo1);

	return 0;
}
static int spear_cpufreq_driver_init(void)
{
	struct device_node *np;
	const struct property *prop;
	struct cpufreq_frequency_table *freq_tbl;
	const __be32 *val;
	int cnt, i, ret;

	np = of_cpu_device_node_get(0);
	if (!np) {
		pr_err("No cpu node found");
		return -ENODEV;
	}

	if (of_property_read_u32(np, "clock-latency",
				&spear_cpufreq.transition_latency))
		spear_cpufreq.transition_latency = CPUFREQ_ETERNAL;

	prop = of_find_property(np, "cpufreq_tbl", NULL);
	if (!prop || !prop->value) {
		pr_err("Invalid cpufreq_tbl");
		ret = -ENODEV;
		goto out_put_node;
	}

	cnt = prop->length / sizeof(u32);
	val = prop->value;

	freq_tbl = kmalloc(sizeof(*freq_tbl) * (cnt + 1), GFP_KERNEL);
	if (!freq_tbl) {
		ret = -ENOMEM;
		goto out_put_node;
	}

	for (i = 0; i < cnt; i++) {
		freq_tbl[i].driver_data = i;
		freq_tbl[i].frequency = be32_to_cpup(val++);
	}

	freq_tbl[i].driver_data = i;
	freq_tbl[i].frequency = CPUFREQ_TABLE_END;

	spear_cpufreq.freq_tbl = freq_tbl;

	of_node_put(np);

	spear_cpufreq.clk = clk_get(NULL, "cpu_clk");
	if (IS_ERR(spear_cpufreq.clk)) {
		pr_err("Unable to get CPU clock\n");
		ret = PTR_ERR(spear_cpufreq.clk);
		goto out_put_mem;
	}

	ret = cpufreq_register_driver(&spear_cpufreq_driver);
	if (!ret)
		return 0;

	pr_err("failed register driver: %d\n", ret);
	clk_put(spear_cpufreq.clk);

out_put_mem:
	kfree(freq_tbl);
	return ret;

out_put_node:
	of_node_put(np);
	return ret;
}
static int32_t msm_led_get_dt_data(struct device_node *of_node,
		struct msm_led_flash_ctrl_t *fctrl)
{
	int32_t rc = 0, i = 0;
	struct msm_camera_gpio_conf *gconf = NULL;
	struct device_node *flash_src_node = NULL;
	struct msm_camera_sensor_board_info *flashdata = NULL;
	uint32_t count = 0;
	uint16_t *gpio_array = NULL;
	uint16_t gpio_array_size = 0;
	uint32_t id_info[3];

	CDBG("called\n");

	if (!of_node) {
		pr_err("of_node NULL\n");
		return -EINVAL;
	}

	fctrl->flashdata = kzalloc(sizeof(
		struct msm_camera_sensor_board_info),
		GFP_KERNEL);
	if (!fctrl->flashdata) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		return -ENOMEM;
	}

	flashdata = fctrl->flashdata;

	flashdata->sensor_init_params = kzalloc(sizeof(
		struct msm_sensor_init_params), GFP_KERNEL);
	if (!flashdata->sensor_init_params) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		return -ENOMEM;
	}

	rc = of_property_read_u32(of_node, "cell-index", &fctrl->subdev_id);
	if (rc < 0) {
		pr_err("failed\n");
		return -EINVAL;
	}

	CDBG("subdev id %d\n", fctrl->subdev_id);

	rc = of_property_read_string(of_node, "qcom,flash-name",
		&flashdata->sensor_name);
	CDBG("%s qcom,flash-name %s, rc %d\n", __func__,
		flashdata->sensor_name, rc);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto ERROR1;
	}

	rc = of_property_read_u32(of_node, "qcom,cci-master",
		&fctrl->cci_i2c_master);
	CDBG("%s qcom,cci-master %d, rc %d\n", __func__, fctrl->cci_i2c_master,
		rc);
	if (rc < 0) {
		/* Set default master 0 */
		fctrl->cci_i2c_master = MASTER_0;
		rc = 0;
	}

	if (of_get_property(of_node, "qcom,flash-source", &count)) {
		count /= sizeof(uint32_t);
		CDBG("count %d\n", count);
		if (count > MAX_LED_TRIGGERS) {
			pr_err("failed\n");
			return -EINVAL;
		}
		for (i = 0; i < count; i++) {
			flash_src_node = of_parse_phandle(of_node,
				"qcom,flash-source", i);
			if (!flash_src_node) {
				pr_err("flash_src_node NULL\n");
				continue;
			}

			rc = of_property_read_string(flash_src_node,
				"linux,default-trigger",
				&fctrl->flash_trigger_name[i]);
			if (rc < 0) {
				pr_err("failed\n");
				of_node_put(flash_src_node);
				continue;
			}

			CDBG("default trigger %s\n",
				 fctrl->flash_trigger_name[i]);

			rc = of_property_read_u32(flash_src_node,
				"qcom,max-current",
				&fctrl->flash_op_current[i]);
			if (rc < 0) {
				pr_err("failed rc %d\n", rc);
				of_node_put(flash_src_node);
				continue;
			}

			of_node_put(flash_src_node);

			CDBG("max_current[%d] %d\n",
				i, fctrl->flash_op_current[i]);

			led_trigger_register_simple(
				fctrl->flash_trigger_name[i],
				&fctrl->flash_trigger[i]);
		}

	} else { /*Handle LED Flash Ctrl by GPIO*/
		flashdata->gpio_conf =
			 kzalloc(sizeof(struct msm_camera_gpio_conf),
				 GFP_KERNEL);
		if (!flashdata->gpio_conf) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			rc = -ENOMEM;
			return rc;
		}
		gconf = flashdata->gpio_conf;

		gpio_array_size = of_gpio_count(of_node);
		CDBG("%s gpio count %d\n", __func__, gpio_array_size);

		if (gpio_array_size) {
			gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size,
				GFP_KERNEL);
			if (!gpio_array) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				rc = -ENOMEM;
				goto ERROR4;
			}
			for (i = 0; i < gpio_array_size; i++) {
				gpio_array[i] = of_get_gpio(of_node, i);
				CDBG("%s gpio_array[%d] = %d\n", __func__, i,
					gpio_array[i]);
			}

			rc = msm_sensor_get_dt_gpio_req_tbl(of_node, gconf,
				gpio_array, gpio_array_size);
			if (rc < 0) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				goto ERROR4;
			}

			rc = msm_sensor_get_dt_gpio_set_tbl(of_node, gconf,
				gpio_array, gpio_array_size);
			if (rc < 0) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				goto ERROR5;
			}

			rc = msm_flash_init_gpio_pin_tbl(of_node, gconf,
				gpio_array, gpio_array_size, fctrl);
			if (rc < 0) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				goto ERROR6;
			}
		}

		flashdata->slave_info =
			kzalloc(sizeof(struct msm_camera_slave_info),
				GFP_KERNEL);
		if (!flashdata->slave_info) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			rc = -ENOMEM;
			goto ERROR8;
		}

		rc = of_property_read_u32_array(of_node, "qcom,slave-id",
			id_info, 3);
		if (rc < 0) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			goto ERROR9;
		}
		/* Fix me - Currently for I2c framework is looking for
		7-bit device node entry in dts. But the camera led framework
		for i2c slaves is looking for 8 bit address.So added a shift.
		Need to fix this.*/
		if (fctrl->flash_device_type == MSM_CAMERA_I2C_DEVICE) {
			fctrl->flashdata->slave_info->sensor_slave_addr =
			id_info[0] << 1;
		} else {
			fctrl->flashdata->slave_info->sensor_slave_addr
			 = id_info[0];
		}

		fctrl->flashdata->slave_info->sensor_id_reg_addr = id_info[1];
		fctrl->flashdata->slave_info->sensor_id = id_info[2];

		kfree(gpio_array);
		return rc;
ERROR9:
		kfree(fctrl->flashdata->slave_info);
ERROR8:
		kfree(fctrl->flashdata->gpio_conf->gpio_num_info);
ERROR6:
		kfree(gconf->cam_gpio_set_tbl);
ERROR5:
		kfree(gconf->cam_gpio_req_tbl);
ERROR4:
		kfree(gconf);
ERROR1:
		kfree(fctrl->flashdata);
		kfree(gpio_array);
	}
	return rc;
}
static int32_t msm_led_cci_query_ic(struct msm_led_cci_ctrl_t *fctrl, struct device_node *of_node)
{
    int32_t i, rc, ret = 0;
	uint32_t count = 0;
    uint16_t chip_id_reg, chip_id;
    bool matched = false;
    struct regulator *cci_regulator = NULL;
	struct msm_camera_i2c_client *cci_i2c_client = NULL;
	struct device_node *flash_src_node = NULL;
    
	CDBG("called\n");

    if (!of_get_property(of_node, "qcom,flash-cci-source", &count)) {
        pr_err("can not get qcom,flash-source\n");
        return -EINVAL;
    }
    count /= sizeof(uint32_t);
	CDBG("count %d\n", count);

    for (i=0; i<count && !matched; i++) {
        fctrl->led_info = NULL;
        /*get led info form dt*/
        flash_src_node = of_parse_phandle(of_node,
            "qcom,flash-cci-source", i);
        if (!flash_src_node) {
            continue;
        }
        rc = msm_led_cci_get_dt_led_data(fctrl, flash_src_node, i);
        if (rc < 0) {
            pr_err("get dt data failed\n");
            of_node_put(flash_src_node);
            goto FAILED;
        }
        of_node_put(flash_src_node);

        /*get power*/
        cci_regulator = regulator_get(&fctrl->pdev->dev, fctrl->led_info->regulator_name);
        if (IS_ERR_OR_NULL(cci_regulator)) {
            pr_err("regulator_get failed\n");
            goto FAILED;
        }
        /*enable power*/
        rc = regulator_enable(cci_regulator);
        if (rc < 0) {
            pr_err("regulator_enable failed\n");
            regulator_put(cci_regulator);
            goto FAILED;
        }
        /*request gpio*/
        rc = gpio_request(fctrl->led_info->gpio_en, "msm_led_cci");
        if (rc < 0) {
            pr_err("get gpio failed\n");
        }
        rc = gpio_direction_output(fctrl->led_info->gpio_en, 1);
        if (rc < 0)
            pr_err("set gpio to 1 failed\n");
        

        /*init cci*/
        fctrl->flash_i2c_client->cci_client->sid = fctrl->led_info->slave_id;
        fctrl->flash_i2c_client->cci_client->cci_i2c_master =
            fctrl->led_info->cci_master;
        cci_i2c_client = fctrl->flash_i2c_client;
        rc = cci_i2c_client->i2c_func_tbl->i2c_util(
    			cci_i2c_client, MSM_CCI_INIT);
    	if (rc < 0) {
    	    pr_err("cci init failed\n");
    	}
    	/*read id*/
    	chip_id_reg = fctrl->led_info->chip_id_reg;
        rc = cci_i2c_client->i2c_func_tbl->i2c_read(
    			cci_i2c_client, chip_id_reg, &chip_id, MSM_CAMERA_I2C_BYTE_DATA);
    	if (rc < 0) {
    	    pr_err("cci read failed\n");
            kzfree(fctrl->led_info);
            ret = -EINVAL;
    	} else {
            if (chip_id == fctrl->led_info->chip_id) {
        	    pr_err("chip id match: 0x%x", chip_id);
        	    matched = true;
        	    ret = 0;
    	    } else {
        	    pr_err("chip id not match: 0x%x", chip_id);
        	    if (fctrl->led_info) {
        	        kzfree(fctrl->led_info);
        	    }
        	    ret = -EINVAL;
    	    }
    	}
    	/*release cci*/
        rc = fctrl->flash_i2c_client->i2c_func_tbl->i2c_util(
            fctrl->flash_i2c_client, MSM_CCI_RELEASE);
    	if (rc < 0) {
    	    pr_err("cci release failed\n");
    	}

        /*release gpio*/
        rc = gpio_direction_output(fctrl->led_info->gpio_en, 0);
        if (!rc)
            gpio_free(fctrl->led_info->gpio_en);
        else
            pr_err("set gpio to 0 failed\n");
        
    	/*disable power*/
        rc = regulator_disable(cci_regulator);
        if (rc < 0) {
            pr_err("regulator_disable failed\n");
            regulator_put(cci_regulator);
            goto FAILED;
        }
        regulator_put(cci_regulator);
    }

    return ret;
FAILED:
    if (fctrl->led_info) {
        kzfree(fctrl->led_info);
        fctrl->led_info = NULL;
    }
    return -EINVAL;
}
Ejemplo n.º 7
0
static int32_t msm_led_get_dt_data(struct device_node *of_node,
		struct msm_led_flash_ctrl_t *fctrl)
{
	int32_t rc = 0, i = 0;
	struct msm_camera_gpio_conf *gconf = NULL;
	struct device_node *flash_src_node = NULL;
	struct msm_camera_sensor_board_info *flashdata = NULL;
	struct msm_camera_power_ctrl_t *power_info = NULL;
	uint32_t count = 0;
	uint16_t *gpio_array = NULL;
	uint16_t gpio_array_size = 0;
	uint32_t id_info[3];

	CDBG("called\n");

	if (!of_node) {
		pr_err("of_node NULL\n");
		return -EINVAL;
	}

	fctrl->flashdata = kzalloc(sizeof(
		struct msm_camera_sensor_board_info),
		GFP_KERNEL);
	if (!fctrl->flashdata) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		return -ENOMEM;
	}

	flashdata = fctrl->flashdata;
	power_info = &flashdata->power_info;

	rc = of_property_read_u32(of_node, "cell-index", &fctrl->subdev_id);
	if (rc < 0) {
		pr_err("failed\n");
		return -EINVAL;
	}

	CDBG("subdev id %d\n", fctrl->subdev_id);

	rc = of_property_read_string(of_node, "label",
		&flashdata->sensor_name);
	CDBG("%s label %s, rc %d\n", __func__,
		flashdata->sensor_name, rc);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto ERROR1;
	}

	rc = of_property_read_u32(of_node, "qcom,cci-master",
		&fctrl->cci_i2c_master);
	CDBG("%s qcom,cci-master %d, rc %d\n", __func__, fctrl->cci_i2c_master,
		rc);
	if (rc < 0) {
		/* Set default master 0 */
		fctrl->cci_i2c_master = MASTER_0;
		rc = 0;
	}

	fctrl->pinctrl_info.use_pinctrl = false;
	fctrl->pinctrl_info.use_pinctrl = of_property_read_bool(of_node,
						"qcom,enable_pinctrl");
	if (of_get_property(of_node, "qcom,flash-source", &count)) {
		count /= sizeof(uint32_t);
		CDBG("count %d\n", count);
		if (count > MAX_LED_TRIGGERS) {
			pr_err("failed\n");
			return -EINVAL;
		}
		for (i = 0; i < count; i++) {
			flash_src_node = of_parse_phandle(of_node,
				"qcom,flash-source", i);
			if (!flash_src_node) {
				pr_err("flash_src_node NULL\n");
				continue;
			}

			rc = of_property_read_string(flash_src_node,
				"linux,default-trigger",
				&fctrl->flash_trigger_name[i]);
			if (rc < 0) {
				pr_err("failed\n");
				of_node_put(flash_src_node);
				continue;
			}

			CDBG("default trigger %s\n",
				 fctrl->flash_trigger_name[i]);

			rc = of_property_read_u32(flash_src_node,
				"qcom,max-current",
				&fctrl->flash_op_current[i]);
			if (rc < 0) {
				pr_err("failed rc %d\n", rc);
				of_node_put(flash_src_node);
				continue;
			}

			of_node_put(flash_src_node);

			CDBG("max_current[%d] %d\n",
				i, fctrl->flash_op_current[i]);

			led_trigger_register_simple(
				fctrl->flash_trigger_name[i],
				&fctrl->flash_trigger[i]);
		}

	} else { /*Handle LED Flash Ctrl by GPIO*/
		power_info->gpio_conf =
			 kzalloc(sizeof(struct msm_camera_gpio_conf),
				 GFP_KERNEL);
		if (!power_info->gpio_conf) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			rc = -ENOMEM;
			return rc;
		}
		gconf = power_info->gpio_conf;

		gpio_array_size = of_gpio_count(of_node);
		CDBG("%s gpio count %d\n", __func__, gpio_array_size);

		if (gpio_array_size) {
			gpio_array = kzalloc(sizeof(uint16_t) * gpio_array_size,
				GFP_KERNEL);
			if (!gpio_array) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				rc = -ENOMEM;
				goto ERROR4;
			}
			for (i = 0; i < gpio_array_size; i++) {
				gpio_array[i] = of_get_gpio(of_node, i);
				CDBG("%s gpio_array[%d] = %d\n", __func__, i,
					gpio_array[i]);
			}

			rc = msm_camera_get_dt_gpio_req_tbl(of_node, gconf,
				gpio_array, gpio_array_size);
			if (rc < 0) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				goto ERROR4;
			}

			rc = msm_camera_get_dt_gpio_set_tbl(of_node, gconf,
				gpio_array, gpio_array_size);
			if (rc < 0) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				goto ERROR5;
			}

			rc = msm_camera_init_gpio_pin_tbl(of_node, gconf,
				gpio_array, gpio_array_size);
			if (rc < 0) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				goto ERROR6;
			}
		}

		/* Read the max current for an LED if present */
		if (of_get_property(of_node, "qcom,max-current", &count)) {
			count /= sizeof(uint32_t);

			if (count > MAX_LED_TRIGGERS) {
				pr_err("failed\n");
				rc = -EINVAL;
				goto ERROR8;
			}

			fctrl->flash_num_sources = count;
			fctrl->torch_num_sources = count;

			rc = of_property_read_u32_array(of_node,
				"qcom,max-current",
				fctrl->flash_max_current, count);
			if (rc < 0) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				goto ERROR8;
			}

			for (; count < MAX_LED_TRIGGERS; count++)
				fctrl->flash_max_current[count] = 0;

			for (count = 0; count < MAX_LED_TRIGGERS; count++)
				fctrl->torch_max_current[count] =
					fctrl->flash_max_current[count] >> 1;
		}

		/* Read the max duration for an LED if present */
		if (of_get_property(of_node, "qcom,max-duration", &count)) {
			count /= sizeof(uint32_t);

			if (count > MAX_LED_TRIGGERS) {
				pr_err("failed\n");
				rc = -EINVAL;
				goto ERROR8;
			}

			rc = of_property_read_u32_array(of_node,
				"qcom,max-duration",
				fctrl->flash_max_duration, count);
			if (rc < 0) {
				pr_err("%s failed %d\n", __func__, __LINE__);
				goto ERROR8;
			}

			for (; count < MAX_LED_TRIGGERS; count++)
				fctrl->flash_max_duration[count] = 0;
		}

		flashdata->slave_info =
			kzalloc(sizeof(struct msm_camera_slave_info),
				GFP_KERNEL);
		if (!flashdata->slave_info) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			rc = -ENOMEM;
			goto ERROR8;
		}

		rc = of_property_read_u32_array(of_node, "qcom,slave-id",
			id_info, 3);
		if (rc < 0) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			goto ERROR9;
		}
		fctrl->flashdata->slave_info->sensor_slave_addr = id_info[0];
		fctrl->flashdata->slave_info->sensor_id_reg_addr = id_info[1];
		fctrl->flashdata->slave_info->sensor_id = id_info[2];

		kfree(gpio_array);
		return rc;
ERROR9:
		kfree(fctrl->flashdata->slave_info);
ERROR8:
		kfree(fctrl->flashdata->power_info.gpio_conf->gpio_num_info);
ERROR6:
		kfree(gconf->cam_gpio_set_tbl);
ERROR5:
		kfree(gconf->cam_gpio_req_tbl);
ERROR4:
		kfree(gconf);
ERROR1:
		kfree(fctrl->flashdata);
		kfree(gpio_array);
	}
static int32_t msm_flash_get_pmic_source_info(
	struct device_node *of_node,
	struct msm_flash_ctrl_t *fctrl)
{
	int32_t rc = 0;
	uint32_t count = 0, i = 0;
	struct device_node *flash_src_node = NULL;
	struct device_node *torch_src_node = NULL;

	if (of_get_property(of_node, "qcom,flash-source", &count)) {
		count /= sizeof(uint32_t);
		CDBG("count %d\n", count);
		if (count > MAX_LED_TRIGGERS) {
			pr_err("invalid count\n");
			return -EINVAL;
		}
		fctrl->flash_num_sources = count;
		CDBG("%s:%d flash_num_sources = %d",
			__func__, __LINE__, fctrl->flash_num_sources);
		for (i = 0; i < count; i++) {
			flash_src_node = of_parse_phandle(of_node,
				"qcom,flash-source", i);
			if (!flash_src_node) {
				pr_err("flash_src_node NULL\n");
				continue;
			}

			rc = of_property_read_string(flash_src_node,
				"qcom,default-led-trigger",
				&fctrl->flash_trigger_name[i]);
			if (rc < 0) {
				rc = of_property_read_string(flash_src_node,
					"linux,default-trigger",
					&fctrl->flash_trigger_name[i]);
				if (rc < 0) {
					pr_err("default-trigger read failed\n");
					of_node_put(flash_src_node);
					continue;
				}
			}

			CDBG("default trigger %s\n",
				fctrl->flash_trigger_name[i]);

			/* Read operational-current */
			rc = of_property_read_u32(flash_src_node,
				"qcom,current",
				&fctrl->flash_op_current[i]);
			if (rc < 0) {
				pr_err("current: read failed\n");
				of_node_put(flash_src_node);
				continue;
			}

			/* Read max-current */
			rc = of_property_read_u32(flash_src_node,
				"qcom,max-current",
				&fctrl->flash_max_current[i]);
			if (rc < 0) {
				pr_err("current: read failed\n");
				of_node_put(flash_src_node);
				continue;
			}

			of_node_put(flash_src_node);

			CDBG("max_current[%d] %d\n",
				i, fctrl->flash_op_current[i]);

			led_trigger_register_simple(
				fctrl->flash_trigger_name[i],
				&fctrl->flash_trigger[i]);
		}
		if (fctrl->flash_driver_type == FLASH_DRIVER_DEFAULT)
			fctrl->flash_driver_type = FLASH_DRIVER_PMIC;
		CDBG("%s:%d fctrl->flash_driver_type = %d", __func__, __LINE__,
			fctrl->flash_driver_type);
	}

	if (of_get_property(of_node, "qcom,torch-source", &count)) {
		count /= sizeof(uint32_t);
		CDBG("count %d\n", count);
		if (count > MAX_LED_TRIGGERS) {
			pr_err("invalid count\n");
			return -EINVAL;
		}
		fctrl->torch_num_sources = count;
		CDBG("%s:%d torch_num_sources = %d",
			__func__, __LINE__, fctrl->torch_num_sources);
		for (i = 0; i < count; i++) {
			torch_src_node = of_parse_phandle(of_node,
				"qcom,torch-source", i);
			if (!torch_src_node) {
				pr_err("torch_src_node NULL\n");
				continue;
			}

			rc = of_property_read_string(torch_src_node,
				"qcom,default-led-trigger",
				&fctrl->torch_trigger_name[i]);
			if (rc < 0) {
				rc = of_property_read_string(torch_src_node,
					"linux,default-trigger",
					&fctrl->torch_trigger_name[i]);
				if (rc < 0) {
					pr_err("default-trigger read failed\n");
					of_node_put(torch_src_node);
					continue;
				}
			}

			CDBG("default trigger %s\n",
				fctrl->torch_trigger_name[i]);

			/* Read operational-current */
			rc = of_property_read_u32(torch_src_node,
				"qcom,current",
				&fctrl->torch_op_current[i]);
			if (rc < 0) {
				pr_err("current: read failed\n");
				of_node_put(torch_src_node);
				continue;
			}

			/* Read max-current */
			rc = of_property_read_u32(torch_src_node,
				"qcom,max-current",
				&fctrl->torch_max_current[i]);
			if (rc < 0) {
				pr_err("current: read failed\n");
				of_node_put(torch_src_node);
				continue;
			}

			of_node_put(torch_src_node);

			CDBG("max_current[%d] %d\n",
				i, fctrl->torch_op_current[i]);

			led_trigger_register_simple(
				fctrl->torch_trigger_name[i],
				&fctrl->torch_trigger[i]);
		}
		if (fctrl->flash_driver_type == FLASH_DRIVER_DEFAULT)
			fctrl->flash_driver_type = FLASH_DRIVER_PMIC;
		CDBG("%s:%d fctrl->flash_driver_type = %d", __func__, __LINE__,
			fctrl->flash_driver_type);
	}

	return 0;
}
Ejemplo n.º 9
0
static int sprd_asoc_i2s_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &all_i2s_card;
	struct device_node *node = pdev->dev.of_node;
	card->dev = &pdev->dev;
	if (node) {
		int i;
		int dai_count;
		struct device_node *pcm_node;
		struct device_node *codec_node;

		if (snd_soc_of_parse_card_name(card, "sprd,model")) {
			pr_err("ERR:Card name is not provided\n");
			return -ENODEV;
		}

		pcm_node = of_parse_phandle(node, "sprd,pcm", 0);
		if (!pcm_node) {
			pr_err("ERR:PCM node is not provided\n");
			return -EINVAL;
		}

		codec_node = of_parse_phandle(node, "sprd,codec", 0);
		if (!codec_node) {
			pr_err("ERR:CODEC node is not provided\n");
			of_node_put(pcm_node);
			return -EINVAL;
		}

		if (!of_get_property(node, "sprd,i2s", &dai_count))
			return -ENOENT;
		dai_count /= sizeof(((struct property *) 0)->length);

		sp_asoc_pr_dbg("Register I2S from DTS count is %d\n",
			       dai_count);

		card->dai_link =
		    devm_kzalloc(&pdev->dev,
				 dai_count * sizeof(struct snd_soc_dai_link),
				 GFP_KERNEL);
		card->num_links = dai_count;

		for (i = 0; i < card->num_links; i++) {
			char uni_name[NAME_SIZE] = { 0 };
			char uni_sname[NAME_SIZE] = { 0 };
			struct device_node *dai_node;
			dai_node = of_parse_phandle(node, "sprd,i2s", i);
			if (dai_node)
				sp_asoc_pr_dbg("Register I2S dai node is %s\n",
				       dai_node->full_name);
			else
				pr_err("ERR:I2S dai node is not provided\n");
			card->dai_link[i] = all_i2s_dai[0];
			snprintf(uni_name, NAME_SIZE, "%s.%d",
				 all_i2s_dai[0].name, i);
			snprintf(uni_sname, NAME_SIZE, "%s.%d",
				 all_i2s_dai[0].stream_name, i);
			card->dai_link[i].name = kstrdup(uni_name, GFP_KERNEL);
			card->dai_link[i].stream_name =
			    kstrdup(uni_sname, GFP_KERNEL);
			card->dai_link[i].cpu_dai_name = NULL;
			card->dai_link[i].cpu_of_node = dai_node;
			card->dai_link[i].platform_name = NULL;
			card->dai_link[i].platform_of_node = pcm_node;
			card->dai_link[i].codec_name = NULL;
			card->dai_link[i].codec_of_node = codec_node;
			of_node_put(dai_node);
		}
		of_node_put(pcm_node);
		of_node_put(codec_node);
	}
	return snd_soc_register_card(card);
}
Ejemplo n.º 10
0
static int32_t msm_led_trigger_probe(struct platform_device *pdev)
{
	int32_t rc = 0, i = 0;
	struct device_node *of_node = pdev->dev.of_node;
	struct device_node *flash_src_node = NULL;
	uint32_t count = 0;

	CDBG("called\n");

	if (!of_node) {
		pr_err("of_node NULL\n");
		return -EINVAL;
	}

	fctrl.pdev = pdev;

	rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
	if (rc < 0) {
		pr_err("failed\n");
		return -EINVAL;
	}
	CDBG("pdev id %d\n", pdev->id);

	rc = of_property_read_string(of_node, "flash-driver",
		&fctrl.flash_driver);
	pr_info("[%s] Flash driver is %s\n", __FUNCTION__,
		fctrl.flash_driver);
	if (rc < 0) {
		pr_err("%s failed %d\n", __FUNCTION__, __LINE__);
		return -EINVAL;
	}

	if (of_get_property(of_node, "qcom,flash-source", &count)) {
		count /= sizeof(uint32_t);
		CDBG("count %d\n", count);
		if (count > MAX_LED_TRIGGERS) {
			pr_err("failed\n");
			return -EINVAL;
		}
		for (i = 0; i < count; i++) {
			flash_src_node = of_parse_phandle(of_node,
				"qcom,flash-source", i);
			if (!flash_src_node) {
				pr_err("flash_src_node NULL\n");
				continue;
			}

			rc = of_property_read_string(flash_src_node,
				"linux,default-trigger",
				&fctrl.led_trigger_name[i]);
			if (rc < 0) {
				pr_err("failed\n");
				of_node_put(flash_src_node);
				continue;
			}

			CDBG("default trigger %s\n", fctrl.led_trigger_name[i]);

			rc = of_property_read_u32(flash_src_node,
				"qcom,max-current", &fctrl.max_current[i]);
			if (rc < 0) {
				pr_err("failed rc %d\n", rc);
				of_node_put(flash_src_node);
				continue;
			}

			of_node_put(flash_src_node);

			CDBG("max_current[%d] %d\n", i, fctrl.max_current[i]);

			led_trigger_register_simple(fctrl.led_trigger_name[i],
				&fctrl.led_trigger[i]);
		}
	}
	rc = msm_led_flash_create_v4lsubdev(pdev, &fctrl);

	return rc;
}
Ejemplo n.º 11
0
static int32_t msm_led_trigger_probe(struct platform_device *pdev)
{
	int32_t rc = 0, i = 0;
	struct device_node *of_node = pdev->dev.of_node;
	struct device_node *flash_src_node = NULL;

	CDBG("called\n");

	if (!of_node) {
		pr_err("of_node NULL\n");
		return -EINVAL;
	}

	fctrl.pdev = pdev;

	rc = of_property_read_u32(of_node, "cell-index", &pdev->id);
	if (rc < 0) {
		pr_err("failed\n");
		return -EINVAL;
	}
	CDBG("pdev id %d\n", pdev->id);

	if (of_get_property(of_node, "qcom,flash-source", &fctrl.num_sources)) {
		fctrl.num_sources /= sizeof(uint32_t);
		CDBG("count %d\n", fctrl.num_sources);
		if (fctrl.num_sources > MAX_LED_TRIGGERS) {
			pr_err("failed\n");
			return -EINVAL;
		}
		for (i = 0; i < fctrl.num_sources; i++) {
			flash_src_node = of_parse_phandle(of_node,
				"qcom,flash-source", i);
			if (!flash_src_node) {
				pr_err("flash_src_node NULL\n");
				continue;
			}

			rc = of_property_read_string(flash_src_node,
				"linux,default-trigger",
				&fctrl.flash_trigger_name[i]);
			if (rc < 0) {
				pr_err("failed\n");
				of_node_put(flash_src_node);
				continue;
			}

			CDBG("default trigger %s\n",
				fctrl.flash_trigger_name[i]);

			rc = of_property_read_u32(flash_src_node,
				"qcom,current", &fctrl.flash_op_current[i]);
			if (rc < 0) {
				pr_err("failed rc %d\n", rc);
				of_node_put(flash_src_node);
				continue;
			}

			of_node_put(flash_src_node);

			CDBG("max_current[%d] %d\n", i,
				fctrl.flash_op_current[i]);

			led_trigger_register_simple(fctrl.flash_trigger_name[i],
				&fctrl.flash_trigger[i]);
		}
		/* Torch source */
		flash_src_node = of_parse_phandle(of_node, "qcom,torch-source",
			0);
		if (flash_src_node) {
			rc = of_property_read_string(flash_src_node,
				"linux,default-trigger",
				&fctrl.torch_trigger_name);
			if (rc < 0) {
				pr_err("failed\n");
			} else {
				CDBG("default trigger %s\n",
					fctrl.torch_trigger_name);

				rc = of_property_read_u32(flash_src_node,
					"qcom,current",
					&fctrl.torch_op_current);
				if (rc < 0) {
					pr_err("failed rc %d\n", rc);
				} else {
					CDBG("torch max_current %d\n",
						fctrl.torch_op_current);

					led_trigger_register_simple(
						fctrl.torch_trigger_name,
						&fctrl.torch_trigger);
				}
			}

			of_node_put(flash_src_node);
		}
	}
	rc = msm_led_flash_create_v4lsubdev(pdev, &fctrl);
	return rc;
}
Ejemplo n.º 12
0
/* ************************************************************************
 *
 * Setup the architecture
 *
 */
static void __init mpc83xx_km_setup_arch(void)
{
	struct device_node *np;

	if (ppc_md.progress)
		ppc_md.progress("kmpbec83xx_setup_arch()", 0);

#ifdef CONFIG_PCI
	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
		mpc83xx_add_bridge(np);
#endif

#ifdef CONFIG_QUICC_ENGINE
	qe_reset();

	np = of_find_node_by_name(NULL, "par_io");
	if (np != NULL) {
		par_io_init(np);
		of_node_put(np);

		for_each_node_by_name(np, "spi")
			par_io_of_config(np);

		for (np = NULL; (np = of_find_node_by_name(np, "ucc")) != NULL;)
			par_io_of_config(np);
	}

	np = of_find_compatible_node(NULL, "network", "ucc_geth");
	if (np != NULL) {
		uint svid;

		/* handle mpc8360ea rev.2.1 erratum 2: RGMII Timing */
		svid = mfspr(SPRN_SVR);
		if (SVR_REV(svid) == 0x0021) {
			struct	device_node *np_par;
			struct	resource res;
			void	__iomem *base;
			int	ret;

			np_par = of_find_node_by_name(NULL, "par_io");
			if (np_par == NULL) {
				printk(KERN_WARNING "%s couldn;t find par_io node\n",
					__func__);
				return;
			}
			/* Map Parallel I/O ports registers */
			ret = of_address_to_resource(np_par, 0, &res);
			if (ret) {
				printk(KERN_WARNING "%s couldn;t map par_io registers\n",
					__func__);
				return;
			}
			base = ioremap(res.start, resource_size(&res));

			/*
			 * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2)
			 * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1)
			 */
			setbits32((base + 0xa8), 0x0c003000);

			/*
			 * IMMR + 0x14AC[20:27] = 10101010
			 * (data delay for both UCC's)
			 */
			clrsetbits_be32((base + 0xac), 0xff0, 0xaa0);
			iounmap(base);
			of_node_put(np_par);
		}
		of_node_put(np);
	}
#endif				/* CONFIG_QUICC_ENGINE */
}
Ejemplo n.º 13
0
/**
 * of_get_named_gpio_flags() - Get a GPIO number and flags to use with GPIO API
 * @np:		device node to get GPIO from
 * @propname:	property name containing gpio specifier(s)
 * @index:	index of the GPIO
 * @flags:	a flags pointer to fill in
 *
 * Returns GPIO number to use with Linux generic GPIO API, or one of the errno
 * value on the error condition. If @flags is not NULL the function also fills
 * in flags for the GPIO.
 */
int of_get_named_gpio_flags(struct device_node *np, const char *propname,
			   int index, enum of_gpio_flags *flags)
{
	/* Return -EPROBE_DEFER to support probe() functions to be called
	 * later when the GPIO actually becomes available
	 */
	struct gg_data gg_data = { .flags = flags, .out_gpio = -EPROBE_DEFER };
	int ret;

	/* .of_xlate might decide to not fill in the flags, so clear it. */
	if (flags)
		*flags = 0;

	ret = of_parse_phandle_with_args(np, propname, "#gpio-cells", index,
					 &gg_data.gpiospec);
	if (ret) {
		pr_debug("%s: can't parse gpios property\n", __func__);
		return ret;
	}

	gpiochip_find(&gg_data, of_gpiochip_find_and_xlate);

	of_node_put(gg_data.gpiospec.np);
	pr_debug("%s exited with status %d\n", __func__, gg_data.out_gpio);
	return gg_data.out_gpio;
}
EXPORT_SYMBOL(of_get_named_gpio_flags);

/**
 * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags
 * @gc:		pointer to the gpio_chip structure
 * @np:		device node of the GPIO chip
 * @gpio_spec:	gpio specifier as found in the device tree
 * @flags:	a flags pointer to fill in
 *
 * This is simple translation function, suitable for the most 1:1 mapped
 * gpio chips. This function performs only one sanity check: whether gpio
 * is less than ngpios (that is specified in the gpio_chip).
 */
int of_gpio_simple_xlate(struct gpio_chip *gc,
			 const struct of_phandle_args *gpiospec, u32 *flags)
{
	/*
	 * We're discouraging gpio_cells < 2, since that way you'll have to
	 * write your own xlate function (that will have to retrive the GPIO
	 * number and the flags from a single gpio cell -- this is possible,
	 * but not recommended).
	 */
	if (gc->of_gpio_n_cells < 2) {
		WARN_ON(1);
		return -EINVAL;
	}

	if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
		return -EINVAL;

	if (gpiospec->args[0] >= gc->ngpio)
		return -EINVAL;

	if (flags)
		*flags = gpiospec->args[1];

	return gpiospec->args[0];
}
EXPORT_SYMBOL(of_gpio_simple_xlate);

/**
 * of_mm_gpiochip_add - Add memory mapped GPIO chip (bank)
 * @np:		device node of the GPIO chip
 * @mm_gc:	pointer to the of_mm_gpio_chip allocated structure
 *
 * To use this function you should allocate and fill mm_gc with:
 *
 * 1) In the gpio_chip structure:
 *    - all the callbacks
 *    - of_gpio_n_cells
 *    - of_xlate callback (optional)
 *
 * 3) In the of_mm_gpio_chip structure:
 *    - save_regs callback (optional)
 *
 * If succeeded, this function will map bank's memory and will
 * do all necessary work for you. Then you'll able to use .regs
 * to manage GPIOs from the callbacks.
 */
int of_mm_gpiochip_add(struct device_node *np,
		       struct of_mm_gpio_chip *mm_gc)
{
	int ret = -ENOMEM;
	struct gpio_chip *gc = &mm_gc->gc;

	gc->label = kstrdup(np->full_name, GFP_KERNEL);
	if (!gc->label)
		goto err0;

	mm_gc->regs = of_iomap(np, 0);
	if (!mm_gc->regs)
		goto err1;

	gc->base = -1;

	if (mm_gc->save_regs)
		mm_gc->save_regs(mm_gc);

	mm_gc->gc.of_node = np;

	ret = gpiochip_add(gc);
	if (ret)
		goto err2;

	return 0;
err2:
	iounmap(mm_gc->regs);
err1:
	kfree(gc->label);
err0:
	pr_err("%s: GPIO chip registration failed with status %d\n",
	       np->full_name, ret);
	return ret;
}
Ejemplo n.º 14
0
unsigned int cpm_pic_init(void)
{
	struct device_node *np = NULL;
	struct resource res;
	unsigned int sirq = 0, hwirq, eirq;
	int ret;

	pr_debug("cpm_pic_init\n");

	np = of_find_compatible_node(NULL, NULL, "fsl,cpm1-pic");
	if (np == NULL)
		np = of_find_compatible_node(NULL, "cpm-pic", "CPM");
	if (np == NULL) {
		printk(KERN_ERR "CPM PIC init: can not find cpm-pic node\n");
		return sirq;
	}

	ret = of_address_to_resource(np, 0, &res);
	if (ret)
		goto end;

	cpic_reg = ioremap(res.start, resource_size(&res));
	if (cpic_reg == NULL)
		goto end;

	sirq = irq_of_parse_and_map(np, 0);
	if (!sirq)
		goto end;

	/* Initialize the CPM interrupt controller. */
	hwirq = (unsigned int)virq_to_hw(sirq);
	out_be32(&cpic_reg->cpic_cicr,
	    (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
		((hwirq/2) << 13) | CICR_HP_MASK);

	out_be32(&cpic_reg->cpic_cimr, 0);

	cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL);
	if (cpm_pic_host == NULL) {
		printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
		sirq = 0;
		goto end;
	}

	/* Install our own error handler. */
	np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
	if (np == NULL)
		np = of_find_node_by_type(NULL, "cpm");
	if (np == NULL) {
		printk(KERN_ERR "CPM PIC init: can not find cpm node\n");
		goto end;
	}

	eirq = irq_of_parse_and_map(np, 0);
	if (!eirq)
		goto end;

	if (setup_irq(eirq, &cpm_error_irqaction))
		printk(KERN_ERR "Could not allocate CPM error IRQ!");

	setbits32(&cpic_reg->cpic_cicr, CICR_IEN);

end:
	of_node_put(np);
	return sirq;
}
Ejemplo n.º 15
0
/**
 * axienet_mdio_setup - MDIO setup function
 * @lp:		Pointer to axienet local data structure.
 * @np:		Pointer to device node
 *
 * Return:	0 on success, -ETIMEDOUT on a timeout, -ENOMEM when
 *		mdiobus_alloc (to allocate memory for mii bus structure) fails.
 *
 * Sets up the MDIO interface by initializing the MDIO clock and enabling the
 * MDIO interface in hardware. Register the MDIO interface.
 **/
int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np)
{
	int ret;
	u32 clk_div, host_clock;
	struct mii_bus *bus;
	struct resource res;
	struct device_node *np1;

	/* clk_div can be calculated by deriving it from the equation:
	 * fMDIO = fHOST / ((1 + clk_div) * 2)
	 *
	 * Where fMDIO <= 2500000, so we get:
	 * fHOST / ((1 + clk_div) * 2) <= 2500000
	 *
	 * Then we get:
	 * 1 / ((1 + clk_div) * 2) <= (2500000 / fHOST)
	 *
	 * Then we get:
	 * 1 / (1 + clk_div) <= ((2500000 * 2) / fHOST)
	 *
	 * Then we get:
	 * 1 / (1 + clk_div) <= (5000000 / fHOST)
	 *
	 * So:
	 * (1 + clk_div) >= (fHOST / 5000000)
	 *
	 * And finally:
	 * clk_div >= (fHOST / 5000000) - 1
	 *
	 * fHOST can be read from the flattened device tree as property
	 * "clock-frequency" from the CPU
	 */

	np1 = of_find_node_by_name(NULL, "cpu");
	if (!np1) {
		netdev_warn(lp->ndev, "Could not find CPU device node.\n");
		netdev_warn(lp->ndev,
			    "Setting MDIO clock divisor to default %d\n",
			    DEFAULT_CLOCK_DIVISOR);
		clk_div = DEFAULT_CLOCK_DIVISOR;
		goto issue;
	}
	if (of_property_read_u32(np1, "clock-frequency", &host_clock)) {
		netdev_warn(lp->ndev, "clock-frequency property not found.\n");
		netdev_warn(lp->ndev,
			    "Setting MDIO clock divisor to default %d\n",
			    DEFAULT_CLOCK_DIVISOR);
		clk_div = DEFAULT_CLOCK_DIVISOR;
		of_node_put(np1);
		goto issue;
	}

	clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1;
	/* If there is any remainder from the division of
	 * fHOST / (MAX_MDIO_FREQ * 2), then we need to add
	 * 1 to the clock divisor or we will surely be above 2.5 MHz
	 */
	if (host_clock % (MAX_MDIO_FREQ * 2))
		clk_div++;

	netdev_dbg(lp->ndev,
		   "Setting MDIO clock divisor to %u/%u Hz host clock.\n",
		   clk_div, host_clock);

	of_node_put(np1);
issue:
	axienet_iow(lp, XAE_MDIO_MC_OFFSET,
		    (((u32) clk_div) | XAE_MDIO_MC_MDIOEN_MASK));

	ret = axienet_mdio_wait_until_ready(lp);
	if (ret < 0)
		return ret;

	bus = mdiobus_alloc();
	if (!bus)
		return -ENOMEM;

	np1 = of_get_parent(lp->phy_node);
	of_address_to_resource(np1, 0, &res);
	snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
		 (unsigned long long) res.start);

	bus->priv = lp;
	bus->name = "Xilinx Axi Ethernet MDIO";
	bus->read = axienet_mdio_read;
	bus->write = axienet_mdio_write;
	bus->parent = lp->dev;
	lp->mii_bus = bus;

	ret = of_mdiobus_register(bus, np1);
	if (ret) {
		mdiobus_free(bus);
		return ret;
	}
	return 0;
}
Ejemplo n.º 16
0
static void drm_release_of(struct device *dev, void *data)
{
	of_node_put(data);
}
static int32_t msm_sensor_fill_eeprom_subdevid_by_name(
				struct msm_sensor_ctrl_t *s_ctrl)
{
	int32_t rc = 0;
	const char *eeprom_name;
	struct device_node *src_node = NULL;
	uint32_t val = 0, count = 0, eeprom_name_len;
	int i;
	int32_t *eeprom_subdev_id;
	struct  msm_sensor_info_t *sensor_info;
	struct device_node *of_node = s_ctrl->of_node;
	const void *p;

	if (!s_ctrl->sensordata->eeprom_name || !of_node)
		return -EINVAL;

	eeprom_name_len = strlen(s_ctrl->sensordata->eeprom_name);
	if (eeprom_name_len >= MAX_SENSOR_NAME)
		return -EINVAL;

	sensor_info = s_ctrl->sensordata->sensor_info;
	eeprom_subdev_id = &sensor_info->subdev_id[SUB_MODULE_EEPROM];
	/*
	 * string for eeprom name is valid, set sudev id to -1
	 *  and try to found new id
	 */
	*eeprom_subdev_id = -1;

	if (0 == eeprom_name_len)
		return 0;

	CDBG("Try to find eeprom subdev for %s\n",
			s_ctrl->sensordata->eeprom_name);
	p = of_get_property(of_node, "qcom,eeprom-src", &count);
	if (!p || !count)
		return 0;

	count /= sizeof(uint32_t);
	for (i = 0; i < count; i++) {
		eeprom_name = NULL;
		src_node = of_parse_phandle(of_node, "qcom,eeprom-src", i);
		if (!src_node) {
			pr_err("eeprom src node NULL\n");
			continue;
		}
		rc = of_property_read_string(src_node, "qcom,eeprom-name",
			&eeprom_name);
		if (rc < 0) {
			pr_err("failed\n");
			of_node_put(src_node);
			continue;
		}
		if (strcmp(eeprom_name, s_ctrl->sensordata->eeprom_name))
			continue;

		rc = of_property_read_u32(src_node, "cell-index", &val);

		CDBG("%s qcom,eeprom cell index %d, rc %d\n", __func__,
			val, rc);
		if (rc < 0) {
			pr_err("failed\n");
			of_node_put(src_node);
			continue;
		}

		*eeprom_subdev_id = val;
		CDBG("Done. Eeprom subdevice id is %d\n", val);
		of_node_put(src_node);
		src_node = NULL;
		break;
	}

	return rc;
}
Ejemplo n.º 18
0
/*
 * Interrupt setup and service.  Interrrupts on the holly come
 * from the four external INT pins, PCI interrupts are routed via
 * PCI interrupt control registers, it generates internal IRQ23
 *
 * Interrupt routing on the Holly Board:
 * TSI108:PB_INT[0] -> CPU0:INT#
 * TSI108:PB_INT[1] -> CPU0:MCP#
 * TSI108:PB_INT[2] -> N/C
 * TSI108:PB_INT[3] -> N/C
 */
static void __init holly_init_IRQ(void)
{
	struct mpic *mpic;
	phys_addr_t mpic_paddr = 0;
	struct device_node *tsi_pic;
#ifdef CONFIG_PCI
	unsigned int cascade_pci_irq;
	struct device_node *tsi_pci;
	struct device_node *cascade_node = NULL;
#endif

	tsi_pic = of_find_node_by_type(NULL, "open-pic");
	if (tsi_pic) {
		unsigned int size;
		const void *prop = of_get_property(tsi_pic, "reg", &size);
		mpic_paddr = of_translate_address(tsi_pic, prop);
	}

	if (mpic_paddr == 0) {
		printk(KERN_ERR "%s: No tsi108 PIC found !\n", __func__);
		return;
	}

	pr_debug("%s: tsi108 pic phys_addr = 0x%x\n", __func__, (u32) mpic_paddr);

	mpic = mpic_alloc(tsi_pic, mpic_paddr,
			MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
			MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108,
			24,
			NR_IRQS-4, /* num_sources used */
			"Tsi108_PIC");

	BUG_ON(mpic == NULL);

	mpic_assign_isu(mpic, 0, mpic_paddr + 0x100);

	mpic_init(mpic);

#ifdef CONFIG_PCI
	tsi_pci = of_find_node_by_type(NULL, "pci");
	if (tsi_pci == NULL) {
		printk(KERN_ERR "%s: No tsi108 pci node found !\n", __func__);
		return;
	}

	cascade_node = of_find_node_by_type(NULL, "pic-router");
	if (cascade_node == NULL) {
		printk(KERN_ERR "%s: No tsi108 pci cascade node found !\n", __func__);
		return;
	}

	cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
	pr_debug("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__, (u32) cascade_pci_irq);
	tsi108_pci_int_init(cascade_node);
	set_irq_data(cascade_pci_irq, mpic);
	set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
#endif
	/* Configure MPIC outputs to CPU0 */
	tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
	of_node_put(tsi_pic);
}
Ejemplo n.º 19
0
static int __init opal_init(void)
{
    struct device_node *np, *consoles;
    const __be32 *irqs;
    int rc, i, irqlen;

    opal_node = of_find_node_by_path("/ibm,opal");
    if (!opal_node) {
        pr_warn("opal: Node not found\n");
        return -ENODEV;
    }

    /* Register OPAL consoles if any ports */
    if (firmware_has_feature(FW_FEATURE_OPALv2))
        consoles = of_find_node_by_path("/ibm,opal/consoles");
    else
        consoles = of_node_get(opal_node);
    if (consoles) {
        for_each_child_of_node(consoles, np) {
            if (strcmp(np->name, "serial"))
                continue;
            of_platform_device_create(np, NULL, NULL);
        }
        of_node_put(consoles);
    }

    /* Find all OPAL interrupts and request them */
    irqs = of_get_property(opal_node, "opal-interrupts", &irqlen);
    pr_debug("opal: Found %d interrupts reserved for OPAL\n",
             irqs ? (irqlen / 4) : 0);
    opal_irq_count = irqlen / 4;
    opal_irqs = kzalloc(opal_irq_count * sizeof(unsigned int), GFP_KERNEL);
    for (i = 0; irqs && i < (irqlen / 4); i++, irqs++) {
        unsigned int hwirq = be32_to_cpup(irqs);
        unsigned int irq = irq_create_mapping(NULL, hwirq);
        if (irq == NO_IRQ) {
            pr_warning("opal: Failed to map irq 0x%x\n", hwirq);
            continue;
        }
        rc = request_irq(irq, opal_interrupt, 0, "opal", NULL);
        if (rc)
            pr_warning("opal: Error %d requesting irq %d"
                       " (0x%x)\n", rc, irq, hwirq);
        opal_irqs[i] = irq;
    }

    /* Create "opal" kobject under /sys/firmware */
    rc = opal_sysfs_init();
    if (rc == 0) {
        /* Setup dump region interface */
        opal_dump_region_init();
        /* Setup error log interface */
        rc = opal_elog_init();
        /* Setup code update interface */
        opal_flash_init();
        /* Setup platform dump extract interface */
        opal_platform_dump_init();
        /* Setup system parameters interface */
        opal_sys_param_init();
        /* Setup message log interface. */
        opal_msglog_init();
    }

    return 0;
}
static void __init mmi_load_panel_from_dt(void)
{
	struct device_node *node;
	int i;
	int found_index = -1;

	if (!strlen(panel_name)) {
		pr_debug("%s: No UTAG for panel name, search in devtree\n",
								__func__);
		load_panel_name_from_dt();
	} else
		pr_info("%s: panel_name =%s is set by UTAG\n",
							__func__, panel_name);

	node = search_panel_from_dt();
	if (!node) {
		// Lookup the panel name in our secondary data table
		i = 0;
		pr_info(">>> i = %d\n", i);
		while ((mmi_disp_info_list[i].name != NULL) && (found_index == -1)) {
			if (!strncmp(panel_name, mmi_disp_info_list[i].name, strlen(panel_name))) {
				pr_info(">>> PANEL EXTRA DATA FOUND!!! [%s]\n", panel_name);
				found_index = i;
			}
			i++;
		}
		pr_info(">>> found_index = %d\n", found_index);
		if (found_index == -1) {
			pr_info(">>> PANEL EXTRA DATA NOT FOUND!!! [%s]\n", panel_name);
			return;
		}
		memcpy(&mmi_disp_info, &mmi_disp_info_list[found_index], sizeof(mmi_disp_info));
		pr_info("%s: partial_mode_supported %d\n", __func__,
			mmi_disp_info.partial_mode_supported);

		if (mmi_disp_info.partial_mode_supported) {
			panel_gpio_init(&mmi_disp_info.mipi_mux_select);
			if (gpio_export(mmi_disp_info.mipi_mux_select.handle, 0))
				pr_err("%s: failed to export mipi_d0_sel\n", __func__);
		}

		print_mmi_disp_data();
		return;
	}
	if (of_property_read_u32(node, "disp_intf", &mmi_disp_info.disp_intf))
		pr_err("%s: no panel interface setting. disp_intf=%d\n",
					__func__, mmi_disp_info.disp_intf);

	load_disp_reset_info_from_dt(node);
	load_disp_regs_info_from_dt(node);
	load_disp_pin_info_from_dt(node, &mmi_disp_info.mipi_mux_select,
		"mipi_d0_sel", 1);
	mmi_disp_info.partial_mode_supported =
		ZERO_IF_NEG(load_disp_value(node, "partial_mode_supported"));
	mmi_disp_info.quickdraw_enabled =
		ZERO_IF_NEG(load_disp_value(node, "quickdraw_enabled"));
	pr_debug("%s: partial_mode_supported %d\n", __func__,
		mmi_disp_info.partial_mode_supported);

	if (mmi_disp_info.partial_mode_supported) {
		panel_gpio_init(&mmi_disp_info.mipi_mux_select);
		if (gpio_export(mmi_disp_info.mipi_mux_select.handle, 0))
			pr_err("%s: failed to export mipi_d0_sel\n", __func__);
	}

	mmi_disp_info.prevent_pwr_off =
		ZERO_IF_NEG(load_disp_value(node, "prevent_pwr_off"));
	pr_debug("%s: prevent_pwr_off %d\n", __func__,
		mmi_disp_info.prevent_pwr_off);

	load_disp_dsi_freq_from_dt(node);

	print_mmi_disp_data();

	of_node_put(node);
}
Ejemplo n.º 21
0
static int imx_spdif_audio_probe(struct platform_device *pdev)
{
	struct device_node *spdif_np, *np = pdev->dev.of_node;
	struct imx_spdif_data *data;
	int ret = 0, num_links = 0;

	spdif_np = of_parse_phandle(np, "spdif-controller", 0);
	if (!spdif_np) {
		dev_err(&pdev->dev, "failed to find spdif-controller\n");
		ret = -EINVAL;
		goto end;
	}

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		ret = -ENOMEM;
		goto end;
	}

	if (of_property_read_bool(np, "spdif-out")) {
		data->dai[num_links].name = "S/PDIF TX";
		data->dai[num_links].stream_name = "S/PDIF PCM Playback";
		data->dai[num_links].codec_dai_name = "dit-hifi";
		data->dai[num_links].codec_name = "spdif-dit";
		data->dai[num_links].cpu_of_node = spdif_np;
		data->dai[num_links].platform_of_node = spdif_np;
		num_links++;

		data->txdev = platform_device_register_simple("spdif-dit", -1, NULL, 0);
		if (IS_ERR(data->txdev)) {
			ret = PTR_ERR(data->txdev);
			dev_err(&pdev->dev, "register dit failed: %d\n", ret);
			goto end;
		}
	}

	if (of_property_read_bool(np, "spdif-in")) {
		data->dai[num_links].name = "S/PDIF RX";
		data->dai[num_links].stream_name = "S/PDIF PCM Capture";
		data->dai[num_links].codec_dai_name = "dir-hifi";
		data->dai[num_links].codec_name = "spdif-dir";
		data->dai[num_links].cpu_of_node = spdif_np;
		data->dai[num_links].platform_of_node = spdif_np;
		num_links++;

		data->rxdev = platform_device_register_simple("spdif-dir", -1, NULL, 0);
		if (IS_ERR(data->rxdev)) {
			ret = PTR_ERR(data->rxdev);
			dev_err(&pdev->dev, "register dir failed: %d\n", ret);
			goto error_dit;
		}
	}

	if (!num_links) {
		dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n");
		goto error_dir;
	}

	data->card.dev = &pdev->dev;
	data->card.num_links = num_links;
	data->card.dai_link = data->dai;

	ret = snd_soc_of_parse_card_name(&data->card, "model");
	if (ret)
		goto error_dir;

	platform_set_drvdata(pdev, &data->card);
	snd_soc_card_set_drvdata(&data->card, data);

	ret = snd_soc_register_card(&data->card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret);
		goto error_dir;
	}

	goto end;

error_dir:
	if (data->rxdev)
		platform_device_unregister(data->rxdev);
error_dit:
	if (data->txdev)
		platform_device_unregister(data->txdev);
end:
	if (spdif_np)
		of_node_put(spdif_np);

	return ret;
}
Ejemplo n.º 22
0
/* create encoder */
struct drm_encoder *xilinx_drm_encoder_create(struct drm_device *drm)
{
	struct xilinx_drm_encoder *encoder;
	struct device_node *sub_node;
	struct i2c_driver *i2c_driver;
	struct drm_i2c_encoder_driver *drm_i2c_driver;
	struct device_driver *device_driver;
	struct platform_driver *platform_driver;
	struct drm_platform_encoder_driver *drm_platform_driver;
	int ret = 0;

	encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL);
	if (!encoder)
		return ERR_PTR(-ENOMEM);

	encoder->dpms = DRM_MODE_DPMS_OFF;

	/* initialize encoder */
	encoder->slave.base.possible_crtcs = 1;
	ret = drm_encoder_init(drm, &encoder->slave.base,
			       &xilinx_drm_encoder_funcs,
			       DRM_MODE_ENCODER_TMDS);
	if (ret) {
		DRM_ERROR("failed to initialize drm encoder\n");
		return ERR_PTR(ret);
	}

	drm_encoder_helper_add(&encoder->slave.base,
			       &xilinx_drm_encoder_helper_funcs);

	/* get slave encoder */
	sub_node = of_parse_phandle(drm->dev->of_node, "xlnx,encoder-slave", 0);
	if (!sub_node) {
		DRM_ERROR("failed to get an encoder slave node\n");
		return ERR_PTR(-ENODEV);
	}

	/* initialize slave encoder */
	encoder->i2c_slv = of_find_i2c_device_by_node(sub_node);
	if (encoder->i2c_slv) {
		i2c_driver = to_i2c_driver(encoder->i2c_slv->dev.driver);
		drm_i2c_driver = to_drm_i2c_encoder_driver(i2c_driver);
		if (!drm_i2c_driver) {
			DRM_ERROR("failed to initialize i2c slave\n");
			ret = -EPROBE_DEFER;
			goto err_out;
		}

		ret = drm_i2c_driver->encoder_init(encoder->i2c_slv, drm,
						   &encoder->slave);
	} else {
		encoder->platform_slv = of_find_device_by_node(sub_node);
		if (!encoder->platform_slv) {
			DRM_DEBUG_KMS("failed to get an encoder slv\n");
			return ERR_PTR(-EPROBE_DEFER);
		}

		device_driver = encoder->platform_slv->dev.driver;
		if (!device_driver) {
			DRM_DEBUG_KMS("failed to get device driver\n");
			return ERR_PTR(-EPROBE_DEFER);
		}

		platform_driver = to_platform_driver(device_driver);
		drm_platform_driver =
			to_drm_platform_encoder_driver(platform_driver);
		if (!drm_platform_driver) {
			DRM_ERROR("failed to initialize platform slave\n");
			ret = -EPROBE_DEFER;
			goto err_out;
		}

		ret = drm_platform_driver->encoder_init(encoder->platform_slv,
							drm,
							&encoder->slave);
	}

	of_node_put(sub_node);

	if (ret) {
		DRM_ERROR("failed to initialize encoder slave\n");
		goto err_out;
	}

	if (!encoder->slave.slave_funcs) {
		DRM_ERROR("there's no encoder slave function\n");
		ret = -ENODEV;
		goto err_out;
	}

	return &encoder->slave.base;

err_out:
	return ERR_PTR(ret);
}
Ejemplo n.º 23
0
/* Parse port node and register as a sub-device any sensor specified there. */
static int fimc_md_parse_port_node(struct fimc_md *fmd,
				   struct device_node *port,
				   unsigned int index)
{
	struct device_node *rem, *ep, *np;
	struct fimc_source_info *pd;
	struct v4l2_of_endpoint endpoint;
	int ret;
	u32 val;

	pd = &fmd->sensor[index].pdata;

	/* Assume here a port node can have only one endpoint node. */
	ep = of_get_next_child(port, NULL);
	if (!ep)
		return 0;

	v4l2_of_parse_endpoint(ep, &endpoint);
	if (WARN_ON(endpoint.port == 0) || index >= FIMC_MAX_SENSORS)
		return -EINVAL;

	pd->mux_id = (endpoint.port - 1) & 0x1;

	rem = v4l2_of_get_remote_port_parent(ep);
	of_node_put(ep);
	if (rem == NULL) {
		v4l2_info(&fmd->v4l2_dev, "Remote device at %s not found\n",
							ep->full_name);
		return 0;
	}
	if (!of_property_read_u32(rem, "samsung,camclk-out", &val))
		pd->clk_id = val;

	if (!of_property_read_u32(rem, "clock-frequency", &val))
		pd->clk_frequency = val;

	if (pd->clk_frequency == 0) {
		v4l2_err(&fmd->v4l2_dev, "Wrong clock frequency at node %s\n",
			 rem->full_name);
		of_node_put(rem);
		return -EINVAL;
	}

	if (fimc_input_is_parallel(endpoint.port)) {
		if (endpoint.bus_type == V4L2_MBUS_PARALLEL)
			pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_601;
		else
			pd->sensor_bus_type = FIMC_BUS_TYPE_ITU_656;
		pd->flags = endpoint.bus.parallel.flags;
	} else if (fimc_input_is_mipi_csi(endpoint.port)) {
		/*
		 * MIPI CSI-2: only input mux selection and
		 * the sensor's clock frequency is needed.
		 */
		pd->sensor_bus_type = FIMC_BUS_TYPE_MIPI_CSI2;
	} else {
		v4l2_err(&fmd->v4l2_dev, "Wrong port id (%u) at node %s\n",
			 endpoint.port, rem->full_name);
	}
	/*
	 * For FIMC-IS handled sensors, that are placed under i2c-isp device
	 * node, FIMC is connected to the FIMC-IS through its ISP Writeback
	 * input. Sensors are attached to the FIMC-LITE hostdata interface
	 * directly or through MIPI-CSIS, depending on the external media bus
	 * used. This needs to be handled in a more reliable way, not by just
	 * checking parent's node name.
	 */
	np = of_get_parent(rem);

	if (np && !of_node_cmp(np->name, "i2c-isp"))
		pd->fimc_bus_type = FIMC_BUS_TYPE_ISP_WRITEBACK;
	else
		pd->fimc_bus_type = pd->sensor_bus_type;

	ret = fimc_md_of_add_sensor(fmd, rem, index);
	of_node_put(rem);

	return ret;
}
Ejemplo n.º 24
0
static int amd_xgbe_phy_probe(struct phy_device *phydev)
{
	struct amd_xgbe_phy_priv *priv;
	struct platform_device *phy_pdev;
	struct device *dev, *phy_dev;
	unsigned int phy_resnum, phy_irqnum;
	int ret;

	if (!phydev->bus || !phydev->bus->parent)
		return -EINVAL;

	dev = phydev->bus->parent;

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

	priv->pdev = to_platform_device(dev);
	priv->adev = ACPI_COMPANION(dev);
	priv->dev = dev;
	priv->phydev = phydev;
	mutex_init(&priv->an_mutex);
	INIT_WORK(&priv->an_irq_work, amd_xgbe_an_irq_work);
	INIT_WORK(&priv->an_work, amd_xgbe_an_state_machine);

	if (!priv->adev || acpi_disabled) {
		struct device_node *bus_node;
		struct device_node *phy_node;

		bus_node = priv->dev->of_node;
		phy_node = of_parse_phandle(bus_node, "phy-handle", 0);
		if (!phy_node) {
			dev_err(dev, "unable to parse phy-handle\n");
			ret = -EINVAL;
			goto err_priv;
		}

		phy_pdev = of_find_device_by_node(phy_node);
		of_node_put(phy_node);

		if (!phy_pdev) {
			dev_err(dev, "unable to obtain phy device\n");
			ret = -EINVAL;
			goto err_priv;
		}

		phy_resnum = 0;
		phy_irqnum = 0;
	} else {
		/* In ACPI, the XGBE and PHY resources are the grouped
		 * together with the PHY resources at the end
		 */
		phy_pdev = priv->pdev;
		phy_resnum = amd_xgbe_phy_resource_count(phy_pdev,
							 IORESOURCE_MEM) - 3;
		phy_irqnum = amd_xgbe_phy_resource_count(phy_pdev,
							 IORESOURCE_IRQ) - 1;
	}
	phy_dev = &phy_pdev->dev;

	/* Get the device mmio areas */
	priv->rxtx_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
					       phy_resnum++);
	priv->rxtx_regs = devm_ioremap_resource(dev, priv->rxtx_res);
	if (IS_ERR(priv->rxtx_regs)) {
		dev_err(dev, "rxtx ioremap failed\n");
		ret = PTR_ERR(priv->rxtx_regs);
		goto err_put;
	}

	priv->sir0_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
					       phy_resnum++);
	priv->sir0_regs = devm_ioremap_resource(dev, priv->sir0_res);
	if (IS_ERR(priv->sir0_regs)) {
		dev_err(dev, "sir0 ioremap failed\n");
		ret = PTR_ERR(priv->sir0_regs);
		goto err_rxtx;
	}

	priv->sir1_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
					       phy_resnum++);
	priv->sir1_regs = devm_ioremap_resource(dev, priv->sir1_res);
	if (IS_ERR(priv->sir1_regs)) {
		dev_err(dev, "sir1 ioremap failed\n");
		ret = PTR_ERR(priv->sir1_regs);
		goto err_sir0;
	}

	/* Get the auto-negotiation interrupt */
	ret = platform_get_irq(phy_pdev, phy_irqnum);
	if (ret < 0) {
		dev_err(dev, "platform_get_irq failed\n");
		goto err_sir1;
	}
	priv->an_irq = ret;

	/* Get the device speed set property */
	ret = device_property_read_u32(phy_dev, XGBE_PHY_SPEEDSET_PROPERTY,
				       &priv->speed_set);
	if (ret) {
		dev_err(dev, "invalid %s property\n",
			XGBE_PHY_SPEEDSET_PROPERTY);
		goto err_sir1;
	}

	switch (priv->speed_set) {
	case AMD_XGBE_PHY_SPEEDSET_1000_10000:
	case AMD_XGBE_PHY_SPEEDSET_2500_10000:
		break;
	default:
		dev_err(dev, "invalid %s property\n",
			XGBE_PHY_SPEEDSET_PROPERTY);
		ret = -EINVAL;
		goto err_sir1;
	}

	if (device_property_present(phy_dev, XGBE_PHY_BLWC_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_PHY_BLWC_PROPERTY,
						     priv->serdes_blwc,
						     XGBE_PHY_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_PHY_BLWC_PROPERTY);
			goto err_sir1;
		}
	} else {
		memcpy(priv->serdes_blwc, amd_xgbe_phy_serdes_blwc,
		       sizeof(priv->serdes_blwc));
	}

	if (device_property_present(phy_dev, XGBE_PHY_CDR_RATE_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_PHY_CDR_RATE_PROPERTY,
						     priv->serdes_cdr_rate,
						     XGBE_PHY_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_PHY_CDR_RATE_PROPERTY);
			goto err_sir1;
		}
	} else {
		memcpy(priv->serdes_cdr_rate, amd_xgbe_phy_serdes_cdr_rate,
		       sizeof(priv->serdes_cdr_rate));
	}

	if (device_property_present(phy_dev, XGBE_PHY_PQ_SKEW_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_PHY_PQ_SKEW_PROPERTY,
						     priv->serdes_pq_skew,
						     XGBE_PHY_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_PHY_PQ_SKEW_PROPERTY);
			goto err_sir1;
		}
	} else {
		memcpy(priv->serdes_pq_skew, amd_xgbe_phy_serdes_pq_skew,
		       sizeof(priv->serdes_pq_skew));
	}

	if (device_property_present(phy_dev, XGBE_PHY_TX_AMP_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_PHY_TX_AMP_PROPERTY,
						     priv->serdes_tx_amp,
						     XGBE_PHY_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_PHY_TX_AMP_PROPERTY);
			goto err_sir1;
		}
	} else {
		memcpy(priv->serdes_tx_amp, amd_xgbe_phy_serdes_tx_amp,
		       sizeof(priv->serdes_tx_amp));
	}

	phydev->priv = priv;

	if (!priv->adev || acpi_disabled)
		platform_device_put(phy_pdev);

	return 0;

err_sir1:
	devm_iounmap(dev, priv->sir1_regs);
	devm_release_mem_region(dev, priv->sir1_res->start,
				resource_size(priv->sir1_res));

err_sir0:
	devm_iounmap(dev, priv->sir0_regs);
	devm_release_mem_region(dev, priv->sir0_res->start,
				resource_size(priv->sir0_res));

err_rxtx:
	devm_iounmap(dev, priv->rxtx_regs);
	devm_release_mem_region(dev, priv->rxtx_res->start,
				resource_size(priv->rxtx_res));

err_put:
	if (!priv->adev || acpi_disabled)
		platform_device_put(phy_pdev);

err_priv:
	devm_kfree(dev, priv);

	return ret;
}
int msm_sensor_get_sub_module_index(struct device_node *of_node,
				    struct  msm_sensor_info_t **s_info)
{
	int rc = 0, i = 0;
	uint32_t val = 0, count = 0;
	uint32_t *val_array = NULL;
	struct device_node *src_node = NULL;
	struct msm_sensor_info_t *sensor_info;

	sensor_info = kzalloc(sizeof(*sensor_info), GFP_KERNEL);
	if (!sensor_info) {
		pr_err("%s:%d failed\n", __func__, __LINE__);
		return -ENOMEM;
	}
	for (i = 0; i < SUB_MODULE_MAX; i++)
		sensor_info->subdev_id[i] = -1;

	src_node = of_parse_phandle(of_node, "qcom,actuator-src", 0);
	if (!src_node) {
		CDBG("%s:%d src_node NULL\n", __func__, __LINE__);
	} else {
		rc = of_property_read_u32(src_node, "cell-index", &val);
		CDBG("%s qcom,actuator cell index %d, rc %d\n", __func__,
			val, rc);
		if (rc < 0) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			goto ERROR;
		}
		sensor_info->subdev_id[SUB_MODULE_ACTUATOR] = val;
		of_node_put(src_node);
		src_node = NULL;
	}

	src_node = of_parse_phandle(of_node, "qcom,eeprom-src", 0);
	if (!src_node) {
		CDBG("%s:%d eeprom src_node NULL\n", __func__, __LINE__);
	} else {
		rc = of_property_read_u32(src_node, "cell-index", &val);
		CDBG("%s qcom,eeprom cell index %d, rc %d\n", __func__,
			val, rc);
		if (rc < 0) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			goto ERROR;
		}
		sensor_info->subdev_id[SUB_MODULE_EEPROM] = val;
		of_node_put(src_node);
		src_node = NULL;
	}

	if (of_property_read_bool(of_node, "qcom,eeprom-sd-index") ==
		true) {
		rc = of_property_read_u32(of_node, "qcom,eeprom-sd-index",
			&val);
		CDBG("%s qcom,eeprom-sd-index %d, rc %d\n", __func__, val, rc);
		if (rc < 0) {
			pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
			goto ERROR;
		}
		sensor_info->subdev_id[SUB_MODULE_EEPROM] = val;
	}

	src_node = of_parse_phandle(of_node, "qcom,led-flash-src", 0);
	if (!src_node) {
		CDBG("%s:%d src_node NULL\n", __func__, __LINE__);
	} else {
		rc = of_property_read_u32(src_node, "cell-index", &val);
		CDBG("%s qcom,led flash cell index %d, rc %d\n", __func__,
			val, rc);
		if (rc < 0) {
			pr_err("%s:%d failed %d\n", __func__, __LINE__, rc);
			goto ERROR;
		}
		sensor_info->subdev_id[SUB_MODULE_LED_FLASH] = val;
		of_node_put(src_node);
		src_node = NULL;
	}

	if (of_property_read_bool(of_node, "qcom,strobe-flash-sd-index") ==
		true) {
		rc = of_property_read_u32(of_node, "qcom,strobe-flash-sd-index",
			&val);
		CDBG("%s qcom,strobe-flash-sd-index %d, rc %d\n", __func__,
			val, rc);
		if (rc < 0) {
			pr_err("%s:%d failed rc %d\n", __func__, __LINE__, rc);
			goto ERROR;
		}
		sensor_info->subdev_id[SUB_MODULE_STROBE_FLASH] = val;
	}

	if (of_get_property(of_node, "qcom,csiphy-sd-index", &count)) {
		count /= sizeof(uint32_t);
		if (count > 2) {
			pr_err("%s qcom,csiphy-sd-index count %d > 2\n",
				__func__, count);
			goto ERROR;
		}
		val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
		if (!val_array) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			rc = -ENOMEM;
			goto ERROR;
		}

		rc = of_property_read_u32_array(of_node, "qcom,csiphy-sd-index",
			val_array, count);
		if (rc < 0) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			kfree(val_array);
			goto ERROR;
		}
		for (i = 0; i < count; i++) {
			sensor_info->subdev_id[SUB_MODULE_CSIPHY + i] =
								val_array[i];
			CDBG("%s csiphy_core[%d] = %d\n",
				__func__, i, val_array[i]);
		}
		kfree(val_array);
	} else {
		pr_err("%s:%d qcom,csiphy-sd-index not present\n", __func__,
			__LINE__);
		rc = -EINVAL;
		goto ERROR;
	}

	if (of_get_property(of_node, "qcom,csid-sd-index", &count)) {
		count /= sizeof(uint32_t);
		if (count > 2) {
			pr_err("%s qcom,csid-sd-index count %d > 2\n",
				__func__, count);
			rc = -EINVAL;
			goto ERROR;
		}
		val_array = kzalloc(sizeof(uint32_t) * count, GFP_KERNEL);
		if (!val_array) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			rc = -ENOMEM;
			goto ERROR;
		}

		rc = of_property_read_u32_array(of_node, "qcom,csid-sd-index",
			val_array, count);
		if (rc < 0) {
			pr_err("%s failed %d\n", __func__, __LINE__);
			kfree(val_array);
			goto ERROR;
		}
		for (i = 0; i < count; i++) {
			sensor_info->subdev_id
				[SUB_MODULE_CSID + i] = val_array[i];
			CDBG("%s csid_core[%d] = %d\n",
				__func__, i, val_array[i]);
		}
		kfree(val_array);
	} else {
		pr_err("%s:%d qcom,csid-sd-index not present\n", __func__,
			__LINE__);
		rc = -EINVAL;
		goto ERROR;
	}

	*s_info = sensor_info;
	return rc;
ERROR:
	kfree(sensor_info);
	return rc;
}
Ejemplo n.º 26
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;
	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;

	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;
}
Ejemplo n.º 27
0
static int tm2_probe(struct platform_device *pdev)
{
	struct device_node *cpu_dai_node[2] = {};
	struct device_node *codec_dai_node[2] = {};
	const char *cells_name = NULL;
	struct device *dev = &pdev->dev;
	struct snd_soc_card *card = &tm2_card;
	struct tm2_machine_priv *priv;
	struct of_phandle_args args;
	int num_codecs, ret, i;

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

	snd_soc_card_set_drvdata(card, priv);
	card->dev = dev;

	priv->gpio_mic_bias = devm_gpiod_get(dev, "mic-bias", GPIOD_OUT_HIGH);
	if (IS_ERR(priv->gpio_mic_bias)) {
		dev_err(dev, "Failed to get mic bias gpio\n");
		return PTR_ERR(priv->gpio_mic_bias);
	}

	ret = snd_soc_of_parse_card_name(card, "model");
	if (ret < 0) {
		dev_err(dev, "Card name is not specified\n");
		return ret;
	}

	ret = snd_soc_of_parse_audio_routing(card, "samsung,audio-routing");
	if (ret < 0) {
		dev_err(dev, "Audio routing is not specified or invalid\n");
		return ret;
	}

	card->aux_dev[0].codec_of_node = of_parse_phandle(dev->of_node,
							"audio-amplifier", 0);
	if (!card->aux_dev[0].codec_of_node) {
		dev_err(dev, "audio-amplifier property invalid or missing\n");
		return -EINVAL;
	}

	num_codecs = of_count_phandle_with_args(dev->of_node, "audio-codec",
						 NULL);

	/* Skip the HDMI link if not specified in DT */
	if (num_codecs > 1) {
		card->num_links = ARRAY_SIZE(tm2_dai_links);
		cells_name = "#sound-dai-cells";
	} else {
		card->num_links = ARRAY_SIZE(tm2_dai_links) - 1;
	}

	for (i = 0; i < num_codecs; i++) {
		struct of_phandle_args args;

		ret = of_parse_phandle_with_args(dev->of_node, "i2s-controller",
						 cells_name, i, &args);
		if (!args.np) {
			dev_err(dev, "i2s-controller property parse error: %d\n", i);
			ret = -EINVAL;
			goto dai_node_put;
		}
		cpu_dai_node[i] = args.np;

		codec_dai_node[i] = of_parse_phandle(dev->of_node,
						     "audio-codec", i);
		if (!codec_dai_node[i]) {
			dev_err(dev, "audio-codec property parse error\n");
			ret = -EINVAL;
			goto dai_node_put;
		}
	}

	/* Initialize WM5110 - I2S and HDMI - I2S1 DAI links */
	for (i = 0; i < card->num_links; i++) {
		unsigned int dai_index = 0; /* WM5110 */

		card->dai_link[i].cpu_name = NULL;
		card->dai_link[i].platform_name = NULL;

		if (num_codecs > 1 && i == card->num_links - 1)
			dai_index = 1; /* HDMI */

		card->dai_link[i].codec_of_node = codec_dai_node[dai_index];
		card->dai_link[i].cpu_of_node = cpu_dai_node[dai_index];
		card->dai_link[i].platform_of_node = cpu_dai_node[dai_index];
	}

	if (num_codecs > 1) {
		/* HDMI DAI link (I2S1) */
		i = card->num_links - 1;

		ret = of_parse_phandle_with_fixed_args(dev->of_node,
						"audio-codec", 0, 1, &args);
		if (ret) {
			dev_err(dev, "audio-codec property parse error\n");
			goto dai_node_put;
		}

		ret = snd_soc_get_dai_name(&args, &card->dai_link[i].codec_dai_name);
		if (ret) {
			dev_err(dev, "Unable to get codec_dai_name\n");
			goto dai_node_put;
		}
	}

	ret = devm_snd_soc_register_component(dev, &tm2_component,
				tm2_ext_dai, ARRAY_SIZE(tm2_ext_dai));
	if (ret < 0) {
		dev_err(dev, "Failed to register component: %d\n", ret);
		goto dai_node_put;
	}

	ret = devm_snd_soc_register_card(dev, card);
	if (ret < 0) {
		dev_err(dev, "Failed to register card: %d\n", ret);
		goto dai_node_put;
	}

dai_node_put:
	for (i = 0; i < num_codecs; i++) {
		of_node_put(codec_dai_node[i]);
		of_node_put(cpu_dai_node[i]);
	}

	of_node_put(card->aux_dev[0].codec_of_node);

	return ret;
}
Ejemplo n.º 28
0
/**
 * of_irq_map_raw - Low level interrupt tree parsing
 * @parent:	the device interrupt parent
 * @intspec:	interrupt specifier ("interrupts" property of the device)
 * @ointsize:   size of the passed in interrupt specifier
 * @addr:	address specifier (start of "reg" property of the device)
 * @out_irq:	structure of_irq filled by this function
 *
 * Returns 0 on success and a negative number on error
 *
 * This function is a low-level interrupt tree walking function. It
 * can be used to do a partial walk with synthetized reg and interrupts
 * properties, for example when resolving PCI interrupts when no device
 * node exist for the parent.
 */
int of_irq_map_raw(struct device_node *parent, const __be32 *intspec,
		   u32 ointsize, const __be32 *addr, struct of_irq *out_irq)
{
	struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
	const __be32 *tmp, *imap, *imask;
	u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
	int imaplen, match, i;

	pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n",
		 parent->full_name, be32_to_cpup(intspec),
		 be32_to_cpup(intspec + 1), ointsize);

	ipar = of_node_get(parent);

	/* First get the #interrupt-cells property of the current cursor
	 * that tells us how to interpret the passed-in intspec. If there
	 * is none, we are nice and just walk up the tree
	 */
	do {
		tmp = of_get_property(ipar, "#interrupt-cells", NULL);
		if (tmp != NULL) {
			intsize = be32_to_cpu(*tmp);
			break;
		}
		tnode = ipar;
		ipar = of_irq_find_parent(ipar);
		of_node_put(tnode);
	} while (ipar);
	if (ipar == NULL) {
		pr_debug(" -> no parent found !\n");
		goto fail;
	}

	pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize);

	if (ointsize != intsize)
		return -EINVAL;

	/* Look for this #address-cells. We have to implement the old linux
	 * trick of looking for the parent here as some device-trees rely on it
	 */
	old = of_node_get(ipar);
	do {
		tmp = of_get_property(old, "#address-cells", NULL);
		tnode = of_get_parent(old);
		of_node_put(old);
		old = tnode;
	} while (old && tmp == NULL);
	of_node_put(old);
	old = NULL;
	addrsize = (tmp == NULL) ? 2 : be32_to_cpu(*tmp);

	pr_debug(" -> addrsize=%d\n", addrsize);

	/* Now start the actual "proper" walk of the interrupt tree */
	while (ipar != NULL) {
		/* Now check if cursor is an interrupt-controller and if it is
		 * then we are done
		 */
		if (of_get_property(ipar, "interrupt-controller", NULL) !=
				NULL) {
			pr_debug(" -> got it !\n");
			for (i = 0; i < intsize; i++)
				out_irq->specifier[i] =
						of_read_number(intspec +i, 1);
			out_irq->size = intsize;
			out_irq->controller = ipar;
			of_node_put(old);
			return 0;
		}

		/* Now look for an interrupt-map */
		imap = of_get_property(ipar, "interrupt-map", &imaplen);
		/* No interrupt map, check for an interrupt parent */
		if (imap == NULL) {
			pr_debug(" -> no map, getting parent\n");
			newpar = of_irq_find_parent(ipar);
			goto skiplevel;
		}
		imaplen /= sizeof(u32);

		/* Look for a mask */
		imask = of_get_property(ipar, "interrupt-map-mask", NULL);

		/* If we were passed no "reg" property and we attempt to parse
		 * an interrupt-map, then #address-cells must be 0.
		 * Fail if it's not.
		 */
		if (addr == NULL && addrsize != 0) {
			pr_debug(" -> no reg passed in when needed !\n");
			goto fail;
		}

		/* Parse interrupt-map */
		match = 0;
		while (imaplen > (addrsize + intsize + 1) && !match) {
			/* Compare specifiers */
			match = 1;
			for (i = 0; i < addrsize && match; ++i) {
				u32 mask = imask ? imask[i] : 0xffffffffu;
				match = ((addr[i] ^ imap[i]) & mask) == 0;
			}
			for (; i < (addrsize + intsize) && match; ++i) {
				u32 mask = imask ? imask[i] : 0xffffffffu;
				match =
				   ((intspec[i-addrsize] ^ imap[i]) & mask) == 0;
			}
			imap += addrsize + intsize;
			imaplen -= addrsize + intsize;

			pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen);

			/* Get the interrupt parent */
			if (of_irq_workarounds & OF_IMAP_NO_PHANDLE)
				newpar = of_node_get(of_irq_dflt_pic);
			else
				newpar = of_find_node_by_phandle(be32_to_cpup(imap));
			imap++;
			--imaplen;

			/* Check if not found */
			if (newpar == NULL) {
				pr_debug(" -> imap parent not found !\n");
				goto fail;
			}

			/* Get #interrupt-cells and #address-cells of new
			 * parent
			 */
			tmp = of_get_property(newpar, "#interrupt-cells", NULL);
			if (tmp == NULL) {
				pr_debug(" -> parent lacks #interrupt-cells!\n");
				goto fail;
			}
			newintsize = be32_to_cpu(*tmp);
			tmp = of_get_property(newpar, "#address-cells", NULL);
			newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp);

			pr_debug(" -> newintsize=%d, newaddrsize=%d\n",
			    newintsize, newaddrsize);

			/* Check for malformed properties */
			if (imaplen < (newaddrsize + newintsize))
				goto fail;

			imap += newaddrsize + newintsize;
			imaplen -= newaddrsize + newintsize;

			pr_debug(" -> imaplen=%d\n", imaplen);
		}
		if (!match)
			goto fail;

		of_node_put(old);
		old = of_node_get(newpar);
		addrsize = newaddrsize;
		intsize = newintsize;
		intspec = imap - intsize;
		addr = intspec - addrsize;

	skiplevel:
		/* Iterate again with new parent */
		pr_debug(" -> new parent: %s\n", newpar ? newpar->full_name : "<>");
		of_node_put(ipar);
		ipar = newpar;
		newpar = NULL;
	}
 fail:
	of_node_put(ipar);
	of_node_put(old);
	of_node_put(newpar);

	return -EINVAL;
}
Ejemplo n.º 29
0
/*
 * Initialize chip structure
 */
static int ndfc_chip_init(struct ndfc_controller *ndfc,
			  struct device_node *node)
{
#ifdef CONFIG_MTD_PARTITIONS
#ifdef CONFIG_MTD_CMDLINE_PARTS
	static const char *part_types[] = { "cmdlinepart", NULL };
#else
	static const char *part_types[] = { NULL };
#endif
#endif
	struct device_node *flash_np;
	struct nand_chip *chip = &ndfc->chip;
	int ret;

	chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA;
	chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA;
	chip->cmd_ctrl = ndfc_hwcontrol;
	chip->dev_ready = ndfc_ready;
	chip->select_chip = ndfc_select_chip;
	chip->chip_delay = 50;
	chip->controller = &ndfc->ndfc_control;
	chip->read_buf = ndfc_read_buf;
	chip->write_buf = ndfc_write_buf;
	chip->verify_buf = ndfc_verify_buf;
	chip->ecc.correct = nand_correct_data;
	chip->ecc.hwctl = ndfc_enable_hwecc;
	chip->ecc.calculate = ndfc_calculate_ecc;
	chip->ecc.mode = NAND_ECC_HW;
	chip->ecc.size = 256;
	chip->ecc.bytes = 3;

	ndfc->mtd.priv = chip;
	ndfc->mtd.owner = THIS_MODULE;

	flash_np = of_get_next_child(node, NULL);
	if (!flash_np)
		return -ENODEV;

	ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s",
			dev_name(&ndfc->ofdev->dev), flash_np->name);
	if (!ndfc->mtd.name) {
		ret = -ENOMEM;
		goto err;
	}

	ret = nand_scan(&ndfc->mtd, 1);
	if (ret)
		goto err;

#ifdef CONFIG_MTD_PARTITIONS
	ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0);
	if (ret < 0)
		goto err;

#ifdef CONFIG_MTD_OF_PARTS
	if (ret == 0) {
		ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np,
					      &ndfc->parts);
		if (ret < 0)
			goto err;
	}
#endif

	if (ret > 0)
		ret = add_mtd_partitions(&ndfc->mtd, ndfc->parts, ret);
	else
#endif
		ret = add_mtd_device(&ndfc->mtd);

err:
	of_node_put(flash_np);
	if (ret)
		kfree(ndfc->mtd.name);
	return ret;
}
Ejemplo n.º 30
0
static void of_get_regulation_constraints(struct device_node *np,
					struct regulator_init_data **init_data,
					const struct regulator_desc *desc)
{
	struct regulation_constraints *constraints = &(*init_data)->constraints;
	struct regulator_state *suspend_state;
	struct device_node *suspend_np;
	unsigned int mode;
	int ret, i, len;
	u32 pval;

	constraints->name = of_get_property(np, "regulator-name", NULL);

	if (!of_property_read_u32(np, "regulator-min-microvolt", &pval))
		constraints->min_uV = pval;

	if (!of_property_read_u32(np, "regulator-max-microvolt", &pval))
		constraints->max_uV = pval;

	/* Voltage change possible? */
	if (constraints->min_uV != constraints->max_uV)
		constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE;

	/* Do we have a voltage range, if so try to apply it? */
	if (constraints->min_uV && constraints->max_uV)
		constraints->apply_uV = true;

	if (!of_property_read_u32(np, "regulator-microvolt-offset", &pval))
		constraints->uV_offset = pval;
	if (!of_property_read_u32(np, "regulator-min-microamp", &pval))
		constraints->min_uA = pval;
	if (!of_property_read_u32(np, "regulator-max-microamp", &pval))
		constraints->max_uA = pval;

	if (!of_property_read_u32(np, "regulator-input-current-limit-microamp",
				  &pval))
		constraints->ilim_uA = pval;

	/* Current change possible? */
	if (constraints->min_uA != constraints->max_uA)
		constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;

	constraints->boot_on = of_property_read_bool(np, "regulator-boot-on");
	constraints->always_on = of_property_read_bool(np, "regulator-always-on");
	if (!constraints->always_on) /* status change should be possible. */
		constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS;

	constraints->pull_down = of_property_read_bool(np, "regulator-pull-down");

	if (of_property_read_bool(np, "regulator-allow-bypass"))
		constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS;

	if (of_property_read_bool(np, "regulator-allow-set-load"))
		constraints->valid_ops_mask |= REGULATOR_CHANGE_DRMS;

	ret = of_property_read_u32(np, "regulator-ramp-delay", &pval);
	if (!ret) {
		if (pval)
			constraints->ramp_delay = pval;
		else
			constraints->ramp_disable = true;
	}

	ret = of_property_read_u32(np, "regulator-settling-time-us", &pval);
	if (!ret)
		constraints->settling_time = pval;

	ret = of_property_read_u32(np, "regulator-settling-time-up-us", &pval);
	if (!ret)
		constraints->settling_time_up = pval;
	if (constraints->settling_time_up && constraints->settling_time) {
		pr_warn("%s: ambiguous configuration for settling time, ignoring 'regulator-settling-time-up-us'\n",
			np->name);
		constraints->settling_time_up = 0;
	}

	ret = of_property_read_u32(np, "regulator-settling-time-down-us",
				   &pval);
	if (!ret)
		constraints->settling_time_down = pval;
	if (constraints->settling_time_down && constraints->settling_time) {
		pr_warn("%s: ambiguous configuration for settling time, ignoring 'regulator-settling-time-down-us'\n",
			np->name);
		constraints->settling_time_down = 0;
	}

	ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval);
	if (!ret)
		constraints->enable_time = pval;

	constraints->soft_start = of_property_read_bool(np,
					"regulator-soft-start");
	ret = of_property_read_u32(np, "regulator-active-discharge", &pval);
	if (!ret) {
		constraints->active_discharge =
				(pval) ? REGULATOR_ACTIVE_DISCHARGE_ENABLE :
					REGULATOR_ACTIVE_DISCHARGE_DISABLE;
	}

	if (!of_property_read_u32(np, "regulator-initial-mode", &pval)) {
		if (desc && desc->of_map_mode) {
			mode = desc->of_map_mode(pval);
			if (mode == REGULATOR_MODE_INVALID)
				pr_err("%s: invalid mode %u\n", np->name, pval);
			else
				constraints->initial_mode = mode;
		} else {
			pr_warn("%s: mapping for mode %d not defined\n",
				np->name, pval);
		}
	}

	len = of_property_count_elems_of_size(np, "regulator-allowed-modes",
						sizeof(u32));
	if (len > 0) {
		if (desc && desc->of_map_mode) {
			for (i = 0; i < len; i++) {
				ret = of_property_read_u32_index(np,
					"regulator-allowed-modes", i, &pval);
				if (ret) {
					pr_err("%s: couldn't read allowed modes index %d, ret=%d\n",
						np->name, i, ret);
					break;
				}
				mode = desc->of_map_mode(pval);
				if (mode == REGULATOR_MODE_INVALID)
					pr_err("%s: invalid regulator-allowed-modes element %u\n",
						np->name, pval);
				else
					constraints->valid_modes_mask |= mode;
			}
			if (constraints->valid_modes_mask)
				constraints->valid_ops_mask
					|= REGULATOR_CHANGE_MODE;
		} else {
			pr_warn("%s: mode mapping not defined\n", np->name);
		}
	}

	if (!of_property_read_u32(np, "regulator-system-load", &pval))
		constraints->system_load = pval;

	if (!of_property_read_u32(np, "regulator-coupled-max-spread",
				  &pval))
		constraints->max_spread = pval;

	constraints->over_current_protection = of_property_read_bool(np,
					"regulator-over-current-protection");

	for (i = 0; i < ARRAY_SIZE(regulator_states); i++) {
		switch (i) {
		case PM_SUSPEND_MEM:
			suspend_state = &constraints->state_mem;
			break;
		case PM_SUSPEND_MAX:
			suspend_state = &constraints->state_disk;
			break;
		case PM_SUSPEND_ON:
		case PM_SUSPEND_TO_IDLE:
		case PM_SUSPEND_STANDBY:
		default:
			continue;
		}

		suspend_np = of_get_child_by_name(np, regulator_states[i]);
		if (!suspend_np || !suspend_state)
			continue;

		if (!of_property_read_u32(suspend_np, "regulator-mode",
					  &pval)) {
			if (desc && desc->of_map_mode) {
				mode = desc->of_map_mode(pval);
				if (mode == REGULATOR_MODE_INVALID)
					pr_err("%s: invalid mode %u\n",
					       np->name, pval);
				else
					suspend_state->mode = mode;
			} else {
				pr_warn("%s: mapping for mode %d not defined\n",
					np->name, pval);
			}
		}

		if (of_property_read_bool(suspend_np,
					"regulator-on-in-suspend"))
			suspend_state->enabled = ENABLE_IN_SUSPEND;
		else if (of_property_read_bool(suspend_np,
					"regulator-off-in-suspend"))
			suspend_state->enabled = DISABLE_IN_SUSPEND;
		else
			suspend_state->enabled = DO_NOTHING_IN_SUSPEND;

		if (!of_property_read_u32(np, "regulator-suspend-min-microvolt",
					  &pval))
			suspend_state->min_uV = pval;

		if (!of_property_read_u32(np, "regulator-suspend-max-microvolt",
					  &pval))
			suspend_state->max_uV = pval;

		if (!of_property_read_u32(suspend_np,
					"regulator-suspend-microvolt", &pval))
			suspend_state->uV = pval;
		else /* otherwise use min_uV as default suspend voltage */
			suspend_state->uV = suspend_state->min_uV;

		if (of_property_read_bool(suspend_np,
					"regulator-changeable-in-suspend"))
			suspend_state->changeable = true;

		if (i == PM_SUSPEND_MEM)
			constraints->initial_state = PM_SUSPEND_MEM;

		of_node_put(suspend_np);
		suspend_state = NULL;
		suspend_np = NULL;
	}
}