コード例 #1
0
ファイル: src.c プロジェクト: 908626950/linux
static void rsnd_of_parse_src(struct platform_device *pdev,
			      const struct rsnd_of_data *of_data,
			      struct rsnd_priv *priv)
{
	struct device_node *src_node;
	struct rcar_snd_info *info = rsnd_priv_to_info(priv);
	struct rsnd_src_platform_info *src_info;
	struct device *dev = &pdev->dev;
	int nr;

	if (!of_data)
		return;

	src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
	if (!src_node)
		return;

	nr = of_get_child_count(src_node);
	if (!nr)
		return;

	src_info = devm_kzalloc(dev,
				sizeof(struct rsnd_src_platform_info) * nr,
				GFP_KERNEL);
	if (!src_info) {
		dev_err(dev, "src info allocation error\n");
		return;
	}

	info->src_info		= src_info;
	info->src_info_nr	= nr;
}
コード例 #2
0
ファイル: pinctrl-imx.c プロジェクト: Cool-Joe/imx23-audio
static int imx_pinctrl_parse_functions(struct device_node *np,
				       struct imx_pinctrl_soc_info *info,
				       u32 index)
{
	struct device_node *child;
	struct imx_pmx_func *func;
	struct imx_pin_group *grp;
	int ret;
	static u32 grp_index;
	u32 i = 0;

	dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);

	func = &info->functions[index];

	/* Initialise function */
	func->name = np->name;
	func->num_groups = of_get_child_count(np);
	if (func->num_groups <= 0) {
		dev_err(info->dev, "no groups defined\n");
		return -EINVAL;
	}
	func->groups = devm_kzalloc(info->dev,
			func->num_groups * sizeof(char *), GFP_KERNEL);

	for_each_child_of_node(np, child) {
		func->groups[i] = child->name;
		grp = &info->groups[grp_index++];
		ret = imx_pinctrl_parse_groups(child, grp, info, i++);
		if (ret)
			return ret;
	}
コード例 #3
0
ファイル: lp8727_charger.c プロジェクト: 03199618/linux
static int lp8727_parse_dt(struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct device_node *child;
	struct lp8727_platform_data *pdata;
	const char *type;

	/* If charging parameter is not defined, just skip parsing the dt */
	if (of_get_child_count(np) == 0)
		goto out;

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

	of_property_read_u32(np, "debounce-ms", &pdata->debounce_msec);

	for_each_child_of_node(np, child) {
		of_property_read_string(child, "charger-type", &type);

		if (!strcmp(type, "ac"))
			pdata->ac = lp8727_parse_charge_pdata(dev, child);

		if (!strcmp(type, "usb"))
			pdata->usb = lp8727_parse_charge_pdata(dev, child);
	}
コード例 #4
0
static void __init
of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
{
	int num;
	int irq = 0;
	u32 id;
	struct clk *clk;
	const char *name;
	struct device_node *sysclknp;
	const char *parent_name;

	num = of_get_child_count(np);
	if (num > (SYSTEM_MAX_ID + 1))
		return;

	for_each_child_of_node(np, sysclknp) {
		if (of_property_read_u32(sysclknp, "reg", &id))
			continue;

		if (of_property_read_string(np, "clock-output-names", &name))
			name = sysclknp->name;

		if (is_pck(id))
			irq = irq_of_parse_and_map(sysclknp, 0);

		parent_name = of_clk_get_parent_name(sysclknp, 0);

		clk = at91_clk_register_system(pmc, name, parent_name, id, irq);
		if (IS_ERR(clk))
			continue;

		of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk);
	}
}
コード例 #5
0
ファイル: phy-bcm-cygnus-pcie.c プロジェクト: JoeGlancy/linux
static int cygnus_pcie_phy_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node, *child;
	struct cygnus_pcie_phy_core *core;
	struct phy_provider *provider;
	struct resource *res;
	unsigned cnt = 0;

	if (of_get_child_count(node) == 0) {
		dev_err(dev, "PHY no child node\n");
		return -ENODEV;
	}

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

	core->dev = dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	core->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(core->base))
		return PTR_ERR(core->base);

	mutex_init(&core->lock);

	for_each_available_child_of_node(node, child) {
		unsigned int id;
		struct cygnus_pcie_phy *p;

		if (of_property_read_u32(child, "reg", &id)) {
			dev_err(dev, "missing reg property for %s\n",
				child->name);
			return -EINVAL;
		}

		if (id >= MAX_NUM_PHYS) {
			dev_err(dev, "invalid PHY id: %u\n", id);
			return -EINVAL;
		}

		if (core->phys[id].phy) {
			dev_err(dev, "duplicated PHY id: %u\n", id);
			return -EINVAL;
		}

		p = &core->phys[id];
		p->phy = devm_phy_create(dev, child, &cygnus_pcie_phy_ops);
		if (IS_ERR(p->phy)) {
			dev_err(dev, "failed to create PHY\n");
			return PTR_ERR(p->phy);
		}

		p->core = core;
		p->id = id;
		phy_set_drvdata(p->phy, p);
		cnt++;
	}
コード例 #6
0
ファイル: i2c-mux-reg.c プロジェクト: 513855417/linux
static int i2c_mux_reg_probe_dt(struct regmux *mux,
				struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *adapter_np, *child;
	struct i2c_adapter *adapter;
	struct resource res;
	unsigned *values;
	int i = 0;

	if (!np)
		return -ENODEV;

	adapter_np = of_parse_phandle(np, "i2c-parent", 0);
	if (!adapter_np) {
		dev_err(&pdev->dev, "Cannot parse i2c-parent\n");
		return -ENODEV;
	}
	adapter = of_find_i2c_adapter_by_node(adapter_np);
	of_node_put(adapter_np);
	if (!adapter)
		return -EPROBE_DEFER;

	mux->data.parent = i2c_adapter_id(adapter);
	put_device(&adapter->dev);

	mux->data.n_values = of_get_child_count(np);
	if (of_find_property(np, "little-endian", NULL)) {
		mux->data.little_endian = true;
	} else if (of_find_property(np, "big-endian", NULL)) {
		mux->data.little_endian = false;
	} else {
#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : \
	defined(__LITTLE_ENDIAN)
		mux->data.little_endian = true;
#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : \
	defined(__BIG_ENDIAN)
		mux->data.little_endian = false;
#else
#error Endianness not defined?
#endif
	}
	if (of_find_property(np, "write-only", NULL))
		mux->data.write_only = true;
	else
		mux->data.write_only = false;

	values = devm_kzalloc(&pdev->dev,
			      sizeof(*mux->data.values) * mux->data.n_values,
			      GFP_KERNEL);
	if (!values) {
		dev_err(&pdev->dev, "Cannot allocate values array");
		return -ENOMEM;
	}

	for_each_child_of_node(np, child) {
		of_property_read_u32(child, "reg", values + i);
		i++;
	}
コード例 #7
0
ファイル: leds-mc13783.c プロジェクト: 3null/linux
static struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt(
	struct platform_device *pdev)
{
	struct mc13xxx_leds *leds = platform_get_drvdata(pdev);
	struct mc13xxx_leds_platform_data *pdata;
	struct device_node *parent, *child;
	struct device *dev = &pdev->dev;
	int i = 0, ret = -ENODATA;

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

	of_node_get(dev->parent->of_node);

	parent = of_find_node_by_name(dev->parent->of_node, "leds");
	if (!parent)
		goto out_node_put;

	ret = of_property_read_u32_array(parent, "led-control",
					 pdata->led_control,
					 leds->devtype->num_regs);
	if (ret)
		goto out_node_put;

	pdata->num_leds = of_get_child_count(parent);

	pdata->led = devm_kzalloc(dev, pdata->num_leds * sizeof(*pdata->led),
				  GFP_KERNEL);
	if (!pdata->led) {
		ret = -ENOMEM;
		goto out_node_put;
	}

	for_each_child_of_node(parent, child) {
		const char *str;
		u32 tmp;

		if (of_property_read_u32(child, "reg", &tmp))
			continue;
		pdata->led[i].id = leds->devtype->led_min + tmp;

		if (!of_property_read_string(child, "label", &str))
			pdata->led[i].name = str;
		if (!of_property_read_string(child, "linux,default-trigger",
					     &str))
			pdata->led[i].default_trigger = str;

		i++;
	}

	pdata->num_leds = i;
	ret = i > 0 ? 0 : -ENODATA;

out_node_put:
	of_node_put(parent);

	return ret ? ERR_PTR(ret) : pdata;
}
コード例 #8
0
ファイル: ssi.c プロジェクト: 19Dan01/linux
static void rsnd_of_parse_ssi(struct platform_device *pdev,
			      const struct rsnd_of_data *of_data,
			      struct rsnd_priv *priv)
{
	struct device_node *node;
	struct device_node *np;
	struct rsnd_ssi_platform_info *ssi_info;
	struct rcar_snd_info *info = rsnd_priv_to_info(priv);
	struct device *dev = &pdev->dev;
	int nr, i;

	if (!of_data)
		return;

	node = rsnd_ssi_of_node(priv);
	if (!node)
		return;

	nr = of_get_child_count(node);
	if (!nr)
		goto rsnd_of_parse_ssi_end;

	ssi_info = devm_kzalloc(dev,
				sizeof(struct rsnd_ssi_platform_info) * nr,
				GFP_KERNEL);
	if (!ssi_info) {
		dev_err(dev, "ssi info allocation error\n");
		goto rsnd_of_parse_ssi_end;
	}

	info->ssi_info		= ssi_info;
	info->ssi_info_nr	= nr;

	i = -1;
	for_each_child_of_node(node, np) {
		i++;

		ssi_info = info->ssi_info + i;

		/*
		 * pin settings
		 */
		if (of_get_property(np, "shared-pin", NULL))
			ssi_info->flags |= RSND_SSI_CLK_PIN_SHARE;

		/*
		 * irq
		 */
		ssi_info->irq = irq_of_parse_and_map(np, 0);

		/*
		 * DMA
		 */
		ssi_info->dma_id = of_get_property(np, "pio-transfer", NULL) ?
			0 : 1;

		if (of_get_property(np, "no-busif", NULL))
			ssi_info->flags |= RSND_SSI_NO_BUSIF;
	}
コード例 #9
0
ファイル: lp872x.c プロジェクト: 020gzh/linux
static struct lp872x_platform_data
*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which)
{
	struct device_node *np = dev->of_node;
	struct lp872x_platform_data *pdata;
	struct of_regulator_match *match;
	int num_matches;
	int count;
	int i;
	u8 dvs_state;

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

	of_property_read_u8(np, "ti,general-config", &pdata->general_config);
	if (of_find_property(np, "ti,update-config", NULL))
		pdata->update_config = true;

	pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL);
	if (!pdata->dvs)
		return ERR_PTR(-ENOMEM);

	pdata->dvs->gpio = of_get_named_gpio(np, "ti,dvs-gpio", 0);
	of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel);
	of_property_read_u8(np, "ti,dvs-state", &dvs_state);
	pdata->dvs->init_state = dvs_state ? DVS_HIGH : DVS_LOW;

	pdata->enable_gpio = of_get_named_gpio(np, "enable-gpios", 0);

	if (of_get_child_count(np) == 0)
		goto out;

	switch (which) {
	case LP8720:
		match = lp8720_matches;
		num_matches = ARRAY_SIZE(lp8720_matches);
		break;
	case LP8725:
		match = lp8725_matches;
		num_matches = ARRAY_SIZE(lp8725_matches);
		break;
	default:
		goto out;
	}

	count = of_regulator_match(dev, np, match, num_matches);
	if (count <= 0)
		goto out;

	for (i = 0; i < num_matches; i++) {
		pdata->regulator_data[i].id =
				(enum lp872x_regulator_id)match[i].driver_data;
		pdata->regulator_data[i].init_data = match[i].init_data;
	}
out:
	return pdata;
}
コード例 #10
0
ファイル: mix.c プロジェクト: krzk/linux
int rsnd_mix_probe(struct rsnd_priv *priv)
{
	struct device_node *node;
	struct device_node *np;
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_mix *mix;
	struct clk *clk;
	char name[MIX_NAME_SIZE];
	int i, nr, ret;

	/* This driver doesn't support Gen1 at this point */
	if (rsnd_is_gen1(priv))
		return 0;

	node = rsnd_mix_of_node(priv);
	if (!node)
		return 0; /* not used is not error */

	nr = of_get_child_count(node);
	if (!nr) {
		ret = -EINVAL;
		goto rsnd_mix_probe_done;
	}

	mix	= devm_kcalloc(dev, nr, sizeof(*mix), GFP_KERNEL);
	if (!mix) {
		ret = -ENOMEM;
		goto rsnd_mix_probe_done;
	}

	priv->mix_nr	= nr;
	priv->mix	= mix;

	i = 0;
	ret = 0;
	for_each_child_of_node(node, np) {
		mix = rsnd_mix_get(priv, i);

		snprintf(name, MIX_NAME_SIZE, "%s.%d",
			 MIX_NAME, i);

		clk = devm_clk_get(dev, name);
		if (IS_ERR(clk)) {
			ret = PTR_ERR(clk);
			of_node_put(np);
			goto rsnd_mix_probe_done;
		}

		ret = rsnd_mod_init(priv, rsnd_mod_get(mix), &rsnd_mix_ops,
				    clk, rsnd_mod_get_status, RSND_MOD_MIX, i);
		if (ret) {
			of_node_put(np);
			goto rsnd_mix_probe_done;
		}

		i++;
	}
コード例 #11
0
ファイル: axidma_of.c プロジェクト: alinaresb/xilinx_axidma
static int axidma_of_parse_channel(struct device_node *dma_node, int channel,
        struct axidma_chan *chan, struct axidma_device *dev)
{
    int rc;
    struct device_node *dma_chan_node;
    u32 channel_id;

    // Verify that the DMA node has two channel (child) nodes, one for TX and RX
    if (of_get_child_count(dma_node) < 1) {
        axidma_node_err(dma_node, "DMA does not have any channel nodes.\n");
        return -EINVAL;
    } else if (of_get_child_count(dma_node) > 2) {
        axidma_node_err(dma_node, "DMA has more than two channel nodes.\n");
        return -EINVAL;
    }

    // Go to the child node that we're parsing
    dma_chan_node = of_get_next_child(dma_node, NULL);
    if (channel == 1) {
        dma_chan_node = of_get_next_child(dma_node, dma_chan_node);
    }

    // Read out the channel's unique device id, and put it in the structure
    if (of_find_property(dma_chan_node, "xlnx,device-id", NULL) == NULL) {
        axidma_node_err(dma_chan_node, "DMA channel is missing the "
                        "'xlnx,device-id' property.\n");
        return -EINVAL;
    }
    rc = of_property_read_u32(dma_chan_node, "xlnx,device-id", &channel_id);
    if (rc < 0) {
        axidma_err("Unable to read the 'xlnx,device-id' property.\n");
        return -EINVAL;
    }
    chan->channel_id = channel_id;

    // Use the compatible string to determine the channel's information
    rc = axidma_parse_compatible_property(dma_chan_node, chan, dev);
    if (rc < 0) {
        return rc;
    }

    return 0;
}
コード例 #12
0
ファイル: dvc.c プロジェクト: AshishNamdev/linux
int rsnd_dvc_probe(struct rsnd_priv *priv)
{
	struct device_node *node;
	struct device_node *np;
	struct device *dev = rsnd_priv_to_dev(priv);
	struct rsnd_dvc *dvc;
	struct clk *clk;
	char name[RSND_DVC_NAME_SIZE];
	int i, nr, ret;

	/* This driver doesn't support Gen1 at this point */
	if (rsnd_is_gen1(priv))
		return 0;

	node = rsnd_dvc_of_node(priv);
	if (!node)
		return 0; /* not used is not error */

	nr = of_get_child_count(node);
	if (!nr) {
		ret = -EINVAL;
		goto rsnd_dvc_probe_done;
	}

	dvc	= devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL);
	if (!dvc) {
		ret = -ENOMEM;
		goto rsnd_dvc_probe_done;
	}

	priv->dvc_nr	= nr;
	priv->dvc	= dvc;

	i = 0;
	ret = 0;
	for_each_child_of_node(node, np) {
		dvc = rsnd_dvc_get(priv, i);

		snprintf(name, RSND_DVC_NAME_SIZE, "%s.%d",
			 DVC_NAME, i);

		clk = devm_clk_get(dev, name);
		if (IS_ERR(clk)) {
			ret = PTR_ERR(clk);
			goto rsnd_dvc_probe_done;
		}

		ret = rsnd_mod_init(priv, rsnd_mod_get(dvc), &rsnd_dvc_ops,
				    clk, rsnd_mod_get_status, RSND_MOD_DVC, i);
		if (ret)
			goto rsnd_dvc_probe_done;

		i++;
	}
コード例 #13
0
ファイル: of-thermal.c プロジェクト: 19Dan01/linux
/**
 * thermal_of_build_thermal_zone - parse and fill one thermal zone data
 * @np: DT node containing a thermal zone node
 *
 * This function parses a thermal zone type of node represented by
 * @np parameter and fills the read data into a __thermal_zone data structure
 * and return this pointer.
 *
 * TODO: Missing properties to parse: thermal-sensor-names and coefficients
 *
 * Return: On success returns a valid struct __thermal_zone,
 * otherwise, it returns a corresponding ERR_PTR(). Caller must
 * check the return value with help of IS_ERR() helper.
 */
static struct __thermal_zone *
thermal_of_build_thermal_zone(struct device_node *np)
{
	struct device_node *child = NULL, *gchild;
	struct __thermal_zone *tz;
	int ret, i;
	u32 prop;

	if (!np) {
		pr_err("no thermal zone np\n");
		return ERR_PTR(-EINVAL);
	}

	tz = kzalloc(sizeof(*tz), GFP_KERNEL);
	if (!tz)
		return ERR_PTR(-ENOMEM);

	ret = of_property_read_u32(np, "polling-delay-passive", &prop);
	if (ret < 0) {
		pr_err("missing polling-delay-passive property\n");
		goto free_tz;
	}
	tz->passive_delay = prop;

	ret = of_property_read_u32(np, "polling-delay", &prop);
	if (ret < 0) {
		pr_err("missing polling-delay property\n");
		goto free_tz;
	}
	tz->polling_delay = prop;

	/* trips */
	child = of_get_child_by_name(np, "trips");

	/* No trips provided */
	if (!child)
		goto finish;

	tz->ntrips = of_get_child_count(child);
	if (tz->ntrips == 0) /* must have at least one child */
		goto finish;

	tz->trips = kzalloc(tz->ntrips * sizeof(*tz->trips), GFP_KERNEL);
	if (!tz->trips) {
		ret = -ENOMEM;
		goto free_tz;
	}

	i = 0;
	for_each_child_of_node(child, gchild) {
		ret = thermal_of_populate_trip(gchild, &tz->trips[i++]);
		if (ret)
			goto free_trips;
	}
コード例 #14
0
ファイル: samsung-keypad.c プロジェクト: 020gzh/linux
static struct samsung_keypad_platdata *
samsung_keypad_parse_dt(struct device *dev)
{
	struct samsung_keypad_platdata *pdata;
	struct matrix_keymap_data *keymap_data;
	uint32_t *keymap, num_rows = 0, num_cols = 0;
	struct device_node *np = dev->of_node, *key_np;
	unsigned int key_count;

	if (!np) {
		dev_err(dev, "missing device tree data\n");
		return ERR_PTR(-EINVAL);
	}

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
		dev_err(dev, "could not allocate memory for platform data\n");
		return ERR_PTR(-ENOMEM);
	}

	of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows);
	of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols);
	if (!num_rows || !num_cols) {
		dev_err(dev, "number of keypad rows/columns not specified\n");
		return ERR_PTR(-EINVAL);
	}
	pdata->rows = num_rows;
	pdata->cols = num_cols;

	keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL);
	if (!keymap_data) {
		dev_err(dev, "could not allocate memory for keymap data\n");
		return ERR_PTR(-ENOMEM);
	}
	pdata->keymap_data = keymap_data;

	key_count = of_get_child_count(np);
	keymap_data->keymap_size = key_count;
	keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL);
	if (!keymap) {
		dev_err(dev, "could not allocate memory for keymap\n");
		return ERR_PTR(-ENOMEM);
	}
	keymap_data->keymap = keymap;

	for_each_child_of_node(np, key_np) {
		u32 row, col, key_code;
		of_property_read_u32(key_np, "keypad,row", &row);
		of_property_read_u32(key_np, "keypad,column", &col);
		of_property_read_u32(key_np, "linux,code", &key_code);
		*keymap++ = KEY(row, col, key_code);
	}
コード例 #15
0
ファイル: clk-generated.c プロジェクト: 020gzh/linux
void __init of_sama5d2_clk_generated_setup(struct device_node *np)
{
	int num;
	u32 id;
	const char *name;
	struct clk *clk;
	unsigned int num_parents;
	const char *parent_names[GENERATED_SOURCE_MAX];
	struct device_node *gcknp;
	struct clk_range range = CLK_RANGE(0, 0);
	struct regmap *regmap;

	num_parents = of_clk_get_parent_count(np);
	if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
		return;

	of_clk_parent_fill(np, parent_names, num_parents);

	num = of_get_child_count(np);
	if (!num || num > PERIPHERAL_MAX)
		return;

	regmap = syscon_node_to_regmap(of_get_parent(np));
	if (IS_ERR(regmap))
		return;

	for_each_child_of_node(np, gcknp) {
		if (of_property_read_u32(gcknp, "reg", &id))
			continue;

		if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
			continue;

		if (of_property_read_string(np, "clock-output-names", &name))
			name = gcknp->name;

		of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
				      &range);

		clk = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
						  parent_names, num_parents,
						  id, &range);
		if (IS_ERR(clk))
			continue;

		of_clk_add_provider(gcknp, of_clk_src_simple_get, clk);
	}
}
コード例 #16
0
ファイル: imc-pmu.c プロジェクト: CCNITSilchar/linux
/*
 * update_events_in_group: Update the "events" information in an attr_group
 *                         and assign the attr_group to the pmu "pmu".
 */
static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu)
{
	struct attribute_group *attr_group;
	struct attribute **attrs, *dev_str;
	struct device_node *np, *pmu_events;
	u32 handle, base_reg;
	int i = 0, j = 0, ct, ret;
	const char *prefix, *g_scale, *g_unit;
	const char *ev_val_str, *ev_scale_str, *ev_unit_str;

	if (!of_property_read_u32(node, "events", &handle))
		pmu_events = of_find_node_by_phandle(handle);
	else
		return 0;

	/* Did not find any node with a given phandle */
	if (!pmu_events)
		return 0;

	/* Get a count of number of child nodes */
	ct = of_get_child_count(pmu_events);

	/* Get the event prefix */
	if (of_property_read_string(node, "events-prefix", &prefix))
		return 0;

	/* Get a global unit and scale data if available */
	if (of_property_read_string(node, "scale", &g_scale))
		g_scale = NULL;

	if (of_property_read_string(node, "unit", &g_unit))
		g_unit = NULL;

	/* "reg" property gives out the base offset of the counters data */
	of_property_read_u32(node, "reg", &base_reg);

	/* Allocate memory for the events */
	pmu->events = kcalloc(ct, sizeof(struct imc_events), GFP_KERNEL);
	if (!pmu->events)
		return -ENOMEM;

	ct = 0;
	/* Parse the events and update the struct */
	for_each_child_of_node(pmu_events, np) {
		ret = imc_parse_event(np, g_scale, g_unit, prefix, base_reg, &pmu->events[ct]);
		if (!ret)
			ct++;
	}
コード例 #17
0
static void __init
of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
		       const struct clk_programmable_layout *layout)
{
	int num;
	u32 id;
	int i;
	unsigned int irq;
	struct clk *clk;
	int num_parents;
	const char *parent_names[PROG_SOURCE_MAX];
	const char *name;
	struct device_node *progclknp;

	num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells");
	if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX)
		return;

	for (i = 0; i < num_parents; ++i) {
		parent_names[i] = of_clk_get_parent_name(np, i);
		if (!parent_names[i])
			return;
	}

	num = of_get_child_count(np);
	if (!num || num > (PROG_ID_MAX + 1))
		return;

	for_each_child_of_node(np, progclknp) {
		if (of_property_read_u32(progclknp, "reg", &id))
			continue;

		if (of_property_read_string(np, "clock-output-names", &name))
			name = progclknp->name;

		irq = irq_of_parse_and_map(progclknp, 0);
		if (!irq)
			continue;

		clk = at91_clk_register_programmable(pmc, irq, name,
						     parent_names, num_parents,
						     id, layout);
		if (IS_ERR(clk))
			continue;

		of_clk_add_provider(progclknp, of_clk_src_simple_get, clk);
	}
}
コード例 #18
0
int mc13xxx_get_num_regulators_dt(struct platform_device *pdev)
{
	struct device_node *parent;
	int num;

	if (!pdev->dev.parent->of_node)
		return -ENODEV;

	parent = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
	if (!parent)
		return -ENODEV;

	num = of_get_child_count(parent);
	of_node_put(parent);
	return num;
}
コード例 #19
0
struct msm_bus_device_node_registration
	*msm_bus_of_to_pdata(struct platform_device *pdev)
{
	struct device_node *of_node, *child_node;
	struct msm_bus_device_node_registration *pdata;
	unsigned int i = 0, j;
	unsigned int ret;

	if (!pdev) {
		pr_err("Error: Null platform device\n");
		return NULL;
	}

	of_node = pdev->dev.of_node;

	pdata = devm_kzalloc(&pdev->dev,
			sizeof(struct msm_bus_device_node_registration),
			GFP_KERNEL);
	if (!pdata) {
		dev_err(&pdev->dev,
				"Error: Memory allocation for pdata failed\n");
		return NULL;
	}

	pdata->num_devices = of_get_child_count(of_node);

	pdata->info = devm_kzalloc(&pdev->dev,
			sizeof(struct msm_bus_node_device_type) *
			pdata->num_devices, GFP_KERNEL);

	if (!pdata->info) {
		dev_err(&pdev->dev,
			"Error: Memory allocation for pdata->info failed\n");
		goto node_reg_err;
	}

	ret = 0;
	for_each_child_of_node(of_node, child_node) {
		ret = get_bus_node_device_data(child_node, pdev,
				&pdata->info[i]);
		if (ret) {
			dev_err(&pdev->dev, "Error: unable to initialize bus nodes\n");
			goto node_reg_err_1;
		}
		i++;
	}
コード例 #20
0
static inline int ivp_setup_onchipmem_sections(struct platform_device *plat_devp, struct ivp_device *ivp_devp)
{
    struct device_node *parent = NULL, *child = NULL;
    size_t i = 0;

    if (plat_devp == NULL || ivp_devp == NULL) {
        ivp_err("pointer is NULL.");
        return -EINVAL;
    }

    parent = of_get_child_by_name(plat_devp->dev.of_node, IVP_SECTION_NODE_NAME);
    if (NULL == parent) {
        ivp_err("Failed to get mem parent node.");
        return -ENODEV;
    }

    
    ivp_devp->sect_count = of_get_child_count(parent);
    ivp_devp->sects = (struct ivp_sect_info *)
                      kmalloc(sizeof(struct ivp_sect_info) * ivp_devp->sect_count, GFP_KERNEL);

    if (NULL == ivp_devp->sects) {
        ivp_err("kmalloc fail.");
        return -ENOMEM;
    }

    ivp_info("section count:%d.", ivp_devp->sect_count);

    memset(ivp_devp->sects, 0, sizeof(struct ivp_sect_info) * ivp_devp->sect_count);
   
    for_each_child_of_node(parent, child) {
        if (ivp_setup_one_onchipmem_section(&ivp_devp->sects[i], child)) {
            ivp_err("setup %lu section fail", i);
            goto err_out;
        }
        i++;
    }

    return 0;

err_out: 
    kfree(ivp_devp->sects);
    ivp_devp->sects = NULL;
    ivp_devp->sect_count = 0;
    return -EFAULT;
}
コード例 #21
0
ファイル: phy-miphy365x.c プロジェクト: 3null/linux
static struct phy *miphy365x_xlate(struct device *dev,
				   struct of_phandle_args *args)
{
	struct miphy365x_dev *miphy_dev = dev_get_drvdata(dev);
	struct miphy365x_phy *miphy_phy = NULL;
	struct device_node *phynode = args->np;
	int ret, index;

	if (!of_device_is_available(phynode)) {
		dev_warn(dev, "Requested PHY is disabled\n");
		return ERR_PTR(-ENODEV);
	}

	if (args->args_count != 1) {
		dev_err(dev, "Invalid number of cells in 'phy' property\n");
		return ERR_PTR(-EINVAL);
	}

	for (index = 0; index < of_get_child_count(dev->of_node); index++)
		if (phynode == miphy_dev->phys[index]->phy->dev.of_node) {
			miphy_phy = miphy_dev->phys[index];
			break;
		}

	if (!miphy_phy) {
		dev_err(dev, "Failed to find appropriate phy\n");
		return ERR_PTR(-EINVAL);
	}

	miphy_phy->type = args->args[0];

	if (!(miphy_phy->type == MIPHY_TYPE_SATA ||
	      miphy_phy->type == MIPHY_TYPE_PCIE)) {
		dev_err(dev, "Unsupported device type: %d\n", miphy_phy->type);
		return ERR_PTR(-EINVAL);
	}

	/* Each port handles SATA and PCIE - third entry is always sysconf. */
	for (index = 0; index < 3; index++) {
		ret = miphy365x_get_addr(dev, miphy_phy, index);
		if (ret < 0)
			return ERR_PTR(ret);
	}

	return miphy_phy->phy;
}
コード例 #22
0
ファイル: lp855x_bl.c プロジェクト: DenisLug/mptcp
static int lp855x_parse_dt(struct lp855x *lp)
{
	struct device *dev = lp->dev;
	struct device_node *node = dev->of_node;
	struct lp855x_platform_data *pdata;
	int rom_length;

	if (!node) {
		dev_err(dev, "no platform data\n");
		return -EINVAL;
	}

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

	of_property_read_string(node, "bl-name", &pdata->name);
	of_property_read_u8(node, "dev-ctrl", &pdata->device_control);
	of_property_read_u8(node, "init-brt", &pdata->initial_brightness);
	of_property_read_u32(node, "pwm-period", &pdata->period_ns);

	/* Fill ROM platform data if defined */
	rom_length = of_get_child_count(node);
	if (rom_length > 0) {
		struct lp855x_rom_data *rom;
		struct device_node *child;
		int i = 0;

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

		for_each_child_of_node(node, child) {
			of_property_read_u8(child, "rom-addr", &rom[i].addr);
			of_property_read_u8(child, "rom-val", &rom[i].val);
			i++;
		}

		pdata->size_program = rom_length;
		pdata->rom_data = &rom[0];
	}
コード例 #23
0
static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
					struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *adapter_np, *child;
	struct i2c_adapter *adapter;
	unsigned *values, *gpios;
	int i = 0, ret;

	if (!np)
		return -ENODEV;

	adapter_np = of_parse_phandle(np, "i2c-parent", 0);
	if (!adapter_np) {
		dev_err(&pdev->dev, "Cannot parse i2c-parent\n");
		return -ENODEV;
	}
	adapter = of_find_i2c_adapter_by_node(adapter_np);
	if (!adapter) {
		dev_err(&pdev->dev, "Cannot find parent bus\n");
		return -EPROBE_DEFER;
	}
	mux->data.parent = i2c_adapter_id(adapter);
	put_device(&adapter->dev);

	mux->data.n_values = of_get_child_count(np);

	values = devm_kzalloc(&pdev->dev,
			      sizeof(*mux->data.values) * mux->data.n_values,
			      GFP_KERNEL);
	if (!values) {
		dev_err(&pdev->dev, "Cannot allocate values array");
		return -ENOMEM;
	}

	for_each_child_of_node(np, child) {
		of_property_read_u32(child, "reg", values + i);
		i++;
	}
コード例 #24
0
ファイル: mc.c プロジェクト: AK101111/linux
static int load_timings(struct tegra_mc *mc, struct device_node *node)
{
	struct device_node *child;
	struct tegra_mc_timing *timing;
	int child_count = of_get_child_count(node);
	int i = 0, err;

	mc->timings = devm_kcalloc(mc->dev, child_count, sizeof(*timing),
				   GFP_KERNEL);
	if (!mc->timings)
		return -ENOMEM;

	mc->num_timings = child_count;

	for_each_child_of_node(node, child) {
		timing = &mc->timings[i++];

		err = load_one_timing(mc, timing, child);
		if (err) {
			of_node_put(child);
			return err;
		}
	}
コード例 #25
0
struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev,
						      struct device_node *np)
{
	struct device_node *child;
	struct lp55xx_platform_data *pdata;
	struct lp55xx_led_config *cfg;
	int num_channels;
	int i = 0;

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

	num_channels = of_get_child_count(np);
	if (num_channels == 0) {
		dev_err(dev, "no LED channels\n");
		return ERR_PTR(-EINVAL);
	}

	cfg = devm_kzalloc(dev, sizeof(*cfg) * num_channels, GFP_KERNEL);
	if (!cfg)
		return ERR_PTR(-ENOMEM);

	pdata->led_config = &cfg[0];
	pdata->num_channels = num_channels;

	for_each_child_of_node(np, child) {
		cfg[i].chan_nr = i;

		of_property_read_string(child, "chan-name", &cfg[i].name);
		of_property_read_u8(child, "led-cur", &cfg[i].led_current);
		of_property_read_u8(child, "max-cur", &cfg[i].max_current);
		cfg[i].default_trigger =
			of_get_property(child, "linux,default-trigger", NULL);

		i++;
	}
コード例 #26
0
ファイル: arche-platform.c プロジェクト: forgivemyheart/linux
static int arche_platform_probe(struct platform_device *pdev)
{
	struct arche_platform_drvdata *arche_pdata;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	int ret;

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

	/* setup svc reset gpio */
	arche_pdata->is_reset_act_hi = of_property_read_bool(np,
					"svc,reset-active-high");
	arche_pdata->svc_reset_gpio = of_get_named_gpio(np, "svc,reset-gpio", 0);
	if (arche_pdata->svc_reset_gpio < 0) {
		dev_err(dev, "failed to get reset-gpio\n");
		return arche_pdata->svc_reset_gpio;
	}
	ret = devm_gpio_request(dev, arche_pdata->svc_reset_gpio, "svc-reset");
	if (ret) {
		dev_err(dev, "failed to request svc-reset gpio:%d\n", ret);
		return ret;
	}
	ret = gpio_direction_output(arche_pdata->svc_reset_gpio,
					arche_pdata->is_reset_act_hi);
	if (ret) {
		dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret);
		return ret;
	}
	arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF);

	arche_pdata->svc_sysboot_gpio = of_get_named_gpio(np,
					"svc,sysboot-gpio", 0);
	if (arche_pdata->svc_sysboot_gpio < 0) {
		dev_err(dev, "failed to get sysboot gpio\n");
		return arche_pdata->svc_sysboot_gpio;
	}
	ret = devm_gpio_request(dev, arche_pdata->svc_sysboot_gpio, "sysboot0");
	if (ret) {
		dev_err(dev, "failed to request sysboot0 gpio:%d\n", ret);
		return ret;
	}
	ret = gpio_direction_output(arche_pdata->svc_sysboot_gpio, 0);
	if (ret) {
		dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret);
		return ret;
	}

	/* setup the clock request gpio first */
	arche_pdata->svc_refclk_req = of_get_named_gpio(np,
					"svc,refclk-req-gpio", 0);
	if (arche_pdata->svc_refclk_req < 0) {
		dev_err(dev, "failed to get svc clock-req gpio\n");
		return arche_pdata->svc_refclk_req;
	}
	ret = devm_gpio_request(dev, arche_pdata->svc_refclk_req, "svc-clk-req");
	if (ret) {
		dev_err(dev, "failed to request svc-clk-req gpio: %d\n", ret);
		return ret;
	}
	ret = gpio_direction_input(arche_pdata->svc_refclk_req);
	if (ret) {
		dev_err(dev, "failed to set svc-clk-req gpio dir :%d\n", ret);
		return ret;
	}

	/* setup refclk2 to follow the pin */
	arche_pdata->svc_ref_clk = devm_clk_get(dev, "svc_ref_clk");
	if (IS_ERR(arche_pdata->svc_ref_clk)) {
		ret = PTR_ERR(arche_pdata->svc_ref_clk);
		dev_err(dev, "failed to get svc_ref_clk: %d\n", ret);
		return ret;
	}

	platform_set_drvdata(pdev, arche_pdata);

	arche_pdata->num_apbs = of_get_child_count(np);
	dev_dbg(dev, "Number of APB's available - %d\n", arche_pdata->num_apbs);

	arche_pdata->wake_detect_gpio = of_get_named_gpio(np, "svc,wake-detect-gpio", 0);
	if (arche_pdata->wake_detect_gpio < 0) {
		dev_err(dev, "failed to get wake detect gpio\n");
		return arche_pdata->wake_detect_gpio;
	}

	ret = devm_gpio_request(dev, arche_pdata->wake_detect_gpio, "wake detect");
	if (ret) {
		dev_err(dev, "Failed requesting wake_detect gpio %d\n",
				arche_pdata->wake_detect_gpio);
		return ret;
	}

	arche_platform_set_wake_detect_state(arche_pdata, WD_STATE_IDLE);

	arche_pdata->dev = &pdev->dev;

	spin_lock_init(&arche_pdata->wake_lock);
	mutex_init(&arche_pdata->platform_state_mutex);
	init_waitqueue_head(&arche_pdata->wq);
	arche_pdata->wake_detect_irq =
		gpio_to_irq(arche_pdata->wake_detect_gpio);

	ret = devm_request_threaded_irq(dev, arche_pdata->wake_detect_irq,
			arche_platform_wd_irq,
			arche_platform_wd_irq_thread,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			dev_name(dev), arche_pdata);
	if (ret) {
		dev_err(dev, "failed to request wake detect IRQ %d\n", ret);
		return ret;
	}
	disable_irq(arche_pdata->wake_detect_irq);

	ret = device_create_file(dev, &dev_attr_state);
	if (ret) {
		dev_err(dev, "failed to create state file in sysfs\n");
		return ret;
	}

	ret = of_platform_populate(np, NULL, NULL, dev);
	if (ret) {
		dev_err(dev, "failed to populate child nodes %d\n", ret);
		goto err_device_remove;
	}

	arche_pdata->pm_notifier.notifier_call = arche_platform_pm_notifier;
	ret = register_pm_notifier(&arche_pdata->pm_notifier);

	if (ret) {
		dev_err(dev, "failed to register pm notifier %d\n", ret);
		goto err_device_remove;
	}

	/* Register callback pointer */
	arche_platform_change_state_cb = arche_platform_change_state;

	/* Explicitly power off if requested */
	if (!of_property_read_bool(pdev->dev.of_node, "arche,init-off")) {
		mutex_lock(&arche_pdata->platform_state_mutex);
		ret = arche_platform_coldboot_seq(arche_pdata);
		if (ret) {
			dev_err(dev, "Failed to cold boot svc %d\n", ret);
			goto err_coldboot;
		}
		arche_platform_wd_irq_en(arche_pdata);
		mutex_unlock(&arche_pdata->platform_state_mutex);
	}

	dev_info(dev, "Device registered successfully\n");
	return 0;

err_coldboot:
	mutex_unlock(&arche_pdata->platform_state_mutex);
err_device_remove:
	device_remove_file(&pdev->dev, &dev_attr_state);
	return ret;
}
コード例 #27
0
ファイル: gpio_keys.c プロジェクト: Flipkart/linux
/*
 * Translate OpenFirmware node properties into platform_data
 */
static struct gpio_keys_platform_data *
gpio_keys_get_devtree_pdata(struct device *dev)
{
	struct device_node *node, *pp;
	struct gpio_keys_platform_data *pdata;
	struct gpio_keys_button *button;
	int error;
	int nbuttons;
	int i;

	node = dev->of_node;
	if (!node)
		return ERR_PTR(-ENODEV);

	nbuttons = of_get_child_count(node);
	if (nbuttons == 0)
		return ERR_PTR(-ENODEV);

	pdata = devm_kzalloc(dev,
			     sizeof(*pdata) + nbuttons * sizeof(*button),
			     GFP_KERNEL);
	if (!pdata)
		return ERR_PTR(-ENOMEM);

	pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
	pdata->nbuttons = nbuttons;

	pdata->rep = !!of_get_property(node, "autorepeat", NULL);

	i = 0;
	for_each_child_of_node(node, pp) {
		enum of_gpio_flags flags;

		button = &pdata->buttons[i++];

		button->gpio = of_get_gpio_flags(pp, 0, &flags);
		if (button->gpio < 0) {
			error = button->gpio;
			if (error != -ENOENT) {
				if (error != -EPROBE_DEFER)
					dev_err(dev,
						"Failed to get gpio flags, error: %d\n",
						error);
				return ERR_PTR(error);
			}
		} else {
			button->active_low = flags & OF_GPIO_ACTIVE_LOW;
		}

		button->irq = irq_of_parse_and_map(pp, 0);

		if (!gpio_is_valid(button->gpio) && !button->irq) {
			dev_err(dev, "Found button without gpios or irqs\n");
			return ERR_PTR(-EINVAL);
		}

		if (of_property_read_u32(pp, "linux,code", &button->code)) {
			dev_err(dev, "Button without keycode: 0x%x\n",
				button->gpio);
			return ERR_PTR(-EINVAL);
		}

		button->desc = of_get_property(pp, "label", NULL);

		if (of_property_read_u32(pp, "linux,input-type", &button->type))
			button->type = EV_KEY;

		button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);

		button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL);

		if (of_property_read_u32(pp, "debounce-interval",
					 &button->debounce_interval))
			button->debounce_interval = 5;
	}

	if (pdata->nbuttons == 0)
		return ERR_PTR(-EINVAL);

	return pdata;
}
コード例 #28
0
/*
 * Translate OpenFirmware node properties into platform_data
 */
static struct gpio_keys_platform_data *
gpio_keys_get_devtree_pdata(struct device *dev)
{
    struct device_node *node, *pp;
    struct gpio_keys_platform_data *pdata;
    struct gpio_keys_button *button;
    int error;
    int nbuttons;
    int i;

    node = dev->of_node;
    if (!node) {
        error = -ENODEV;
        goto err_out;
    }

    nbuttons = of_get_child_count(node);
    if (nbuttons == 0) {
        error = -ENODEV;
        goto err_out;
    }

    pdata = kzalloc(sizeof(*pdata) + nbuttons * (sizeof *button),
                    GFP_KERNEL);
    if (!pdata) {
        error = -ENOMEM;
        goto err_out;
    }

    pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
    pdata->nbuttons = nbuttons;

    pdata->rep = !!of_get_property(node, "autorepeat", NULL);

    i = 0;
    for_each_child_of_node(node, pp) {
        int gpio;
        enum of_gpio_flags flags;

        if (!of_find_property(pp, "gpios", NULL)) {
            pdata->nbuttons--;
            dev_warn(dev, "Found button without gpios\n");
            continue;
        }

        gpio = of_get_gpio_flags(pp, 0, &flags);
        if (gpio < 0) {
            error = gpio;
            if (error != -EPROBE_DEFER)
                dev_err(dev,
                        "Failed to get gpio flags, error: %d\n",
                        error);
            goto err_free_pdata;
        }

        button = &pdata->buttons[i++];

        button->gpio = gpio;
        button->active_low = flags & OF_GPIO_ACTIVE_LOW;

        if (of_property_read_u32(pp, "linux,code", &button->code)) {
            dev_err(dev, "Button without keycode: 0x%x\n",
                    button->gpio);
            error = -EINVAL;
            goto err_free_pdata;
        }

        button->desc = of_get_property(pp, "label", NULL);

        if (of_property_read_u32(pp, "linux,input-type", &button->type))
            button->type = EV_KEY;

        button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);

        if (of_property_read_u32(pp, "debounce-interval",
                                 &button->debounce_interval))
            button->debounce_interval = 5;
    }
コード例 #29
0
static int max17135_pmic_dt_parse_pdata(struct platform_device *pdev,
					struct max17135_platform_data *pdata)
{
	struct max17135 *max17135 = dev_get_drvdata(pdev->dev.parent);
	struct device_node *pmic_np, *regulators_np, *reg_np;
	struct max17135_regulator_data *rdata;
	int i, ret;

	pmic_np = of_node_get(max17135->dev->of_node);
	if (!pmic_np) {
		dev_err(&pdev->dev, "could not find pmic sub-node\n");
		return -ENODEV;
	}

	regulators_np = of_find_node_by_name(pmic_np, "regulators");
	if (!regulators_np) {
		dev_err(&pdev->dev, "could not find regulators sub-node\n");
		return -EINVAL;
	}

	pdata->num_regulators = of_get_child_count(regulators_np);
	dev_dbg(&pdev->dev, "num_regulators %d\n", pdata->num_regulators);

	rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
				pdata->num_regulators, GFP_KERNEL);
	if (!rdata) {
		of_node_put(regulators_np);
		dev_err(&pdev->dev, "could not allocate memory for"
			"regulator data\n");
		return -ENOMEM;
	}

	pdata->regulators = rdata;
	for_each_child_of_node(regulators_np, reg_np) {
		for (i = 0; i < ARRAY_SIZE(max17135_reg); i++)
			if (!of_node_cmp(reg_np->name, max17135_reg[i].name))
				break;

		if (i == ARRAY_SIZE(max17135_reg)) {
			dev_warn(&pdev->dev, "don't know how to configure"
				"regulator %s\n", reg_np->name);
			continue;
		}

		rdata->id = i;
		rdata->initdata = of_get_regulator_init_data(&pdev->dev,
							     reg_np,
							     &max17135_reg[i]);
		rdata->reg_node = reg_np;
		rdata++;
	}
	of_node_put(regulators_np);

	CHECK_PROPERTY_ERROR_KFREE(vneg_pwrup);
	CHECK_PROPERTY_ERROR_KFREE(gvee_pwrup);
	CHECK_PROPERTY_ERROR_KFREE(vpos_pwrup);
	CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrup);
	CHECK_PROPERTY_ERROR_KFREE(gvdd_pwrdn);
	CHECK_PROPERTY_ERROR_KFREE(vpos_pwrdn);
	CHECK_PROPERTY_ERROR_KFREE(gvee_pwrdn);
	CHECK_PROPERTY_ERROR_KFREE(vneg_pwrdn);

	dev_dbg(&pdev->dev, "vneg_pwrup %d, vneg_pwrdn %d, vpos_pwrup %d,"
		"vpos_pwrdn %d, gvdd_pwrup %d, gvdd_pwrdn %d, gvee_pwrup %d,"
		"gvee_pwrdn %d\n", max17135->vneg_pwrup, max17135->vneg_pwrdn,
		max17135->vpos_pwrup, max17135->vpos_pwrdn,
		max17135->gvdd_pwrup, max17135->gvdd_pwrdn,
		max17135->gvee_pwrup, max17135->gvee_pwrdn);

	max17135->max_wait = max17135->vpos_pwrup + max17135->vneg_pwrup +
		max17135->gvdd_pwrup + max17135->gvee_pwrup;

	max17135->gpio_pmic_wakeup = of_get_named_gpio(pmic_np,
					"gpio_pmic_wakeup", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_wakeup)) {
		dev_err(&pdev->dev, "no epdc pmic wakeup pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_wakeup,
				GPIOF_OUT_INIT_LOW, "epdc-pmic-wake");
	if (ret < 0)
		goto err;

	max17135->gpio_pmic_vcom_ctrl = of_get_named_gpio(pmic_np,
					"gpio_pmic_vcom_ctrl", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_vcom_ctrl)) {
		dev_err(&pdev->dev, "no epdc pmic vcom_ctrl pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_vcom_ctrl,
				GPIOF_OUT_INIT_LOW, "epdc-vcom");
	if (ret < 0)
		goto err;

	max17135->gpio_pmic_v3p3 = of_get_named_gpio(pmic_np,
					"gpio_pmic_v3p3", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_v3p3)) {
		dev_err(&pdev->dev, "no epdc pmic v3p3 pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_v3p3,
				GPIOF_OUT_INIT_LOW, "epdc-v3p3");
	if (ret < 0)
		goto err;

	max17135->gpio_pmic_intr = of_get_named_gpio(pmic_np,
					"gpio_pmic_intr", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_intr)) {
		dev_err(&pdev->dev, "no epdc pmic intr pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_intr,
				GPIOF_IN, "epdc-pmic-int");
	if (ret < 0)
		goto err;

	max17135->gpio_pmic_pwrgood = of_get_named_gpio(pmic_np,
					"gpio_pmic_pwrgood", 0);
	if (!gpio_is_valid(max17135->gpio_pmic_pwrgood)) {
		dev_err(&pdev->dev, "no epdc pmic pwrgood pin available\n");
		goto err;
	}
	ret = devm_gpio_request_one(&pdev->dev, max17135->gpio_pmic_pwrgood,
				GPIOF_IN, "epdc-pwrstat");
	if (ret < 0)
		goto err;

err:
	return 0;

}
コード例 #30
0
ファイル: oxnas_nand.c プロジェクト: AshishNamdev/linux
/*
 * Probe for the NAND device.
 */
static int oxnas_nand_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *nand_np;
	struct oxnas_nand_ctrl *oxnas;
	struct nand_chip *chip;
	struct mtd_info *mtd;
	struct resource *res;
	int nchips = 0;
	int count = 0;
	int err = 0;

	/* Allocate memory for the device structure (and zero it) */
	oxnas = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
			     GFP_KERNEL);
	if (!oxnas)
		return -ENOMEM;

	nand_hw_control_init(&oxnas->base);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	oxnas->io_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(oxnas->io_base))
		return PTR_ERR(oxnas->io_base);

	oxnas->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(oxnas->clk))
		oxnas->clk = NULL;

	/* Only a single chip node is supported */
	count = of_get_child_count(np);
	if (count > 1)
		return -EINVAL;

	clk_prepare_enable(oxnas->clk);
	device_reset_optional(&pdev->dev);

	for_each_child_of_node(np, nand_np) {
		chip = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
				    GFP_KERNEL);
		if (!chip)
			return -ENOMEM;

		chip->controller = &oxnas->base;

		nand_set_flash_node(chip, nand_np);
		nand_set_controller_data(chip, oxnas);

		mtd = nand_to_mtd(chip);
		mtd->dev.parent = &pdev->dev;
		mtd->priv = chip;

		chip->cmd_ctrl = oxnas_nand_cmd_ctrl;
		chip->read_buf = oxnas_nand_read_buf;
		chip->read_byte = oxnas_nand_read_byte;
		chip->write_buf = oxnas_nand_write_buf;
		chip->chip_delay = 30;

		/* Scan to find existence of the device */
		err = nand_scan(mtd, 1);
		if (err)
			return err;

		err = mtd_device_register(mtd, NULL, 0);
		if (err) {
			nand_release(mtd);
			return err;
		}

		oxnas->chips[nchips] = chip;
		++nchips;
	}