static int create_sysfs_entry_channel(struct hidma_mgmt_dev *mdev, char *name,
				      int mode, int index,
				      struct kobject *parent)
{
	struct hidma_chan_attr *chattr;
	char *name_copy;

	chattr = devm_kmalloc(&mdev->pdev->dev, sizeof(*chattr), GFP_KERNEL);
	if (!chattr)
		return -ENOMEM;

	name_copy = devm_kstrdup(&mdev->pdev->dev, name, GFP_KERNEL);
	if (!name_copy)
		return -ENOMEM;

	chattr->mdev = mdev;
	chattr->index = index;
	chattr->attr.attr.name = name_copy;
	chattr->attr.attr.mode = mode;
	chattr->attr.show = show_values_channel;
	chattr->attr.store = set_values_channel;
	sysfs_attr_init(&chattr->attr.attr);

	return sysfs_create_file(parent, &chattr->attr.attr);
}
Пример #2
0
static int __ufs_qcom_phy_init_vreg(struct device *dev,
                                    struct ufs_qcom_phy_vreg *vreg, const char *name, bool optional)
{
    int err = 0;

    char prop_name[MAX_PROP_NAME];

    vreg->name = devm_kstrdup(dev, name, GFP_KERNEL);
    if (!vreg->name) {
        err = -ENOMEM;
        goto out;
    }

    vreg->reg = devm_regulator_get(dev, name);
    if (IS_ERR(vreg->reg)) {
        err = PTR_ERR(vreg->reg);
        vreg->reg = NULL;
        if (!optional)
            dev_err(dev, "failed to get %s, %d\n", name, err);
        goto out;
    }

    if (dev->of_node) {
        snprintf(prop_name, MAX_PROP_NAME, "%s-max-microamp", name);
        err = of_property_read_u32(dev->of_node,
                                   prop_name, &vreg->max_uA);
        if (err && err != -EINVAL) {
            dev_err(dev, "%s: failed to read %s\n",
                    __func__, prop_name);
            goto out;
        } else if (err == -EINVAL || !vreg->max_uA) {
            if (regulator_count_voltages(vreg->reg) > 0) {
                dev_err(dev, "%s: %s is mandatory\n",
                        __func__, prop_name);
                goto out;
            }
            err = 0;
        }
        snprintf(prop_name, MAX_PROP_NAME, "%s-always-on", name);
        vreg->is_always_on = of_property_read_bool(dev->of_node,
                             prop_name);
    }

    if (!strcmp(name, "vdda-pll")) {
        vreg->max_uV = VDDA_PLL_MAX_UV;
        vreg->min_uV = VDDA_PLL_MIN_UV;
    } else if (!strcmp(name, "vdda-phy")) {
        vreg->max_uV = VDDA_PHY_MAX_UV;
        vreg->min_uV = VDDA_PHY_MIN_UV;
    } else if (!strcmp(name, "vddp-ref-clk")) {
        vreg->max_uV = VDDP_REF_CLK_MAX_UV;
        vreg->min_uV = VDDP_REF_CLK_MIN_UV;
    }

out:
    if (err)
        kfree(vreg->name);
    return err;
}
Пример #3
0
static int __init gef_gpio_probe(struct platform_device *pdev)
{
	const struct of_device_id *of_id =
		of_match_device(gef_gpio_ids, &pdev->dev);
	struct gpio_chip *gc;
	void __iomem *regs;
	int ret;

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

	regs = of_iomap(pdev->dev.of_node, 0);
	if (!regs)
		return -ENOMEM;

	ret = bgpio_init(gc, &pdev->dev, 4, regs + GEF_GPIO_IN,
			 regs + GEF_GPIO_OUT, NULL, NULL,
			 regs + GEF_GPIO_DIRECT, BGPIOF_BIG_ENDIAN_BYTE_ORDER);
	if (ret) {
		dev_err(&pdev->dev, "bgpio_init failed\n");
		goto err0;
	}

	/* Setup pointers to chip functions */
	gc->label = devm_kstrdup(&pdev->dev, pdev->dev.of_node->full_name,
				     GFP_KERNEL);
	if (!gc->label) {
		ret = -ENOMEM;
		goto err0;
	}

	gc->base = -1;
	gc->ngpio = (u16)(uintptr_t)of_id->data;
	gc->of_gpio_n_cells = 2;
	gc->of_node = pdev->dev.of_node;

	/* This function adds a memory mapped GPIO chip */
	ret = devm_gpiochip_add_data(&pdev->dev, gc, NULL);
	if (ret)
		goto err0;

	return 0;
err0:
	iounmap(regs);
	pr_err("%s: GPIO chip registration failed\n",
			pdev->dev.of_node->full_name);
	return ret;
};
Пример #4
0
/*
 * of_coresight_parse_endpoint : Parse the given output endpoint @ep
 * and fill the connection information in @conn
 *
 * Parses the local port, remote device name and the remote port.
 *
 * Returns :
 *	 1	- If the parsing is successful and a connection record
 *		  was created for an output connection.
 *	 0	- If the parsing completed without any fatal errors.
 *	-Errno	- Fatal error, abort the scanning.
 */
static int of_coresight_parse_endpoint(struct device *dev,
				       struct device_node *ep,
				       struct coresight_connection *conn)
{
	int ret = 0;
	struct of_endpoint endpoint, rendpoint;
	struct device_node *rparent = NULL;
	struct device_node *rep = NULL;
	struct device *rdev = NULL;

	do {
		/* Parse the local port details */
		if (of_graph_parse_endpoint(ep, &endpoint))
			break;
		/*
		 * Get a handle on the remote endpoint and the device it is
		 * attached to.
		 */
		rep = of_graph_get_remote_endpoint(ep);
		if (!rep)
			break;
		rparent = of_coresight_get_port_parent(rep);
		if (!rparent)
			break;
		if (of_graph_parse_endpoint(rep, &rendpoint))
			break;

		/* If the remote device is not available, defer probing */
		rdev = of_coresight_get_endpoint_device(rparent);
		if (!rdev) {
			ret = -EPROBE_DEFER;
			break;
		}

		conn->outport = endpoint.port;
		conn->child_name = devm_kstrdup(dev,
						dev_name(rdev),
						GFP_KERNEL);
		conn->child_port = rendpoint.port;
		/* Connection record updated */
		ret = 1;
	} while (0);

	of_node_put(rparent);
	of_node_put(rep);
	put_device(rdev);

	return ret;
}
static int create_sysfs_entry(struct hidma_mgmt_dev *dev, char *name, int mode)
{
	struct device_attribute *attrs;
	char *name_copy;

	attrs = devm_kmalloc(&dev->pdev->dev,
			     sizeof(struct device_attribute), GFP_KERNEL);
	if (!attrs)
		return -ENOMEM;

	name_copy = devm_kstrdup(&dev->pdev->dev, name, GFP_KERNEL);
	if (!name_copy)
		return -ENOMEM;

	attrs->attr.name = name_copy;
	attrs->attr.mode = mode;
	attrs->show = show_values;
	attrs->store = set_values;
	sysfs_attr_init(&attrs->attr);

	return device_create_file(&dev->pdev->dev, attrs);
}
Пример #6
0
static int reg_fixed_voltage_probe(struct platform_device *pdev)
{
	struct fixed_voltage_config *config;
	struct fixed_voltage_data *drvdata;
	struct regulator_config cfg = { };
	int ret;

	if (pdev->dev.of_node) {
		config = of_get_fixed_voltage_config(&pdev->dev);
		if (IS_ERR(config))
			return PTR_ERR(config);
	} else {
		config = dev_get_platdata(&pdev->dev);
	}

	if (!config)
		return -ENOMEM;

	drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
			       GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	drvdata->desc.name = devm_kstrdup(&pdev->dev,
					  config->supply_name,
					  GFP_KERNEL);
	if (drvdata->desc.name == NULL) {
		dev_err(&pdev->dev, "Failed to allocate supply name\n");
		return -ENOMEM;
	}
	drvdata->desc.type = REGULATOR_VOLTAGE;
	drvdata->desc.owner = THIS_MODULE;
	drvdata->desc.ops = &fixed_voltage_ops;

	drvdata->desc.enable_time = config->startup_delay;

	if (config->input_supply) {
		drvdata->desc.supply_name = devm_kstrdup(&pdev->dev,
					    config->input_supply,
					    GFP_KERNEL);
		if (!drvdata->desc.supply_name) {
			dev_err(&pdev->dev,
				"Failed to allocate input supply\n");
			return -ENOMEM;
		}
	}

	if (config->microvolts)
		drvdata->desc.n_voltages = 1;

	drvdata->desc.fixed_uV = config->microvolts;

	if (config->gpio >= 0)
		cfg.ena_gpio = config->gpio;
	cfg.ena_gpio_invert = !config->enable_high;
	if (config->enabled_at_boot) {
		if (config->enable_high)
			cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
		else
			cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW;
	} else {
		if (config->enable_high)
			cfg.ena_gpio_flags |= GPIOF_OUT_INIT_LOW;
		else
			cfg.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
	}
	if (config->gpio_is_open_drain)
		cfg.ena_gpio_flags |= GPIOF_OPEN_DRAIN;

	cfg.dev = &pdev->dev;
	cfg.init_data = config->init_data;
	cfg.driver_data = drvdata;
	cfg.of_node = pdev->dev.of_node;

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

	platform_set_drvdata(pdev, drvdata);

	dev_dbg(&pdev->dev, "%s supplying %duV\n", drvdata->desc.name,
		drvdata->desc.fixed_uV);

	return 0;
}
Пример #7
0
/*
 * The SD/eMMC IP block has an internal mux and divider used for
 * generating the MMC clock.  Use the clock framework to create and
 * manage these clocks.
 */
static int meson_mmc_clk_init(struct meson_host *host)
{
	struct clk_init_data init;
	char clk_name[32];
	int i, ret = 0;
	const char *mux_parent_names[MUX_CLK_NUM_PARENTS];
	unsigned int mux_parent_count = 0;
	const char *clk_div_parents[1];
	u32 clk_reg, cfg;

	/* get the mux parents */
	for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
		char name[16];

		snprintf(name, sizeof(name), "clkin%d", i);
		host->mux_parent[i] = devm_clk_get(host->dev, name);
		if (IS_ERR(host->mux_parent[i])) {
			ret = PTR_ERR(host->mux_parent[i]);
			if (PTR_ERR(host->mux_parent[i]) != -EPROBE_DEFER)
				dev_err(host->dev, "Missing clock %s\n", name);
			host->mux_parent[i] = NULL;
			return ret;
		}

		mux_parent_names[i] = __clk_get_name(host->mux_parent[i]);
		mux_parent_count++;
	}

	/* create the mux */
	snprintf(clk_name, sizeof(clk_name), "%s#mux", dev_name(host->dev));
	init.name = clk_name;
	init.ops = &clk_mux_ops;
	init.flags = 0;
	init.parent_names = mux_parent_names;
	init.num_parents = mux_parent_count;

	host->mux.reg = host->regs + SD_EMMC_CLOCK;
	host->mux.shift = CLK_SRC_SHIFT;
	host->mux.mask = CLK_SRC_MASK;
	host->mux.flags = 0;
	host->mux.table = NULL;
	host->mux.hw.init = &init;

	host->mux_clk = devm_clk_register(host->dev, &host->mux.hw);
	if (WARN_ON(IS_ERR(host->mux_clk)))
		return PTR_ERR(host->mux_clk);

	/* create the divider */
	snprintf(clk_name, sizeof(clk_name), "%s#div", dev_name(host->dev));
	init.name = devm_kstrdup(host->dev, clk_name, GFP_KERNEL);
	init.ops = &clk_divider_ops;
	init.flags = CLK_SET_RATE_PARENT;
	clk_div_parents[0] = __clk_get_name(host->mux_clk);
	init.parent_names = clk_div_parents;
	init.num_parents = ARRAY_SIZE(clk_div_parents);

	host->cfg_div.reg = host->regs + SD_EMMC_CLOCK;
	host->cfg_div.shift = CLK_DIV_SHIFT;
	host->cfg_div.width = CLK_DIV_WIDTH;
	host->cfg_div.hw.init = &init;
	host->cfg_div.flags = CLK_DIVIDER_ONE_BASED |
		CLK_DIVIDER_ROUND_CLOSEST | CLK_DIVIDER_ALLOW_ZERO;

	host->cfg_div_clk = devm_clk_register(host->dev, &host->cfg_div.hw);
	if (WARN_ON(PTR_ERR_OR_ZERO(host->cfg_div_clk)))
		return PTR_ERR(host->cfg_div_clk);

	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
	clk_reg = 0;
	clk_reg |= CLK_PHASE_180 << CLK_PHASE_SHIFT;
	clk_reg |= CLK_SRC_XTAL << CLK_SRC_SHIFT;
	clk_reg |= CLK_DIV_MAX << CLK_DIV_SHIFT;
	clk_reg &= ~CLK_ALWAYS_ON;
	writel(clk_reg, host->regs + SD_EMMC_CLOCK);

	/* Ensure clock starts in "auto" mode, not "always on" */
	cfg = readl(host->regs + SD_EMMC_CFG);
	cfg &= ~CFG_CLK_ALWAYS_ON;
	cfg |= CFG_AUTO_CLK;
	writel(cfg, host->regs + SD_EMMC_CFG);

	ret = clk_prepare_enable(host->cfg_div_clk);
	if (ret)
		return ret;

	/* Get the nearest minimum clock to 400KHz */
	host->mmc->f_min = clk_round_rate(host->cfg_div_clk, 400000);

	ret = meson_mmc_clk_set(host, host->mmc->f_min);
	if (!ret)
		clk_disable_unprepare(host->cfg_div_clk);

	return ret;
}
Пример #8
0
static int iio_hwmon_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct iio_hwmon_state *st;
	struct sensor_device_attribute *a;
	int ret, i;
	int in_i = 1, temp_i = 1, curr_i = 1, humidity_i = 1;
	enum iio_chan_type type;
	struct iio_channel *channels;
	const char *name = "iio_hwmon";
	char *sname;

	if (dev->of_node && dev->of_node->name)
		name = dev->of_node->name;

	channels = iio_channel_get_all(dev);
	if (IS_ERR(channels))
		return PTR_ERR(channels);

	st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
	if (st == NULL) {
		ret = -ENOMEM;
		goto error_release_channels;
	}

	st->channels = channels;

	/* count how many attributes we have */
	while (st->channels[st->num_channels].indio_dev)
		st->num_channels++;

	st->attrs = devm_kzalloc(dev,
				 sizeof(*st->attrs) * (st->num_channels + 1),
				 GFP_KERNEL);
	if (st->attrs == NULL) {
		ret = -ENOMEM;
		goto error_release_channels;
	}

	for (i = 0; i < st->num_channels; i++) {
		a = devm_kzalloc(dev, sizeof(*a), GFP_KERNEL);
		if (a == NULL) {
			ret = -ENOMEM;
			goto error_release_channels;
		}

		sysfs_attr_init(&a->dev_attr.attr);
		ret = iio_get_channel_type(&st->channels[i], &type);
		if (ret < 0)
			goto error_release_channels;

		switch (type) {
		case IIO_VOLTAGE:
			a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
							  "in%d_input",
							  in_i++);
			break;
		case IIO_TEMP:
			a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
							  "temp%d_input",
							  temp_i++);
			break;
		case IIO_CURRENT:
			a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
							  "curr%d_input",
							  curr_i++);
			break;
		case IIO_HUMIDITYRELATIVE:
			a->dev_attr.attr.name = kasprintf(GFP_KERNEL,
							  "humidity%d_input",
							  humidity_i++);
			break;
		default:
			ret = -EINVAL;
			goto error_release_channels;
		}
		if (a->dev_attr.attr.name == NULL) {
			ret = -ENOMEM;
			goto error_release_channels;
		}
		a->dev_attr.show = iio_hwmon_read_val;
		a->dev_attr.attr.mode = S_IRUGO;
		a->index = i;
		st->attrs[i] = &a->dev_attr.attr;
	}

	st->attr_group.attrs = st->attrs;
	st->groups[0] = &st->attr_group;

	sname = devm_kstrdup(dev, name, GFP_KERNEL);
	if (!sname) {
		ret = -ENOMEM;
		goto error_release_channels;
	}

	strreplace(sname, '-', '_');
	st->hwmon_dev = hwmon_device_register_with_groups(dev, sname, st,
							  st->groups);
	if (IS_ERR(st->hwmon_dev)) {
		ret = PTR_ERR(st->hwmon_dev);
		goto error_release_channels;
	}
	platform_set_drvdata(pdev, st);
	return 0;

error_release_channels:
	iio_channel_release_all(channels);
	return ret;
}
Пример #9
0
static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
{
	struct clk_init_data init;
	int i, ret;
	struct device *dev = &dwmac->pdev->dev;
	char clk_name[32];
	const char *clk_div_parents[1];
	const char *mux_parent_names[MUX_CLK_NUM_PARENTS];

	/* get the mux parents from DT */
	for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
		char name[16];

		snprintf(name, sizeof(name), "clkin%d", i);
		dwmac->m250_mux_parent[i] = devm_clk_get(dev, name);
		if (IS_ERR(dwmac->m250_mux_parent[i])) {
			ret = PTR_ERR(dwmac->m250_mux_parent[i]);
			if (ret != -EPROBE_DEFER)
				dev_err(dev, "Missing clock %s\n", name);
			return ret;
		}

		mux_parent_names[i] =
			__clk_get_name(dwmac->m250_mux_parent[i]);
	}

	/* create the m250_mux */
	snprintf(clk_name, sizeof(clk_name), "%s#m250_sel", dev_name(dev));
	init.name = clk_name;
	init.ops = &clk_mux_ops;
	init.flags = CLK_SET_RATE_PARENT;
	init.parent_names = mux_parent_names;
	init.num_parents = MUX_CLK_NUM_PARENTS;

	dwmac->m250_mux.reg = dwmac->regs + PRG_ETH0;
	dwmac->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT;
	dwmac->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK;
	dwmac->m250_mux.flags = 0;
	dwmac->m250_mux.table = NULL;
	dwmac->m250_mux.hw.init = &init;

	dwmac->m250_mux_clk = devm_clk_register(dev, &dwmac->m250_mux.hw);
	if (WARN_ON(IS_ERR(dwmac->m250_mux_clk)))
		return PTR_ERR(dwmac->m250_mux_clk);

	/* create the m250_div */
	snprintf(clk_name, sizeof(clk_name), "%s#m250_div", dev_name(dev));
	init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
	init.ops = &clk_divider_ops;
	init.flags = CLK_SET_RATE_PARENT;
	clk_div_parents[0] = __clk_get_name(dwmac->m250_mux_clk);
	init.parent_names = clk_div_parents;
	init.num_parents = ARRAY_SIZE(clk_div_parents);

	dwmac->m250_div.reg = dwmac->regs + PRG_ETH0;
	dwmac->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT;
	dwmac->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH;
	dwmac->m250_div.hw.init = &init;
	dwmac->m250_div.flags = CLK_DIVIDER_ONE_BASED |
				CLK_DIVIDER_ALLOW_ZERO |
				CLK_DIVIDER_ROUND_CLOSEST;

	dwmac->m250_div_clk = devm_clk_register(dev, &dwmac->m250_div.hw);
	if (WARN_ON(IS_ERR(dwmac->m250_div_clk)))
		return PTR_ERR(dwmac->m250_div_clk);

	/* create the fixed_div2 */
	snprintf(clk_name, sizeof(clk_name), "%s#fixed_div2", dev_name(dev));
	init.name = devm_kstrdup(dev, clk_name, GFP_KERNEL);
	init.ops = &clk_fixed_factor_ops;
	init.flags = CLK_SET_RATE_PARENT;
	clk_div_parents[0] = __clk_get_name(dwmac->m250_div_clk);
	init.parent_names = clk_div_parents;
	init.num_parents = ARRAY_SIZE(clk_div_parents);

	dwmac->fixed_div2.mult = 1;
	dwmac->fixed_div2.div = 2;
	dwmac->fixed_div2.hw.init = &init;

	dwmac->fixed_div2_clk = devm_clk_register(dev, &dwmac->fixed_div2.hw);
	if (WARN_ON(IS_ERR(dwmac->fixed_div2_clk)))
		return PTR_ERR(dwmac->fixed_div2_clk);

	/* create the rgmii_tx_en */
	init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#rgmii_tx_en",
				   dev_name(dev));
	init.ops = &clk_gate_ops;
	init.flags = CLK_SET_RATE_PARENT;
	clk_div_parents[0] = __clk_get_name(dwmac->fixed_div2_clk);
	init.parent_names = clk_div_parents;
	init.num_parents = ARRAY_SIZE(clk_div_parents);

	dwmac->rgmii_tx_en.reg = dwmac->regs + PRG_ETH0;
	dwmac->rgmii_tx_en.bit_idx = PRG_ETH0_RGMII_TX_CLK_EN;
	dwmac->rgmii_tx_en.hw.init = &init;

	dwmac->rgmii_tx_en_clk = devm_clk_register(dev,
						   &dwmac->rgmii_tx_en.hw);
	if (WARN_ON(IS_ERR(dwmac->rgmii_tx_en_clk)))
		return PTR_ERR(dwmac->rgmii_tx_en_clk);

	return 0;
}