···11+Marvell Dove Platforms Device Tree Bindings22+-----------------------------------------------33+44+Boards with a Marvell Dove SoC shall have the following properties:55+66+Required root node property:77+- compatible: must contain "marvell,dove";88+99+* Global Configuration registers1010+1111+Global Configuration registers of Dove SoC are shared by a syscon node.1212+1313+Required properties:1414+- compatible: must contain "marvell,dove-global-config" and "syscon".1515+- reg: base address and size of the Global Configuration registers.1616+1717+Example:1818+1919+gconf: global-config@e802c {2020+ compatible = "marvell,dove-global-config", "syscon";2121+ reg = <0xe802c 0x14>;2222+};
···5566Required properties:77- compatible: "marvell,88f6710-pinctrl"88+- reg: register specifier of MPP registers89910Available mpp pins/groups and functions:1011Note: brackets (x) are not part of the mpp name for marvell,function and given
···66Required properties:77- compatible: "marvell,mv78230-pinctrl", "marvell,mv78260-pinctrl",88 "marvell,mv78460-pinctrl"99+- reg: register specifier of MPP registers9101011This driver supports all Armada XP variants, i.e. mv78230, mv78260, and mv78460.1112
···66Required properties:77- compatible: "marvell,dove-pinctrl"88- clocks: (optional) phandle of pdma clock99+- reg: register specifiers of MPP, MPP4, and PMU MPP registers9101011Available mpp pins/groups and functions:1112Note: brackets (x) are not part of the mpp name for marvell,function and given
···88 "marvell,88f6190-pinctrl", "marvell,88f6192-pinctrl",99 "marvell,88f6281-pinctrl", "marvell,88f6282-pinctrl"1010 "marvell,98dx4122-pinctrl"1111+- reg: register specifier of MPP registers11121213This driver supports all kirkwood variants, i.e. 88f6180, 88f619x, and 88f628x.1314It also support the 88f6281-based variant in the 98dx412x Bobcat SoCs.
···5050 struct device *dev;5151 struct pinctrl_dev *pctldev;5252 struct pinctrl_desc desc;5353- void __iomem *base;5453 struct mvebu_pinctrl_group *groups;5554 unsigned num_groups;5655 struct mvebu_pinctrl_function *functions;···137138 return NULL;138139}139140140140-/*141141- * Common mpp pin configuration registers on MVEBU are142142- * registers of eight 4-bit values for each mpp setting.143143- * Register offset and bit mask are calculated accordingly below.144144- */145145-static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl,146146- struct mvebu_pinctrl_group *grp,147147- unsigned long *config)148148-{149149- unsigned pin = grp->gid;150150- unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;151151- unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;152152-153153- *config = readl(pctl->base + off);154154- *config >>= shift;155155- *config &= MPP_MASK;156156-157157- return 0;158158-}159159-160160-static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl,161161- struct mvebu_pinctrl_group *grp,162162- unsigned long config)163163-{164164- unsigned pin = grp->gid;165165- unsigned off = (pin / MPPS_PER_REG) * MPP_BITS;166166- unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS;167167- unsigned long reg;168168-169169- reg = readl(pctl->base + off);170170- reg &= ~(MPP_MASK << shift);171171- reg |= (config << shift);172172- writel(reg, pctl->base + off);173173-174174- return 0;175175-}176176-177141static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,178142 unsigned gid, unsigned long *config)179143{···146184 if (!grp->ctrl)147185 return -EINVAL;148186149149- if (grp->ctrl->mpp_get)150150- return grp->ctrl->mpp_get(grp->ctrl, config);151151-152152- return mvebu_common_mpp_get(pctl, grp, config);187187+ return grp->ctrl->mpp_get(grp->pins[0], config);153188}154189155190static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,···161202 return -EINVAL;162203163204 for (i = 0; i < num_configs; i++) {164164- if (grp->ctrl->mpp_set)165165- ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);166166- else167167- ret = mvebu_common_mpp_set(pctl, grp, configs[i]);168168-205205+ ret = grp->ctrl->mpp_set(grp->pins[0], configs[i]);169206 if (ret)170207 return ret;171208 } /* for each config */···302347 return -EINVAL;303348304349 if (grp->ctrl->mpp_gpio_req)305305- return grp->ctrl->mpp_gpio_req(grp->ctrl, offset);350350+ return grp->ctrl->mpp_gpio_req(offset);306351307352 setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);308353 if (!setting)···325370 return -EINVAL;326371327372 if (grp->ctrl->mpp_gpio_dir)328328- return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input);373373+ return grp->ctrl->mpp_gpio_dir(offset, input);329374330375 setting = mvebu_pinctrl_find_gpio_setting(pctl, grp);331376 if (!setting)···548593int mvebu_pinctrl_probe(struct platform_device *pdev)549594{550595 struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev);551551- struct resource *res;552596 struct mvebu_pinctrl *pctl;553553- void __iomem *base;554597 struct pinctrl_pin_desc *pdesc;555598 unsigned gid, n, k;599599+ unsigned size, noname = 0;600600+ char *noname_buf;601601+ void *p;556602 int ret;557603558604 if (!soc || !soc->controls || !soc->modes) {559605 dev_err(&pdev->dev, "wrong pinctrl soc info\n");560606 return -EINVAL;561607 }562562-563563- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);564564- base = devm_ioremap_resource(&pdev->dev, res);565565- if (IS_ERR(base))566566- return PTR_ERR(base);567608568609 pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl),569610 GFP_KERNEL);···574623 pctl->desc.pmxops = &mvebu_pinmux_ops;575624 pctl->desc.confops = &mvebu_pinconf_ops;576625 pctl->variant = soc->variant;577577- pctl->base = base;578626 pctl->dev = &pdev->dev;579627 platform_set_drvdata(pdev, pctl);580628···583633 pctl->desc.npins = 0;584634 for (n = 0; n < soc->ncontrols; n++) {585635 struct mvebu_mpp_ctrl *ctrl = &soc->controls[n];586586- char *names;587636588637 pctl->desc.npins += ctrl->npins;589589- /* initial control pins */638638+ /* initialize control's pins[] array */590639 for (k = 0; k < ctrl->npins; k++)591640 ctrl->pins[k] = ctrl->pid + k;592641593593- /* special soc specific control */594594- if (ctrl->mpp_get || ctrl->mpp_set) {595595- if (!ctrl->name || !ctrl->mpp_get || !ctrl->mpp_set) {596596- dev_err(&pdev->dev, "wrong soc control info\n");597597- return -EINVAL;598598- }642642+ /*643643+ * We allow to pass controls with NULL name that we treat644644+ * as a range of one-pin groups with generic mvebu register645645+ * controls.646646+ */647647+ if (!ctrl->name) {648648+ pctl->num_groups += ctrl->npins;649649+ noname += ctrl->npins;650650+ } else {599651 pctl->num_groups += 1;600600- continue;601652 }602602-603603- /* generic mvebu register control */604604- names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL);605605- if (!names) {606606- dev_err(&pdev->dev, "failed to alloc mpp names\n");607607- return -ENOMEM;608608- }609609- for (k = 0; k < ctrl->npins; k++)610610- sprintf(names + 8*k, "mpp%d", ctrl->pid+k);611611- ctrl->name = names;612612- pctl->num_groups += ctrl->npins;613653 }614654615655 pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins *···613673 pdesc[n].number = n;614674 pctl->desc.pins = pdesc;615675616616- pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups *617617- sizeof(struct mvebu_pinctrl_group), GFP_KERNEL);618618- if (!pctl->groups) {619619- dev_err(&pdev->dev, "failed to alloc pinctrl groups\n");676676+ /*677677+ * allocate groups and name buffers for unnamed groups.678678+ */679679+ size = pctl->num_groups * sizeof(*pctl->groups) + noname * 8;680680+ p = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);681681+ if (!p) {682682+ dev_err(&pdev->dev, "failed to alloc group data\n");620683 return -ENOMEM;621684 }685685+ pctl->groups = p;686686+ noname_buf = p + pctl->num_groups * sizeof(*pctl->groups);622687623688 /* assign mpp controls to groups */624689 gid = 0;···635690 pctl->groups[gid].pins = ctrl->pins;636691 pctl->groups[gid].npins = ctrl->npins;637692638638- /* generic mvebu register control maps to a number of groups */639639- if (!ctrl->mpp_get && !ctrl->mpp_set) {693693+ /*694694+ * We treat unnamed controls as a range of one-pin groups695695+ * with generic mvebu register controls. Use one group for696696+ * each in this range and assign a default group name.697697+ */698698+ if (!ctrl->name) {699699+ pctl->groups[gid].name = noname_buf;640700 pctl->groups[gid].npins = 1;701701+ sprintf(noname_buf, "mpp%d", ctrl->pid+0);702702+ noname_buf += 8;641703642704 for (k = 1; k < ctrl->npins; k++) {643705 gid++;644706 pctl->groups[gid].gid = gid;645707 pctl->groups[gid].ctrl = ctrl;646646- pctl->groups[gid].name = &ctrl->name[8*k];708708+ pctl->groups[gid].name = noname_buf;647709 pctl->groups[gid].pins = &ctrl->pins[k];648710 pctl->groups[gid].npins = 1;711711+ sprintf(noname_buf, "mpp%d", ctrl->pid+k);712712+ noname_buf += 8;649713 }650714 }651715 gid++;
+35-20
drivers/pinctrl/mvebu/pinctrl-mvebu.h
···2828 * between two or more different settings, e.g. assign mpp pin 13 to2929 * uart1 or sata.3030 *3131- * If optional mpp_get/_set functions are set these are used to get/set3232- * a specific mode. Otherwise it is assumed that the mpp control is based3333- * on 4-bit groups in subsequent registers. The optional mpp_gpio_req/_dir3434- * functions can be used to allow pin settings with varying gpio pins.3131+ * The mpp_get/_set functions are mandatory and are used to get/set a3232+ * specific mode. The optional mpp_gpio_req/_dir functions can be used3333+ * to allow pin settings with varying gpio pins.3534 */3635struct mvebu_mpp_ctrl {3736 const char *name;3837 u8 pid;3938 u8 npins;4039 unsigned *pins;4141- int (*mpp_get)(struct mvebu_mpp_ctrl *ctrl, unsigned long *config);4242- int (*mpp_set)(struct mvebu_mpp_ctrl *ctrl, unsigned long config);4343- int (*mpp_gpio_req)(struct mvebu_mpp_ctrl *ctrl, u8 pid);4444- int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl *ctrl, u8 pid, bool input);4040+ int (*mpp_get)(unsigned pid, unsigned long *config);4141+ int (*mpp_set)(unsigned pid, unsigned long config);4242+ int (*mpp_gpio_req)(unsigned pid);4343+ int (*mpp_gpio_dir)(unsigned pid, bool input);4544};46454746/**···113114 int ngpioranges;114115};115116116116-#define MPP_REG_CTRL(_idl, _idh) \117117- { \118118- .name = NULL, \119119- .pid = _idl, \120120- .npins = _idh - _idl + 1, \121121- .pins = (unsigned[_idh - _idl + 1]) { }, \122122- .mpp_get = NULL, \123123- .mpp_set = NULL, \124124- .mpp_gpio_req = NULL, \125125- .mpp_gpio_dir = NULL, \126126- }127127-128117#define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \129118 { \130119 .name = _name, \···172185 .base = _gpiobase, \173186 .npins = _npins, \174187 }188188+189189+#define MVEBU_MPPS_PER_REG 8190190+#define MVEBU_MPP_BITS 4191191+#define MVEBU_MPP_MASK 0xf192192+193193+static inline int default_mpp_ctrl_get(void __iomem *base, unsigned int pid,194194+ unsigned long *config)195195+{196196+ unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;197197+ unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;198198+199199+ *config = (readl(base + off) >> shift) & MVEBU_MPP_MASK;200200+201201+ return 0;202202+}203203+204204+static inline int default_mpp_ctrl_set(void __iomem *base, unsigned int pid,205205+ unsigned long config)206206+{207207+ unsigned off = (pid / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;208208+ unsigned shift = (pid % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;209209+ unsigned long reg;210210+211211+ reg = readl(base + off) & ~(MVEBU_MPP_MASK << shift);212212+ writel(reg | (config << shift), base + off);213213+214214+ return 0;215215+}175216176217int mvebu_pinctrl_probe(struct platform_device *pdev);177218int mvebu_pinctrl_remove(struct platform_device *pdev);