switch (type) { case IRQ_TYPE_EDGE_BOTH:
hisi_gpio_write_reg(chip, HISI_GPIO_INT_DEDGE_SET, mask); break; case IRQ_TYPE_EDGE_RISING:
hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_SET_WX, mask);
hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_SET_WX, mask); break; case IRQ_TYPE_EDGE_FALLING:
hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_SET_WX, mask);
hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_CLR_WX, mask); break; case IRQ_TYPE_LEVEL_HIGH:
hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_CLR_WX, mask);
hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_SET_WX, mask); break; case IRQ_TYPE_LEVEL_LOW:
hisi_gpio_write_reg(chip, HISI_GPIO_INTTYPE_EDGE_CLR_WX, mask);
hisi_gpio_write_reg(chip, HISI_GPIO_INT_POLARITY_CLR_WX, mask); break; default: return -EINVAL;
}
/* * The dual-edge interrupt and other interrupt's registers do not * take effect at the same time. The registers of the two-edge * interrupts have higher priorities, the configuration of * the dual-edge interrupts must be disabled before the configuration * of other kind of interrupts.
*/ if (type != IRQ_TYPE_EDGE_BOTH) { unsignedint both = hisi_gpio_read_reg(chip, HISI_GPIO_INT_DEDGE_ST);
if (both & mask)
hisi_gpio_write_reg(chip, HISI_GPIO_INT_DEDGE_CLR, mask);
}
device_for_each_child_node(dev, fwnode) { /* Cycle for once, no need for an array to save line_num */ if (fwnode_property_read_u32(fwnode, "ngpios",
&hisi_gpio->line_num)) {
dev_err(dev, "failed to get number of lines for port%d and use default value instead\n",
idx);
hisi_gpio->line_num = HISI_GPIO_LINE_NUM_MAX;
}
if (WARN_ON(hisi_gpio->line_num > HISI_GPIO_LINE_NUM_MAX))
hisi_gpio->line_num = HISI_GPIO_LINE_NUM_MAX;
hisi_gpio->irq = platform_get_irq(pdev, idx);
dev_info(dev, "get hisi_gpio[%d] with %u lines\n", idx,
hisi_gpio->line_num);
idx++;
}
}
staticint hisi_gpio_probe(struct platform_device *pdev)
{ struct device *dev = &pdev->dev; struct hisi_gpio *hisi_gpio; int port_num; int ret;
/* * One GPIO controller own one port currently, * if we get more from ACPI table, return error.
*/
port_num = device_get_child_node_count(dev); if (WARN_ON(port_num != 1)) return -ENODEV;
hisi_gpio = devm_kzalloc(dev, sizeof(*hisi_gpio), GFP_KERNEL); if (!hisi_gpio) return -ENOMEM;
hisi_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(hisi_gpio->reg_base)) return PTR_ERR(hisi_gpio->reg_base);
hisi_gpio_get_pdata(dev, hisi_gpio);
hisi_gpio->dev = dev;
ret = bgpio_init(&hisi_gpio->chip, hisi_gpio->dev, 0x4,
hisi_gpio->reg_base + HISI_GPIO_EXT_PORT_WX,
hisi_gpio->reg_base + HISI_GPIO_SWPORT_DR_SET_WX,
hisi_gpio->reg_base + HISI_GPIO_SWPORT_DR_CLR_WX,
hisi_gpio->reg_base + HISI_GPIO_SWPORT_DDR_SET_WX,
hisi_gpio->reg_base + HISI_GPIO_SWPORT_DDR_CLR_WX,
BGPIOF_NO_SET_ON_INPUT); if (ret) {
dev_err(dev, "failed to init, ret = %d\n", ret); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.