diff options
author | Song Hui <hui.song_1@nxp.com> | 2019-07-18 05:49:02 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2019-08-02 18:15:03 -0400 |
commit | bd4bd337039df9d5c6a3c11c439511fd99e11f52 (patch) | |
tree | e8849a67faa8065d55b6d20e51ea204c92e823a1 | |
parent | 49281a222ac42724b94f6c874f43a284ec58d37e (diff) |
gpio: mpc8xxx: Add ls1028a device specify function.
There is a device specify register(named GPIO_IBE)
on ls1028a need to enable in initial stage.
Signed-off-by: Song Hui <hui.song_1@nxp.com>
Link: https://lore.kernel.org/r/20190718094902.15562-2-hui.song_1@nxp.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/gpio/gpio-mpc8xxx.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index c8673a5d9412..1a680aa28769 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #define GPIO_IMR 0x10 | 32 | #define GPIO_IMR 0x10 |
33 | #define GPIO_ICR 0x14 | 33 | #define GPIO_ICR 0x14 |
34 | #define GPIO_ICR2 0x18 | 34 | #define GPIO_ICR2 0x18 |
35 | #define GPIO_IBE 0x18 | ||
35 | 36 | ||
36 | struct mpc8xxx_gpio_chip { | 37 | struct mpc8xxx_gpio_chip { |
37 | struct gpio_chip gc; | 38 | struct gpio_chip gc; |
@@ -45,6 +46,27 @@ struct mpc8xxx_gpio_chip { | |||
45 | unsigned int irqn; | 46 | unsigned int irqn; |
46 | }; | 47 | }; |
47 | 48 | ||
49 | /* The GPIO Input Buffer Enable register(GPIO_IBE) is used to | ||
50 | * control the input enable of each individual GPIO port. | ||
51 | * When an individual GPIO port’s direction is set to | ||
52 | * input (GPIO_GPDIR[DRn=0]), the associated input enable must be | ||
53 | * set (GPIOxGPIE[IEn]=1) to propagate the port value to the GPIO | ||
54 | * Data Register. | ||
55 | */ | ||
56 | static int ls1028a_gpio_dir_in_init(struct gpio_chip *gc) | ||
57 | { | ||
58 | unsigned long flags; | ||
59 | struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc); | ||
60 | |||
61 | spin_lock_irqsave(&gc->bgpio_lock, flags); | ||
62 | |||
63 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IBE, 0xffffffff); | ||
64 | |||
65 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
48 | /* | 70 | /* |
49 | * This hardware has a big endian bit assignment such that GPIO line 0 is | 71 | * This hardware has a big endian bit assignment such that GPIO line 0 is |
50 | * connected to bit 31, line 1 to bit 30 ... line 31 to bit 0. | 72 | * connected to bit 31, line 1 to bit 30 ... line 31 to bit 0. |
@@ -261,6 +283,7 @@ static const struct irq_domain_ops mpc8xxx_gpio_irq_ops = { | |||
261 | }; | 283 | }; |
262 | 284 | ||
263 | struct mpc8xxx_gpio_devtype { | 285 | struct mpc8xxx_gpio_devtype { |
286 | int (*gpio_dir_in_init)(struct gpio_chip *chip); | ||
264 | int (*gpio_dir_out)(struct gpio_chip *, unsigned int, int); | 287 | int (*gpio_dir_out)(struct gpio_chip *, unsigned int, int); |
265 | int (*gpio_get)(struct gpio_chip *, unsigned int); | 288 | int (*gpio_get)(struct gpio_chip *, unsigned int); |
266 | int (*irq_set_type)(struct irq_data *, unsigned int); | 289 | int (*irq_set_type)(struct irq_data *, unsigned int); |
@@ -271,6 +294,10 @@ static const struct mpc8xxx_gpio_devtype mpc512x_gpio_devtype = { | |||
271 | .irq_set_type = mpc512x_irq_set_type, | 294 | .irq_set_type = mpc512x_irq_set_type, |
272 | }; | 295 | }; |
273 | 296 | ||
297 | static const struct mpc8xxx_gpio_devtype ls1028a_gpio_devtype = { | ||
298 | .gpio_dir_in_init = ls1028a_gpio_dir_in_init, | ||
299 | }; | ||
300 | |||
274 | static const struct mpc8xxx_gpio_devtype mpc5125_gpio_devtype = { | 301 | static const struct mpc8xxx_gpio_devtype mpc5125_gpio_devtype = { |
275 | .gpio_dir_out = mpc5125_gpio_dir_out, | 302 | .gpio_dir_out = mpc5125_gpio_dir_out, |
276 | .irq_set_type = mpc512x_irq_set_type, | 303 | .irq_set_type = mpc512x_irq_set_type, |
@@ -291,6 +318,7 @@ static const struct of_device_id mpc8xxx_gpio_ids[] = { | |||
291 | { .compatible = "fsl,mpc5121-gpio", .data = &mpc512x_gpio_devtype, }, | 318 | { .compatible = "fsl,mpc5121-gpio", .data = &mpc512x_gpio_devtype, }, |
292 | { .compatible = "fsl,mpc5125-gpio", .data = &mpc5125_gpio_devtype, }, | 319 | { .compatible = "fsl,mpc5125-gpio", .data = &mpc5125_gpio_devtype, }, |
293 | { .compatible = "fsl,pq3-gpio", }, | 320 | { .compatible = "fsl,pq3-gpio", }, |
321 | { .compatible = "fsl,ls1028a-gpio", .data = &ls1028a_gpio_devtype, }, | ||
294 | { .compatible = "fsl,qoriq-gpio", }, | 322 | { .compatible = "fsl,qoriq-gpio", }, |
295 | {} | 323 | {} |
296 | }; | 324 | }; |
@@ -376,6 +404,9 @@ static int mpc8xxx_probe(struct platform_device *pdev) | |||
376 | /* ack and mask all irqs */ | 404 | /* ack and mask all irqs */ |
377 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0xffffffff); | 405 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0xffffffff); |
378 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0); | 406 | gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0); |
407 | /* enable input buffer */ | ||
408 | if (devtype->gpio_dir_in_init) | ||
409 | devtype->gpio_dir_in_init(gc); | ||
379 | 410 | ||
380 | irq_set_chained_handler_and_data(mpc8xxx_gc->irqn, | 411 | irq_set_chained_handler_and_data(mpc8xxx_gc->irqn, |
381 | mpc8xxx_gpio_irq_cascade, mpc8xxx_gc); | 412 | mpc8xxx_gpio_irq_cascade, mpc8xxx_gc); |