// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later /* Copyright 2013-2019 IBM Corp. */ #include #include #include #include #include #include #include #include #include #include #include "astbmc.h" enum ast_flash_style { raw_flash, raw_mem, ipmi_hiomap, mbox_hiomap, }; static enum ast_flash_style ast_flash_get_fallback_style(void) { if (ast_lpc_fw_mbox_hiomap()) return mbox_hiomap; if (ast_lpc_fw_maps_flash()) return raw_flash; return raw_mem; } int pnor_init(void) { struct spi_flash_ctrl *pnor_ctrl = NULL; struct blocklevel_device *bl = NULL; enum ast_flash_style style; int rc = 0; if (ast_lpc_fw_ipmi_hiomap()) { style = ipmi_hiomap; rc = ipmi_hiomap_init(&bl); } if (!ast_lpc_fw_ipmi_hiomap() || rc) { if (!ast_sio_is_enabled()) return -ENODEV; style = ast_flash_get_fallback_style(); if (style == mbox_hiomap) rc = mbox_flash_init(&bl); else if (style == raw_flash) rc = ast_sf_open(AST_SF_TYPE_PNOR, &pnor_ctrl); else if (style == raw_mem) rc = ast_sf_open(AST_SF_TYPE_MEM, &pnor_ctrl); else { prerror("Unhandled flash mode: %d\n", style); return -ENODEV; } } if (rc) { prerror("PLAT: Failed to init PNOR driver\n"); goto fail; } if (style == raw_flash || style == raw_mem) { rc = flash_init(pnor_ctrl, &bl, NULL); if (rc) goto fail; } rc = flash_register(bl); if (!rc) return 0; fail: if (bl) { switch (style) { case raw_flash: case raw_mem: flash_exit(bl); break; case ipmi_hiomap: ipmi_hiomap_exit(bl); break; case mbox_hiomap: mbox_flash_exit(bl); break; } } if (pnor_ctrl) ast_sf_close(pnor_ctrl); return rc; }