diff options
-rw-r--r-- | drivers/gpio/gpio-generic.c | 56 | ||||
-rw-r--r-- | include/linux/basic_mmio_gpio.h | 1 |
2 files changed, 48 insertions, 9 deletions
diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index 05fcc0f247ca..42d470632aea 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c | |||
@@ -104,6 +104,26 @@ static unsigned long bgpio_read64(void __iomem *reg) | |||
104 | } | 104 | } |
105 | #endif /* BITS_PER_LONG >= 64 */ | 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 | static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin) | 127 | static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin) |
108 | { | 128 | { |
109 | return 1 << pin; | 129 | return 1 << pin; |
@@ -249,7 +269,8 @@ static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val) | |||
249 | 269 | ||
250 | static int bgpio_setup_accessors(struct device *dev, | 270 | static int bgpio_setup_accessors(struct device *dev, |
251 | struct bgpio_chip *bgc, | 271 | struct bgpio_chip *bgc, |
252 | bool be) | 272 | bool bit_be, |
273 | bool byte_be) | ||
253 | { | 274 | { |
254 | 275 | ||
255 | switch (bgc->bits) { | 276 | switch (bgc->bits) { |
@@ -258,17 +279,33 @@ static int bgpio_setup_accessors(struct device *dev, | |||
258 | bgc->write_reg = bgpio_write8; | 279 | bgc->write_reg = bgpio_write8; |
259 | break; | 280 | break; |
260 | case 16: | 281 | case 16: |
261 | bgc->read_reg = bgpio_read16; | 282 | if (byte_be) { |
262 | bgc->write_reg = bgpio_write16; | 283 | bgc->read_reg = bgpio_read16be; |
284 | bgc->write_reg = bgpio_write16be; | ||
285 | } else { | ||
286 | bgc->read_reg = bgpio_read16; | ||
287 | bgc->write_reg = bgpio_write16; | ||
288 | } | ||
263 | break; | 289 | break; |
264 | case 32: | 290 | case 32: |
265 | bgc->read_reg = bgpio_read32; | 291 | if (byte_be) { |
266 | bgc->write_reg = bgpio_write32; | 292 | bgc->read_reg = bgpio_read32be; |
293 | bgc->write_reg = bgpio_write32be; | ||
294 | } else { | ||
295 | bgc->read_reg = bgpio_read32; | ||
296 | bgc->write_reg = bgpio_write32; | ||
297 | } | ||
267 | break; | 298 | break; |
268 | #if BITS_PER_LONG >= 64 | 299 | #if BITS_PER_LONG >= 64 |
269 | case 64: | 300 | case 64: |
270 | bgc->read_reg = bgpio_read64; | 301 | if (byte_be) { |
271 | bgc->write_reg = bgpio_write64; | 302 | dev_err(dev, |
303 | "64 bit big endian byte order unsupported\n"); | ||
304 | return -EINVAL; | ||
305 | } else { | ||
306 | bgc->read_reg = bgpio_read64; | ||
307 | bgc->write_reg = bgpio_write64; | ||
308 | } | ||
272 | break; | 309 | break; |
273 | #endif /* BITS_PER_LONG >= 64 */ | 310 | #endif /* BITS_PER_LONG >= 64 */ |
274 | default: | 311 | default: |
@@ -276,7 +313,7 @@ static int bgpio_setup_accessors(struct device *dev, | |||
276 | return -EINVAL; | 313 | return -EINVAL; |
277 | } | 314 | } |
278 | 315 | ||
279 | bgc->pin2mask = be ? bgpio_pin2mask_be : bgpio_pin2mask; | 316 | bgc->pin2mask = bit_be ? bgpio_pin2mask_be : bgpio_pin2mask; |
280 | 317 | ||
281 | return 0; | 318 | return 0; |
282 | } | 319 | } |
@@ -385,7 +422,8 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev, | |||
385 | if (ret) | 422 | if (ret) |
386 | return ret; | 423 | return ret; |
387 | 424 | ||
388 | ret = bgpio_setup_accessors(dev, bgc, flags & BGPIOF_BIG_ENDIAN); | 425 | ret = bgpio_setup_accessors(dev, bgc, flags & BGPIOF_BIG_ENDIAN, |
426 | flags & BGPIOF_BIG_ENDIAN_BYTE_ORDER); | ||
389 | if (ret) | 427 | if (ret) |
390 | return ret; | 428 | return ret; |
391 | 429 | ||
diff --git a/include/linux/basic_mmio_gpio.h b/include/linux/basic_mmio_gpio.h index 1c504ca5bdb3..d8a97ec0e2b8 100644 --- a/include/linux/basic_mmio_gpio.h +++ b/include/linux/basic_mmio_gpio.h | |||
@@ -72,5 +72,6 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev, | |||
72 | #define BGPIOF_BIG_ENDIAN BIT(0) | 72 | #define BGPIOF_BIG_ENDIAN BIT(0) |
73 | #define BGPIOF_UNREADABLE_REG_SET BIT(1) /* reg_set is unreadable */ | 73 | #define BGPIOF_UNREADABLE_REG_SET BIT(1) /* reg_set is unreadable */ |
74 | #define BGPIOF_UNREADABLE_REG_DIR BIT(2) /* reg_dir is unreadable */ | 74 | #define BGPIOF_UNREADABLE_REG_DIR BIT(2) /* reg_dir is unreadable */ |
75 | #define BGPIOF_BIG_ENDIAN_BYTE_ORDER BIT(3) | ||
75 | 76 | ||
76 | #endif /* __BASIC_MMIO_GPIO_H */ | 77 | #endif /* __BASIC_MMIO_GPIO_H */ |