Microchip: XEC GPIO driver interrupt enable fix part 2
Fixes issue 34879 This PR updates previous PR's 37138 and 37139. Refer to issue 34879 for information from MCHP HW designers. A delay after enabling interrupts is a more appropriate work-around than depending upon behavior of ARM DMB instruction. Signed-off-by: Scott Worley <scott.worley@microchip.com>
This commit is contained in:
parent
d1eee6a966
commit
114b84a58b
2 changed files with 13 additions and 9 deletions
|
@ -9,13 +9,12 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <device.h>
|
#include <device.h>
|
||||||
#include <drivers/gpio.h>
|
#include <drivers/gpio.h>
|
||||||
|
#include <sys/sys_io.h>
|
||||||
#include <soc.h>
|
#include <soc.h>
|
||||||
|
|
||||||
#include "gpio_utils.h"
|
#include "gpio_utils.h"
|
||||||
|
|
||||||
#define XEC_GPIO_EDGE_DLY_COUNT 8
|
#define XEC_GPIO_EDGE_DLY_COUNT 4
|
||||||
/* read only register in same AHB segmment for dummy writes */
|
|
||||||
#define XEC_GPIO_DLY_ADDR 0x40080150u
|
|
||||||
|
|
||||||
#define GPIO_IN_BASE(config) \
|
#define GPIO_IN_BASE(config) \
|
||||||
((__IO uint32_t *)(GPIO_PARIN_BASE + (config->port_num << 2)))
|
((__IO uint32_t *)(GPIO_PARIN_BASE + (config->port_num << 2)))
|
||||||
|
@ -215,7 +214,10 @@ static int gpio_xec_pin_interrupt_configure(const struct device *dev,
|
||||||
*/
|
*/
|
||||||
current_pcr1 = config->pcr1_base + pin;
|
current_pcr1 = config->pcr1_base + pin;
|
||||||
*current_pcr1 = (*current_pcr1 & ~mask) | pcr1;
|
*current_pcr1 = (*current_pcr1 & ~mask) | pcr1;
|
||||||
__DMB(); /* insure write completes */
|
/* delay for HW to synchronize after it ungates its clock */
|
||||||
|
for (int i = 0; i < XEC_GPIO_EDGE_DLY_COUNT; i++) {
|
||||||
|
(void)*current_pcr1;
|
||||||
|
}
|
||||||
|
|
||||||
if (mode != GPIO_INT_MODE_DISABLED) {
|
if (mode != GPIO_INT_MODE_DISABLED) {
|
||||||
/* We enable the interrupts in the EC aggregator so that the
|
/* We enable the interrupts in the EC aggregator so that the
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include "gpio_utils.h"
|
#include "gpio_utils.h"
|
||||||
|
|
||||||
#define XEC_ECIA_REGS ((struct ecia_regs *)(DT_REG_ADDR(DT_NODELABEL(ecia))))
|
#define XEC_GPIO_EDGE_DLY_COUNT 4
|
||||||
|
|
||||||
static const uint32_t valid_ctrl_masks[NUM_MCHP_GPIO_PORTS] = {
|
static const uint32_t valid_ctrl_masks[NUM_MCHP_GPIO_PORTS] = {
|
||||||
(MCHP_GPIO_PORT_A_BITMAP),
|
(MCHP_GPIO_PORT_A_BITMAP),
|
||||||
|
@ -268,7 +268,6 @@ static int gpio_xec_pin_interrupt_configure(const struct device *dev,
|
||||||
} else {
|
} else {
|
||||||
pcr1 |= MCHP_GPIO_CTRL_IDET_LVL_LO;
|
pcr1 |= MCHP_GPIO_CTRL_IDET_LVL_LO;
|
||||||
}
|
}
|
||||||
sys_write32(pcr1, pcr1_addr);
|
|
||||||
} else if (mode == GPIO_INT_MODE_EDGE) {
|
} else if (mode == GPIO_INT_MODE_EDGE) {
|
||||||
if (trig == GPIO_INT_TRIG_LOW) {
|
if (trig == GPIO_INT_TRIG_LOW) {
|
||||||
pcr1 |= MCHP_GPIO_CTRL_IDET_FEDGE;
|
pcr1 |= MCHP_GPIO_CTRL_IDET_FEDGE;
|
||||||
|
@ -277,11 +276,14 @@ static int gpio_xec_pin_interrupt_configure(const struct device *dev,
|
||||||
} else if (trig == GPIO_INT_TRIG_BOTH) {
|
} else if (trig == GPIO_INT_TRIG_BOTH) {
|
||||||
pcr1 |= MCHP_GPIO_CTRL_IDET_BEDGE;
|
pcr1 |= MCHP_GPIO_CTRL_IDET_BEDGE;
|
||||||
}
|
}
|
||||||
sys_write32(pcr1, pcr1_addr);
|
|
||||||
__DMB(); /* insure write completes */
|
|
||||||
} else {
|
} else {
|
||||||
pcr1 |= MCHP_GPIO_CTRL_IDET_DISABLE;
|
pcr1 |= MCHP_GPIO_CTRL_IDET_DISABLE;
|
||||||
sys_write32(pcr1, pcr1_addr);
|
}
|
||||||
|
|
||||||
|
sys_write32(pcr1, pcr1_addr);
|
||||||
|
/* delay for HW to synchronize after it ungates its clock */
|
||||||
|
for (int i = 0; i < XEC_GPIO_EDGE_DLY_COUNT; i++) {
|
||||||
|
sys_read32(pcr1_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
mchp_soc_ecia_girq_src_clr(config->girq_id, pin);
|
mchp_soc_ecia_girq_src_clr(config->girq_id, pin);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue