Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55387764 authored by Jason Cooper's avatar Jason Cooper
Browse files

Merge tag 'tags/for-mvebu-pinctrl-cleanup' into mvebu/pinctrl

Sign for-mvebu/pinctrl-cleanup
parents 38dbfb59 78c2c3d3
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -23,6 +23,18 @@

#include "pinctrl-mvebu.h"

static void __iomem *mpp_base;

static int armada_370_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
	return default_mpp_ctrl_get(mpp_base, pid, config);
}

static int armada_370_mpp_ctrl_set(unsigned pid, unsigned long config)
{
	return default_mpp_ctrl_set(mpp_base, pid, config);
}

static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = {
	MPP_MODE(0,
	   MPP_FUNCTION(0x0, "gpio", NULL),
@@ -373,7 +385,7 @@ static struct of_device_id armada_370_pinctrl_of_match[] = {
};

static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = {
	MPP_REG_CTRL(0, 65),
	MPP_FUNC_CTRL(0, 65, NULL, armada_370_mpp_ctrl),
};

static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
@@ -385,6 +397,12 @@ static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = {
static int armada_370_pinctrl_probe(struct platform_device *pdev)
{
	struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info;
	struct resource *res;

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

	soc->variant = 0; /* no variants for Armada 370 */
	soc->controls = mv88f6710_mpp_controls;
+21 −3
Original line number Diff line number Diff line
@@ -33,6 +33,18 @@

#include "pinctrl-mvebu.h"

static void __iomem *mpp_base;

static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
	return default_mpp_ctrl_get(mpp_base, pid, config);
}

static int armada_xp_mpp_ctrl_set(unsigned pid, unsigned long config)
{
	return default_mpp_ctrl_set(mpp_base, pid, config);
}

enum armada_xp_variant {
	V_MV78230	= BIT(0),
	V_MV78260	= BIT(1),
@@ -366,7 +378,7 @@ static struct of_device_id armada_xp_pinctrl_of_match[] = {
};

static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = {
	MPP_REG_CTRL(0, 48),
	MPP_FUNC_CTRL(0, 48, NULL, armada_xp_mpp_ctrl),
};

static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
@@ -375,7 +387,7 @@ static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = {
};

static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = {
	MPP_REG_CTRL(0, 66),
	MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
};

static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
@@ -385,7 +397,7 @@ static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = {
};

static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = {
	MPP_REG_CTRL(0, 66),
	MPP_FUNC_CTRL(0, 66, NULL, armada_xp_mpp_ctrl),
};

static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = {
@@ -399,10 +411,16 @@ static int armada_xp_pinctrl_probe(struct platform_device *pdev)
	struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info;
	const struct of_device_id *match =
		of_match_device(armada_xp_pinctrl_of_match, &pdev->dev);
	struct resource *res;

	if (!match)
		return -ENODEV;

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

	soc->variant = (unsigned) match->data & 0xff;

	switch (soc->variant) {
+58 −75
Original line number Diff line number Diff line
@@ -49,62 +49,64 @@
#define  DOVE_SD1_GPIO_SEL		BIT(1)
#define  DOVE_SD0_GPIO_SEL		BIT(0)

#define MPPS_PER_REG	8
#define MPP_BITS	4
#define MPP_MASK	0xf

#define CONFIG_PMU	BIT(4)

static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
				 unsigned long *config)
static void __iomem *mpp_base;

static int dove_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
	return default_mpp_ctrl_get(mpp_base, pid, config);
}

static int dove_mpp_ctrl_set(unsigned pid, unsigned long config)
{
	return default_mpp_ctrl_set(mpp_base, pid, config);
}

static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
	unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
	unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
	unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
	unsigned long func;

	if (pmu & (1 << ctrl->pid)) {
	if ((pmu & BIT(pid)) == 0)
		return default_mpp_ctrl_get(mpp_base, pid, config);

	func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
		*config = (func >> shift) & MPP_MASK;
	*config = (func >> shift) & MVEBU_MPP_MASK;
	*config |= CONFIG_PMU;
	} else {
		func = readl(DOVE_MPP_VIRT_BASE + off);
		*config = (func >> shift) & MPP_MASK;
	}

	return 0;
}

static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
				 unsigned long config)
static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config)
{
	unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS;
	unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS;
	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
	unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);
	unsigned long func;

	if (config & CONFIG_PMU) {
		writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
	if ((config & CONFIG_PMU) == 0) {
		writel(pmu & ~BIT(pid), DOVE_PMU_MPP_GENERAL_CTRL);
		return default_mpp_ctrl_set(mpp_base, pid, config);
	}

	writel(pmu | BIT(pid), DOVE_PMU_MPP_GENERAL_CTRL);
	func = readl(DOVE_PMU_SIGNAL_SELECT_0 + off);
		func &= ~(MPP_MASK << shift);
		func |= (config & MPP_MASK) << shift;
	func &= ~(MVEBU_MPP_MASK << shift);
	func |= (config & MVEBU_MPP_MASK) << shift;
	writel(func, DOVE_PMU_SIGNAL_SELECT_0 + off);
	} else {
		writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL);
		func = readl(DOVE_MPP_VIRT_BASE + off);
		func &= ~(MPP_MASK << shift);
		func |= (config & MPP_MASK) << shift;
		writel(func, DOVE_MPP_VIRT_BASE + off);
	}

	return 0;
}

static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
			      unsigned long *config)
static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config)
{
	unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
	unsigned long mask;

	switch (ctrl->pid) {
	switch (pid) {
	case 24: /* mpp_camera */
		mask = DOVE_CAM_GPIO_SEL;
		break;
@@ -129,13 +131,12 @@ static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
	return 0;
}

static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
			      unsigned long config)
static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config)
{
	unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
	unsigned long mask;

	switch (ctrl->pid) {
	switch (pid) {
	case 24: /* mpp_camera */
		mask = DOVE_CAM_GPIO_SEL;
		break;
@@ -164,8 +165,7 @@ static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
	return 0;
}

static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
			      unsigned long *config)
static int dove_nand_ctrl_get(unsigned pid, unsigned long *config)
{
	unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);

@@ -174,8 +174,7 @@ static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
	return 0;
}

static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
			      unsigned long config)
static int dove_nand_ctrl_set(unsigned pid, unsigned long config)
{
	unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE);

@@ -188,8 +187,7 @@ static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
	return 0;
}

static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
				unsigned long *config)
static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config)
{
	unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);

@@ -198,8 +196,7 @@ static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
	return 0;
}

static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
				unsigned long config)
static int dove_audio0_ctrl_set(unsigned pid, unsigned long config)
{
	unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL);

@@ -211,8 +208,7 @@ static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
	return 0;
}

static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
				unsigned long *config)
static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config)
{
	unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
	unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
@@ -238,8 +234,7 @@ static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
	return 0;
}

static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
				unsigned long config)
static int dove_audio1_ctrl_set(unsigned pid, unsigned long config)
{
	unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
	unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1);
@@ -276,11 +271,11 @@ static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
 * break other functions. If you require all mpps as gpio
 * enforce gpio setting by pinctrl mapping.
 */
static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
static int dove_audio1_ctrl_gpio_req(unsigned pid)
{
	unsigned long config;

	dove_audio1_ctrl_get(ctrl, &config);
	dove_audio1_ctrl_get(pid, &config);

	switch (config) {
	case 0x02: /* i2s1 : gpio[56:57] */
@@ -303,16 +298,14 @@ static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid)
}

/* mpp[52:57] has gpio pins capable of in and out */
static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid,
				bool input)
static int dove_audio1_ctrl_gpio_dir(unsigned pid, bool input)
{
	if (pid < 52 || pid > 57)
		return -ENOTSUPP;
	return 0;
}

static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
			      unsigned long *config)
static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config)
{
	unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
	unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
@@ -328,8 +321,7 @@ static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl,
	return 0;
}

static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
				unsigned long config)
static int dove_twsi_ctrl_set(unsigned pid, unsigned long config)
{
	unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1);
	unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2);
@@ -356,23 +348,8 @@ static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl,
}

static struct mvebu_mpp_ctrl dove_mpp_controls[] = {
	MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl),
	MPP_REG_CTRL(16, 23),
	MPP_FUNC_CTRL(0, 15, NULL, dove_pmu_mpp_ctrl),
	MPP_FUNC_CTRL(16, 23, NULL, dove_mpp_ctrl),
	MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl),
	MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl),
	MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl),
@@ -774,6 +751,7 @@ static struct of_device_id dove_pinctrl_of_match[] = {

static int dove_pinctrl_probe(struct platform_device *pdev)
{
	struct resource *res;
	const struct of_device_id *match =
		of_match_device(dove_pinctrl_of_match, &pdev->dev);
	pdev->dev.platform_data = (void *)match->data;
@@ -789,6 +767,11 @@ static int dove_pinctrl_probe(struct platform_device *pdev)
	}
	clk_prepare_enable(clk);

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

	return mvebu_pinctrl_probe(pdev);
}

+22 −3
Original line number Diff line number Diff line
@@ -21,6 +21,18 @@

#include "pinctrl-mvebu.h"

static void __iomem *mpp_base;

static int kirkwood_mpp_ctrl_get(unsigned pid, unsigned long *config)
{
	return default_mpp_ctrl_get(mpp_base, pid, config);
}

static int kirkwood_mpp_ctrl_set(unsigned pid, unsigned long config)
{
	return default_mpp_ctrl_set(mpp_base, pid, config);
}

#define V(f6180, f6190, f6192, f6281, f6282, dx4122)	\
	((f6180 << 0) | (f6190 << 1) | (f6192 << 2) |	\
	 (f6281 << 3) | (f6282 << 4) | (dx4122 << 5))
@@ -359,7 +371,7 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = {
};

static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = {
	MPP_REG_CTRL(0, 29),
	MPP_FUNC_CTRL(0, 29, NULL, kirkwood_mpp_ctrl),
};

static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
@@ -367,7 +379,7 @@ static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = {
};

static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = {
	MPP_REG_CTRL(0, 35),
	MPP_FUNC_CTRL(0, 35, NULL, kirkwood_mpp_ctrl),
};

static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
@@ -376,7 +388,7 @@ static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = {
};

static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = {
	MPP_REG_CTRL(0, 49),
	MPP_FUNC_CTRL(0, 49, NULL, kirkwood_mpp_ctrl),
};

static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = {
@@ -456,9 +468,16 @@ static struct of_device_id kirkwood_pinctrl_of_match[] = {

static int kirkwood_pinctrl_probe(struct platform_device *pdev)
{
	struct resource *res;
	const struct of_device_id *match =
		of_match_device(kirkwood_pinctrl_of_match, &pdev->dev);
	pdev->dev.platform_data = (void *)match->data;

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

	return mvebu_pinctrl_probe(pdev);
}

+38 −84
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ struct mvebu_pinctrl {
	struct device *dev;
	struct pinctrl_dev *pctldev;
	struct pinctrl_desc desc;
	void __iomem *base;
	struct mvebu_pinctrl_group *groups;
	unsigned num_groups;
	struct mvebu_pinctrl_function *functions;
@@ -138,43 +137,6 @@ static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name(
	return NULL;
}

/*
 * Common mpp pin configuration registers on MVEBU are
 * registers of eight 4-bit values for each mpp setting.
 * Register offset and bit mask are calculated accordingly below.
 */
static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl,
				struct mvebu_pinctrl_group *grp,
				unsigned long *config)
{
	unsigned pin = grp->gid;
	unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
	unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;

	*config = readl(pctl->base + off);
	*config >>= shift;
	*config &= MPP_MASK;

	return 0;
}

static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl,
				struct mvebu_pinctrl_group *grp,
				unsigned long config)
{
	unsigned pin = grp->gid;
	unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;
	unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;
	unsigned long reg;

	reg = readl(pctl->base + off);
	reg &= ~(MPP_MASK << shift);
	reg |= (config << shift);
	writel(reg, pctl->base + off);

	return 0;
}

static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
				unsigned gid, unsigned long *config)
{
@@ -184,10 +146,7 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
	if (!grp->ctrl)
		return -EINVAL;

	if (grp->ctrl->mpp_get)
		return grp->ctrl->mpp_get(grp->ctrl, config);

	return mvebu_common_mpp_get(pctl, grp, config);
	return grp->ctrl->mpp_get(grp->pins[0], config);
}

static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
@@ -202,11 +161,7 @@ static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
		return -EINVAL;

	for (i = 0; i < num_configs; i++) {
		if (grp->ctrl->mpp_set)
			ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);
		else
			ret = mvebu_common_mpp_set(pctl, grp, configs[i]);

		ret = grp->ctrl->mpp_set(grp->pins[0], configs[i]);
		if (ret)
			return ret;
	} /* for each config */
@@ -347,7 +302,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
		return -EINVAL;

	if (grp->ctrl->mpp_gpio_req)
		return grp->ctrl->mpp_gpio_req(grp->ctrl, offset);
		return grp->ctrl->mpp_gpio_req(offset);

	setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
	if (!setting)
@@ -370,7 +325,7 @@ static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
		return -EINVAL;

	if (grp->ctrl->mpp_gpio_dir)
		return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input);
		return grp->ctrl->mpp_gpio_dir(offset, input);

	setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
	if (!setting)
@@ -593,11 +548,12 @@ static int mvebu_pinctrl_build_functions(struct platform_device *pdev,
int mvebu_pinctrl_probe(struct platform_device *pdev)
{
	struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
	struct resource *res;
	struct mvebu_pinctrl *pctl;
	void __iomem *base;
	struct pinctrl_pin_desc *pdesc;
	unsigned gid, n, k;
	unsigned size, noname = 0;
	char *noname_buf;
	void *p;
	int ret;

	if (!soc || !soc->controls || !soc->modes) {
@@ -605,11 +561,6 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
		return -EINVAL;
	}

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

	pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),
			GFP_KERNEL);
	if (!pctl) {
@@ -623,7 +574,6 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
	pctl->desc.pmxops = &mvebu_pinmux_ops;
	pctl->desc.confops = &mvebu_pinconf_ops;
	pctl->variant = soc->variant;
	pctl->base = base;
	pctl->dev = &pdev->dev;
	platform_set_drvdata(pdev, pctl);

@@ -633,33 +583,23 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
	pctl->desc.npins = 0;
	for (n = 0; n < soc->ncontrols; n++) {
		struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
		char *names;

		pctl->desc.npins += ctrl->npins;
		/* initial control pins */
		/* initialize control's pins[] array */
		for (k = 0; k < ctrl->npins; k++)
			ctrl->pins[k] = ctrl->pid + k;

		/* special soc specific control */
		if (ctrl->mpp_get || ctrl->mpp_set) {
			if (!ctrl->name || !ctrl->mpp_get || !ctrl->mpp_set) {
				dev_err(&pdev->dev, "wrong soc control info\n");
				return -EINVAL;
			}
		/*
		 * We allow to pass controls with NULL name that we treat
		 * as a range of one-pin groups with generic mvebu register
		 * controls.
		 */
		if (!ctrl->name) {
			pctl->num_groups += ctrl->npins;
			noname += ctrl->npins;
		} else {
			pctl->num_groups += 1;
			continue;
		}

		/* generic mvebu register control */
		names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL);
		if (!names) {
			dev_err(&pdev->dev, "failed to alloc mpp names\n");
			return -ENOMEM;
		}
		for (k = 0; k < ctrl->npins; k++)
			sprintf(names + 8*k, "mpp%d", ctrl->pid+k);
		ctrl->name = names;
		pctl->num_groups += ctrl->npins;
	}

	pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins *
@@ -673,12 +613,17 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
		pdesc[n].number = n;
	pctl->desc.pins = pdesc;

	pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups *
			     sizeof(struct mvebu_pinctrl_group), GFP_KERNEL);
	if (!pctl->groups) {
		dev_err(&pdev->dev, "failed to alloc pinctrl groups\n");
	/*
	 * allocate groups and name buffers for unnamed groups.
	 */
	size = pctl->num_groups * sizeof(*pctl->groups) + noname * 8;
	p = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
	if (!p) {
		dev_err(&pdev->dev, "failed to alloc group data\n");
		return -ENOMEM;
	}
	pctl->groups = p;
	noname_buf = p + pctl->num_groups * sizeof(*pctl->groups);

	/* assign mpp controls to groups */
	gid = 0;
@@ -690,17 +635,26 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
		pctl->groups[gid].pins = ctrl->pins;
		pctl->groups[gid].npins = ctrl->npins;

		/* generic mvebu register control maps to a number of groups */
		if (!ctrl->mpp_get && !ctrl->mpp_set) {
		/*
		 * We treat unnamed controls as a range of one-pin groups
		 * with generic mvebu register controls. Use one group for
		 * each in this range and assign a default group name.
		 */
		if (!ctrl->name) {
			pctl->groups[gid].name = noname_buf;
			pctl->groups[gid].npins = 1;
			sprintf(noname_buf, "mpp%d", ctrl->pid+0);
			noname_buf += 8;

			for (k = 1; k < ctrl->npins; k++) {
				gid++;
				pctl->groups[gid].gid = gid;
				pctl->groups[gid].ctrl = ctrl;
				pctl->groups[gid].name = &ctrl->name[8*k];
				pctl->groups[gid].name = noname_buf;
				pctl->groups[gid].pins = &ctrl->pins[k];
				pctl->groups[gid].npins = 1;
				sprintf(noname_buf, "mpp%d", ctrl->pid+k);
				noname_buf += 8;
			}
		}
		gid++;
Loading