Skip to content

Commit 8c0a1cf

Browse files
driver: espi: implement espi PM function
1. add cs pin as espi driver wake up reference 2. removed the unnecessary update of the cached date 3. removed the unnecessary busy wait in notify funciton Signed-off-by: Lin Yu-Cheng <[email protected]>
1 parent 9354e06 commit 8c0a1cf

File tree

3 files changed

+74
-36
lines changed

3 files changed

+74
-36
lines changed

drivers/espi/espi_realtek_rts5912.c

Lines changed: 64 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ LOG_MODULE_REGISTER(espi, CONFIG_ESPI_LOG_LEVEL);
2323
#include "reg/reg_kbc.h"
2424
#include "reg/reg_port80.h"
2525

26+
#ifdef CONFIG_PM
27+
#include "reg/reg_gpio.h"
28+
#include <zephyr/pm/device.h>
29+
#include <zephyr/pm/policy.h>
30+
#include "reg/reg_system.h"
31+
#include "zephyr/drivers/gpio/gpio_rts5912.h"
32+
#endif
33+
2634
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "support only one espi compatible node");
2735

2836
struct espi_rts5912_config {
@@ -56,6 +64,9 @@ struct espi_rts5912_config {
5664
volatile struct port80_reg *const port80_reg;
5765
uint32_t port80_clk_grp;
5866
uint32_t port80_clk_idx;
67+
#endif
68+
#ifdef CONFIG_PM
69+
struct gpio_dt_spec cs_pin;
5970
#endif
6071
const struct device *clk_dev;
6172
const struct pinctrl_dev_config *pcfg;
@@ -1197,7 +1208,6 @@ static void notify_host_warning(const struct device *dev, enum espi_vwire_signal
11971208
uint8_t status = 0;
11981209

11991210
espi_rts5912_receive_vwire(dev, signal, &status);
1200-
k_busy_wait(200);
12011211

12021212
switch (signal) {
12031213
case ESPI_VWIRE_SIGNAL_SUS_WARN:
@@ -1394,8 +1404,6 @@ static int espi_rts5912_send_vwire(const struct device *dev, enum espi_vwire_sig
13941404
static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_signal signal,
13951405
uint8_t *level)
13961406
{
1397-
const struct espi_rts5912_config *const espi_config = dev->config;
1398-
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
13991407
uint8_t vw_idx, lev_msk, valid_msk;
14001408
uint8_t vw_data;
14011409

@@ -1412,9 +1420,6 @@ static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_
14121420
vw_data = espi_vw_ch_cached_data.idx2;
14131421
break;
14141422
case VW_CH_IDX3:
1415-
if (espi_vw_ch_cached_data.idx3 != espi_reg->EVIDX3) {
1416-
espi_vw_ch_cached_data.idx3 = espi_reg->EVIDX3;
1417-
}
14181423
vw_data = espi_vw_ch_cached_data.idx3;
14191424
break;
14201425
case VW_CH_IDX4:
@@ -1427,60 +1432,33 @@ static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_
14271432
vw_data = espi_vw_tx_cached_data.idx6;
14281433
break;
14291434
case VW_CH_IDX7:
1430-
if (espi_vw_ch_cached_data.idx7 != espi_reg->EVIDX7) {
1431-
espi_vw_ch_cached_data.idx7 = espi_reg->EVIDX7;
1432-
}
14331435
vw_data = espi_vw_ch_cached_data.idx7;
14341436
break;
14351437
case VW_CH_IDX40:
14361438
vw_data = espi_vw_tx_cached_data.idx40;
14371439
break;
14381440
case VW_CH_IDX41:
1439-
if (espi_vw_ch_cached_data.idx41 != espi_reg->EVIDX41) {
1440-
espi_vw_ch_cached_data.idx41 = espi_reg->EVIDX41;
1441-
}
14421441
vw_data = espi_vw_ch_cached_data.idx41;
14431442
break;
14441443
case VW_CH_IDX42:
1445-
if (espi_vw_ch_cached_data.idx42 != espi_reg->EVIDX42) {
1446-
espi_vw_ch_cached_data.idx42 = espi_reg->EVIDX42;
1447-
}
14481444
vw_data = espi_vw_ch_cached_data.idx42;
14491445
break;
14501446
case VW_CH_IDX43:
1451-
if (espi_vw_ch_cached_data.idx43 != espi_reg->EVIDX43) {
1452-
espi_vw_ch_cached_data.idx43 = espi_reg->EVIDX43;
1453-
}
14541447
vw_data = espi_vw_ch_cached_data.idx43;
14551448
break;
14561449
case VW_CH_IDX44:
1457-
if (espi_vw_ch_cached_data.idx44 != espi_reg->EVIDX44) {
1458-
espi_vw_ch_cached_data.idx44 = espi_reg->EVIDX44;
1459-
}
14601450
vw_data = espi_vw_ch_cached_data.idx44;
14611451
break;
14621452
case VW_CH_IDX47:
1463-
if (espi_vw_ch_cached_data.idx47 != espi_reg->EVIDX47) {
1464-
espi_vw_ch_cached_data.idx47 = espi_reg->EVIDX47;
1465-
}
14661453
vw_data = espi_vw_ch_cached_data.idx47;
14671454
break;
14681455
case VW_CH_IDX4A:
1469-
if (espi_vw_ch_cached_data.idx4a != espi_reg->EVIDX4A) {
1470-
espi_vw_ch_cached_data.idx4a = espi_reg->EVIDX4A;
1471-
}
14721456
vw_data = espi_vw_ch_cached_data.idx4a;
14731457
break;
14741458
case VW_CH_IDX51:
1475-
if (espi_vw_ch_cached_data.idx51 != espi_reg->EVIDX51) {
1476-
espi_vw_ch_cached_data.idx51 = espi_reg->EVIDX51;
1477-
}
14781459
vw_data = espi_vw_ch_cached_data.idx51;
14791460
break;
14801461
case VW_CH_IDX61:
1481-
if (espi_vw_ch_cached_data.idx61 != espi_reg->EVIDX61) {
1482-
espi_vw_ch_cached_data.idx61 = espi_reg->EVIDX61;
1483-
}
14841462
vw_data = espi_vw_ch_cached_data.idx61;
14851463
break;
14861464
default:
@@ -2293,7 +2271,18 @@ static void espi_bus_reset_setup(const struct device *dev)
22932271
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
22942272
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), bus_rst, irq));
22952273
}
2274+
#ifdef CONFIG_PM
2275+
void espi_cs_low_isr(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins)
2276+
{
2277+
gpio_flags_t cs_pin_config;
22962278

2279+
gpio_pin_get_config(port, pins, &cs_pin_config);
2280+
if (cs_pin_config & GPIO_INT_ENABLE) {
2281+
gpio_pin_interrupt_configure(port, (find_msb_set(pins) - 1),
2282+
GPIO_INT_MODE_DISABLED);
2283+
}
2284+
}
2285+
#endif
22972286
static int espi_rts5912_init(const struct device *dev)
22982287
{
22992288
const struct espi_rts5912_config *const espi_config = dev->config;
@@ -2393,13 +2382,44 @@ static int espi_rts5912_init(const struct device *dev)
23932382
goto exit;
23942383
}
23952384
#endif
2396-
2385+
#ifdef CONFIG_PM
2386+
static struct gpio_callback cb;
2387+
uint32_t cs_irq_nun = gpio_rts5912_get_pin_num(&espi_config->cs_pin);
2388+
2389+
NVIC_ClearPendingIRQ(cs_irq_nun);
2390+
gpio_init_callback(&cb, espi_cs_low_isr, BIT(espi_config->cs_pin.pin));
2391+
gpio_add_callback(espi_config->cs_pin.port, &cb);
2392+
irq_enable(cs_irq_nun);
2393+
#endif
23972394
exit:
23982395
return rc;
23992396
}
2397+
#ifdef CONFIG_PM
2398+
static inline int espi_rts5912_pm_action(const struct device *dev, enum pm_device_action action)
2399+
{
2400+
const struct espi_rts5912_config *const espi_config = dev->config;
2401+
SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE;
24002402

2401-
PINCTRL_DT_INST_DEFINE(0);
2403+
switch (action) {
2404+
case PM_DEVICE_ACTION_RESUME:
2405+
sys_reg->SLPCTRL &= ~SYSTEM_SLPCTRL_GPIOWKEN_Msk;
2406+
gpio_pin_interrupt_configure_dt(&espi_config->cs_pin, GPIO_INT_MODE_DISABLED);
2407+
break;
2408+
case PM_DEVICE_ACTION_SUSPEND:
2409+
sys_reg->SLPCTRL |= SYSTEM_SLPCTRL_GPIOWKEN_Msk;
2410+
gpio_pin_interrupt_configure_dt(&espi_config->cs_pin,
2411+
GPIO_INT_MODE_EDGE | GPIO_INT_TRIG_LOW);
2412+
break;
2413+
default:
2414+
return -ENOTSUP;
2415+
}
24022416

2417+
return 0;
2418+
}
2419+
PM_DEVICE_DT_INST_DEFINE(0, espi_rts5912_pm_action);
2420+
#endif
2421+
2422+
PINCTRL_DT_INST_DEFINE(0);
24032423
static struct espi_rts5912_data espi_rts5912_data_0;
24042424

24052425
static const struct espi_rts5912_config espi_rts5912_config = {
@@ -2434,10 +2454,18 @@ static const struct espi_rts5912_config espi_rts5912_config = {
24342454
.port80_reg = (volatile struct port80_reg *const)DT_INST_REG_ADDR_BY_NAME(0, port80),
24352455
.port80_clk_grp = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(0), port80, clk_grp),
24362456
.port80_clk_idx = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(0), port80, clk_idx),
2457+
#endif
2458+
#ifdef CONFIG_PM
2459+
.cs_pin = GPIO_DT_SPEC_INST_GET(0, cs_gpios),
24372460
#endif
24382461
.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
24392462
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
24402463
};
2441-
2464+
#ifdef CONFIG_PM
2465+
DEVICE_DT_INST_DEFINE(0, &espi_rts5912_init, PM_DEVICE_DT_INST_GET(0), &espi_rts5912_data_0,
2466+
&espi_rts5912_config, PRE_KERNEL_2, CONFIG_ESPI_INIT_PRIORITY,
2467+
&espi_rts5912_driver_api);
2468+
#else
24422469
DEVICE_DT_INST_DEFINE(0, &espi_rts5912_init, NULL, &espi_rts5912_data_0, &espi_rts5912_config,
24432470
PRE_KERNEL_2, CONFIG_ESPI_INIT_PRIORITY, &espi_rts5912_driver_api);
2471+
#endif

dts/arm/realtek/ec/rts5912.dtsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <zephyr/dt-bindings/pwm/pwm.h>
1313
#include <mem.h>
1414
#include <zephyr/dt-bindings/i2c/i2c.h>
15+
#include <zephyr/dt-bindings/gpio/realtek-gpio.h>
1516

1617
/ {
1718
cpus {
@@ -171,6 +172,7 @@
171172

172173
espi0: espi0@400b1000 {
173174
compatible = "realtek,rts5912-espi";
175+
cs-gpios = <RTS5912_GPIO004 0>;
174176
status = "disabled";
175177

176178
reg = <0x400b1000 0x200 /* espi target */

dts/bindings/espi/realtek,rts5912-espi.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,11 @@ properties:
1717

1818
pinctrl-names:
1919
required: true
20+
21+
cs-gpios:
22+
description: |
23+
select the cs pin to support the espi wakeup
24+
please check include/zephyr/dt-bindings/gpio/realtek-gpio.h
25+
For example:
26+
cs-gpios = <RTS5912_GPIO004 0>;
27+
type: phandle-array

0 commit comments

Comments
 (0)