Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpio: gpio-generic: Add 16 and 32 bit big endian byte order support

There is no general support for 64-bit big endian accesses, so that is
left unsupported.

Signed-off-by: Andreas Larsson <andreas@gaisler.com>
Acked-by: Anton Vorontsov <anton@enomsg.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Andreas Larsson and committed by
Linus Walleij
2b78f1e1 43158441

+48 -9
+47 -9
drivers/gpio/gpio-generic.c
··· 104 104 } 105 105 #endif /* BITS_PER_LONG >= 64 */ 106 106 107 + static void bgpio_write16be(void __iomem *reg, unsigned long data) 108 + { 109 + iowrite16be(data, reg); 110 + } 111 + 112 + static unsigned long bgpio_read16be(void __iomem *reg) 113 + { 114 + return ioread16be(reg); 115 + } 116 + 117 + static void bgpio_write32be(void __iomem *reg, unsigned long data) 118 + { 119 + iowrite32be(data, reg); 120 + } 121 + 122 + static unsigned long bgpio_read32be(void __iomem *reg) 123 + { 124 + return ioread32be(reg); 125 + } 126 + 107 127 static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin) 108 128 { 109 129 return 1 << pin; ··· 269 249 270 250 static int bgpio_setup_accessors(struct device *dev, 271 251 struct bgpio_chip *bgc, 272 - bool be) 252 + bool bit_be, 253 + bool byte_be) 273 254 { 274 255 275 256 switch (bgc->bits) { ··· 279 258 bgc->write_reg = bgpio_write8; 280 259 break; 281 260 case 16: 282 - bgc->read_reg = bgpio_read16; 283 - bgc->write_reg = bgpio_write16; 261 + if (byte_be) { 262 + bgc->read_reg = bgpio_read16be; 263 + bgc->write_reg = bgpio_write16be; 264 + } else { 265 + bgc->read_reg = bgpio_read16; 266 + bgc->write_reg = bgpio_write16; 267 + } 284 268 break; 285 269 case 32: 286 - bgc->read_reg = bgpio_read32; 287 - bgc->write_reg = bgpio_write32; 270 + if (byte_be) { 271 + bgc->read_reg = bgpio_read32be; 272 + bgc->write_reg = bgpio_write32be; 273 + } else { 274 + bgc->read_reg = bgpio_read32; 275 + bgc->write_reg = bgpio_write32; 276 + } 288 277 break; 289 278 #if BITS_PER_LONG >= 64 290 279 case 64: 291 - bgc->read_reg = bgpio_read64; 292 - bgc->write_reg = bgpio_write64; 280 + if (byte_be) { 281 + dev_err(dev, 282 + "64 bit big endian byte order unsupported\n"); 283 + return -EINVAL; 284 + } else { 285 + bgc->read_reg = bgpio_read64; 286 + bgc->write_reg = bgpio_write64; 287 + } 293 288 break; 294 289 #endif /* BITS_PER_LONG >= 64 */ 295 290 default: ··· 313 276 return -EINVAL; 314 277 } 315 278 316 - bgc->pin2mask = be ? bgpio_pin2mask_be : bgpio_pin2mask; 279 + bgc->pin2mask = bit_be ? bgpio_pin2mask_be : bgpio_pin2mask; 317 280 318 281 return 0; 319 282 } ··· 422 385 if (ret) 423 386 return ret; 424 387 425 - ret = bgpio_setup_accessors(dev, bgc, flags & BGPIOF_BIG_ENDIAN); 388 + ret = bgpio_setup_accessors(dev, bgc, flags & BGPIOF_BIG_ENDIAN, 389 + flags & BGPIOF_BIG_ENDIAN_BYTE_ORDER); 426 390 if (ret) 427 391 return ret; 428 392
+1
include/linux/basic_mmio_gpio.h
··· 72 72 #define BGPIOF_BIG_ENDIAN BIT(0) 73 73 #define BGPIOF_UNREADABLE_REG_SET BIT(1) /* reg_set is unreadable */ 74 74 #define BGPIOF_UNREADABLE_REG_DIR BIT(2) /* reg_dir is unreadable */ 75 + #define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3) 75 76 76 77 #endif /* __BASIC_MMIO_GPIO_H */