in pinctrl-microchip-sgpio.c [696:812]
static int microchip_sgpio_register_bank(struct device *dev,
struct sgpio_priv *priv,
struct fwnode_handle *fwnode,
int bankno)
{
struct pinctrl_pin_desc *pins;
struct pinctrl_desc *pctl_desc;
struct pinctrl_dev *pctldev;
struct sgpio_bank *bank;
struct gpio_chip *gc;
u32 ngpios;
int i, ret;
/* Get overall bank struct */
bank = (bankno == 0) ? &priv->in : &priv->out;
bank->priv = priv;
if (fwnode_property_read_u32(fwnode, "ngpios", &ngpios)) {
dev_info(dev, "failed to get number of gpios for bank%d\n",
bankno);
ngpios = 64;
}
priv->bitcount = ngpios / SGPIO_BITS_PER_WORD;
if (priv->bitcount > SGPIO_MAX_BITS) {
dev_err(dev, "Bit width exceeds maximum (%d)\n",
SGPIO_MAX_BITS);
return -EINVAL;
}
pctl_desc = &bank->pctl_desc;
pctl_desc->name = devm_kasprintf(dev, GFP_KERNEL, "%s-%sput",
dev_name(dev),
bank->is_input ? "in" : "out");
pctl_desc->pctlops = &sgpio_pctl_ops;
pctl_desc->pmxops = &sgpio_pmx_ops;
pctl_desc->confops = &sgpio_confops;
pctl_desc->owner = THIS_MODULE;
pins = devm_kzalloc(dev, sizeof(*pins)*ngpios, GFP_KERNEL);
if (!pins)
return -ENOMEM;
pctl_desc->npins = ngpios;
pctl_desc->pins = pins;
for (i = 0; i < ngpios; i++) {
struct sgpio_port_addr addr;
sgpio_pin_to_addr(priv, i, &addr);
pins[i].number = i;
pins[i].name = devm_kasprintf(dev, GFP_KERNEL,
"SGPIO_%c_p%db%d",
bank->is_input ? 'I' : 'O',
addr.port, addr.bit);
if (!pins[i].name)
return -ENOMEM;
}
pctldev = devm_pinctrl_register(dev, pctl_desc, bank);
if (IS_ERR(pctldev))
return dev_err_probe(dev, PTR_ERR(pctldev), "Failed to register pinctrl\n");
gc = &bank->gpio;
gc->label = pctl_desc->name;
gc->parent = dev;
gc->of_node = to_of_node(fwnode);
gc->owner = THIS_MODULE;
gc->get_direction = microchip_sgpio_get_direction;
gc->direction_input = microchip_sgpio_direction_input;
gc->direction_output = microchip_sgpio_direction_output;
gc->get = microchip_sgpio_get_value;
gc->set = microchip_sgpio_set_value;
gc->request = gpiochip_generic_request;
gc->free = gpiochip_generic_free;
gc->of_xlate = microchip_sgpio_of_xlate;
gc->of_gpio_n_cells = 3;
gc->base = -1;
gc->ngpio = ngpios;
if (bank->is_input && priv->properties->flags & SGPIO_FLAGS_HAS_IRQ) {
int irq = fwnode_irq_get(fwnode, 0);
if (irq) {
struct gpio_irq_chip *girq = &gc->irq;
girq->chip = devm_kmemdup(dev, µchip_sgpio_irqchip,
sizeof(microchip_sgpio_irqchip),
GFP_KERNEL);
if (!girq->chip)
return -ENOMEM;
girq->parent_handler = sgpio_irq_handler;
girq->num_parents = 1;
girq->parents = devm_kcalloc(dev, 1,
sizeof(*girq->parents),
GFP_KERNEL);
if (!girq->parents)
return -ENOMEM;
girq->parents[0] = irq;
girq->default_type = IRQ_TYPE_NONE;
girq->handler = handle_bad_irq;
/* Disable all individual pins */
for (i = 0; i < SGPIO_MAX_BITS; i++)
sgpio_writel(priv, 0, REG_INT_ENABLE, i);
/* Master enable */
sgpio_clrsetbits(priv, REG_SIO_CONFIG, 0, 0, SGPIO_MASTER_INTR_ENA);
}
}
ret = devm_gpiochip_add_data(dev, gc, bank);
if (ret)
dev_err(dev, "Failed to register: ret %d\n", ret);
return ret;
}