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

Commit 44aa9d06 authored by Russell King's avatar Russell King Committed by Linus Walleij
Browse files

pinctrl: mvebu: provide generic simple mmio-based implementation



Provide a generic simple mmio-based probe function and methods, which
pinctrl drivers can use to initialise the mvebu pinctrl subsystem.
Most mvebu pinctrl drivers can use this.

Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 20955c5f
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -58,6 +58,30 @@ struct mvebu_pinctrl {
	u8 variant;
};

int mvebu_mmio_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
			     unsigned int pid, unsigned long *config)
{
	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;

	*config = (readl(data->base + off) >> shift) & MVEBU_MPP_MASK;

	return 0;
}

int mvebu_mmio_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
			     unsigned int pid, unsigned long config)
{
	unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
	unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
	unsigned long reg;

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

	return 0;
}

static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid(
	struct mvebu_pinctrl *pctl, unsigned pid)
{
@@ -723,3 +747,36 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)

	return 0;
}

/*
 * mvebu_pinctrl_simple_mmio_probe - probe a simple mmio pinctrl
 * @pdev: platform device (with platform data already attached)
 *
 * Initialise a simple (single base address) mmio pinctrl driver,
 * assigning the MMIO base address to all mvebu mpp ctrl instances.
 */
int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev)
{
	struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);
	struct mvebu_mpp_ctrl_data *mpp_data;
	struct resource *res;
	void __iomem *base;
	int i;

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

	mpp_data = devm_kcalloc(&pdev->dev, soc->ncontrols, sizeof(*mpp_data),
				GFP_KERNEL);
	if (!mpp_data)
		return -ENOMEM;

	for (i = 0; i < soc->ncontrols; i++)
		mpp_data[i].base = base;

	soc->control_data = mpp_data;

	return mvebu_pinctrl_probe(pdev);
}
+6 −0
Original line number Diff line number Diff line
@@ -214,6 +214,12 @@ static inline int default_mpp_ctrl_set(void __iomem *base, unsigned int pid,
	return 0;
}

int mvebu_mmio_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
			       unsigned long *config);
int mvebu_mmio_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
			       unsigned long config);

int mvebu_pinctrl_probe(struct platform_device *pdev);
int mvebu_pinctrl_simple_mmio_probe(struct platform_device *pdev);

#endif