0001
0002
0003
0004 #include <linux/bitops.h>
0005 #include <linux/gpio/driver.h>
0006 #include <linux/irq.h>
0007 #include <linux/module.h>
0008 #include <linux/mod_devicetable.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/spinlock.h>
0011
0012 #define IDT_PIC_IRQ_PEND 0x00
0013 #define IDT_PIC_IRQ_MASK 0x08
0014
0015 #define IDT_GPIO_DIR 0x00
0016 #define IDT_GPIO_DATA 0x04
0017 #define IDT_GPIO_ILEVEL 0x08
0018 #define IDT_GPIO_ISTAT 0x0C
0019
0020 struct idt_gpio_ctrl {
0021 struct gpio_chip gc;
0022 void __iomem *pic;
0023 void __iomem *gpio;
0024 u32 mask_cache;
0025 };
0026
0027 static void idt_gpio_dispatch(struct irq_desc *desc)
0028 {
0029 struct gpio_chip *gc = irq_desc_get_handler_data(desc);
0030 struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
0031 struct irq_chip *host_chip = irq_desc_get_chip(desc);
0032 unsigned int bit, virq;
0033 unsigned long pending;
0034
0035 chained_irq_enter(host_chip, desc);
0036
0037 pending = readl(ctrl->pic + IDT_PIC_IRQ_PEND);
0038 pending &= ~ctrl->mask_cache;
0039 for_each_set_bit(bit, &pending, gc->ngpio) {
0040 virq = irq_linear_revmap(gc->irq.domain, bit);
0041 if (virq)
0042 generic_handle_irq(virq);
0043 }
0044
0045 chained_irq_exit(host_chip, desc);
0046 }
0047
0048 static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
0049 {
0050 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
0051 struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
0052 unsigned int sense = flow_type & IRQ_TYPE_SENSE_MASK;
0053 unsigned long flags;
0054 u32 ilevel;
0055
0056
0057 if (sense == IRQ_TYPE_NONE || (sense & IRQ_TYPE_EDGE_BOTH))
0058 return -EINVAL;
0059
0060 raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
0061
0062 ilevel = readl(ctrl->gpio + IDT_GPIO_ILEVEL);
0063 if (sense & IRQ_TYPE_LEVEL_HIGH)
0064 ilevel |= BIT(d->hwirq);
0065 else if (sense & IRQ_TYPE_LEVEL_LOW)
0066 ilevel &= ~BIT(d->hwirq);
0067
0068 writel(ilevel, ctrl->gpio + IDT_GPIO_ILEVEL);
0069 irq_set_handler_locked(d, handle_level_irq);
0070
0071 raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
0072 return 0;
0073 }
0074
0075 static void idt_gpio_ack(struct irq_data *d)
0076 {
0077 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
0078 struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
0079
0080 writel(~BIT(d->hwirq), ctrl->gpio + IDT_GPIO_ISTAT);
0081 }
0082
0083 static void idt_gpio_mask(struct irq_data *d)
0084 {
0085 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
0086 struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
0087 unsigned long flags;
0088
0089 raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
0090
0091 ctrl->mask_cache |= BIT(d->hwirq);
0092 writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
0093
0094 raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
0095 }
0096
0097 static void idt_gpio_unmask(struct irq_data *d)
0098 {
0099 struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
0100 struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
0101 unsigned long flags;
0102
0103 raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
0104
0105 ctrl->mask_cache &= ~BIT(d->hwirq);
0106 writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
0107
0108 raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
0109 }
0110
0111 static int idt_gpio_irq_init_hw(struct gpio_chip *gc)
0112 {
0113 struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
0114
0115
0116 ctrl->mask_cache = 0xffffffff;
0117 writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
0118
0119 return 0;
0120 }
0121
0122 static struct irq_chip idt_gpio_irqchip = {
0123 .name = "IDTGPIO",
0124 .irq_mask = idt_gpio_mask,
0125 .irq_ack = idt_gpio_ack,
0126 .irq_unmask = idt_gpio_unmask,
0127 .irq_set_type = idt_gpio_irq_set_type
0128 };
0129
0130 static int idt_gpio_probe(struct platform_device *pdev)
0131 {
0132 struct device *dev = &pdev->dev;
0133 struct gpio_irq_chip *girq;
0134 struct idt_gpio_ctrl *ctrl;
0135 int parent_irq;
0136 int ngpios;
0137 int ret;
0138
0139
0140 ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
0141 if (!ctrl)
0142 return -ENOMEM;
0143
0144 ctrl->gpio = devm_platform_ioremap_resource_byname(pdev, "gpio");
0145 if (IS_ERR(ctrl->gpio))
0146 return PTR_ERR(ctrl->gpio);
0147
0148 ctrl->gc.parent = dev;
0149
0150 ret = bgpio_init(&ctrl->gc, &pdev->dev, 4, ctrl->gpio + IDT_GPIO_DATA,
0151 NULL, NULL, ctrl->gpio + IDT_GPIO_DIR, NULL, 0);
0152 if (ret) {
0153 dev_err(dev, "bgpio_init failed\n");
0154 return ret;
0155 }
0156
0157 ret = device_property_read_u32(dev, "ngpios", &ngpios);
0158 if (!ret)
0159 ctrl->gc.ngpio = ngpios;
0160
0161 if (device_property_read_bool(dev, "interrupt-controller")) {
0162 ctrl->pic = devm_platform_ioremap_resource_byname(pdev, "pic");
0163 if (IS_ERR(ctrl->pic))
0164 return PTR_ERR(ctrl->pic);
0165
0166 parent_irq = platform_get_irq(pdev, 0);
0167 if (parent_irq < 0)
0168 return parent_irq;
0169
0170 girq = &ctrl->gc.irq;
0171 girq->chip = &idt_gpio_irqchip;
0172 girq->init_hw = idt_gpio_irq_init_hw;
0173 girq->parent_handler = idt_gpio_dispatch;
0174 girq->num_parents = 1;
0175 girq->parents = devm_kcalloc(dev, girq->num_parents,
0176 sizeof(*girq->parents),
0177 GFP_KERNEL);
0178 if (!girq->parents)
0179 return -ENOMEM;
0180
0181 girq->parents[0] = parent_irq;
0182 girq->default_type = IRQ_TYPE_NONE;
0183 girq->handler = handle_bad_irq;
0184 }
0185
0186 return devm_gpiochip_add_data(&pdev->dev, &ctrl->gc, ctrl);
0187 }
0188
0189 static const struct of_device_id idt_gpio_of_match[] = {
0190 { .compatible = "idt,32434-gpio" },
0191 { }
0192 };
0193 MODULE_DEVICE_TABLE(of, idt_gpio_of_match);
0194
0195 static struct platform_driver idt_gpio_driver = {
0196 .probe = idt_gpio_probe,
0197 .driver = {
0198 .name = "idt3243x-gpio",
0199 .of_match_table = idt_gpio_of_match,
0200 },
0201 };
0202 module_platform_driver(idt_gpio_driver);
0203
0204 MODULE_DESCRIPTION("IDT 79RC3243x GPIO/PIC Driver");
0205 MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
0206 MODULE_LICENSE("GPL");