pinctrl: single: Prepare for supporting SoC specific features

Let's replace is_pinconf with flags and add struct pcs_soc_data
so we can support SoC specific features like pin wake-up events.

Done in collaboration with Roger Quadros <rogerq@ti.com>.

Cc: Peter Ujfalusi <peter.ujfalusi@ti.com>
Cc: Grygorii Strashko <grygorii.strashko@ti.com>
Cc: Prakash Manjunathappa <prakash.pm@ti.com>
Cc: linux-kernel@vger.kernel.org
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Reviewed-by: Kevin Hilman <khilman@linaro.org>
Tested-by: Kevin Hilman <khilman@linaro.org>
Signed-off-by: Roger Quadros <rogerq@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
This commit is contained in:
Tony Lindgren 2013-10-02 21:39:39 -07:00
parent d0e639c9e0
commit 02e483f66d
1 changed files with 29 additions and 9 deletions

View File

@ -149,6 +149,14 @@ struct pcs_name {
char name[PCS_REG_NAME_LEN];
};
/**
* struct pcs_soc_data - SoC specific settings
* @flags: initial SoC specific PCS_FEAT_xxx values
*/
struct pcs_soc_data {
unsigned flags;
};
/**
* struct pcs_device - pinctrl device instance
* @res: resources
@ -156,13 +164,13 @@ struct pcs_name {
* @size: size of the ioremapped area
* @dev: device entry
* @pctl: pin controller device
* @flags: mask of PCS_FEAT_xxx values
* @mutex: mutex protecting the lists
* @width: bits per mux register
* @fmask: function register mask
* @fshift: function register shift
* @foff: value to turn mux off
* @fmax: max number of functions in fmask
* @is_pinconf: whether supports pinconf
* @bits_per_pin:number of bits per pin
* @names: array of register names for pins
* @pins: physical pins on the SoC
@ -183,6 +191,8 @@ struct pcs_device {
unsigned size;
struct device *dev;
struct pinctrl_dev *pctl;
unsigned flags;
#define PCS_FEAT_PINCONF (1 << 0)
struct mutex mutex;
unsigned width;
unsigned fmask;
@ -190,7 +200,6 @@ struct pcs_device {
unsigned foff;
unsigned fmax;
bool bits_per_mux;
bool is_pinconf;
unsigned bits_per_pin;
struct pcs_name *names;
struct pcs_data pins;
@ -206,6 +215,8 @@ struct pcs_device {
void (*write)(unsigned val, void __iomem *reg);
};
#define PCS_HAS_PINCONF (pcs->flags & PCS_FEAT_PINCONF)
static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config);
static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
@ -1060,7 +1071,7 @@ static int pcs_parse_pinconf(struct pcs_device *pcs, struct device_node *np,
};
/* If pinconf isn't supported, don't parse properties in below. */
if (!pcs->is_pinconf)
if (!PCS_HAS_PINCONF)
return 0;
/* cacluate how much properties are supported in current node */
@ -1184,7 +1195,7 @@ static int pcs_parse_one_pinctrl_entry(struct pcs_device *pcs,
(*map)->data.mux.group = np->name;
(*map)->data.mux.function = np->name;
if (pcs->is_pinconf) {
if (PCS_HAS_PINCONF) {
res = pcs_parse_pinconf(pcs, np, function, map);
if (res)
goto free_pingroups;
@ -1305,7 +1316,7 @@ static int pcs_parse_bits_in_pinctrl_entry(struct pcs_device *pcs,
(*map)->data.mux.group = np->name;
(*map)->data.mux.function = np->name;
if (pcs->is_pinconf) {
if (PCS_HAS_PINCONF) {
dev_err(pcs->dev, "pinconf not supported\n");
goto free_pingroups;
}
@ -1525,6 +1536,7 @@ static int pcs_probe(struct platform_device *pdev)
const struct of_device_id *match;
struct resource *res;
struct pcs_device *pcs;
const struct pcs_soc_data *soc;
int ret;
match = of_match_device(pcs_of_match, &pdev->dev);
@ -1541,7 +1553,8 @@ static int pcs_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&pcs->pingroups);
INIT_LIST_HEAD(&pcs->functions);
INIT_LIST_HEAD(&pcs->gpiofuncs);
pcs->is_pinconf = match->data;
soc = match->data;
pcs->flags = soc->flags;
PCS_GET_PROP_U32("pinctrl-single,register-width", &pcs->width,
"register width not specified\n");
@ -1610,7 +1623,7 @@ static int pcs_probe(struct platform_device *pdev)
pcs->desc.name = DRIVER_NAME;
pcs->desc.pctlops = &pcs_pinctrl_ops;
pcs->desc.pmxops = &pcs_pinmux_ops;
if (pcs->is_pinconf)
if (PCS_HAS_PINCONF)
pcs->desc.confops = &pcs_pinconf_ops;
pcs->desc.owner = THIS_MODULE;
@ -1652,9 +1665,16 @@ static int pcs_remove(struct platform_device *pdev)
return 0;
}
static const struct pcs_soc_data pinctrl_single = {
};
static const struct pcs_soc_data pinconf_single = {
.flags = PCS_FEAT_PINCONF,
};
static struct of_device_id pcs_of_match[] = {
{ .compatible = "pinctrl-single", .data = (void *)false },
{ .compatible = "pinconf-single", .data = (void *)true },
{ .compatible = "pinctrl-single", .data = &pinctrl_single },
{ .compatible = "pinconf-single", .data = &pinconf_single },
{ },
};
MODULE_DEVICE_TABLE(of, pcs_of_match);