Skip to content

Commit f31fbe8

Browse files
committed
drivers: serial: Add support for group interrupt in the serial driver
Apply the grp irq support in serial driver for MCB-RX26T Signed-off-by: Quy Tran <[email protected]>
1 parent 2038606 commit f31fbe8

File tree

3 files changed

+252
-18
lines changed

3 files changed

+252
-18
lines changed

drivers/serial/uart_renesas_rx_sci.c

Lines changed: 214 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
#include <zephyr/irq.h>
1414
#include <zephyr/spinlock.h>
1515

16+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
17+
#include <zephyr/drivers/interrupt_controller/intc_renesas_rx_grp_int.h>
18+
#endif
19+
1620
#include "r_sci_rx_if.h"
1721
#include "iodefine_sci.h"
1822

@@ -33,6 +37,13 @@ LOG_MODULE_REGISTER(rx_uart_sci, CONFIG_UART_LOG_LEVEL);
3337
#define DEV_CFG(dev) ((const struct uart_rx_sci_config *const)(dev)->config)
3438
#define DEV_BASE(dev) (DEV_CFG(dev)->regs)
3539

40+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
41+
#define _SCI_INT_TEI_SRC(chan) BSP_INT_SRC_BL0_SCI##chan##_TEI##chan
42+
#define SCI_INT_TEI_SRC(chan) _SCI_INT_TEI_SRC(chan)
43+
#define _SCI_INT_ERI_SRC(chan) BSP_INT_SRC_BL0_SCI##chan##_ERI##chan
44+
#define SCI_INT_ERI_SRC(chan) _SCI_INT_ERI_SRC(chan)
45+
#endif
46+
3647
#if defined(CONFIG_UART_INTERRUPT_DRIVEN)
3748
static void uart_rx_sci_txi_isr(const struct device *dev);
3849
#endif
@@ -64,13 +75,121 @@ struct uart_rx_sci_data {
6475
#if defined(CONFIG_UART_INTERRUPT_DRIVEN)
6576
uint8_t rxi_irq;
6677
uint8_t txi_irq;
78+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
79+
bsp_int_src_t tei_src;
80+
bsp_int_src_t eri_src;
81+
/* Group interrupt controller for the transmit end interrupt (TEI) */
82+
const struct device *tei_ctrl;
83+
/* Group interrupt number for the transmit end interrupt (TEI) */
84+
uint8_t tei_num;
85+
/* Group interrupt controller for the error interrupt (ERI) */
86+
const struct device *eri_ctrl;
87+
/* Group interrupt number for the error interrupt (ERI) */
88+
uint8_t eri_num;
89+
#else
6790
uint8_t tei_irq;
6891
uint8_t eri_irq;
92+
#endif
6993
uart_irq_callback_user_data_t user_cb;
7094
void *user_cb_data;
7195
#endif
7296
};
7397

98+
#if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API)
99+
#ifdef CONFIG_RENESAS_RX_GRP_INTC
100+
101+
void uart_rx_sci_tei_isr(bsp_int_cb_args_t *p_args)
102+
{
103+
struct device *sci_dev = (struct device *)(p_args->p_context);
104+
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(sci_dev);
105+
106+
/* Disable SCI.SCR.TEIE */
107+
sci->SCR.BIT.TEIE = 0;
108+
109+
#if defined(CONFIG_UART_INTERRUPT_DRIVEN)
110+
struct uart_rx_sci_data *data = sci_dev->data;
111+
112+
if (data->user_cb != NULL) {
113+
114+
data->user_cb(sci_dev, data->user_cb_data);
115+
}
116+
#endif
117+
}
118+
119+
void uart_rx_sci_eri_isr(bsp_int_cb_args_t *p_args)
120+
{
121+
struct device *sci_dev = (struct device *)(p_args->p_context);
122+
123+
#if defined(CONFIG_UART_INTERRUPT_DRIVEN)
124+
struct uart_rx_sci_data *data = sci_dev->data;
125+
126+
if (data->user_cb != NULL) {
127+
128+
data->user_cb(sci_dev, data->user_cb_data);
129+
}
130+
#endif
131+
}
132+
133+
static inline int uart_rx_sci_tei_grp_int(const struct device *dev, bool enable)
134+
{
135+
struct uart_rx_sci_data *data = dev->data;
136+
int err;
137+
138+
if (enable) {
139+
err = rx_grp_intc_set_callback(data->tei_ctrl, (bsp_int_src_t)data->tei_src,
140+
(bsp_int_cb_t)uart_rx_sci_tei_isr, (void *)dev);
141+
if (err != 0) {
142+
LOG_ERR("Failed to set callback for group interrupt TEI: %d", err);
143+
return err;
144+
}
145+
}
146+
147+
err = rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, enable);
148+
if (err != 0) {
149+
LOG_ERR("Failed to allow interrupt request for TEI: %d", err);
150+
return err;
151+
}
152+
153+
err = rx_grp_intc_set_grp_int(data->tei_ctrl, (bsp_int_src_t)data->tei_src, enable);
154+
if (err != 0) {
155+
LOG_ERR("Failed to enable group interrupt for TEI: %d", err);
156+
return err;
157+
}
158+
159+
return 0;
160+
}
161+
162+
static inline int uart_rx_sci_eri_grp_int(const struct device *dev, bool enable)
163+
{
164+
struct uart_rx_sci_data *data = dev->data;
165+
int err;
166+
167+
if (enable) {
168+
err = rx_grp_intc_set_callback(data->eri_ctrl, (bsp_int_src_t)data->eri_src,
169+
(bsp_int_cb_t)uart_rx_sci_eri_isr, (void *)dev);
170+
if (err != 0) {
171+
LOG_ERR("Failed to set callback for group interrupt ERI: %d", err);
172+
return err;
173+
}
174+
}
175+
176+
err = rx_grp_intc_set_gen(data->eri_ctrl, data->eri_num, enable);
177+
if (err != 0) {
178+
LOG_ERR("Failed to allow interrupt request for ERI: %d", err);
179+
return err;
180+
}
181+
182+
err = rx_grp_intc_set_grp_int(data->eri_ctrl, (bsp_int_src_t)data->eri_src, enable);
183+
if (err != 0) {
184+
LOG_ERR("Failed to enable group interrupt for ERI: %d", err);
185+
return err;
186+
}
187+
188+
return 0;
189+
}
190+
#endif
191+
#endif
192+
74193
static int uart_rx_sci_poll_in(const struct device *dev, unsigned char *c)
75194
{
76195
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
@@ -234,12 +353,24 @@ static int uart_rx_fifo_fill(const struct device *dev, const uint8_t *tx_data, i
234353
{
235354
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
236355
uint8_t num_tx = 0U;
356+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
357+
struct uart_rx_sci_data *data = dev->data;
237358

359+
/* Disable ICU.GEN and SCI.SCR.TEIE*/
360+
rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, false);
361+
sci->SCR.BIT.TEIE = 0;
362+
#endif
238363
if (size > 0 && sci->SSR.BIT.TDRE) {
239364
/* Send a character (8bit , parity none) */
240365
sci->TDR = tx_data[num_tx++];
241366
}
242367

368+
#if defined(CONFIG_RENESAS_RX_GRP_INTC)
369+
/* Enable ICU.GEN and SCI.SCR.TEIE*/
370+
sci->SCR.BIT.TEIE = 1;
371+
rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, true);
372+
#endif
373+
243374
return num_tx;
244375
}
245376

@@ -258,11 +389,20 @@ static int uart_rx_fifo_read(const struct device *dev, uint8_t *rx_data, const i
258389

259390
static void uart_rx_irq_tx_enable(const struct device *dev)
260391
{
261-
struct uart_rx_sci_data *data = dev->data;
262392
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
263-
264393
sci->SCR.BYTE |= (BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos));
394+
395+
#ifdef CONFIG_RENESAS_RX_GRP_INTC
396+
/* Allows the interrupt request for the tei interrupt */
397+
int err = uart_rx_sci_tei_grp_int(dev, true);
398+
if (err != 0) {
399+
LOG_ERR("Failed to enable group interrupt TEI: %d", err);
400+
return;
401+
}
402+
#else
403+
struct uart_rx_sci_data *data = dev->data;
265404
irq_enable(data->tei_irq);
405+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
266406
if (sci->SSR.BIT.TDRE) {
267407
/* the callback function is usually called from an interrupt,
268408
* preventing other interrupts to be triggered during execution
@@ -278,11 +418,20 @@ static void uart_rx_irq_tx_enable(const struct device *dev)
278418

279419
static void uart_rx_irq_tx_disable(const struct device *dev)
280420
{
281-
struct uart_rx_sci_data *data = dev->data;
282421
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
283422

284423
sci->SCR.BYTE &= ~(BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos));
424+
#ifdef CONFIG_RENESAS_RX_GRP_INTC
425+
/* Disable the interrupt request for the tei interrupt */
426+
int err = uart_rx_sci_tei_grp_int(dev, false);
427+
if (err != 0) {
428+
LOG_ERR("Failed to disable group interrupt TEI: %d", err);
429+
return;
430+
}
431+
#else
432+
struct uart_rx_sci_data *data = dev->data;
285433
irq_disable(data->tei_irq);
434+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
286435
}
287436

288437
static int uart_rx_irq_tx_ready(const struct device *dev)
@@ -305,6 +454,15 @@ static void uart_rx_irq_rx_enable(const struct device *dev)
305454
volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev);
306455

307456
sci->SCR.BIT.RIE = 1U;
457+
458+
#ifdef CONFIG_RENESAS_RX_GRP_INTC
459+
/* Allows the interrupt request for the tei interrupt */
460+
int err = uart_rx_sci_eri_grp_int(dev, true);
461+
if (err != 0) {
462+
LOG_ERR("Failed to enable group interrupt ERI: %d", err);
463+
return;
464+
}
465+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
308466
}
309467

310468
static void uart_rx_irq_rx_disable(const struct device *dev)
@@ -323,16 +481,36 @@ static int uart_rx_irq_rx_ready(const struct device *dev)
323481

324482
static void uart_rx_irq_err_enable(const struct device *dev)
325483
{
326-
struct uart_rx_sci_data *data = dev->data;
327484

485+
#ifndef CONFIG_RENESAS_RX_GRP_INTC
486+
struct uart_rx_sci_data *data = dev->data;
328487
irq_enable(data->eri_irq);
488+
#else
489+
/* Allows the interrupt request for the eri interrupt */
490+
int err = uart_rx_sci_eri_grp_int(dev, true);
491+
if (err != 0) {
492+
LOG_ERR("Failed to enable group interrupt ERI: %d", err);
493+
return;
494+
}
495+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
329496
}
330497

331498
static void uart_rx_irq_err_disable(const struct device *dev)
332499
{
333-
struct uart_rx_sci_data *data = dev->data;
334500

501+
#ifndef CONFIG_RENESAS_RX_GRP_INTC
502+
struct uart_rx_sci_data *data = dev->data;
335503
irq_disable(data->eri_irq);
504+
505+
#else
506+
/* Allows the interrupt request for the eri interrupt */
507+
int err = uart_rx_sci_eri_grp_int(dev, false);
508+
if (err != 0) {
509+
LOG_ERR("Failed to enable group interrupt ERI: %d", err);
510+
return;
511+
}
512+
513+
#endif /* CONFIG_RENESAS_RX_GRP_INTC */
336514
}
337515

338516
static int uart_rx_irq_is_pending(const struct device *dev)
@@ -446,7 +624,7 @@ static void uart_rx_sci_txi_isr(const struct device *dev)
446624
}
447625
#endif
448626

449-
#ifndef CONFIG_SOC_SERIES_RX26T
627+
#ifndef CONFIG_RENESAS_RX_GRP_INTC
450628
static void uart_rx_sci_tei_isr(const struct device *dev)
451629
{
452630
struct uart_rx_sci_data *data = dev->data;
@@ -466,18 +644,8 @@ static void uart_rx_sci_eri_isr(const struct device *dev)
466644
}
467645
#endif
468646

469-
#if defined(CONFIG_SOC_SERIES_RX26T)
470-
#define UART_RX_SCI_CONFIG_INIT(index)
471-
#else
472-
#define UART_RX_SCI_CONFIG_INIT(index) \
473-
.rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
474-
.txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \
475-
.tei_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \
476-
.eri_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq),
477-
#endif
478-
479647
#if CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_ASYNC_API
480-
#ifndef CONFIG_SOC_SERIES_RX26T
648+
#ifndef CONFIG_RENESAS_RX_GRP_INTC
481649
#define UART_RX_SCI_IRQ_INIT(index) \
482650
do { \
483651
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
@@ -495,11 +663,39 @@ static void uart_rx_sci_eri_isr(const struct device *dev)
495663
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)); \
496664
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)); \
497665
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq)); \
498-
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq)); \
499666
} while (0)
667+
668+
#define UART_RX_SCI_CONFIG_INIT(index) \
669+
.rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
670+
.txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \
671+
.tei_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \
672+
.eri_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq),
673+
#else
674+
#define UART_RX_SCI_IRQ_INIT(index) \
675+
do { \
676+
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
677+
DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, priority), \
678+
uart_rx_sci_rxi_isr, DEVICE_DT_INST_GET(index), 0); \
679+
IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \
680+
DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, priority), \
681+
uart_rx_sci_txi_isr, DEVICE_DT_INST_GET(index), 0); \
682+
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)); \
683+
irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)); \
684+
} while (0)
685+
686+
#define UART_RX_SCI_CONFIG_INIT(index) \
687+
.rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \
688+
.txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \
689+
.tei_src = SCI_INT_TEI_SRC(DT_PROP(DT_INST_PARENT(index), channel)), \
690+
.eri_src = SCI_INT_ERI_SRC(DT_PROP(DT_INST_PARENT(index), channel)), \
691+
.tei_ctrl = DEVICE_DT_GET(DT_PHANDLE(DT_INST_PARENT(index), tei_ctrl)), \
692+
.tei_num = DT_PROP(DT_INST_PARENT(index), tei_number), \
693+
.eri_ctrl = DEVICE_DT_GET(DT_PHANDLE(DT_INST_PARENT(index), eri_ctrl)), \
694+
.eri_num = DT_PROP(DT_INST_PARENT(index), eri_number),
500695
#endif
501696
#else
502697
#define UART_RX_SCI_IRQ_INIT(index)
698+
#define UART_RX_SCI_CONFIG_INIT(index)
503699
#endif
504700

505701
#define UART_RX_INIT(index) \

dts/bindings/misc/renesas,rx-sci.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,25 @@ properties:
1414
channel:
1515
type: int
1616
required: true
17+
18+
tei-ctrl:
19+
type: phandle
20+
description: |
21+
Group interrupt controller for the transmit end interrupt (TEI). This only applies
22+
in cases the RX MCU supports group interrupt feature
23+
24+
tei-number:
25+
type: int
26+
description: |
27+
Number of the TEI in the interrupt group of tei-ctrl
28+
29+
eri-ctrl:
30+
type: phandle
31+
description: |
32+
Group interrupt controller for the error interrupt (ERI). This only applies
33+
in cases the RX MCU supports group interrupt feature
34+
35+
eri-number:
36+
type: int
37+
description: |
38+
Number of the ERI in the interrupt group of eri-ctrl

0 commit comments

Comments
 (0)