modify jh7110 gpio driver
authorHuan.Feng <huan.feng@starfivetech.com>
Fri, 3 Dec 2021 02:54:10 +0000 (10:54 +0800)
committerHuan.Feng <huan.feng@starfivetech.com>
Fri, 3 Dec 2021 02:54:10 +0000 (10:54 +0800)
drivers/gpio/gpio-starfive-jh7110.c

index 2ca62b0..82bb840 100644 (file)
 #include <linux/uaccess.h>
 #include <linux/spinlock.h>
 
-#define GPIO_EN                0xe0
-#define GPIO_IS_LOW    0xe4
-#define GPIO_IS_HIGH   0xe8
-#define GPIO_IBE_LOW   0xf4
-#define GPIO_IBE_HIGH  0xf8
-#define GPIO_IEV_LOW   0xfc
-#define GPIO_IEV_HIGH  0x100
-#define GPIO_IE_LOW    0x104
-#define GPIO_IE_HIGH   0x108
-#define GPIO_IC_LOW    0xec
-#define GPIO_IC_HIGH   0xf0
+#define GPIO_EN                0xdc
+#define GPIO_IS_LOW    0xe0
+#define GPIO_IS_HIGH   0xe4
+#define GPIO_IC_LOW    0xe8
+#define GPIO_IC_HIGH   0xec
+#define GPIO_IBE_LOW   0xf0
+#define GPIO_IBE_HIGH  0xf4
+#define GPIO_IEV_LOW   0xf8
+#define GPIO_IEV_HIGH  0xfc
+#define GPIO_IE_LOW    0x100
+#define GPIO_IE_HIGH   0x104
+
 //read only
-#define GPIO_RIS_LOW   0x10c
-#define GPIO_RIS_HIGH  0x110
-#define GPIO_MIS_LOW   0x114
-#define GPIO_MIS_HIGH  0x118
-#define GPIO_DIN_LOW   0x11C
-#define GPIO_DIN_HIGH  0x120
+#define GPIO_RIS_LOW   0x108
+#define GPIO_RIS_HIGH  0x10c
+#define GPIO_MIS_LOW   0x110
+#define GPIO_MIS_HIGH  0x114
+#define GPIO_DIN_LOW   0x118
+#define GPIO_DIN_HIGH  0x11c
 
-#define GPIO_DOUT_X_REG        0x0
-#define GPIO_DOEN_X_REG        0x40
+#define GPIO_DOEN_X_REG        0x0
+#define GPIO_DOUT_X_REG        0x40
 
-#define GPIO_INPUT_ENABLE_X_REG        0x124
+#define GPIO_INPUT_ENABLE_X_REG        0x120
 
 #define MAX_GPIO        64
 
@@ -93,7 +94,7 @@ static int sfvic7110_direction_input(struct gpio_chip *gc, unsigned offset)
 
        if (offset >= gc->ngpio)
                return -EINVAL;
-
+       
        raw_spin_lock_irqsave(&chip->lock, flags);
        v = readl_relaxed(chip->base + GPIO_DOEN_X_REG + (offset & ~0x3));
        v &= ~(0x3f << ((offset & 0x3) * 8));
@@ -112,13 +113,14 @@ static int sfvic7110_direction_output(struct gpio_chip *gc, unsigned offset, int
 
        if (offset >= gc->ngpio)
                return -EINVAL;
+       
        raw_spin_lock_irqsave(&chip->lock, flags);
        v = readl_relaxed(chip->base + GPIO_DOEN_X_REG + (offset & ~0x3));
        v &= ~(0x3f << ((offset & 0x3) * 8));
        writel_relaxed(v, chip->base + GPIO_DOEN_X_REG + (offset & ~0x3));
 
        v = readl_relaxed(chip->base + GPIO_DOUT_X_REG + (offset & ~0x3));
-       v &= ~(0x3f << ((offset & 0x3) * 8));
+       v &= ~(0x7f << ((offset & 0x3) * 8));
        v |= value << ((offset & 0x3) * 8);
        writel_relaxed(v, chip->base + GPIO_DOUT_X_REG + (offset & ~0x3));
        raw_spin_unlock_irqrestore(&chip->lock, flags);
@@ -166,7 +168,7 @@ static void sfvic7110_set_value(struct gpio_chip *gc, unsigned offset, int value
 
        raw_spin_lock_irqsave(&chip->lock, flags);
        v = readl_relaxed(chip->base + GPIO_DOUT_X_REG + (offset & ~0x3));
-       v &= ~(0x3f << ((offset & 0x3) * 8));
+       v &= ~(0x7f << ((offset & 0x3) * 8));
        v |= value << ((offset & 0x3) * 8);
        writel_relaxed(v, chip->base + GPIO_DOUT_X_REG + (offset & ~0x3));
        raw_spin_unlock_irqrestore(&chip->lock, flags);
@@ -217,10 +219,10 @@ static int sfvic7110_irq_set_type(struct irq_data *d, unsigned trigger)
                reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
                reg_is  &= (~(0x1<< index));
                reg_ibe &= (~(0x1<< index));
-               reg_iev |= (0x1<< index);
-               writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
-               writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
+               reg_iev |= (~(0x1<< index));
                writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
+               writel_relaxed(reg_ibe, chip->base + GPIO_IBE_LOW + reg_offset);
+               writel_relaxed(reg_iev, chip->base + GPIO_IEV_LOW + reg_offset);
                break;
        case IRQ_TYPE_LEVEL_LOW:
                reg_is = readl_relaxed(chip->base + GPIO_IS_LOW + reg_offset);
@@ -230,41 +232,41 @@ static int sfvic7110_irq_set_type(struct irq_data *d, unsigned trigger)
                reg_ibe &= (~(0x1<< index));
                reg_iev &= (0x1<< index);
                writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
-               writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
-               writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
+               writel_relaxed(reg_ibe, chip->base + GPIO_IBE_LOW + reg_offset);
+               writel_relaxed(reg_iev, chip->base + GPIO_IEV_LOW + reg_offset);
                break;
        case IRQ_TYPE_EDGE_BOTH:
                reg_is = readl_relaxed(chip->base + GPIO_IS_LOW + reg_offset);
                reg_ibe = readl_relaxed(chip->base + GPIO_IBE_LOW + reg_offset);
-               //reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
-               reg_is  |= (~(0x1<< index));
-               reg_ibe |= (~(0x1<< index));
-               //reg_iev |= (0x1<< index);
-               writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
+               reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
+               reg_is  |= (0x1<< index);
+               reg_ibe |= (0x1<< index);
+               reg_iev |= (~(0x1<< index));
                writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
-               //writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
+               writel_relaxed(reg_ibe, chip->base + GPIO_IBE_LOW + reg_offset);
+               writel_relaxed(reg_iev, chip->base + GPIO_IEV_LOW + reg_offset);
                break;
        case IRQ_TYPE_EDGE_RISING:
                reg_is = readl_relaxed(chip->base + GPIO_IS_LOW + reg_offset);
                reg_ibe = readl_relaxed(chip->base + GPIO_IBE_LOW + reg_offset);
                reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
-               reg_is  |= (~(0x1<< index));
+               reg_is  |= (0x1<< index);
                reg_ibe &= (~(0x1<< index));
                reg_iev |= (0x1<< index);
                writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
-               writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
-               writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
+               writel_relaxed(reg_ibe, chip->base + GPIO_IBE_LOW + reg_offset);
+               writel_relaxed(reg_iev, chip->base + GPIO_IEV_LOW + reg_offset);
                break;
        case IRQ_TYPE_EDGE_FALLING:
                reg_is = readl_relaxed(chip->base + GPIO_IS_LOW + reg_offset);
                reg_ibe = readl_relaxed(chip->base + GPIO_IBE_LOW + reg_offset);
                reg_iev = readl_relaxed(chip->base + GPIO_IEV_LOW + reg_offset);
-               reg_is  |= (~(0x1<< index));
+               reg_is  |= (0x1<< index);
                reg_ibe &= (~(0x1<< index));
-               reg_iev &= (0x1<< index);
-               writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
-               writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
+               reg_iev &= (~(0x1<< index));
                writel_relaxed(reg_is, chip->base + GPIO_IS_LOW + reg_offset);
+               writel_relaxed(reg_ibe, chip->base + GPIO_IBE_LOW + reg_offset);
+               writel_relaxed(reg_iev, chip->base + GPIO_IEV_LOW + reg_offset);
                break;
        }
 
@@ -351,22 +353,6 @@ static struct irq_chip sfvic7110_irqchip = {
        .irq_disable    = sfvic7110_irq_disable,
 };
 
-
-static int starfive_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
-                                            unsigned int child,
-                                            unsigned int child_type,
-                                            unsigned int *parent,
-                                            unsigned int *parent_type)
-{
-       struct sfvic7110_gpio *chip = gpiochip_get_data(gc);
-       struct irq_data *d = irq_get_irq_data(chip->irq_parent[child]);
-
-       *parent_type = IRQ_TYPE_NONE;
-       *parent = irqd_to_hwirq(d);
-
-       return 0;
-}
-
 static irqreturn_t sfvic7110_irq_handler(int irq, void *gc)
 {
        int offset;
@@ -411,7 +397,7 @@ void sf_vic_gpio_dout_reverse(int gpio,int en)
 
        spin_lock(&sfg_lock);
        value = ioread32(gpio_base + offset);
-       value &= ~(0x3f << ((offset & 0x3) * 8));
+       value &= ~(0x7f << ((offset & 0x3) * 8));
        value |= (en & 0x1) << ((offset & 0x3) * 8);
        iowrite32(value, gpio_base + offset);
        spin_unlock(&sfg_lock);
@@ -430,8 +416,8 @@ void sf_vic_gpio_dout_value(int gpio,int v)
 
        spin_lock(&sfg_lock);
        value = ioread32(gpio_base + offset);
-       value &= ~(0x3f << ((offset & 0x3) * 8));
-       value |= (v & 0x3f) << ((offset & 0x3) * 8);
+       value &= ~(0x7f << ((offset & 0x3) * 8));
+       value |= (v & 0x7f) << ((offset & 0x3) * 8);
        iowrite32(value,gpio_base + offset);
        spin_unlock(&sfg_lock);
 }
@@ -651,10 +637,6 @@ static int sfvic7110_gpio_probe(struct platform_device *pdev)
        struct resource *res;
        int irq, ret, ngpio;
        int loop;
-       struct gpio_irq_chip *girq;
-       struct device_node *node = pdev->dev.of_node;
-       struct device_node *irq_parent;
-       struct irq_domain *parent;
 
        chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
        if (!chip) {
@@ -684,60 +666,30 @@ static int sfvic7110_gpio_probe(struct platform_device *pdev)
        chip->gc.parent = dev;
        chip->gc.owner = THIS_MODULE;
 
-       irq_parent = of_irq_find_parent(node);
-       if (!irq_parent) {
-               dev_err(dev, "no IRQ parent node\n");
-               return -ENODEV;
-       }
-       parent = irq_find_host(irq_parent);
-       if (!parent) {
-               dev_err(dev, "no IRQ parent domain\n");
-               return -ENODEV;
-       }
-
-       girq = &chip->gc.irq;
-       girq->chip = &sfvic7110_irqchip;
-       girq->fwnode = of_node_to_fwnode(node);
-       girq->parent_domain = parent;
-       girq->child_to_parent_hwirq = starfive_gpio_child_to_parent_hwirq;
-       girq->handler = handle_simple_irq;
-       girq->default_type = IRQ_TYPE_NONE;
-
-       /* Disable all GPIO interrupts before enabling parent interrupts */
-       iowrite32(0, chip->base + GPIO_IE_HIGH);
-       iowrite32(0, chip->base + GPIO_IE_LOW);
-       chip->enabled = 0;
-       
-       platform_set_drvdata(pdev, chip);
        ret = gpiochip_add_data(&chip->gc, chip);
        if (ret){
                dev_err(dev, "gpiochip_add_data ret=%d!\n", ret);
                return ret;
        }
-       
-#if 0
+
        /* Disable all GPIO interrupts before enabling parent interrupts */
        iowrite32(0, chip->base + GPIO_IE_HIGH);
        iowrite32(0, chip->base + GPIO_IE_LOW);
        chip->enabled = 0;
 
-       ret = gpiochip_gpiochip_add(&chip->gc, &sfvic7110_irqchip, 0,
+       ret = gpiochip_irqchip_add(&chip->gc, &sfvic7110_irqchip, 0,
                                   handle_simple_irq, IRQ_TYPE_NONE);
        if (ret) {
                dev_err(dev, "could not add irqchip\n");
                gpiochip_remove(&chip->gc);
                return ret;
        }
-#endif
-
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
                dev_err(dev, "Cannot get IRQ resource\n");
                return irq;
        }
 
-       chip->irq_parent[0] = irq;
-       
        ret = devm_request_irq(dev, irq, sfvic7110_irq_handler, IRQF_SHARED,
                               dev_name(dev), chip);
        if (ret) {