Skip to content

Commit 36ff55c

Browse files
henrikbrixandersengalak
authored andcommitted
gpio: rv32m1: enable GPIO port clocks
Enable the clock for GPIO ports on the RV32M1 SoC before attempting to access the port controller registers. Fixes: #15339 Signed-off-by: Henrik Brix Andersen <[email protected]>
1 parent 3e798df commit 36ff55c

File tree

2 files changed

+77
-5
lines changed

2 files changed

+77
-5
lines changed

drivers/gpio/gpio_rv32m1.c

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@
1212
#include <soc.h>
1313
#include <fsl_common.h>
1414
#include <fsl_port.h>
15+
#include <clock_control.h>
1516

1617
#include "gpio_utils.h"
1718

1819
struct gpio_rv32m1_config {
1920
GPIO_Type *gpio_base;
2021
PORT_Type *port_base;
2122
unsigned int flags;
23+
char *clock_controller;
24+
clock_control_subsys_t clock_subsys;
25+
int (*irq_config_func)(struct device *dev);
2226
};
2327

2428
struct gpio_rv32m1_data {
@@ -228,6 +232,27 @@ static void gpio_rv32m1_port_isr(void *arg)
228232
config->port_base->ISFR = 0xFFFFFFFF;
229233
}
230234

235+
static int gpio_rv32m1_init(struct device *dev)
236+
{
237+
const struct gpio_rv32m1_config *config = dev->config->config_info;
238+
struct device *clk;
239+
int ret;
240+
241+
if (config->clock_controller) {
242+
clk = device_get_binding(config->clock_controller);
243+
if (!clk) {
244+
return -ENODEV;
245+
}
246+
247+
ret = clock_control_on(clk, config->clock_subsys);
248+
249+
if (ret < 0) {
250+
return ret;
251+
}
252+
}
253+
254+
return config->irq_config_func(dev);
255+
}
231256

232257
static const struct gpio_driver_api gpio_rv32m1_driver_api = {
233258
.config = gpio_rv32m1_configure,
@@ -248,13 +273,21 @@ static const struct gpio_rv32m1_config gpio_rv32m1_porta_config = {
248273
.flags = GPIO_INT,
249274
#else
250275
.flags = 0,
276+
#endif
277+
.irq_config_func = gpio_rv32m1_porta_init,
278+
#ifdef DT_OPENISA_RV32M1_GPIO_GPIO_A_CLOCK_CONTROLLER
279+
.clock_controller = DT_OPENISA_RV32M1_GPIO_GPIO_A_CLOCK_CONTROLLER,
280+
.clock_subsys = (clock_control_subsys_t)
281+
DT_OPENISA_RV32M1_GPIO_GPIO_A_CLOCK_NAME,
282+
#else
283+
.clock_controller = NULL,
251284
#endif
252285
};
253286

254287
static struct gpio_rv32m1_data gpio_rv32m1_porta_data;
255288

256289
DEVICE_AND_API_INIT(gpio_rv32m1_porta, DT_OPENISA_RV32M1_GPIO_GPIO_A_LABEL,
257-
gpio_rv32m1_porta_init,
290+
gpio_rv32m1_init,
258291
&gpio_rv32m1_porta_data, &gpio_rv32m1_porta_config,
259292
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
260293
&gpio_rv32m1_driver_api);
@@ -285,13 +318,21 @@ static const struct gpio_rv32m1_config gpio_rv32m1_portb_config = {
285318
.flags = GPIO_INT,
286319
#else
287320
.flags = 0,
321+
#endif
322+
.irq_config_func = gpio_rv32m1_portb_init,
323+
#ifdef DT_OPENISA_RV32M1_GPIO_GPIO_B_CLOCK_CONTROLLER
324+
.clock_controller = DT_OPENISA_RV32M1_GPIO_GPIO_B_CLOCK_CONTROLLER,
325+
.clock_subsys = (clock_control_subsys_t)
326+
DT_OPENISA_RV32M1_GPIO_GPIO_B_CLOCK_NAME,
327+
#else
328+
.clock_controller = NULL,
288329
#endif
289330
};
290331

291332
static struct gpio_rv32m1_data gpio_rv32m1_portb_data;
292333

293334
DEVICE_AND_API_INIT(gpio_rv32m1_portb, DT_OPENISA_RV32M1_GPIO_GPIO_B_LABEL,
294-
gpio_rv32m1_portb_init,
335+
gpio_rv32m1_init,
295336
&gpio_rv32m1_portb_data, &gpio_rv32m1_portb_config,
296337
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
297338
&gpio_rv32m1_driver_api);
@@ -323,12 +364,21 @@ static const struct gpio_rv32m1_config gpio_rv32m1_portc_config = {
323364
#else
324365
.flags = 0,
325366
#endif
367+
.irq_config_func = gpio_rv32m1_portc_init,
368+
#ifdef DT_OPENISA_RV32M1_GPIO_GPIO_C_CLOCK_CONTROLLER
369+
.clock_controller = DT_OPENISA_RV32M1_GPIO_GPIO_C_CLOCK_CONTROLLER,
370+
.clock_subsys = (clock_control_subsys_t)
371+
DT_OPENISA_RV32M1_GPIO_GPIO_C_CLOCK_NAME,
372+
#else
373+
.clock_controller = NULL,
374+
#endif
375+
326376
};
327377

328378
static struct gpio_rv32m1_data gpio_rv32m1_portc_data;
329379

330380
DEVICE_AND_API_INIT(gpio_rv32m1_portc, DT_OPENISA_RV32M1_GPIO_GPIO_C_LABEL,
331-
gpio_rv32m1_portc_init,
381+
gpio_rv32m1_init,
332382
&gpio_rv32m1_portc_data, &gpio_rv32m1_portc_config,
333383
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
334384
&gpio_rv32m1_driver_api);
@@ -359,13 +409,21 @@ static const struct gpio_rv32m1_config gpio_rv32m1_portd_config = {
359409
.flags = GPIO_INT,
360410
#else
361411
.flags = 0,
412+
#endif
413+
.irq_config_func = gpio_rv32m1_portd_init,
414+
#ifdef DT_OPENISA_RV32M1_GPIO_GPIO_D_CLOCK_CONTROLLER
415+
.clock_controller = DT_OPENISA_RV32M1_GPIO_GPIO_D_CLOCK_CONTROLLER,
416+
.clock_subsys = (clock_control_subsys_t)
417+
DT_OPENISA_RV32M1_GPIO_GPIO_D_CLOCK_NAME,
418+
#else
419+
.clock_controller = NULL,
362420
#endif
363421
};
364422

365423
static struct gpio_rv32m1_data gpio_rv32m1_portd_data;
366424

367425
DEVICE_AND_API_INIT(gpio_rv32m1_portd, DT_OPENISA_RV32M1_GPIO_GPIO_D_LABEL,
368-
gpio_rv32m1_portd_init,
426+
gpio_rv32m1_init,
369427
&gpio_rv32m1_portd_data, &gpio_rv32m1_portd_config,
370428
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
371429
&gpio_rv32m1_driver_api);
@@ -396,13 +454,21 @@ static const struct gpio_rv32m1_config gpio_rv32m1_porte_config = {
396454
.flags = GPIO_INT,
397455
#else
398456
.flags = 0,
457+
#endif
458+
.irq_config_func = gpio_rv32m1_porte_init,
459+
#ifdef DT_OPENISA_RV32M1_GPIO_GPIO_E_CLOCK_CONTROLLER
460+
.clock_controller = DT_OPENISA_RV32M1_GPIO_GPIO_E_CLOCK_CONTROLLER,
461+
.clock_subsys = (clock_control_subsys_t)
462+
DT_OPENISA_RV32M1_GPIO_GPIO_E_CLOCK_NAME,
463+
#else
464+
.clock_controller = NULL,
399465
#endif
400466
};
401467

402468
static struct gpio_rv32m1_data gpio_rv32m1_porte_data;
403469

404470
DEVICE_AND_API_INIT(gpio_rv32m1_porte, DT_OPENISA_RV32M1_GPIO_GPIO_E_LABEL,
405-
gpio_rv32m1_porte_init,
471+
gpio_rv32m1_init,
406472
&gpio_rv32m1_porte_data, &gpio_rv32m1_porte_config,
407473
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
408474
&gpio_rv32m1_driver_api);

dts/bindings/gpio/openisa,rv32m1-gpio.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ properties:
3131
description: Human readable string describing the device (used by Zephyr for API name)
3232
generation: define
3333

34+
clocks:
35+
type: array
36+
category: optional
37+
description: Clock gate control information
38+
generation: define
39+
3440
"#cells":
3541
- pin
3642
- flags

0 commit comments

Comments
 (0)