pinctrl: mvebu: provide per-control private data

Provide per-control private data into each mvebu pinctrl method, which
will allow us to provide some completely generic helpers without the
global variable and per-instance function definitions that would be
required when we have multiple pin controllers on a SoC.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Russell King 2017-01-13 11:03:20 +00:00 committed by Linus Walleij
parent 30be3fb9b8
commit 20955c5f5c
10 changed files with 88 additions and 39 deletions

View File

@ -25,12 +25,14 @@
static void __iomem *mpp_base; static void __iomem *mpp_base;
static int armada_370_mpp_ctrl_get(unsigned pid, unsigned long *config) static int armada_370_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long *config)
{ {
return default_mpp_ctrl_get(mpp_base, pid, config); return default_mpp_ctrl_get(mpp_base, pid, config);
} }
static int armada_370_mpp_ctrl_set(unsigned pid, unsigned long config) static int armada_370_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long config)
{ {
return default_mpp_ctrl_set(mpp_base, pid, config); return default_mpp_ctrl_set(mpp_base, pid, config);
} }

View File

@ -25,12 +25,14 @@
static void __iomem *mpp_base; static void __iomem *mpp_base;
static int armada_375_mpp_ctrl_get(unsigned pid, unsigned long *config) static int armada_375_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long *config)
{ {
return default_mpp_ctrl_get(mpp_base, pid, config); return default_mpp_ctrl_get(mpp_base, pid, config);
} }
static int armada_375_mpp_ctrl_set(unsigned pid, unsigned long config) static int armada_375_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long config)
{ {
return default_mpp_ctrl_set(mpp_base, pid, config); return default_mpp_ctrl_set(mpp_base, pid, config);
} }

View File

@ -24,12 +24,14 @@
static void __iomem *mpp_base; static void __iomem *mpp_base;
static int armada_38x_mpp_ctrl_get(unsigned pid, unsigned long *config) static int armada_38x_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long *config)
{ {
return default_mpp_ctrl_get(mpp_base, pid, config); return default_mpp_ctrl_get(mpp_base, pid, config);
} }
static int armada_38x_mpp_ctrl_set(unsigned pid, unsigned long config) static int armada_38x_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long config)
{ {
return default_mpp_ctrl_set(mpp_base, pid, config); return default_mpp_ctrl_set(mpp_base, pid, config);
} }

View File

@ -24,12 +24,14 @@
static void __iomem *mpp_base; static void __iomem *mpp_base;
static int armada_39x_mpp_ctrl_get(unsigned pid, unsigned long *config) static int armada_39x_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long *config)
{ {
return default_mpp_ctrl_get(mpp_base, pid, config); return default_mpp_ctrl_get(mpp_base, pid, config);
} }
static int armada_39x_mpp_ctrl_set(unsigned pid, unsigned long config) static int armada_39x_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long config)
{ {
return default_mpp_ctrl_set(mpp_base, pid, config); return default_mpp_ctrl_set(mpp_base, pid, config);
} }

View File

@ -33,12 +33,14 @@
static void __iomem *mpp_base; static void __iomem *mpp_base;
static u32 *mpp_saved_regs; static u32 *mpp_saved_regs;
static int armada_xp_mpp_ctrl_get(unsigned pid, unsigned long *config) static int armada_xp_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long *config)
{ {
return default_mpp_ctrl_get(mpp_base, pid, config); return default_mpp_ctrl_get(mpp_base, pid, config);
} }
static int armada_xp_mpp_ctrl_set(unsigned pid, unsigned long config) static int armada_xp_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long config)
{ {
return default_mpp_ctrl_set(mpp_base, pid, config); return default_mpp_ctrl_set(mpp_base, pid, config);
} }

View File

@ -66,17 +66,20 @@ static void __iomem *mpp4_base;
static void __iomem *pmu_base; static void __iomem *pmu_base;
static struct regmap *gconfmap; static struct regmap *gconfmap;
static int dove_mpp_ctrl_get(unsigned pid, unsigned long *config) static int dove_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long *config)
{ {
return default_mpp_ctrl_get(mpp_base, pid, config); return default_mpp_ctrl_get(mpp_base, pid, config);
} }
static int dove_mpp_ctrl_set(unsigned pid, unsigned long config) static int dove_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long config)
{ {
return default_mpp_ctrl_set(mpp_base, pid, config); return default_mpp_ctrl_set(mpp_base, pid, config);
} }
static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config) static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long *config)
{ {
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
@ -93,7 +96,8 @@ static int dove_pmu_mpp_ctrl_get(unsigned pid, unsigned long *config)
return 0; return 0;
} }
static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config) static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long config)
{ {
unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
@ -114,7 +118,8 @@ static int dove_pmu_mpp_ctrl_set(unsigned pid, unsigned long config)
return 0; return 0;
} }
static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config) static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long *config)
{ {
unsigned long mpp4 = readl(mpp4_base); unsigned long mpp4 = readl(mpp4_base);
unsigned long mask; unsigned long mask;
@ -144,7 +149,8 @@ static int dove_mpp4_ctrl_get(unsigned pid, unsigned long *config)
return 0; return 0;
} }
static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config) static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long config)
{ {
unsigned long mpp4 = readl(mpp4_base); unsigned long mpp4 = readl(mpp4_base);
unsigned long mask; unsigned long mask;
@ -178,7 +184,8 @@ static int dove_mpp4_ctrl_set(unsigned pid, unsigned long config)
return 0; return 0;
} }
static int dove_nand_ctrl_get(unsigned pid, unsigned long *config) static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long *config)
{ {
unsigned int gmpp; unsigned int gmpp;
@ -188,7 +195,8 @@ static int dove_nand_ctrl_get(unsigned pid, unsigned long *config)
return 0; return 0;
} }
static int dove_nand_ctrl_set(unsigned pid, unsigned long config) static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long config)
{ {
regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG, regmap_update_bits(gconfmap, MPP_GENERAL_CONFIG,
NAND_GPIO_EN, NAND_GPIO_EN,
@ -196,7 +204,8 @@ static int dove_nand_ctrl_set(unsigned pid, unsigned long config)
return 0; return 0;
} }
static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config) static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long *config)
{ {
unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
@ -205,7 +214,8 @@ static int dove_audio0_ctrl_get(unsigned pid, unsigned long *config)
return 0; return 0;
} }
static int dove_audio0_ctrl_set(unsigned pid, unsigned long config) static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long config)
{ {
unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL); unsigned long pmu = readl(mpp_base + PMU_MPP_GENERAL_CTRL);
@ -217,7 +227,8 @@ static int dove_audio0_ctrl_set(unsigned pid, unsigned long config)
return 0; return 0;
} }
static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config) static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long *config)
{ {
unsigned int mpp4 = readl(mpp4_base); unsigned int mpp4 = readl(mpp4_base);
unsigned int sspc1; unsigned int sspc1;
@ -247,7 +258,8 @@ static int dove_audio1_ctrl_get(unsigned pid, unsigned long *config)
return 0; return 0;
} }
static int dove_audio1_ctrl_set(unsigned pid, unsigned long config) static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long config)
{ {
unsigned int mpp4 = readl(mpp4_base); unsigned int mpp4 = readl(mpp4_base);
@ -274,11 +286,12 @@ static int dove_audio1_ctrl_set(unsigned pid, unsigned long config)
* break other functions. If you require all mpps as gpio * break other functions. If you require all mpps as gpio
* enforce gpio setting by pinctrl mapping. * enforce gpio setting by pinctrl mapping.
*/ */
static int dove_audio1_ctrl_gpio_req(unsigned pid) static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl_data *data,
unsigned pid)
{ {
unsigned long config; unsigned long config;
dove_audio1_ctrl_get(pid, &config); dove_audio1_ctrl_get(data, pid, &config);
switch (config) { switch (config) {
case 0x02: /* i2s1 : gpio[56:57] */ case 0x02: /* i2s1 : gpio[56:57] */
@ -301,14 +314,16 @@ static int dove_audio1_ctrl_gpio_req(unsigned pid)
} }
/* mpp[52:57] has gpio pins capable of in and out */ /* mpp[52:57] has gpio pins capable of in and out */
static int dove_audio1_ctrl_gpio_dir(unsigned pid, bool input) static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl_data *data,
unsigned pid, bool input)
{ {
if (pid < 52 || pid > 57) if (pid < 52 || pid > 57)
return -ENOTSUPP; return -ENOTSUPP;
return 0; return 0;
} }
static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config) static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long *config)
{ {
unsigned int gcfg1; unsigned int gcfg1;
unsigned int gcfg2; unsigned int gcfg2;
@ -327,7 +342,8 @@ static int dove_twsi_ctrl_get(unsigned pid, unsigned long *config)
return 0; return 0;
} }
static int dove_twsi_ctrl_set(unsigned pid, unsigned long config) static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl_data *data, unsigned pid,
unsigned long config)
{ {
unsigned int gcfg1 = 0; unsigned int gcfg1 = 0;
unsigned int gcfg2 = 0; unsigned int gcfg2 = 0;

View File

@ -23,12 +23,14 @@
static void __iomem *mpp_base; static void __iomem *mpp_base;
static int kirkwood_mpp_ctrl_get(unsigned pid, unsigned long *config) static int kirkwood_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long *config)
{ {
return default_mpp_ctrl_get(mpp_base, pid, config); return default_mpp_ctrl_get(mpp_base, pid, config);
} }
static int kirkwood_mpp_ctrl_set(unsigned pid, unsigned long config) static int kirkwood_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long config)
{ {
return default_mpp_ctrl_set(mpp_base, pid, config); return default_mpp_ctrl_set(mpp_base, pid, config);
} }

View File

@ -39,6 +39,7 @@ struct mvebu_pinctrl_function {
struct mvebu_pinctrl_group { struct mvebu_pinctrl_group {
const char *name; const char *name;
const struct mvebu_mpp_ctrl *ctrl; const struct mvebu_mpp_ctrl *ctrl;
struct mvebu_mpp_ctrl_data *data;
struct mvebu_mpp_ctrl_setting *settings; struct mvebu_mpp_ctrl_setting *settings;
unsigned num_settings; unsigned num_settings;
unsigned gid; unsigned gid;
@ -146,7 +147,7 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
if (!grp->ctrl) if (!grp->ctrl)
return -EINVAL; return -EINVAL;
return grp->ctrl->mpp_get(grp->pins[0], config); return grp->ctrl->mpp_get(grp->data, grp->pins[0], config);
} }
static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev, static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
@ -161,7 +162,7 @@ static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
return -EINVAL; return -EINVAL;
for (i = 0; i < num_configs; i++) { for (i = 0; i < num_configs; i++) {
ret = grp->ctrl->mpp_set(grp->pins[0], configs[i]); ret = grp->ctrl->mpp_set(grp->data, grp->pins[0], configs[i]);
if (ret) if (ret)
return ret; return ret;
} /* for each config */ } /* for each config */
@ -302,7 +303,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
return -EINVAL; return -EINVAL;
if (grp->ctrl->mpp_gpio_req) if (grp->ctrl->mpp_gpio_req)
return grp->ctrl->mpp_gpio_req(offset); return grp->ctrl->mpp_gpio_req(grp->data, offset);
setting = mvebu_pinctrl_find_gpio_setting(pctl, grp); setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
if (!setting) if (!setting)
@ -325,7 +326,7 @@ static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
return -EINVAL; return -EINVAL;
if (grp->ctrl->mpp_gpio_dir) if (grp->ctrl->mpp_gpio_dir)
return grp->ctrl->mpp_gpio_dir(offset, input); return grp->ctrl->mpp_gpio_dir(grp->data, offset, input);
setting = mvebu_pinctrl_find_gpio_setting(pctl, grp); setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);
if (!setting) if (!setting)
@ -621,8 +622,12 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
gid = 0; gid = 0;
for (n = 0; n < soc->ncontrols; n++) { for (n = 0; n < soc->ncontrols; n++) {
const struct mvebu_mpp_ctrl *ctrl = &soc->controls[n]; const struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];
struct mvebu_mpp_ctrl_data *data = soc->control_data ?
&soc->control_data[n] : NULL;
pctl->groups[gid].gid = gid; pctl->groups[gid].gid = gid;
pctl->groups[gid].ctrl = ctrl; pctl->groups[gid].ctrl = ctrl;
pctl->groups[gid].data = data;
pctl->groups[gid].name = ctrl->name; pctl->groups[gid].name = ctrl->name;
pctl->groups[gid].pins = ctrl->pins; pctl->groups[gid].pins = ctrl->pins;
pctl->groups[gid].npins = ctrl->npins; pctl->groups[gid].npins = ctrl->npins;
@ -642,6 +647,7 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
gid++; gid++;
pctl->groups[gid].gid = gid; pctl->groups[gid].gid = gid;
pctl->groups[gid].ctrl = ctrl; pctl->groups[gid].ctrl = ctrl;
pctl->groups[gid].data = data;
pctl->groups[gid].name = noname_buf; pctl->groups[gid].name = noname_buf;
pctl->groups[gid].pins = &ctrl->pins[k]; pctl->groups[gid].pins = &ctrl->pins[k];
pctl->groups[gid].npins = 1; pctl->groups[gid].npins = 1;

View File

@ -13,6 +13,14 @@
#ifndef __PINCTRL_MVEBU_H__ #ifndef __PINCTRL_MVEBU_H__
#define __PINCTRL_MVEBU_H__ #define __PINCTRL_MVEBU_H__
/**
* struct mvebu_mpp_ctrl_data - private data for the mpp ctrl operations
* @base: base address of pinctrl hardware
*/
struct mvebu_mpp_ctrl_data {
void __iomem *base;
};
/** /**
* struct mvebu_mpp_ctrl - describe a mpp control * struct mvebu_mpp_ctrl - describe a mpp control
* @name: name of the control group * @name: name of the control group
@ -37,10 +45,13 @@ struct mvebu_mpp_ctrl {
u8 pid; u8 pid;
u8 npins; u8 npins;
unsigned *pins; unsigned *pins;
int (*mpp_get)(unsigned pid, unsigned long *config); int (*mpp_get)(struct mvebu_mpp_ctrl_data *data, unsigned pid,
int (*mpp_set)(unsigned pid, unsigned long config); unsigned long *config);
int (*mpp_gpio_req)(unsigned pid); int (*mpp_set)(struct mvebu_mpp_ctrl_data *data, unsigned pid,
int (*mpp_gpio_dir)(unsigned pid, bool input); unsigned long config);
int (*mpp_gpio_req)(struct mvebu_mpp_ctrl_data *data, unsigned pid);
int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl_data *data, unsigned pid,
bool input);
}; };
/** /**
@ -93,6 +104,7 @@ struct mvebu_mpp_mode {
* struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu * struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu
* @variant: variant mask of soc_info * @variant: variant mask of soc_info
* @controls: list of available mvebu_mpp_ctrls * @controls: list of available mvebu_mpp_ctrls
* @control_data: optional array, one entry for each control
* @ncontrols: number of available mvebu_mpp_ctrls * @ncontrols: number of available mvebu_mpp_ctrls
* @modes: list of available mvebu_mpp_modes * @modes: list of available mvebu_mpp_modes
* @nmodes: number of available mvebu_mpp_modes * @nmodes: number of available mvebu_mpp_modes
@ -106,6 +118,7 @@ struct mvebu_mpp_mode {
struct mvebu_pinctrl_soc_info { struct mvebu_pinctrl_soc_info {
u8 variant; u8 variant;
const struct mvebu_mpp_ctrl *controls; const struct mvebu_mpp_ctrl *controls;
struct mvebu_mpp_ctrl_data *control_data;
int ncontrols; int ncontrols;
struct mvebu_mpp_mode *modes; struct mvebu_mpp_mode *modes;
int nmodes; int nmodes;

View File

@ -32,7 +32,8 @@
static void __iomem *mpp_base; static void __iomem *mpp_base;
static void __iomem *high_mpp_base; static void __iomem *high_mpp_base;
static int orion_mpp_ctrl_get(unsigned pid, unsigned long *config) static int orion_mpp_ctrl_get(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long *config)
{ {
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
@ -47,7 +48,8 @@ static int orion_mpp_ctrl_get(unsigned pid, unsigned long *config)
return 0; return 0;
} }
static int orion_mpp_ctrl_set(unsigned pid, unsigned long config) static int orion_mpp_ctrl_set(struct mvebu_mpp_ctrl_data *data,
unsigned pid, unsigned long config)
{ {
unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS; unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;