* [PATCH v1 0/1] gpio: mmio: add get_set inverted direction io support @ 2018-07-30 9:34 Tomer Maimon 2018-07-30 9:34 ` [PATCH v1 1/1] gpio: mmio: add inverted direction get_set " Tomer Maimon 0 siblings, 1 reply; 4+ messages in thread From: Tomer Maimon @ 2018-07-30 9:34 UTC (permalink / raw) To: linus.walleij; +Cc: linux-kernel, linux-gpio, Tomer Maimon When bgpio direction register use dirin and setting BGPIOF_READ_OUTPUT_REG_SET flag, the get_set I/O functions reading the inverted set register of each direction, it means: when direction=in the get_set function read set register. when direction=out the get_set function read dat register. but is should be inverted. conversion about it with Linus Walleij: https://www.spinics.net/lists/devicetree/msg241973.html to solve it, adding get_set_inv_dir and get_set_multiple_inv_dir I/O functions to call the data register when the direction is input and set register when the direction is output. the functions will linked to the I/O get functions if the user set BGPIOF_INVERTED_REG_DIR flag in the bgpio initialization. Tomer Maimon (1): gpio: mmio: add inverted direction get_set io support drivers/gpio/gpio-mmio.c | 48 ++++++++++++++++++++++++++++++++++++++++++--- include/linux/gpio/driver.h | 1 + 2 files changed, 46 insertions(+), 3 deletions(-) -- 2.14.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v1 1/1] gpio: mmio: add inverted direction get_set io support 2018-07-30 9:34 [PATCH v1 0/1] gpio: mmio: add get_set inverted direction io support Tomer Maimon @ 2018-07-30 9:34 ` Tomer Maimon 2018-07-30 17:14 ` Andy Shevchenko 2018-08-02 23:34 ` Linus Walleij 0 siblings, 2 replies; 4+ messages in thread From: Tomer Maimon @ 2018-07-30 9:34 UTC (permalink / raw) To: linus.walleij; +Cc: linux-kernel, linux-gpio, Tomer Maimon Add get_set_inv_dir and get_set_multiple_inv_dir I/O functions to call the data register when the dirction is input and set register when the direction is output. the functions will linked to the I/O get functions if the user set BGPIOF_INVERTED_REG_DIR flag in the bgpio initialization. Signed-off-by: Tomer Maimon <tmaimon77@gmail.com> --- drivers/gpio/gpio-mmio.c | 48 ++++++++++++++++++++++++++++++++++++++++++--- include/linux/gpio/driver.h | 1 + 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index 7b14d6280e44..46f664459853 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c @@ -168,6 +168,40 @@ static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask, return 0; } +/* get set function when the direction is inverted */ +static int bgpio_get_set_inv_dir(struct gpio_chip *gc, unsigned int gpio) +{ + unsigned long pinmask = bgpio_line2mask(gc, gpio); + + if (gc->bgpio_dir & pinmask) + return !!(gc->read_reg(gc->reg_dat) & pinmask); + else + return !!(gc->read_reg(gc->reg_set) & pinmask); +} + +/* get set multiple function when the direction is inverted */ +static int bgpio_get_set_multiple_inv_dir(struct gpio_chip *gc, + unsigned long *mask, + unsigned long *bits) +{ + unsigned long get_mask = 0; + unsigned long set_mask = 0; + + /* Make sure we first clear any bits that are zero when we read the register */ + *bits &= ~*mask; + + /* Exploit the fact that we know which directions are set */ + set_mask = *mask & ~gc->bgpio_dir; + get_mask = *mask & gc->bgpio_dir; + + if (set_mask) + *bits |= gc->read_reg(gc->reg_set) & set_mask; + if (get_mask) + *bits |= gc->read_reg(gc->reg_dat) & get_mask; + + return 0; +} + static int bgpio_get(struct gpio_chip *gc, unsigned int gpio) { return !!(gc->read_reg(gc->reg_dat) & bgpio_line2mask(gc, gpio)); @@ -525,9 +559,17 @@ static int bgpio_setup_io(struct gpio_chip *gc, if (!(flags & BGPIOF_UNREADABLE_REG_SET) && (flags & BGPIOF_READ_OUTPUT_REG_SET)) { - gc->get = bgpio_get_set; - if (!gc->be_bits) - gc->get_multiple = bgpio_get_set_multiple; + /* if the direction inverted */ + if (flags & BGPIOF_INVERTED_REG_DIR) { + gc->get = bgpio_get_set_inv_dir; + if (!gc->be_bits) + gc->get_multiple = + bgpio_get_set_multiple_inv_dir; + } else { + gc->get = bgpio_get_set; + if (!gc->be_bits) + gc->get_multiple = bgpio_get_set_multiple; + } /* * We deliberately avoid assigning the ->get_multiple() call * for big endian mirrored registers which are ALSO reflecting diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 5382b5183b7e..63570580707c 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -425,6 +425,7 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev, #define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3) #define BGPIOF_READ_OUTPUT_REG_SET BIT(4) /* reg_set stores output value */ #define BGPIOF_NO_OUTPUT BIT(5) /* only input */ +#define BGPIOF_INVERTED_REG_DIR BIT(6) /* reg_dir inverted */ #endif -- 2.14.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v1 1/1] gpio: mmio: add inverted direction get_set io support 2018-07-30 9:34 ` [PATCH v1 1/1] gpio: mmio: add inverted direction get_set " Tomer Maimon @ 2018-07-30 17:14 ` Andy Shevchenko 2018-08-02 23:34 ` Linus Walleij 1 sibling, 0 replies; 4+ messages in thread From: Andy Shevchenko @ 2018-07-30 17:14 UTC (permalink / raw) To: Tomer Maimon Cc: Linus Walleij, Linux Kernel Mailing List, open list:GPIO SUBSYSTEM On Mon, Jul 30, 2018 at 12:34 PM, Tomer Maimon <tmaimon77@gmail.com> wrote: > Add get_set_inv_dir and get_set_multiple_inv_dir I/O functions > to call the data register when the dirction is input and > set register when the direction is output. > the functions will linked to the I/O get functions if the user set > BGPIOF_INVERTED_REG_DIR flag in the bgpio initialization. > + /* Make sure we first clear any bits that are zero when we read the register */ > + *bits &= ~*mask; Theoretically it's possible to get mask and bits longer than one long, and bitmap API has to be used. Though, it seems entire driver has been written in an assumption that it's never happen. > + gc->get_multiple = > + bgpio_get_set_multiple_inv_dir; I think you may keep it on one line. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v1 1/1] gpio: mmio: add inverted direction get_set io support 2018-07-30 9:34 ` [PATCH v1 1/1] gpio: mmio: add inverted direction get_set " Tomer Maimon 2018-07-30 17:14 ` Andy Shevchenko @ 2018-08-02 23:34 ` Linus Walleij 1 sibling, 0 replies; 4+ messages in thread From: Linus Walleij @ 2018-08-02 23:34 UTC (permalink / raw) To: tmaimon77; +Cc: linux-kernel@vger.kernel.org, open list:GPIO SUBSYSTEM On Mon, Jul 30, 2018 at 11:34 AM Tomer Maimon <tmaimon77@gmail.com> wrote: > Add get_set_inv_dir and get_set_multiple_inv_dir I/O functions > to call the data register when the dirction is input and > set register when the direction is output. > the functions will linked to the I/O get functions if the user set > BGPIOF_INVERTED_REG_DIR flag in the bgpio initialization. > > Signed-off-by: Tomer Maimon <tmaimon77@gmail.com> I think you uncovered a bug. This is however not the best fix IMO. Sorry for not understanding the issue at first, I am sometimes pretty slow in the head. :( I'm sending a patch that I hope fixes the real problem in an elegant way, and makes it possible to just define dirin and BGPIOF_READ_OUTPUT_REG_SET. Yours, Linus Walleij ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-08-02 23:34 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-07-30 9:34 [PATCH v1 0/1] gpio: mmio: add get_set inverted direction io support Tomer Maimon 2018-07-30 9:34 ` [PATCH v1 1/1] gpio: mmio: add inverted direction get_set " Tomer Maimon 2018-07-30 17:14 ` Andy Shevchenko 2018-08-02 23:34 ` Linus Walleij
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).