Skip to content

Commit d56a0c9

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 169b47c commit d56a0c9

File tree

3 files changed

+70
-38
lines changed

3 files changed

+70
-38
lines changed

drivers/espi/espi_realtek_rts5912.c

Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ 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+
#endif
32+
2633
BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "support only one espi compatible node");
2734

2835
struct espi_rts5912_config {
@@ -56,6 +63,9 @@ struct espi_rts5912_config {
5663
volatile struct port80_reg *const port80_reg;
5764
uint32_t port80_clk_grp;
5865
uint32_t port80_clk_idx;
66+
#endif
67+
#ifdef CONFIG_PM
68+
struct gpio_dt_spec cs_pin;
5969
#endif
6070
const struct device *clk_dev;
6171
const struct pinctrl_dev_config *pcfg;
@@ -1197,7 +1207,6 @@ static void notify_host_warning(const struct device *dev, enum espi_vwire_signal
11971207
uint8_t status = 0;
11981208

11991209
espi_rts5912_receive_vwire(dev, signal, &status);
1200-
k_busy_wait(200);
12011210

12021211
switch (signal) {
12031212
case ESPI_VWIRE_SIGNAL_SUS_WARN:
@@ -1394,8 +1403,6 @@ static int espi_rts5912_send_vwire(const struct device *dev, enum espi_vwire_sig
13941403
static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_signal signal,
13951404
uint8_t *level)
13961405
{
1397-
const struct espi_rts5912_config *const espi_config = dev->config;
1398-
volatile struct espi_reg *const espi_reg = espi_config->espi_reg;
13991406
uint8_t vw_idx, lev_msk, valid_msk;
14001407
uint8_t vw_data;
14011408

@@ -1412,9 +1419,6 @@ static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_
14121419
vw_data = espi_vw_ch_cached_data.idx2;
14131420
break;
14141421
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-
}
14181422
vw_data = espi_vw_ch_cached_data.idx3;
14191423
break;
14201424
case VW_CH_IDX4:
@@ -1427,60 +1431,33 @@ static int espi_rts5912_receive_vwire(const struct device *dev, enum espi_vwire_
14271431
vw_data = espi_vw_tx_cached_data.idx6;
14281432
break;
14291433
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-
}
14331434
vw_data = espi_vw_ch_cached_data.idx7;
14341435
break;
14351436
case VW_CH_IDX40:
14361437
vw_data = espi_vw_tx_cached_data.idx40;
14371438
break;
14381439
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-
}
14421440
vw_data = espi_vw_ch_cached_data.idx41;
14431441
break;
14441442
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-
}
14481443
vw_data = espi_vw_ch_cached_data.idx42;
14491444
break;
14501445
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-
}
14541446
vw_data = espi_vw_ch_cached_data.idx43;
14551447
break;
14561448
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-
}
14601449
vw_data = espi_vw_ch_cached_data.idx44;
14611450
break;
14621451
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-
}
14661452
vw_data = espi_vw_ch_cached_data.idx47;
14671453
break;
14681454
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-
}
14721455
vw_data = espi_vw_ch_cached_data.idx4a;
14731456
break;
14741457
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-
}
14781458
vw_data = espi_vw_ch_cached_data.idx51;
14791459
break;
14801460
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-
}
14841461
vw_data = espi_vw_ch_cached_data.idx61;
14851462
break;
14861463
default:
@@ -2293,7 +2270,18 @@ static void espi_bus_reset_setup(const struct device *dev)
22932270
DEVICE_DT_GET(DT_DRV_INST(0)), 0);
22942271
irq_enable(DT_IRQ_BY_NAME(DT_DRV_INST(0), bus_rst, irq));
22952272
}
2273+
#ifdef CONFIG_PM
2274+
void espi_cs_low_isr(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins)
2275+
{
2276+
gpio_flags_t cs_pin_config;
22962277

2278+
gpio_pin_get_config(port, pins, &cs_pin_config);
2279+
if (cs_pin_config & GPIO_INT_ENABLE) {
2280+
gpio_pin_interrupt_configure(port, (find_msb_set(pins) - 1),
2281+
GPIO_INT_MODE_DISABLED);
2282+
}
2283+
}
2284+
#endif
22972285
static int espi_rts5912_init(const struct device *dev)
22982286
{
22992287
const struct espi_rts5912_config *const espi_config = dev->config;
@@ -2393,13 +2381,44 @@ static int espi_rts5912_init(const struct device *dev)
23932381
goto exit;
23942382
}
23952383
#endif
2396-
2384+
#ifdef CONFIG_PM
2385+
static struct gpio_callback cb;
2386+
uint32_t cs_irq_nun = DT_IRQ_BY_NAME(DT_DRV_INST(0), cs_low, irq);
2387+
2388+
NVIC_ClearPendingIRQ(cs_irq_nun);
2389+
gpio_init_callback(&cb, espi_cs_low_isr, BIT(espi_config->cs_pin.pin));
2390+
gpio_add_callback(espi_config->cs_pin.port, &cb);
2391+
irq_enable(cs_irq_nun);
2392+
#endif
23972393
exit:
23982394
return rc;
23992395
}
2396+
#ifdef CONFIG_PM
2397+
static inline int espi_rts5912_pm_action(const struct device *dev, enum pm_device_action action)
2398+
{
2399+
const struct espi_rts5912_config *const espi_config = dev->config;
2400+
SYSTEM_Type *sys_reg = RTS5912_SCCON_REG_BASE;
24002401

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

2416+
return 0;
2417+
}
2418+
PM_DEVICE_DT_INST_DEFINE(0, espi_rts5912_pm_action);
2419+
#endif
2420+
2421+
PINCTRL_DT_INST_DEFINE(0);
24032422
static struct espi_rts5912_data espi_rts5912_data_0;
24042423

24052424
static const struct espi_rts5912_config espi_rts5912_config = {
@@ -2434,10 +2453,18 @@ static const struct espi_rts5912_config espi_rts5912_config = {
24342453
.port80_reg = (volatile struct port80_reg *const)DT_INST_REG_ADDR_BY_NAME(0, port80),
24352454
.port80_clk_grp = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(0), port80, clk_grp),
24362455
.port80_clk_idx = DT_CLOCKS_CELL_BY_NAME(DT_DRV_INST(0), port80, clk_idx),
2456+
#endif
2457+
#ifdef CONFIG_PM
2458+
.cs_pin = GPIO_DT_SPEC_INST_GET(0, cs_gpios),
24372459
#endif
24382460
.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
24392461
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
24402462
};
2441-
2463+
#ifdef CONFIG_PM
2464+
DEVICE_DT_INST_DEFINE(0, &espi_rts5912_init, PM_DEVICE_DT_INST_GET(0), &espi_rts5912_data_0,
2465+
&espi_rts5912_config, PRE_KERNEL_2, CONFIG_ESPI_INIT_PRIORITY,
2466+
&espi_rts5912_driver_api);
2467+
#else
24422468
DEVICE_DT_INST_DEFINE(0, &espi_rts5912_init, NULL, &espi_rts5912_data_0, &espi_rts5912_config,
24432469
PRE_KERNEL_2, CONFIG_ESPI_INIT_PRIORITY, &espi_rts5912_driver_api);
2470+
#endif

dts/arm/realtek/ec/rts5912.dtsi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@
171171

172172
espi0: espi0@400b1000 {
173173
compatible = "realtek,rts5912-espi";
174+
cs-gpios = <&gpioa 4 0>;
174175
status = "disabled";
175176

176177
reg = <0x400b1000 0x200 /* espi target */
@@ -229,7 +230,7 @@
229230
<216 0>, <217 0>, <218 0>,
230231
<219 0>, <147 0>, <148 0>,
231232
<149 0>, <152 0>, <153 0>,
232-
<166 0>, <220 0>;
233+
<166 0>, <220 0>, <4 0>;
233234

234235
interrupt-names = "bus-rst", "periph-ch", "vw-ch",
235236
"vw-idx2", "vw-idx3", "vw-idx7",
@@ -244,7 +245,7 @@
244245
"emi4", "emi5", "emi6",
245246
"emi7", "oob_tx", "oob_rx",
246247
"oob_chg", "maf_tr", "flash_chg",
247-
"port80", "mbx";
248+
"port80", "mbx", "cs_low";
248249

249250
};
250251

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

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

1818
pinctrl-names:
1919
required: true
20+
21+
cs-gpios:
22+
description: select the cs pin to support the espi wakeup
23+
type: phandle-array

0 commit comments

Comments
 (0)