diff options
author | martin yan <martin.yan@microchip.corp-partner.google.com> | 2022-01-14 11:04:50 -0500 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2022-01-24 20:12:52 +0000 |
commit | 294e26a203fb74d2a3a3218279b6e18ca22780be (patch) | |
tree | 62ee3de9a81598a226bb76409e309f8c7c1142c7 | |
parent | 96525123ba63b081f0855197961f8029539b937b (diff) | |
download | chrome-ec-294e26a203fb74d2a3a3218279b6e18ca22780be.tar.gz |
zephyr: mchp: Add cros_flash driver
Add cros_flash driver and related configs
BUG=none
BRANCH=main
TEST=zmake testall
Signed-off-by: martin yan <martin.yan@microchip.corp-partner.google.com>
Change-Id: I4b8aadf5820871e0abcff0306eefae634a4ee8df
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3388451
Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r-- | zephyr/Kconfig.flash | 2 | ||||
-rw-r--r-- | zephyr/Kconfig.header | 3 | ||||
-rw-r--r-- | zephyr/Kconfig.init_priority | 1 | ||||
-rw-r--r-- | zephyr/drivers/cros_flash/CMakeLists.txt | 5 | ||||
-rw-r--r-- | zephyr/drivers/cros_flash/Kconfig | 23 | ||||
-rw-r--r-- | zephyr/drivers/cros_flash/cros_flash_xec.c | 617 | ||||
-rw-r--r-- | zephyr/dts/bindings/cros_flash/microchip,xec-cros-flash.yaml | 9 |
7 files changed, 658 insertions, 2 deletions
diff --git a/zephyr/Kconfig.flash b/zephyr/Kconfig.flash index f6a8b2d103..0e0fd6ce49 100644 --- a/zephyr/Kconfig.flash +++ b/zephyr/Kconfig.flash @@ -6,6 +6,7 @@ if PLATFORM_EC_FLASH_CROS config PLATFORM_EC_SPI_FLASH_REGS bool "Enable SPI flash registers" + default y if SOC_FAMILY_MEC default y if SOC_FAMILY_NPCX help Enables flash registers for SPI flash (both internal and external). @@ -64,6 +65,7 @@ config PLATFORM_EC_CONSOLE_CMD_SYSJUMP choice PLATFORM_EC_STORAGE_TYPE prompt "Code storage type" default PLATFORM_EC_EXTERNAL_STORAGE if SOC_FAMILY_NPCX + default PLATFORM_EC_EXTERNAL_STORAGE if SOC_FAMILY_MEC default PLATFORM_EC_INTERNAL_STORAGE if SOC_FAMILY_RISCV_ITE help Sets the EC code storage type. diff --git a/zephyr/Kconfig.header b/zephyr/Kconfig.header index 43e66ec3e4..e5c137b99e 100644 --- a/zephyr/Kconfig.header +++ b/zephyr/Kconfig.header @@ -6,7 +6,7 @@ config PLATFORM_EC_RO_HEADER bool "RO section includes a header" default y depends on CROS_EC_RO - depends on SOC_FAMILY_NPCX + depends on SOC_FAMILY_NPCX || SOC_FAMILY_MEC help The RO image residing on flash memory has a header section. The header is used on some chips (such as the npcx) to load the image correctly @@ -24,6 +24,7 @@ config PLATFORM_EC_RO_HEADER_OFFSET config PLATFORM_EC_RO_HEADER_SIZE hex "Size of the RO header" default 0x40 if SOC_FAMILY_NPCX + default 0x140 if SOC_SERIES_MEC172X default 0x0 help The size of the RO header in bytes. This values should come from the diff --git a/zephyr/Kconfig.init_priority b/zephyr/Kconfig.init_priority index 5370072c2c..c974bb4d8f 100644 --- a/zephyr/Kconfig.init_priority +++ b/zephyr/Kconfig.init_priority @@ -5,6 +5,7 @@ config PLATFORM_EC_FLASH_INIT_PRIORITY int "Init priority of the flash module" default 90 if SOC_FAMILY_NPCX + default 90 if SOC_FAMILY_MEC default 52 help The initialization priority of the flash module. This should always be diff --git a/zephyr/drivers/cros_flash/CMakeLists.txt b/zephyr/drivers/cros_flash/CMakeLists.txt index 6611589ad4..1846d10576 100644 --- a/zephyr/drivers/cros_flash/CMakeLists.txt +++ b/zephyr/drivers/cros_flash/CMakeLists.txt @@ -1,4 +1,7 @@ -# SPDX-License-Identifier: Apache-2.0 +# Copyright 2021 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. zephyr_library_sources_ifdef(CONFIG_CROS_FLASH_IT8XXX2 cros_flash_it8xxx2.c) zephyr_library_sources_ifdef(CONFIG_CROS_FLASH_NPCX cros_flash_npcx.c) +zephyr_library_sources_ifdef(CONFIG_CROS_FLASH_XEC cros_flash_xec.c) diff --git a/zephyr/drivers/cros_flash/Kconfig b/zephyr/drivers/cros_flash/Kconfig index 05de5c5e5b..5c73e0c3b9 100644 --- a/zephyr/drivers/cros_flash/Kconfig +++ b/zephyr/drivers/cros_flash/Kconfig @@ -33,3 +33,26 @@ config CROS_FLASH_IT8XXX2 This option enables the flash driver for the it8xxx2 chip. We can access the flash by read, write and erase. The it8xxx2 flash size is 1M byte. + +config CROS_FLASH_XEC + bool "Microchip XEC flash driver for the Zephyr shim" + depends on SOC_FAMILY_MEC + default y + help + This option enables the flash driver for the MEC172x chips. Flash + access is via the QSPI driver to one of three ports: internal 512KB + SPI flash in the MEC1727 or external shared or private ports on + MEC1723, etc. + +if CROS_FLASH_XEC + +config CROS_FLASH_XEC_INIT_PRIORITY + int "Microchip XEC flash driver priority for the Zephyr shim" + default 85 + help + This sets the priority of the MCHP flash driver for zephyr shim. + This driver depends on the SPI controller and SPI NOR flash drivers. + Its priority must be lower than CONFIG_SPI_INIT_PRIORITY and + CONFIG_SPI_NOR_INIT_PRIORITY. + +endif # CROS_FLASH_XEC diff --git a/zephyr/drivers/cros_flash/cros_flash_xec.c b/zephyr/drivers/cros_flash/cros_flash_xec.c new file mode 100644 index 0000000000..e9a8b6a3b0 --- /dev/null +++ b/zephyr/drivers/cros_flash/cros_flash_xec.c @@ -0,0 +1,617 @@ +/* Copyright 2022 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#define DT_DRV_COMPAT microchip_xec_cros_flash + +#include <drivers/cros_flash.h> +#include <drivers/flash.h> +#include <drivers/gpio.h> +#include <drivers/spi.h> +#include <kernel.h> +#include <logging/log.h> +#include <soc.h> + +#include "flash.h" +#include "gpio.h" +#include "spi_flash_reg.h" +#include "../drivers/flash/spi_nor.h" + +LOG_MODULE_REGISTER(cros_flash, LOG_LEVEL_ERR); + +static int all_protected; +static int addr_prot_start; +static int addr_prot_length; +static uint8_t saved_sr1; + +/* Device data */ +struct cros_flash_xec_data { + const struct device *flash_dev; + const struct device *spi_ctrl_dev; +}; + +static struct spi_config spi_cfg; + +#define FLASH_DEV DT_NODELABEL(int_flash) +#define SPI_CONTROLLER_DEV DT_NODELABEL(spi0) + +/* cros ec flash local functions */ +static int cros_flash_xec_get_status_reg(const struct device *dev, + uint8_t cmd_code, uint8_t *data) +{ + uint8_t opcode; + struct cros_flash_xec_data *dev_data = dev->data; + + struct spi_buf spi_buf[2] = { + [0] = { + .buf = &opcode, + .len = 1, + }, + [1] = { + .buf = data, + .len = 1, + } + }; + + const struct spi_buf_set tx_set = { + .buffers = spi_buf, + .count = 2, + }; + + const struct spi_buf_set rx_set = { + .buffers = spi_buf, + .count = 2, + }; + + if (data == 0) + return -EINVAL; + + opcode = cmd_code; + return spi_transceive(dev_data->spi_ctrl_dev, &spi_cfg, &tx_set, + &rx_set); +} + +static int cros_flash_xec_wait_ready(const struct device *dev) +{ + int wait_period = 10; /* 10 us period t0 check status register */ + int timeout = (10 * USEC_PER_SEC) / wait_period; /* 10 seconds */ + + do { + uint8_t reg; + + cros_flash_xec_get_status_reg(dev, SPI_NOR_CMD_RDSR, ®); + if ((reg & SPI_NOR_WIP_BIT) == 0) + break; + + k_usleep(wait_period); + } while (--timeout); /* Wait for busy bit clear */ + + if (timeout) + return 0; + else + return -ETIMEDOUT; +} + +/* Check the BUSY bit is cleared and WE bit is set */ +static int cros_flash_xec_wait_ready_and_we(const struct device *dev) +{ + int wait_period = 10; /* 10 us period t0 check status register */ + int timeout = (10 * USEC_PER_SEC) / wait_period; /* 10 seconds */ + + do { + uint8_t reg; + + cros_flash_xec_get_status_reg(dev, SPI_NOR_CMD_RDSR, ®); + if ((reg & SPI_NOR_WIP_BIT) == 0 && + (reg & SPI_NOR_WEL_BIT) != 0) { + break; + } + k_usleep(wait_period); + } while (--timeout); /* Wait for busy bit clear */ + + if (timeout) + return 0; + else + return -ETIMEDOUT; +} + +static int cros_flash_xec_set_write_enable(const struct device *dev) +{ + int ret; + uint8_t opcode = SPI_NOR_CMD_WREN; + struct cros_flash_xec_data *data = dev->data; + + struct spi_buf spi_buf = { + .buf = &opcode, + .len = 1, + }; + + const struct spi_buf_set tx_set = { + .buffers = &spi_buf, + .count = 1, + }; + + /* Wait for previous operation to complete */ + ret = cros_flash_xec_wait_ready(dev); + if (ret != 0) + return ret; + + /* Write enable command */ + ret = spi_transceive(data->spi_ctrl_dev, &spi_cfg, &tx_set, NULL); + if (ret != 0) + return ret; + + /* Wait for flash is not busy */ + return cros_flash_xec_wait_ready_and_we(dev); +} + +static int cros_flash_xec_set_status_reg(const struct device *dev, + uint8_t *data) +{ + uint8_t opcode = SPI_NOR_CMD_WRSR; + int ret = 0; + struct cros_flash_xec_data *dev_data = dev->data; + + struct spi_buf spi_buf[2] = { + [0] = { + .buf = &opcode, + .len = 1, + }, + [1] = { + .buf = data, + .len = 1, + } + }; + + const struct spi_buf_set tx_set = { + .buffers = spi_buf, + .count = 2, + }; + + if (data == 0) + return -EINVAL; + + /* Enable write */ + ret = cros_flash_xec_set_write_enable(dev); + if (ret != 0) + return ret; + + ret = spi_transceive(dev_data->spi_ctrl_dev, &spi_cfg, &tx_set, NULL); + if (ret != 0) + return ret; + return cros_flash_xec_wait_ready(dev); +} + +static int cros_flash_xec_write_protection_set(const struct device *dev, + bool enable) +{ + int ret = 0; + + /* Write protection can be cleared only by core domain reset */ + if (!enable) { + LOG_ERR("WP can be disabled only via core domain reset "); + return -ENOTSUP; + } + /* MCHP TODO need API call to set flash WP# pin active: GPIO driver? */ + + return ret; +} + +static int cros_flash_xec_write_protection_is_set(const struct device *dev) +{ + /* MCHP TODO - Read WP# pin state: GPIO driver? */ + return 0; +} + +static int cros_flash_xec_uma_lock(const struct device *dev, bool enable) +{ + struct cros_flash_xec_data *data = dev->data; + + if (enable) + spi_cfg.operation |= SPI_LOCK_ON; + else + spi_cfg.operation &= ~SPI_LOCK_ON; + + return spi_transceive(data->spi_ctrl_dev, &spi_cfg, NULL, NULL); +} + +static void flash_get_status(const struct device *dev, uint8_t *sr1) +{ + if (all_protected) { + *sr1 = saved_sr1; + return; + } + + /* Lock physical flash operations */ + crec_flash_lock_mapped_storage(1); + + /* Read status register1 */ + cros_flash_xec_get_status_reg(dev, SPI_NOR_CMD_RDSR, sr1); + + /* Unlock physical flash operations */ + crec_flash_lock_mapped_storage(0); +} + +static int flash_set_status(const struct device *dev, uint8_t sr1) +{ + int rv; + uint8_t regs[2]; + + regs[0] = sr1; + regs[1] = 0; + + /* Lock physical flash operations */ + crec_flash_lock_mapped_storage(1); + rv = cros_flash_xec_set_status_reg(dev, regs); + /* Unlock physical flash operations */ + crec_flash_lock_mapped_storage(0); + + return rv; +} + +static int is_int_flash_protected(const struct device *dev) +{ + return cros_flash_xec_write_protection_is_set(dev); +} + +static void flash_protect_int_flash(const struct device *dev, int enable) +{ + /* + * Please notice the type of WP_IF bit is R/W1S. Once it's set, + * only rebooting EC can clear it. + */ + if (enable) + cros_flash_xec_write_protection_set(dev, enable); +} + +static void flash_uma_lock(const struct device *dev, int enable) +{ + if (enable && !all_protected) { + /* + * Store SR1 for later use since we're about to lock + * out all access (including read access) to these regs. + */ + flash_get_status(dev, &saved_sr1); + } + + cros_flash_xec_uma_lock(dev, enable); + all_protected = enable; +} + +static int flash_set_status_for_prot(const struct device *dev, int reg1) +{ + /* + * Writing SR regs will fail if our UMA lock is enabled. If WP + * is deasserted then remove the lock and allow the write. + */ + if (all_protected) { + if (is_int_flash_protected(dev)) + return EC_ERROR_ACCESS_DENIED; + + if (crec_flash_get_protect() & EC_FLASH_PROTECT_GPIO_ASSERTED) + return EC_ERROR_ACCESS_DENIED; + + flash_uma_lock(dev, 0); + } + + /* + * If WP# is active and ec doesn't protect the status registers of + * internal spi-flash, protect it now before setting them. + */ +#ifdef CONFIG_WP_ACTIVE_HIGH + flash_protect_int_flash(dev, gpio_get_level(GPIO_WP)); +#else + flash_protect_int_flash(dev, !gpio_get_level(GPIO_WP_L)); +#endif /*_CONFIG_WP_ACTIVE_HIGH_*/ + + flash_set_status(dev, reg1); + + spi_flash_reg_to_protect(reg1, 0, &addr_prot_start, + &addr_prot_length); + + return EC_SUCCESS; +} + +static int flash_check_prot_reg(const struct device *dev, unsigned int offset, + unsigned int bytes) +{ + unsigned int start; + unsigned int len; + uint8_t sr1; + int rv = EC_SUCCESS; + + /* + * If WP# is active and ec doesn't protect the status registers of + * internal spi-flash, protect it now. + */ +#ifdef CONFIG_WP_ACTIVE_HIGH + flash_protect_int_flash(dev, gpio_get_level(GPIO_WP)); +#else + flash_protect_int_flash(dev, !gpio_get_level(GPIO_WP_L)); +#endif /* CONFIG_WP_ACTIVE_HIGH */ + + /* Invalid value */ + if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) + return EC_ERROR_INVAL; + + /* Compute current protect range */ + flash_get_status(dev, &sr1); + rv = spi_flash_reg_to_protect(sr1, 0, &start, &len); + if (rv) + return rv; + + /* Check if ranges overlap */ + if (MAX(start, offset) < MIN(start + len, offset + bytes)) + return EC_ERROR_ACCESS_DENIED; + + return EC_SUCCESS; +} + +static int flash_write_prot_reg(const struct device *dev, unsigned int offset, + unsigned int bytes, int hw_protect) +{ + int rv; + uint8_t sr1; + + /* Invalid values */ + if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) + return EC_ERROR_INVAL; + + /* Compute desired protect range */ + flash_get_status(dev, &sr1); + rv = spi_flash_protect_to_reg(offset, bytes, &sr1, 0); + if (rv) + return rv; + + if (hw_protect) + sr1 |= SPI_FLASH_SR1_SRP0; + + return flash_set_status_for_prot(dev, sr1); +} + +static int flash_check_prot_range(unsigned int offset, unsigned int bytes) +{ + /* Invalid value */ + if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) + return EC_ERROR_INVAL; + + /* Check if ranges overlap */ + if (MAX(addr_prot_start, offset) < + MIN(addr_prot_start + addr_prot_length, offset + bytes)) { + return EC_ERROR_ACCESS_DENIED; + } + + return EC_SUCCESS; +} + +/* cros ec flash api functions */ +static int cros_flash_xec_init(const struct device *dev) +{ + /* Initialize UMA to unlocked */ + flash_uma_lock(dev, 0); + + /* + * Protect status registers of internal spi-flash if WP# is active + * during ec initialization. + */ +#ifdef CONFIG_WP_ACTIVE_HIGH + flash_protect_int_flash(dev, gpio_get_level(GPIO_WP)); +#else + flash_protect_int_flash(dev, !gpio_get_level(GPIO_WP_L)); +#endif /*CONFIG_WP_ACTIVE_HIGH */ + + return 0; +} + +/* TODO(b/205175314): Migrate cros-flash driver to Zephyr flash driver) */ +static int cros_flash_xec_read(const struct device *dev, int offset, int size, + char *dst_data) +{ + struct cros_flash_xec_data *data = dev->data; + + return flash_read(data->flash_dev, offset, dst_data, size); +} + +static int cros_flash_xec_write(const struct device *dev, int offset, int size, + const char *src_data) +{ + int ret = 0; + struct cros_flash_xec_data *data = dev->data; + + /* check protection */ + if (all_protected) + return EC_ERROR_ACCESS_DENIED; + + /* check protection */ + if (flash_check_prot_range(offset, size)) + return EC_ERROR_ACCESS_DENIED; + + /* Invalid data pointer? */ + if (src_data == 0) + return -EINVAL; + + ret = flash_write(data->flash_dev, offset, src_data, size); + + return ret; +} + +static int cros_flash_xec_erase(const struct device *dev, int offset, int size) +{ + int ret = 0; + struct cros_flash_xec_data *data = dev->data; + + /* check protection */ + if (all_protected) + return EC_ERROR_ACCESS_DENIED; + + /* check protection */ + if (flash_check_prot_range(offset, size)) + return EC_ERROR_ACCESS_DENIED; + + /* address must be aligned to erase size */ + if ((offset % CONFIG_FLASH_ERASE_SIZE) != 0) + return -EINVAL; + + /* Erase size must be a non-zero multiple of sectors */ + if ((size == 0) || (size % CONFIG_FLASH_ERASE_SIZE) != 0) + return -EINVAL; + + ret = flash_erase(data->flash_dev, offset, size); + + return ret; +} + +static int cros_flash_xec_get_protect(const struct device *dev, int bank) +{ + uint32_t addr = bank * CONFIG_FLASH_BANK_SIZE; + + return flash_check_prot_reg(dev, addr, CONFIG_FLASH_BANK_SIZE); +} + +static uint32_t cros_flash_xec_get_protect_flags(const struct device *dev) +{ + uint32_t flags = 0; + int rv; + uint8_t sr1; + unsigned int start, len; + + /* Check if WP region is protected in status register */ + rv = flash_check_prot_reg(dev, WP_BANK_OFFSET * CONFIG_FLASH_BANK_SIZE, + WP_BANK_COUNT * CONFIG_FLASH_BANK_SIZE); + if (rv == EC_ERROR_ACCESS_DENIED) + flags |= EC_FLASH_PROTECT_RO_AT_BOOT; + else if (rv) + return EC_FLASH_PROTECT_ERROR_UNKNOWN; + + /* + * If the status register protects a range, but SRP0 is not set, + * or Quad Enable (QE) is set, + * flags should indicate EC_FLASH_PROTECT_ERROR_INCONSISTENT. + */ + flash_get_status(dev, &sr1); + rv = spi_flash_reg_to_protect(sr1, 0, &start, &len); + if (rv) + return EC_FLASH_PROTECT_ERROR_UNKNOWN; + + if (len && (!(sr1 & SPI_FLASH_SR1_SRP0))) + flags |= EC_FLASH_PROTECT_ERROR_INCONSISTENT; + + /* Read all-protected state from our shadow copy */ + if (all_protected) + flags |= EC_FLASH_PROTECT_ALL_NOW; + + return flags; +} + +static int cros_flash_xec_protect_at_boot(const struct device *dev, + uint32_t new_flags) +{ + int ret; + + if ((new_flags & (EC_FLASH_PROTECT_RO_AT_BOOT | + EC_FLASH_PROTECT_ALL_AT_BOOT)) == 0) { + /* Clear protection bits in status register */ + return flash_set_status_for_prot(dev, 0); + } + + ret = flash_write_prot_reg(dev, CONFIG_WP_STORAGE_OFF, + CONFIG_WP_STORAGE_SIZE, 1); + + /* + * Set UMA_LOCK bit for locking all UMA transaction. + * But we still can read directly from flash mapping address + */ + if (new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT) + flash_uma_lock(dev, 1); + + return ret; +} + +static int cros_flash_xec_protect_now(const struct device *dev, int all) +{ + if (all) { + /* + * Set UMA_LOCK bit for locking all UMA transaction. + * But we still can read directly from flash mapping address + */ + flash_uma_lock(dev, 1); + } else { + /* TODO: Implement RO "now" protection */ + } + + return EC_SUCCESS; +} + +static int cros_flash_xec_get_jedec_id(const struct device *dev, + uint8_t *manufacturer, uint16_t *device) +{ + int ret; + uint8_t jedec_id[3]; + struct cros_flash_xec_data *data = dev->data; + + /* Lock physical flash operations */ + crec_flash_lock_mapped_storage(1); + + ret = flash_read_jedec_id(data->flash_dev, jedec_id); + if (ret == 0) { + *manufacturer = jedec_id[0]; + *device = (jedec_id[1] << 8) | jedec_id[2]; + } + + /* Unlock physical flash operations */ + crec_flash_lock_mapped_storage(0); + + return ret; +} + +static int cros_flash_xec_get_status(const struct device *dev, uint8_t *sr1, + uint8_t *sr2) +{ + flash_get_status(dev, sr1); + *sr2 = 0; + + return EC_SUCCESS; +} + +/* cros ec flash driver registration */ +static const struct cros_flash_driver_api cros_flash_xec_driver_api = { + .init = cros_flash_xec_init, + .physical_read = cros_flash_xec_read, + .physical_write = cros_flash_xec_write, + .physical_erase = cros_flash_xec_erase, + .physical_get_protect = cros_flash_xec_get_protect, + .physical_get_protect_flags = cros_flash_xec_get_protect_flags, + .physical_protect_at_boot = cros_flash_xec_protect_at_boot, + .physical_protect_now = cros_flash_xec_protect_now, + .physical_get_jedec_id = cros_flash_xec_get_jedec_id, + .physical_get_status = cros_flash_xec_get_status, +}; + +static int flash_xec_init(const struct device *dev) +{ + struct cros_flash_xec_data *data = dev->data; + + data->flash_dev = DEVICE_DT_GET(FLASH_DEV); + if (!device_is_ready(data->flash_dev)) { + LOG_ERR("%s device not ready", data->flash_dev->name); + return -ENODEV; + } + + data->spi_ctrl_dev = DEVICE_DT_GET(SPI_CONTROLLER_DEV); + if (!device_is_ready(data->spi_ctrl_dev)) { + LOG_ERR("%s device not ready", data->spi_ctrl_dev->name); + return -ENODEV; + } + + return EC_SUCCESS; +} + +#if CONFIG_CROS_FLASH_XEC_INIT_PRIORITY <= CONFIG_SPI_NOR_INIT_PRIORITY +#error "CONFIG_CROS_FLASH_XEC_INIT_PRIORITY must be greater than" \ + "CONFIG_SPI_NOR_INIT_PRIORITY." +#endif +static struct cros_flash_xec_data cros_flash_data; +DEVICE_DT_INST_DEFINE(0, flash_xec_init, NULL, &cros_flash_data, NULL, + POST_KERNEL, CONFIG_CROS_FLASH_XEC_INIT_PRIORITY, + &cros_flash_xec_driver_api); diff --git a/zephyr/dts/bindings/cros_flash/microchip,xec-cros-flash.yaml b/zephyr/dts/bindings/cros_flash/microchip,xec-cros-flash.yaml new file mode 100644 index 0000000000..2b9aea1554 --- /dev/null +++ b/zephyr/dts/bindings/cros_flash/microchip,xec-cros-flash.yaml @@ -0,0 +1,9 @@ +# Copyright 2022 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description: Microchip, XEC-cros-flash node + +compatible: "microchip,xec-cros-flash" + +include: cros-flash-controller.yaml |