summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/pinctrl-equilibrium.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl/pinctrl-equilibrium.c')
-rw-r--r--drivers/pinctrl/pinctrl-equilibrium.c144
1 files changed, 73 insertions, 71 deletions
diff --git a/drivers/pinctrl/pinctrl-equilibrium.c b/drivers/pinctrl/pinctrl-equilibrium.c
index 99cf24eb67ae..2d04829b29c9 100644
--- a/drivers/pinctrl/pinctrl-equilibrium.c
+++ b/drivers/pinctrl/pinctrl-equilibrium.c
@@ -2,6 +2,7 @@
/* Copyright (C) 2019 Intel Corporation */
#include <linux/gpio/driver.h>
+#include <linux/gpio/generic.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -32,6 +33,7 @@ static void eqbr_gpio_disable_irq(struct irq_data *d)
raw_spin_lock_irqsave(&gctrl->lock, flags);
writel(BIT(offset), gctrl->membase + GPIO_IRNENCLR);
raw_spin_unlock_irqrestore(&gctrl->lock, flags);
+ gpiochip_disable_irq(gc, offset);
}
static void eqbr_gpio_enable_irq(struct irq_data *d)
@@ -42,6 +44,7 @@ static void eqbr_gpio_enable_irq(struct irq_data *d)
unsigned long flags;
gc->direction_input(gc, offset);
+ gpiochip_enable_irq(gc, offset);
raw_spin_lock_irqsave(&gctrl->lock, flags);
writel(BIT(offset), gctrl->membase + GPIO_IRNRNSET);
raw_spin_unlock_irqrestore(&gctrl->lock, flags);
@@ -161,14 +164,27 @@ static void eqbr_irq_handler(struct irq_desc *desc)
chained_irq_exit(ic, desc);
}
+static const struct irq_chip eqbr_irq_chip = {
+ .name = "gpio_irq",
+ .irq_mask = eqbr_gpio_disable_irq,
+ .irq_unmask = eqbr_gpio_enable_irq,
+ .irq_ack = eqbr_gpio_ack_irq,
+ .irq_mask_ack = eqbr_gpio_mask_ack_irq,
+ .irq_set_type = eqbr_gpio_set_irq_type,
+ .flags = IRQCHIP_IMMUTABLE,
+ GPIOCHIP_IRQ_RESOURCE_HELPERS,
+};
+
static int gpiochip_setup(struct device *dev, struct eqbr_gpio_ctrl *gctrl)
{
struct gpio_irq_chip *girq;
struct gpio_chip *gc;
- gc = &gctrl->chip;
+ gc = &gctrl->chip.gc;
gc->label = gctrl->name;
gc->fwnode = gctrl->fwnode;
+ gc->request = gpiochip_generic_request;
+ gc->free = gpiochip_generic_free;
if (!fwnode_property_read_bool(gctrl->fwnode, "interrupt-controller")) {
dev_dbg(dev, "gc %s: doesn't act as interrupt controller!\n",
@@ -176,15 +192,8 @@ static int gpiochip_setup(struct device *dev, struct eqbr_gpio_ctrl *gctrl)
return 0;
}
- gctrl->ic.name = "gpio_irq";
- gctrl->ic.irq_mask = eqbr_gpio_disable_irq;
- gctrl->ic.irq_unmask = eqbr_gpio_enable_irq;
- gctrl->ic.irq_ack = eqbr_gpio_ack_irq;
- gctrl->ic.irq_mask_ack = eqbr_gpio_mask_ack_irq;
- gctrl->ic.irq_set_type = eqbr_gpio_set_irq_type;
-
- girq = &gctrl->chip.irq;
- girq->chip = &gctrl->ic;
+ girq = &gctrl->chip.gc.irq;
+ gpio_irq_chip_set_chip(girq, &eqbr_irq_chip);
girq->parent_handler = eqbr_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents), GFP_KERNEL);
@@ -200,6 +209,7 @@ static int gpiochip_setup(struct device *dev, struct eqbr_gpio_ctrl *gctrl)
static int gpiolib_reg(struct eqbr_pinctrl_drv_data *drvdata)
{
+ struct gpio_generic_chip_config config;
struct device *dev = drvdata->dev;
struct eqbr_gpio_ctrl *gctrl;
struct device_node *np;
@@ -231,12 +241,16 @@ static int gpiolib_reg(struct eqbr_pinctrl_drv_data *drvdata)
}
raw_spin_lock_init(&gctrl->lock);
- ret = bgpio_init(&gctrl->chip, dev, gctrl->bank->nr_pins / 8,
- gctrl->membase + GPIO_IN,
- gctrl->membase + GPIO_OUTSET,
- gctrl->membase + GPIO_OUTCLR,
- gctrl->membase + GPIO_DIR,
- NULL, 0);
+ config = (struct gpio_generic_chip_config) {
+ .dev = dev,
+ .sz = gctrl->bank->nr_pins / 8,
+ .dat = gctrl->membase + GPIO_IN,
+ .set = gctrl->membase + GPIO_OUTSET,
+ .clr = gctrl->membase + GPIO_OUTCLR,
+ .dirout = gctrl->membase + GPIO_DIR,
+ };
+
+ ret = gpio_generic_chip_init(&gctrl->chip, &config);
if (ret) {
dev_err(dev, "unable to init generic GPIO\n");
return ret;
@@ -246,7 +260,7 @@ static int gpiolib_reg(struct eqbr_pinctrl_drv_data *drvdata)
if (ret)
return ret;
- ret = devm_gpiochip_add_data(dev, &gctrl->chip, gctrl);
+ ret = devm_gpiochip_add_data(dev, &gctrl->chip.gc, gctrl);
if (ret)
return ret;
}
@@ -311,7 +325,7 @@ static int eqbr_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned int selector, unsigned int group)
{
struct eqbr_pinctrl_drv_data *pctl = pinctrl_dev_get_drvdata(pctldev);
- struct function_desc *func;
+ const struct function_desc *func;
struct group_desc *grp;
unsigned int *pinmux;
int i;
@@ -325,8 +339,8 @@ static int eqbr_pinmux_set_mux(struct pinctrl_dev *pctldev,
return -EINVAL;
pinmux = grp->data;
- for (i = 0; i < grp->num_pins; i++)
- eqbr_set_pin_mux(pctl, pinmux[i], grp->pins[i]);
+ for (i = 0; i < grp->grp.npins; i++)
+ eqbr_set_pin_mux(pctl, pinmux[i], grp->grp.pins[i]);
return 0;
}
@@ -431,7 +445,7 @@ static int eqbr_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
}
raw_spin_unlock_irqrestore(&pctl->lock, flags);
*config = pinconf_to_config_packed(param, val);
-;
+
return 0;
}
@@ -491,7 +505,7 @@ static int eqbr_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
bank->pin_base, pin);
return -ENODEV;
}
- gc = &gctrl->chip;
+ gc = &gctrl->chip.gc;
gc->direction_output(gc, offset, 0);
continue;
default:
@@ -560,8 +574,8 @@ static const struct pinconf_ops eqbr_pinconf_ops = {
.pin_config_config_dbg_show = pinconf_generic_dump_config,
};
-static bool is_func_exist(struct eqbr_pmx_func *funcs, const char *name,
- unsigned int nr_funcs, unsigned int *idx)
+static bool is_func_exist(struct pinfunction *funcs, const char *name,
+ unsigned int nr_funcs, unsigned int *idx)
{
int i;
@@ -578,18 +592,18 @@ static bool is_func_exist(struct eqbr_pmx_func *funcs, const char *name,
return false;
}
-static int funcs_utils(struct device *dev, struct eqbr_pmx_func *funcs,
+static int funcs_utils(struct device *dev, struct pinfunction *funcs,
unsigned int *nr_funcs, funcs_util_ops op)
{
struct device_node *node = dev->of_node;
- struct device_node *np;
struct property *prop;
const char *fn_name;
+ const char **groups;
unsigned int fid;
int i, j;
i = 0;
- for_each_child_of_node(node, np) {
+ for_each_child_of_node_scoped(node, np) {
prop = of_find_property(np, "groups", NULL);
if (!prop)
continue;
@@ -614,20 +628,20 @@ static int funcs_utils(struct device *dev, struct eqbr_pmx_func *funcs,
case OP_COUNT_NR_FUNC_GRPS:
if (is_func_exist(funcs, fn_name, *nr_funcs, &fid))
- funcs[fid].nr_groups++;
+ funcs[fid].ngroups++;
break;
case OP_ADD_FUNC_GRPS:
if (is_func_exist(funcs, fn_name, *nr_funcs, &fid)) {
- for (j = 0; j < funcs[fid].nr_groups; j++)
- if (!funcs[fid].groups[j])
+ groups = (const char **)funcs[fid].groups;
+ for (j = 0; j < funcs[fid].ngroups; j++)
+ if (!groups[j])
break;
- funcs[fid].groups[j] = prop->value;
+ groups[j] = prop->value;
}
break;
default:
- of_node_put(np);
return -EINVAL;
}
i++;
@@ -639,7 +653,7 @@ static int funcs_utils(struct device *dev, struct eqbr_pmx_func *funcs,
static int eqbr_build_functions(struct eqbr_pinctrl_drv_data *drvdata)
{
struct device *dev = drvdata->dev;
- struct eqbr_pmx_func *funcs = NULL;
+ struct pinfunction *funcs = NULL;
unsigned int nr_funcs = 0;
int i, ret;
@@ -660,9 +674,9 @@ static int eqbr_build_functions(struct eqbr_pinctrl_drv_data *drvdata)
return ret;
for (i = 0; i < nr_funcs; i++) {
- if (!funcs[i].nr_groups)
+ if (!funcs[i].ngroups)
continue;
- funcs[i].groups = devm_kcalloc(dev, funcs[i].nr_groups,
+ funcs[i].groups = devm_kcalloc(dev, funcs[i].ngroups,
sizeof(*(funcs[i].groups)),
GFP_KERNEL);
if (!funcs[i].groups)
@@ -679,11 +693,8 @@ static int eqbr_build_functions(struct eqbr_pinctrl_drv_data *drvdata)
if (funcs[i].name == NULL)
continue;
- ret = pinmux_generic_add_function(drvdata->pctl_dev,
- funcs[i].name,
- funcs[i].groups,
- funcs[i].nr_groups,
- drvdata);
+ ret = pinmux_generic_add_pinfunction(drvdata->pctl_dev,
+ &funcs[i], drvdata);
if (ret < 0) {
dev_err(dev, "Failed to register function %s\n",
funcs[i].name);
@@ -698,67 +709,58 @@ static int eqbr_build_groups(struct eqbr_pinctrl_drv_data *drvdata)
{
struct device *dev = drvdata->dev;
struct device_node *node = dev->of_node;
- unsigned int *pinmux, pin_id, pinmux_id;
- struct group_desc group;
- struct device_node *np;
+ unsigned int *pins, *pinmux, pin_id, pinmux_id;
+ struct pingroup group, *grp = &group;
struct property *prop;
int j, err;
- for_each_child_of_node(node, np) {
+ for_each_child_of_node_scoped(node, np) {
prop = of_find_property(np, "groups", NULL);
if (!prop)
continue;
- group.num_pins = of_property_count_u32_elems(np, "pins");
- if (group.num_pins < 0) {
+ err = of_property_count_u32_elems(np, "pins");
+ if (err < 0) {
dev_err(dev, "No pins in the group: %s\n", prop->name);
- of_node_put(np);
- return -EINVAL;
+ return err;
}
- group.name = prop->value;
- group.pins = devm_kcalloc(dev, group.num_pins,
- sizeof(*(group.pins)), GFP_KERNEL);
- if (!group.pins) {
- of_node_put(np);
+ grp->npins = err;
+ grp->name = prop->value;
+ pins = devm_kcalloc(dev, grp->npins, sizeof(*pins), GFP_KERNEL);
+ if (!pins)
return -ENOMEM;
- }
- pinmux = devm_kcalloc(dev, group.num_pins, sizeof(*pinmux),
- GFP_KERNEL);
- if (!pinmux) {
- of_node_put(np);
+ grp->pins = pins;
+
+ pinmux = devm_kcalloc(dev, grp->npins, sizeof(*pinmux), GFP_KERNEL);
+ if (!pinmux)
return -ENOMEM;
- }
- for (j = 0; j < group.num_pins; j++) {
+ for (j = 0; j < grp->npins; j++) {
if (of_property_read_u32_index(np, "pins", j, &pin_id)) {
dev_err(dev, "Group %s: Read intel pins id failed\n",
- group.name);
- of_node_put(np);
+ grp->name);
return -EINVAL;
}
if (pin_id >= drvdata->pctl_desc.npins) {
dev_err(dev, "Group %s: Invalid pin ID, idx: %d, pin %u\n",
- group.name, j, pin_id);
- of_node_put(np);
+ grp->name, j, pin_id);
return -EINVAL;
}
- group.pins[j] = pin_id;
+ pins[j] = pin_id;
if (of_property_read_u32_index(np, "pinmux", j, &pinmux_id)) {
dev_err(dev, "Group %s: Read intel pinmux id failed\n",
- group.name);
- of_node_put(np);
+ grp->name);
return -EINVAL;
}
pinmux[j] = pinmux_id;
}
- err = pinctrl_generic_add_group(drvdata->pctl_dev, group.name,
- group.pins, group.num_pins,
+ err = pinctrl_generic_add_group(drvdata->pctl_dev,
+ grp->name, grp->pins, grp->npins,
pinmux);
if (err < 0) {
- dev_err(dev, "Failed to register group %s\n", group.name);
- of_node_put(np);
+ dev_err(dev, "Failed to register group %s\n", grp->name);
return err;
}
memset(&group, 0, sizeof(group));