On Thu, Feb 18, 2016 at 3:50 AM, Barry Song <baohua@xxxxxxxxxx> wrote: > gpiochip_add(chip will call this automatically since range is set in dtsi: > gpio_0: gpio_mediam@17040000 { > #gpio-cells = <2>; > #interrupt-cells = <2>; > compatible = "sirf,atlas7-gpio"; > reg = <0x17040000 0x1000>; > interrupts = <0 13 0>, <0 14 0>; > clocks = <&car 98>; > clock-names = "gpio0_io"; > gpio-controller; > interrupt-controller; > > gpio-banks = <2>; > gpio-ranges = <&pinctrl 0 0 0>, > <&pinctrl 32 0 0>; > gpio-ranges-group-names = "lvds_gpio_grp", > "jtag_uart_nand_gpio_grp"; Aha I see. >> - >> - /* Records gpio_pin_range to a7gc */ >> - list_for_each_entry(pin_range, &chip->pin_ranges, node) { >> - struct pinctrl_gpio_range *range; >> - >> - range = &pin_range->range; >> - if (range->id == NGPIO_OF_BANK * idx) { >> - bank->gpio_offset = range->id; >> - bank->ngpio = range->npins; >> - bank->gpio_pins = range->pins; >> - bank->pctldev = pin_range->pctldev; >> - break; >> - } >> - } >> - >> - BUG_ON(!bank->pctldev); > > this doesn't work. my pin range is not continuous and linear, so we > need the "if (range->id == NGPIO_OF_BANK * idx)" to calculate the > gpio_offset. > and gpio_offset is used in many places: Can't you use: struct pinctrl_gpio_range *range = pinctrl_find_gpio_range_from_pin(pctldev, pin); In these places instead? ? That is what most drivers do. Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html