On Tue, Aug 29, 2023 at 2:35 PM Yinbo Zhu <zhuyinbo@xxxxxxxxxxx> wrote: > > This patch was to add loongson 2k0500, 2k2000 and 3a5000 gpio chip > driver support. > > Signed-off-by: Yinbo Zhu <zhuyinbo@xxxxxxxxxxx> > --- > drivers/gpio/gpio-loongson-64bit.c | 125 ++++++++++++++++++++++++++--- > 1 file changed, 113 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpio/gpio-loongson-64bit.c b/drivers/gpio/gpio-loongson-64bit.c > index 06213bbfabdd..2608f7eeba3b 100644 > --- a/drivers/gpio/gpio-loongson-64bit.c > +++ b/drivers/gpio/gpio-loongson-64bit.c > @@ -23,9 +23,10 @@ enum loongson_gpio_mode { > struct loongson_gpio_chip_data { > const char *label; > enum loongson_gpio_mode mode; > - unsigned int conf_offset; > - unsigned int out_offset; > - unsigned int in_offset; > + u32 conf_offset; > + u32 out_offset; > + u32 in_offset; > + u32 inten_offset; Why are you doing this? If this change is needed, it warrants at least a mention in the commit message. Bart > }; > > struct loongson_gpio_chip { > @@ -117,19 +118,29 @@ static void loongson_gpio_set(struct gpio_chip *chip, unsigned int pin, int valu > > static int loongson_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) > { > + unsigned int u; > struct platform_device *pdev = to_platform_device(chip->parent); > + struct loongson_gpio_chip *lgpio = to_loongson_gpio_chip(chip); > + > + if (lgpio->chip_data->mode == BIT_CTRL_MODE) { > + /* Get the register index from offset then multiply by bytes per register */ > + u = readl(lgpio->reg_base + lgpio->chip_data->inten_offset + (offset / 32) * 4); > + u |= BIT(offset % 32); > + writel(u, lgpio->reg_base + lgpio->chip_data->inten_offset + (offset / 32) * 4); > + } else { > + writeb(1, lgpio->reg_base + lgpio->chip_data->inten_offset + offset); > + } > > return platform_get_irq(pdev, offset); > } > > static int loongson_gpio_init(struct device *dev, struct loongson_gpio_chip *lgpio, > - struct device_node *np, void __iomem *reg_base) > + void __iomem *reg_base) > { > int ret; > u32 ngpios; > > lgpio->reg_base = reg_base; > - > if (lgpio->chip_data->mode == BIT_CTRL_MODE) { > ret = bgpio_init(&lgpio->chip, dev, 8, > lgpio->reg_base + lgpio->chip_data->in_offset, > @@ -148,15 +159,15 @@ static int loongson_gpio_init(struct device *dev, struct loongson_gpio_chip *lgp > lgpio->chip.direction_output = loongson_gpio_direction_output; > lgpio->chip.set = loongson_gpio_set; > lgpio->chip.parent = dev; > + device_property_read_u32(dev, "ngpios", &ngpios); > + lgpio->chip.ngpio = ngpios; > spin_lock_init(&lgpio->lock); > } > > - device_property_read_u32(dev, "ngpios", &ngpios); > - > - lgpio->chip.can_sleep = 0; > - lgpio->chip.ngpio = ngpios; > lgpio->chip.label = lgpio->chip_data->label; > - lgpio->chip.to_irq = loongson_gpio_to_irq; > + lgpio->chip.can_sleep = false; > + if (lgpio->chip_data->inten_offset) > + lgpio->chip.to_irq = loongson_gpio_to_irq; > > return devm_gpiochip_add_data(dev, &lgpio->chip, lgpio); > } > @@ -165,7 +176,6 @@ static int loongson_gpio_probe(struct platform_device *pdev) > { > void __iomem *reg_base; > struct loongson_gpio_chip *lgpio; > - struct device_node *np = pdev->dev.of_node; > struct device *dev = &pdev->dev; > > lgpio = devm_kzalloc(dev, sizeof(*lgpio), GFP_KERNEL); > @@ -178,7 +188,7 @@ static int loongson_gpio_probe(struct platform_device *pdev) > if (IS_ERR(reg_base)) > return PTR_ERR(reg_base); > > - return loongson_gpio_init(dev, lgpio, np, reg_base); > + return loongson_gpio_init(dev, lgpio, reg_base); > } > > static const struct loongson_gpio_chip_data loongson_gpio_ls2k_data = { > @@ -187,6 +197,57 @@ static const struct loongson_gpio_chip_data loongson_gpio_ls2k_data = { > .conf_offset = 0x0, > .in_offset = 0x20, > .out_offset = 0x10, > + .inten_offset = 0x30, > +}; > + > +static const struct loongson_gpio_chip_data loongson_gpio_ls2k0500_data0 = { > + .label = "ls2k0500_gpio", > + .mode = BIT_CTRL_MODE, > + .conf_offset = 0x0, > + .in_offset = 0x8, > + .out_offset = 0x10, > + .inten_offset = 0xb0, > +}; > + > +static const struct loongson_gpio_chip_data loongson_gpio_ls2k0500_data1 = { > + .label = "ls2k0500_gpio", > + .mode = BIT_CTRL_MODE, > + .conf_offset = 0x0, > + .in_offset = 0x8, > + .out_offset = 0x10, > + .inten_offset = 0x98, > +}; > + > +static const struct loongson_gpio_chip_data loongson_gpio_ls2k2000_data0 = { > + .label = "ls2k2000_gpio", > + .mode = BIT_CTRL_MODE, > + .conf_offset = 0x0, > + .in_offset = 0xc, > + .out_offset = 0x8, > +}; > + > +static const struct loongson_gpio_chip_data loongson_gpio_ls2k2000_data1 = { > + .label = "ls2k2000_gpio", > + .mode = BIT_CTRL_MODE, > + .conf_offset = 0x0, > + .in_offset = 0x20, > + .out_offset = 0x10, > +}; > + > +static const struct loongson_gpio_chip_data loongson_gpio_ls2k2000_data2 = { > + .label = "ls2k2000_gpio", > + .mode = BIT_CTRL_MODE, > + .conf_offset = 0x84, > + .in_offset = 0x88, > + .out_offset = 0x80, > +}; > + > +static const struct loongson_gpio_chip_data loongson_gpio_ls3a5000_data = { > + .label = "ls3a5000_gpio", > + .mode = BIT_CTRL_MODE, > + .conf_offset = 0x0, > + .in_offset = 0xc, > + .out_offset = 0x8, > }; > > static const struct loongson_gpio_chip_data loongson_gpio_ls7a_data = { > @@ -202,6 +263,30 @@ static const struct of_device_id loongson_gpio_of_match[] = { > .compatible = "loongson,ls2k-gpio", > .data = &loongson_gpio_ls2k_data, > }, > + { > + .compatible = "loongson,ls2k0500-gpio0", > + .data = &loongson_gpio_ls2k0500_data0, > + }, > + { > + .compatible = "loongson,ls2k0500-gpio1", > + .data = &loongson_gpio_ls2k0500_data1, > + }, > + { > + .compatible = "loongson,ls2k2000-gpio0", > + .data = &loongson_gpio_ls2k2000_data0, > + }, > + { > + .compatible = "loongson,ls2k2000-gpio1", > + .data = &loongson_gpio_ls2k2000_data1, > + }, > + { > + .compatible = "loongson,ls2k2000-gpio2", > + .data = &loongson_gpio_ls2k2000_data2, > + }, > + { > + .compatible = "loongson,ls3a5000-gpio", > + .data = &loongson_gpio_ls3a5000_data, > + }, > { > .compatible = "loongson,ls7a-gpio", > .data = &loongson_gpio_ls7a_data, > @@ -215,6 +300,22 @@ static const struct acpi_device_id loongson_gpio_acpi_match[] = { > .id = "LOON0002", > .driver_data = (kernel_ulong_t)&loongson_gpio_ls7a_data, > }, > + { > + .id = "LOON0007", > + .driver_data = (kernel_ulong_t)&loongson_gpio_ls3a5000_data, > + }, > + { > + .id = "LOON000A", > + .driver_data = (kernel_ulong_t)&loongson_gpio_ls2k2000_data0, > + }, > + { > + .id = "LOON000B", > + .driver_data = (kernel_ulong_t)&loongson_gpio_ls2k2000_data1, > + }, > + { > + .id = "LOON000C", > + .driver_data = (kernel_ulong_t)&loongson_gpio_ls2k2000_data2, > + }, > {} > }; > MODULE_DEVICE_TABLE(acpi, loongson_gpio_acpi_match); > -- > 2.20.1 >