Revert "[R-7.2.0] uwb: update qm35 driver"

Revert submission 2615259-R-7.2.0

Reason for revert: b/311753464 - fw 6.3.11 for additional soak in main

Reverted changes: /q/submissionid:2615259-R-7.2.0

Bug: 311753464
Change-Id: Ib423da42e3b441e4ffcace355fff4e66e49df915
Signed-off-by: Victor Liu <victorliu@google.com>
diff --git a/Kbuild b/Kbuild
index 7e16ab7..c2fd666 100644
--- a/Kbuild
+++ b/Kbuild
@@ -1,4 +1,4 @@
-ccflags-y := -I$(srctree)/$(src)/libqmrom/include -I$(srctree)/$(src)/libfwupdater/include -Werror
+ccflags-y := -I$(srctree)/$(src)/libqmrom/include -Werror
 
 obj-$(CONFIG_QM35_SPI) := qm35.o
 
@@ -7,11 +7,10 @@
 	qm35_rb.o \
 	qmrom_spi.o \
 	libqmrom/src/qmrom_common.o \
-	libqmrom/src/qm357xx_rom_common.o \
-	libqmrom/src/qm357xx_rom_b0.o \
-	libqmrom/src/qm357xx_rom_c0.o \
+	libqmrom/src/qmrom_a0.o \
+	libqmrom/src/qmrom_b0.o \
+	libqmrom/src/qmrom_c0.o \
 	libqmrom/src/qmrom_log.o \
-	libfwupdater/src/fwupdater.o \
 	hsspi.o \
 	hsspi_uci.o \
 	hsspi_log.o \
diff --git a/debug.c b/debug.c
index dcfb9a1..6b80fd4 100644
--- a/debug.c
+++ b/debug.c
@@ -390,14 +390,14 @@
 static int debug_socid_show(struct seq_file *s, void *unused)
 {
 	struct debug *debug = (struct debug *)s->private;
-	uint8_t soc_id[QM357XX_ROM_SOC_ID_LEN];
+	uint8_t soc_id[ROM_SOC_ID_LEN];
 	int rc;
 
 	if (debug->trace_ops && debug->trace_ops->get_soc_id) {
 		rc = debug->trace_ops->get_soc_id(debug, soc_id);
 		if (rc < 0)
 			return -EIO;
-		seq_printf(s, "%*phN\n", QM357XX_ROM_SOC_ID_LEN, soc_id);
+		seq_printf(s, "%*phN\n", ROM_SOC_ID_LEN, soc_id);
 	}
 	return 0;
 }
diff --git a/debug_qmrom.c b/debug_qmrom.c
index 9b10c44..8c77bd3 100644
--- a/debug_qmrom.c
+++ b/debug_qmrom.c
@@ -25,7 +25,6 @@
  * QM35 LOG layer HSSPI Protocol
  */
 
-#include <linux/interrupt.h>
 #include <linux/version.h>
 #include <linux/printk.h>
 #include <linux/debugfs.h>
@@ -40,16 +39,10 @@
 #include <qmrom.h>
 #include <qmrom_log.h>
 #include <qmrom_spi.h>
-#include <qmrom_utils.h>
-
-#include <fwupdater.h>
 
 #include "qm35.h"
 #include "debug.h"
 
-extern int fu_spi_speed_hz;
-extern int qmrom_spi_speed_hz;
-
 #define QMROM_RETRIES 10
 
 static void *priv_from_file(const struct file *filp)
@@ -61,31 +54,19 @@
 {
 	struct debug *debug = priv_from_file(filp);
 	struct qm35_ctx *qm35_hdl = container_of(debug, struct qm35_ctx, debug);
-	int irq = gpiod_to_irq(qm35_hdl->gpio_ss_rdy);
 
 	qm35_hsspi_stop(qm35_hdl);
 	qmrom_set_log_device(&qm35_hdl->spi->dev, LOG_DBG);
-
-	if (irq >= 0)
-		enable_irq(irq);
-
-	qm35_hdl->flashing = true;
 	return qm35_hdl;
 }
 
 static void rom_test_unprepare(struct qm35_ctx *qm35_hdl)
 {
-	int irq = gpiod_to_irq(qm35_hdl->gpio_ss_rdy);
-
-	if (irq >= 0)
-		disable_irq_nosync(irq);
-
-	qm35_hdl->flashing = false;
 	qmrom_set_log_device(&qm35_hdl->spi->dev, LOG_WARN);
 	qm35_hsspi_start(qm35_hdl);
 }
 
-static struct firmware *file2firmware(const char *filename)
+static struct firmware *file2firmware(const char *filename, size_t file_size)
 {
 	struct firmware *firmware =
 		kmalloc(sizeof(struct firmware), GFP_KERNEL | __GFP_ZERO);
@@ -99,12 +80,12 @@
 			filename, 0, (void **)&firmware->data, INT_MAX,
 			&firmware->size, READING_FIRMWARE);
 		if (bytes_read < 0) {
-			pr_err("qm35: kernel_read_file_from_path(%s) returned %d\n",
+			pr_err("kernel_read_file_from_path(%s) returned %d\n",
 			       filename, (int)bytes_read);
 			goto fail;
 		}
 		if (bytes_read != firmware->size) {
-			pr_err("qm35: kernel_read_file_from_path returned %zu; expected %zu\n",
+			pr_err("kernel_read_file_from_path returned %zu; expected %zu\n",
 			       bytes_read, firmware->size);
 			goto fail;
 		}
@@ -117,7 +98,7 @@
 						     &size, INT_MAX,
 						     READING_FIRMWARE);
 		if (ret < 0) {
-			pr_err("qm35: kernel_read_file_from_path(%s) returned %d\n",
+			pr_err("kernel_read_file_from_path(%s) returned %d\n",
 			       filename, ret);
 			goto fail;
 		}
@@ -125,8 +106,8 @@
 	}
 #endif
 
-	print_hex_dump(KERN_DEBUG, "qm35: Bin file:", DUMP_PREFIX_ADDRESS, 16,
-		       1, firmware->data, 16, false);
+	print_hex_dump(KERN_DEBUG, "Bin file:", DUMP_PREFIX_ADDRESS, 16, 1,
+		       firmware->data, 16, false);
 	return firmware;
 
 fail:
@@ -144,29 +125,24 @@
 	struct qm35_ctx *qm35_hdl = rom_test_prepare(filp);
 	struct qmrom_handle *h;
 
-	pr_info("qm35: Starting the probe test...\n");
-	h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
-		       qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
-		       qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+	pr_info("Starting the probe test...\n");
+	h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+		       QMROM_RETRIES, qmrom_spi_reset_device);
 	if (!h) {
-		pr_err("qm35: qmrom_init failed\n");
+		pr_err("qmrom_init failed\n");
 		goto end;
 	}
 
-	pr_info("qm35: chip_revision %#2x\n", h->chip_rev);
-	pr_info("qm35: device version %#02x\n", h->device_version);
+	pr_info("chip_revision %#2x\n", h->chip_rev);
+	pr_info("device version %#02x\n", h->device_version);
 	if (h->chip_rev != 0xa001) {
-		pr_info("qm35: lcs_state %u\n", h->qm357xx_soc_info.lcs_state);
-		print_hex_dump(KERN_DEBUG, "qm35: soc_id:", DUMP_PREFIX_NONE,
-			       16, 1, h->qm357xx_soc_info.soc_id,
-			       sizeof(h->qm357xx_soc_info.soc_id), false);
-		print_hex_dump(KERN_DEBUG, "qm35: uuid:", DUMP_PREFIX_NONE, 16,
-			       1, h->qm357xx_soc_info.uuid,
-			       sizeof(h->qm357xx_soc_info.uuid), false);
+		pr_info("lcs_state %d\n", h->lcs_state);
+		print_hex_dump(KERN_DEBUG, "soc_id:", DUMP_PREFIX_NONE, 16, 1,
+			       h->soc_id, sizeof(h->soc_id), false);
+		print_hex_dump(KERN_DEBUG, "uuid:", DUMP_PREFIX_NONE, 16, 1,
+			       h->uuid, sizeof(h->uuid), false);
 	}
 	qmrom_deinit(h);
-	qmrom_spi_reset_device(qm35_hdl);
-	qmrom_msleep(100);
 
 end:
 	rom_test_unprepare(qm35_hdl);
@@ -190,15 +166,14 @@
 
 	err = copy_from_user(filename, buff, count);
 	if (err) {
-		pr_err("qm35: copy_from_user failed with error %d\n", err);
+		pr_err("copy_from_user failed with error %d\n", err);
 		count = err;
 		goto end;
 	}
 	filename[count - 1] = '\0';
-	certificate = file2firmware(filename);
-	if (!certificate || certificate->size != DEBUG_CERTIFICATE_SIZE) {
-		pr_err("qm35: %s: file retrieval failed, abort (%s)\n",
-		       __func__, certificate ? "wrong size" : "not found");
+	certificate = file2firmware(filename, DEBUG_CERTIFICATE_SIZE);
+	if (!certificate) {
+		pr_err("%s: file retrieval failed, abort\n", __func__);
 		count = -1;
 		goto end;
 	}
@@ -206,20 +181,18 @@
 	/* Flash the debug certificate */
 	pr_info("Flashing debug certificate %s...\n", filename);
 
-	h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
-		       qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
-		       qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+	h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+		       QMROM_RETRIES, qmrom_spi_reset_device);
 	if (!h) {
-		pr_err("qm35: qmrom_init failed\n");
+		pr_err("qmrom_init failed\n");
 		goto end;
 	}
-	err = qm357xx_rom_flash_dbg_cert(h, certificate);
+	err = qmrom_flash_dbg_cert(h, certificate);
 	if (err)
-		pr_err("qm35: Flashing debug certificate %s failed with %d!\n",
+		pr_err("Flashing debug certificate %s failed with %d!\n",
 		       filename, err);
 	else
-		pr_info("qm35: Flashing debug certificate %s succeeded!\n",
-			filename);
+		pr_info("Flashing debug certificate %s succeeded!\n", filename);
 
 end:
 	if (h)
@@ -229,9 +202,6 @@
 			vfree(certificate->data);
 		kfree(certificate);
 	}
-	qmrom_spi_reset_device(qm35_hdl);
-	qmrom_msleep(100);
-
 	rom_test_unprepare(qm35_hdl);
 	return count;
 }
@@ -243,29 +213,23 @@
 	struct qmrom_handle *h = NULL;
 	int err;
 
-	pr_info("qm35: Erasing debug certificate...\n");
+	pr_info("Erasing debug certificate...\n");
 
-	h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
-		       qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
-		       qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+	h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+		       QMROM_RETRIES, qmrom_spi_reset_device);
 	if (!h) {
-		pr_err("qm35: qmrom_init failed\n");
+		pr_err("qmrom_init failed\n");
 		goto end;
 	}
-	err = qm357xx_rom_erase_dbg_cert(h);
+	err = qmrom_erase_dbg_cert(h);
 	if (err)
-		pr_err("qm35: Erasing debug certificate failed with %d!\n",
-		       err);
+		pr_err("Erasing debug certificate failed with %d!\n", err);
 	else
-		pr_info("qm35: Erasing debug certificate succeeded!\n");
+		pr_info("Erasing debug certificate succeeded!\n");
 
 end:
 	if (h)
 		qmrom_deinit(h);
-
-	qmrom_spi_reset_device(qm35_hdl);
-	qmrom_msleep(100);
-
 	rom_test_unprepare(qm35_hdl);
 	return count;
 }
@@ -287,122 +251,34 @@
 
 	rc = copy_from_user(filename, buff, count);
 	if (rc) {
-		pr_err("qm35: copy_from_user failed with error %d\n", rc);
+		pr_err("copy_from_user failed with error %d\n", rc);
 		goto end;
 	}
 	filename[count - 1] = '\0';
-	fw = file2firmware(filename);
+	fw = file2firmware(filename, 0);
 	if (!fw) {
-		pr_err("qm35: %s: file %s retrieval failed, abort\n", __func__,
-		       filename);
+		pr_err("%s: file retrieval failed, abort\n", __func__);
 		rc = -1;
 		goto end;
 	}
 
-	pr_info("qm35: Flashing image %s (%pK->data %pK)...\n", filename, fw,
+	pr_info("Flashing image %s (%pK->data %pK)...\n", filename, fw,
 		fw->data);
 
-	h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
-		       qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
-		       qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+	h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+		       QMROM_RETRIES, qmrom_spi_reset_device);
 	if (!h) {
-		pr_err("qm35: qmrom_init failed\n");
+		pr_err("qmrom_init failed\n");
 		rc = -1;
 		goto end;
 	}
-	rc = qm357xx_rom_flash_fw(h, fw);
+	rc = qmrom_flash_fw(h, fw);
 	if (rc)
-		pr_err("qm35: Flashing firmware %s failed with %d!\n", filename,
-		       rc);
+		pr_err("Flashing firmware %s failed with %d!\n", filename, rc);
 	else
-		pr_info("qm35: Flashing firmware %s succeeded!\n", filename);
+		pr_info("Flashing firmware %s succeeded!\n", filename);
 
 end:
-	kfree(filename);
-	if (h)
-		qmrom_deinit(h);
-	if (fw) {
-		if (fw->data)
-			vfree(fw->data);
-		kfree(fw);
-	}
-	rom_test_unprepare(qm35_hdl);
-	return count;
-}
-
-static ssize_t rom_flash_fw_pkg(struct file *filp, const char __user *buff,
-				size_t count, loff_t *off)
-{
-	struct qm35_ctx *qm35_hdl = rom_test_prepare(filp);
-	const struct firmware *fw = NULL;
-	struct qmrom_handle *h = NULL;
-	char *filename = NULL, *fw_data;
-	uint32_t fw_size;
-	int rc;
-
-	if (fu_spi_speed_hz == 0)
-		fu_spi_speed_hz = FWUPDATER_SPI_SPEED_HZ;
-
-	filename = kmalloc(count, GFP_KERNEL);
-	if (!filename) {
-		count = -ENOMEM;
-		goto end;
-	}
-	rc = copy_from_user(filename, buff, count);
-	if (rc) {
-		pr_err("qm35: copy_from_user failed with error %d\n", rc);
-		goto end;
-	}
-	filename[count - 1] = '\0';
-	fw = file2firmware(filename);
-	if (!fw || !fw->data) {
-		pr_err("qm35: %s file %s retrieval failed (%s), abort\n",
-		       __func__, filename, fw ? "no data read" : "not found");
-		rc = -1;
-		goto end;
-	}
-
-	pr_info("qm35: Flashing fw_updater...\n");
-	h = qmrom_init(&qm35_hdl->spi->dev, qm35_hdl, qm35_hdl,
-		       qm35_hdl->gpio_ss_irq, qmrom_spi_speed_hz, QMROM_RETRIES,
-		       qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
-	if (!h) {
-		pr_err("qm35: qmrom_init failed\n");
-		rc = -1;
-		goto end;
-	}
-	rc = qm357xx_rom_flash_fw(h, fw);
-	if (rc) {
-		pr_err("qm35: Flashing fw_updater failed with %d!\n", rc);
-		goto end;
-	}
-
-	pr_info("qm35: Flashing fw_updater succeeded, flashing the fw package now...\n");
-	qmrom_spi_set_freq(fu_spi_speed_hz);
-
-	rc = qm357xx_rom_fw_macro_pkg_get_fw_idx(fw, 1, &fw_size, &fw_data);
-	if (rc) {
-		pr_err("qm35: %s FW MACRO PACKAGE corrupted = %d\n", __func__,
-		       rc);
-		goto end;
-	}
-
-	if (*(uint32_t *)fw_data == CRYPTO_FIRMWARE_PACK_MAGIC_VALUE) {
-		rc = run_fwupdater(h, fw_data, fw_size);
-	} else {
-		rc = -EINVAL;
-		pr_err("qm35: FW PACKAGE not found - %04x! fw_size = %d\n",
-		       *(uint32_t *)fw_data, fw_size);
-		goto end;
-	}
-	pr_info("qm35: FW package flashing %s (rc = %d), rebooting the QM...\n",
-		rc ? "failed" : "succeeded", rc);
-
-end:
-	qmrom_spi_reset_device(qm35_hdl);
-
-	if (filename)
-		kfree(filename);
 	if (h)
 		qmrom_deinit(h);
 	if (fw) {
@@ -432,11 +308,6 @@
 	.write = rom_flash_fw
 };
 
-static const struct file_operations rom_flash_fw_pkg_fops = {
-	.owner = THIS_MODULE,
-	.write = rom_flash_fw_pkg
-};
-
 void debug_rom_code_init(struct debug *debug)
 {
 	struct dentry *file;
@@ -467,11 +338,4 @@
 		pr_err("qm35: failed to create uwb0/fw/rom_flash_fw\n");
 		return;
 	}
-
-	file = debugfs_create_file("rom_flash_fw_pkg", 0200, debug->fw_dir,
-				   debug, &rom_flash_fw_pkg_fops);
-	if (!file) {
-		pr_err("qm35: failed to create uwb0/fw/rom_flash_fw_pkg\n");
-		return;
-	}
 }
diff --git a/hsspi.c b/hsspi.c
index 3b39ae7..1170ca1 100644
--- a/hsspi.c
+++ b/hsspi.c
@@ -52,8 +52,6 @@
 #define HSSPI_MANUAL_CS_SETUP_US SPI_CS_SETUP_DELAY_US
 #endif
 
-extern int spi_speed_hz;
-
 struct hsspi_work {
 	struct list_head list;
 	enum hsspi_work_type type;
@@ -217,13 +215,11 @@
 			.tx_buf = hsspi->host,
 			.rx_buf = hsspi->soc,
 			.len = sizeof(*(hsspi->host)),
-			.speed_hz = spi_speed_hz,
 		},
 		{
 			.tx_buf = tx,
 			.rx_buf = rx,
 			.len = length,
-			.speed_hz = spi_speed_hz,
 		},
 	};
 	int ret, retry = 5;
diff --git a/hsspi.h b/hsspi.h
index 9cb62cc..c57c849 100644
--- a/hsspi.h
+++ b/hsspi.h
@@ -173,6 +173,7 @@
 	struct gpio_desc *gpio_ss_rdy;
 	struct gpio_desc *gpio_exton;
 
+	volatile bool xfer_ongoing;
 	volatile bool waiting_ss_rdy;
 };
 
diff --git a/hsspi_coredump.c b/hsspi_coredump.c
index 0172ef4..36ddbb6 100644
--- a/hsspi_coredump.c
+++ b/hsspi_coredump.c
@@ -234,12 +234,6 @@
 		break;
 
 	case COREDUMP_BODY_NTF:
-		pr_debug(
-			"qm35: coredump: saving coredump data with len: %d [%d/%d]\n",
-			cch_body_size,
-			layer->coredump_data_wr_idx + cch_body_size,
-			layer->coredump_size);
-
 		if (coredump_body_ntf_received(layer, cch_body, cch_body_size))
 			break;
 
@@ -346,6 +340,5 @@
 
 void coredump_layer_deinit(struct coredump_layer *layer)
 {
-	del_timer_sync(&layer->timer);
 	kfree(layer->coredump_data);
 }
diff --git a/hsspi_test.c b/hsspi_test.c
index 2ac5e21..ae02d52 100644
--- a/hsspi_test.c
+++ b/hsspi_test.c
@@ -114,7 +114,6 @@
 {
 	static uint64_t bytes, msgs, errors, bytes0, msgs0, errors0;
 	static time64_t last_perf_dump;
-	uint32_t rem;
 	int error = check_rx(blk->data, blk->length) ? 1 : 0;
 	time64_t now;
 	errors += error;
@@ -143,8 +142,7 @@
 	bytes += blk->length;
 	msgs++;
 	error |= hsspi_send(ghsspi, layer, blk);
-	div_u64_rem(msgs, 100, &rem);
-	if (error || (rem == 0))
+	if (error || ((msgs % 100) == 0))
 		pr_info("hsspi test: bytes received %llu, msgs %llu, errors %llu\n",
 			bytes, msgs, errors);
 	if (now > last_perf_dump) {
@@ -155,9 +153,9 @@
 		uint64_t derrors = errors >= errors0 ? errors - errors0 :
 						       ~0ULL - errors0 + errors;
 		pr_info("hsspi test perfs: %llu B/s, %llu msgs/s, %llu errors/s\n",
-			div_u64(dbytes, (now - last_perf_dump)),
-			div_u64(dmsgs, (now - last_perf_dump)),
-			div_u64(derrors, (now - last_perf_dump)));
+			dbytes / (now - last_perf_dump),
+			dmsgs / (now - last_perf_dump),
+			derrors / (now - last_perf_dump));
 		bytes0 = bytes;
 		msgs0 = msgs;
 		errors0 = errors;
@@ -169,12 +167,10 @@
 		     int status)
 {
 	static uint64_t bytes, msgs, errors;
-	uint32_t rem;
 	errors += status ? 1 : 0;
 	msgs++;
 	bytes += blk->length;
-	div_u64_rem(msgs, 100, &rem);
-	if (status || (rem == 0))
+	if (status || ((msgs % 100) == 0))
 		pr_info("hsspi test: bytes sent %llu, msgs %llu, errors %llu\n",
 			bytes, msgs, errors);
 	kfree(blk);
diff --git a/libfwupdater/CMakeLists.txt b/libfwupdater/CMakeLists.txt
deleted file mode 100644
index 8f18673..0000000
--- a/libfwupdater/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-set(SOURCES
-    src/fwupdater.c
-    tests/fwupdater_unit_tests.c
-    tests/comms_tests.c
-    tests/fwpkg_tests.c
-)
-
-add_library(fwupdater SHARED ${SOURCES})
-
-target_include_directories(fwupdater PUBLIC
-    include
-)
-
-target_link_libraries(fwupdater
-    PRIVATE
-        qmrom
-)
diff --git a/libfwupdater/include/fwupdater.h b/libfwupdater/include/fwupdater.h
deleted file mode 100644
index 2875090..0000000
--- a/libfwupdater/include/fwupdater.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#ifndef __FWUPDATER_H__
-#define __FWUPDATER_H__
-
-#ifndef __KERNEL__
-#include <stdint.h>
-#include <stddef.h>
-#else
-#include <linux/types.h>
-#endif
-
-#include <qmrom.h>
-#include <qm357xx_fwpkg.h>
-
-#ifndef CONFIG_NB_RETRIES
-#define CONFIG_NB_RETRIES 10
-#endif
-
-// #define CONFIG_INJECT_ERROR 1
-
-enum fw_pkg_error_e {
-	FW_PKG_SUCCESS = 0,
-	FW_PKG_DOWNLOAD_ERROR,
-	FW_PKG_MAGIC_NUM_INVALID,
-	FW_PKG_VERSION_INVALID,
-	FW_PKG_ENCRYPTION_MODE_INVALID,
-	FW_PKG_IMG_HDR_MAGIC_NUM_INVALID,
-	FW_PKG_IMG_HDR_VERSION_INVALID,
-	FW_PKG_IMG_HDR_CERT_SIZE_INVALID,
-	FW_PKG_IMG_HDR_IMG_NUM_INVALID,
-	FW_PKG_PLD_CHK_MAGIC_NUM_INVALID,
-	FW_PKG_PLD_CHK_VERSION_INVALID,
-	FW_PKG_PLD_CHK_LENGTH_INVALID,
-	FW_PKG_HDR_CRYPTO_ERROR,
-	FW_PKG_HDR_CRYPTO_INVALID,
-	FW_PKG_HDR_PAYLOAD_SIZE_INVALID,
-	FW_PKG_IMG_HDR_SIZE_INVALID,
-	FW_PKG_IMG_HDR_CRYPTO_ERROR,
-	FW_PKG_IMG_HDR_NUMDESCS_INVALID,
-	FW_PKG_CERT_CHAIN_SIZE_INVALID,
-	FW_PKG_CERT_CHAIN_INVALID,
-	FW_PKG_CERT_INSTALLED_FW_VERSION_INVALID,
-	FW_PKG_CERT_KEY1_CHECK_INVALID,
-	FW_PKG_CERT_KEY2_CHECK_INVALID,
-	FW_PKG_CERT_CONTENT_CHECK_INVALID,
-	FW_PKG_CERT_CHAIN_CRYPTO_ERROR,
-	FW_PKG_CERT_CHAIN_IMG_RANGE_INVALID,
-	FW_PKG_CERT_CHAIN_WRITE_ERROR,
-	FW_PKG_IMG_CHUNK_CRYPTO_ERROR,
-	FW_PKG_IMG_CHUNK_WRITE_ERROR,
-	FW_PKG_IMG_FIXUP_FAILED
-};
-
-/*! Firmware Update Status fields */
-struct fw_updater_status_t {
-	uint32_t magic;
-	uint32_t status;
-	uint32_t suberror;
-	uint32_t spi_errors;
-	uint32_t cksum_errors;
-	uint32_t rram_errors;
-	uint32_t crypto_errors;
-} __attribute__((packed));
-
-#define FWUPDATER_STATUS_MAGIC 0xCAFECAFE
-
-void run_fwupdater_unit_tests(void *spi_handle);
-int run_fwupdater(struct qmrom_handle *handle, char *fwpkg_bin, size_t size);
-
-#endif /* __FWUPDATER_H__ */
diff --git a/libfwupdater/src/fwupdater.c b/libfwupdater/src/fwupdater.c
deleted file mode 100644
index 187e703..0000000
--- a/libfwupdater/src/fwupdater.c
+++ /dev/null
@@ -1,343 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#ifndef __KERNEL__
-#include <stddef.h>
-#endif
-
-#include <qmrom_spi.h>
-#include <qmrom_log.h>
-#include <qmrom_utils.h>
-#include <spi_rom_protocol.h>
-
-#include <fwupdater.h>
-
-/* Extract from C0 rom code */
-#define MAX_CERTIFICATE_SIZE 0x400
-#define MAX_CHUNK_SIZE 3072
-#define WAIT_SS_RDY_CHUNK_TIMEOUT 100
-#define WAIT_SS_RDY_STATUS_TIMEOUT 10
-#define RESULT_RETRIES 3
-#define RESULT_CMD_INTERVAL_MS 50
-#define CKSUM_TYPE uint32_t
-#define CKSUM_SIZE (sizeof(CKSUM_TYPE))
-#define TRANPORT_HEADER_SIZE (sizeof(struct stc) + CKSUM_SIZE)
-#define EMERGENCY_SPI_FREQ 1000000 /* 1MHz */
-
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-#ifndef __KERNEL__
-_Static_assert(MAX_CHUNK_SIZE >= CRYPTO_IMAGES_CERT_PKG_SIZE);
-_Static_assert(TRANPORT_HEADER_SIZE + MAX_CERTIFICATE_SIZE < MAX_CHUNK_SIZE);
-#endif
-
-/* local stats */
-static int gstats_spi_errors;
-static int gstats_ss_rdy_timeouts;
-
-static int send_data_chunks(struct qmrom_handle *handle, char *data,
-			    size_t size);
-
-int run_fwupdater(struct qmrom_handle *handle, char *fwpkg_bin, size_t size)
-{
-	int rc;
-
-	gstats_spi_errors = 0;
-	gstats_ss_rdy_timeouts = 0;
-
-	if (size < sizeof(struct fw_pkg_hdr_t) +
-			   sizeof(struct fw_pkg_img_hdr_t) +
-			   CRYPTO_IMAGES_CERT_PKG_SIZE +
-			   CRYPTO_FIRMWARE_CHUNK_MIN_SIZE) {
-		LOG_ERR("Cannot extract enough data from fw package binary\n");
-		return -EINVAL;
-	}
-
-	rc = send_data_chunks(handle, fwpkg_bin, size);
-	if (rc) {
-		LOG_ERR("Sending image failed with %d\n", rc);
-		return rc;
-	}
-	return 0;
-}
-
-static int run_fwupdater_get_status(struct qmrom_handle *handle,
-				    struct stc *hstc, struct stc *sstc,
-				    struct fw_updater_status_t *status)
-{
-	uint32_t i = 0;
-	CKSUM_TYPE *cksum = (CKSUM_TYPE *)(hstc + 1);
-	bool owa;
-	memset(hstc, 0, TRANPORT_HEADER_SIZE + sizeof(*status));
-
-	while (i++ < RESULT_RETRIES) {
-		// Poll the QM
-		sstc->all = 0;
-		hstc->all = 0;
-		*cksum = 0;
-		qmrom_spi_transfer(handle->spi_handle, (char *)sstc,
-				   (const char *)hstc, TRANPORT_HEADER_SIZE);
-		qmrom_spi_wait_for_ready_line(handle->ss_rdy_handle,
-					      WAIT_SS_RDY_STATUS_TIMEOUT);
-		sstc->all = 0;
-		hstc->all = 0;
-		hstc->host_flags.pre_read = 1;
-		*cksum = 0;
-		qmrom_spi_transfer(handle->spi_handle, (char *)sstc,
-				   (const char *)hstc, TRANPORT_HEADER_SIZE);
-		// LOG_INFO("Pre-Read received:\n");
-		// hexdump(LOG_INFO, sstc, sizeof(sstc));
-
-		/* Stops the loop when QM has a result to share */
-		owa = sstc->soc_flags.out_waiting;
-		qmrom_spi_wait_for_ready_line(handle->ss_rdy_handle,
-					      WAIT_SS_RDY_STATUS_TIMEOUT);
-		sstc->all = 0;
-		hstc->all = 0;
-		hstc->host_flags.read = 1;
-		hstc->len = sizeof(*status);
-		*cksum = 0;
-		qmrom_spi_transfer(handle->spi_handle, (char *)sstc,
-				   (const char *)hstc,
-				   TRANPORT_HEADER_SIZE + sizeof(*status));
-		// LOG_INFO("Read received:\n");
-		// hexdump(LOG_INFO, sstc, sizeof(*hstc) + sizeof(uint32_t));
-		if (owa) {
-			memcpy(status, sstc->payload, sizeof(*status));
-			if (status->magic == FWUPDATER_STATUS_MAGIC)
-				break;
-		}
-		qmrom_spi_wait_for_ready_line(handle->ss_rdy_handle,
-					      WAIT_SS_RDY_STATUS_TIMEOUT);
-		// Failed to get the status, reduces the spi speed to
-		// an emergency speed to maximize the chance to get the
-		// final status
-		qmrom_spi_set_freq(EMERGENCY_SPI_FREQ);
-		gstats_spi_errors++;
-	}
-	if (status->magic != FWUPDATER_STATUS_MAGIC) {
-		LOG_ERR("Timedout waiting for result\n");
-		return -1;
-	}
-	return 0;
-}
-
-static CKSUM_TYPE checksum(const void *data, const size_t size)
-{
-	CKSUM_TYPE cksum = 0;
-	CKSUM_TYPE *ptr = (CKSUM_TYPE *)data;
-	CKSUM_TYPE remainder = size & (CKSUM_SIZE - 1);
-	size_t idx;
-
-	for (idx = 0; idx < size; idx += CKSUM_SIZE, ptr++)
-		cksum += *ptr;
-
-	if (!remainder)
-		return cksum;
-
-	cksum += ((uint8_t *)data)[size - 1];
-	if (remainder > 1) {
-		cksum += ((uint8_t *)data)[size - 2];
-		if (remainder > 2) {
-			cksum += ((uint8_t *)data)[size - 3];
-		}
-	}
-
-	return cksum;
-}
-
-static void prepare_hstc(struct stc *hstc, char *data, size_t len)
-{
-	CKSUM_TYPE *cksum = (CKSUM_TYPE *)(hstc + 1);
-	void *payload = cksum + 1;
-
-	hstc->all = 0;
-	hstc->host_flags.write = 1;
-	hstc->len = len + CKSUM_SIZE;
-	*cksum = checksum(data, len);
-#if IS_ENABLED(CONFIG_INJECT_ERROR)
-	*cksum += 2;
-#endif
-	memcpy(payload, data, len);
-}
-
-static int xfer_payload_prep_next(struct qmrom_handle *handle,
-				  const char *step_name, struct stc *hstc,
-				  struct stc *sstc, struct stc *hstc_next,
-				  char **data, size_t *size)
-{
-	int rc = 0, nb_retry = CONFIG_NB_RETRIES;
-	CKSUM_TYPE *cksum = (CKSUM_TYPE *)(hstc + 1);
-
-	do {
-		int ss_rdy_rc, irq_up;
-		sstc->all = 0;
-		rc = qmrom_spi_transfer(handle->spi_handle, (char *)sstc,
-					(const char *)hstc,
-					hstc->len + sizeof(struct stc));
-		if (hstc_next) {
-			/* Don't wait idle, prepare the next hstc to be sent */
-			size_t to_send = MIN(MAX_CHUNK_SIZE, *size);
-			prepare_hstc(hstc_next, *data, to_send);
-			*size -= to_send;
-			*data += to_send;
-			hstc_next = NULL;
-		}
-		ss_rdy_rc = qmrom_spi_wait_for_ready_line(
-			handle->ss_rdy_handle, WAIT_SS_RDY_CHUNK_TIMEOUT);
-		if (ss_rdy_rc) {
-			LOG_ERR("%s Waiting for ss-rdy failed with %d (nb_retry %d , cksum 0x%x)\n",
-				step_name, ss_rdy_rc, nb_retry, *cksum);
-			gstats_ss_rdy_timeouts++;
-			rc = -EAGAIN;
-		}
-		irq_up = qmrom_spi_read_irq_line(handle->ss_irq_handle);
-		if ((!rc && !sstc->soc_flags.ready) || irq_up) {
-			LOG_ERR("%s Retry rc %d, sstc 0x%08x, irq %d, cksum %08x\n",
-				step_name, rc, sstc->all, irq_up, *cksum);
-			rc = -EAGAIN;
-			gstats_spi_errors++;
-		}
-#if IS_ENABLED(CONFIG_INJECT_ERROR)
-		(*cksum)--;
-#endif
-	} while (rc && --nb_retry > 0);
-	if (rc) {
-		LOG_ERR("%s transfer failed with %d - (sstc 0x%08x)\n",
-			step_name, rc, sstc->all);
-	}
-	return rc;
-}
-
-static int xfer_payload(struct qmrom_handle *handle, const char *step_name,
-			struct stc *hstc, struct stc *sstc)
-{
-	return xfer_payload_prep_next(handle, step_name, hstc, sstc, NULL, NULL,
-				      NULL);
-}
-
-static int send_data_chunks(struct qmrom_handle *handle, char *data,
-			    size_t size)
-{
-	struct fw_updater_status_t status;
-	uint32_t chunk_nr = 0;
-	struct stc *hstc, *sstc, *hstc_current, *hstc_next;
-	char *rx, *tx;
-	CKSUM_TYPE *cksum;
-	int rc = 0;
-
-	qmrom_alloc(rx, MAX_CHUNK_SIZE + TRANPORT_HEADER_SIZE);
-	qmrom_alloc(tx, 2 * (MAX_CHUNK_SIZE + TRANPORT_HEADER_SIZE));
-	if (!rx || !tx) {
-		LOG_ERR("Rx/Tx buffers allocation failure\n");
-		rc = -ENOMEM;
-		goto exit_nomem;
-	}
-
-	sstc = (struct stc *)rx;
-	hstc = (struct stc *)tx;
-	hstc_current = hstc;
-	hstc_next = (struct stc *)&tx[MAX_CHUNK_SIZE + TRANPORT_HEADER_SIZE];
-	cksum = (CKSUM_TYPE *)(hstc + 1);
-
-	/* wait for the QM to be ready */
-	rc = qmrom_spi_wait_for_ready_line(handle->ss_rdy_handle,
-					   WAIT_SS_RDY_CHUNK_TIMEOUT);
-	if (rc)
-		LOG_ERR("Waiting for ss-rdy failed with %d\n", rc);
-
-	/* Sending the fw package header */
-	prepare_hstc(hstc, data, sizeof(struct fw_pkg_hdr_t));
-	LOG_INFO("Sending the fw package header (%zu bytes, cksum is 0x%08x)\n",
-		 sizeof(struct fw_pkg_hdr_t), *cksum);
-	// hexdump(LOG_INFO, hstc->payload + 4, sizeof(struct fw_pkg_hdr_t));
-	rc = xfer_payload(handle, "fw package header", hstc, sstc);
-	if (rc)
-		goto exit;
-	/* Move the data to the next offset minus the header footprint */
-	size -= sizeof(struct fw_pkg_hdr_t);
-	data += sizeof(struct fw_pkg_hdr_t);
-
-	/* Sending the image header */
-	prepare_hstc(hstc, data, sizeof(struct fw_pkg_img_hdr_t));
-	LOG_INFO("Sending the image header (%zu bytes cksum 0x%08x)\n",
-		 sizeof(struct fw_pkg_img_hdr_t), *cksum);
-	// hexdump(LOG_INFO, hstc->payload + 4, sizeof(struct fw_pkg_img_hdr_t));
-	rc = xfer_payload(handle, "image header", hstc, sstc);
-	if (rc)
-		goto exit;
-	size -= sizeof(struct fw_pkg_img_hdr_t);
-	data += sizeof(struct fw_pkg_img_hdr_t);
-
-	/* Sending the cert chain */
-	prepare_hstc(hstc, data, CRYPTO_IMAGES_CERT_PKG_SIZE);
-	LOG_INFO("Sending the cert chain (%d bytes cksum 0x%08x)\n",
-		 CRYPTO_IMAGES_CERT_PKG_SIZE, *cksum);
-	rc = xfer_payload(handle, "cert chain", hstc, sstc);
-	if (rc)
-		goto exit;
-	size -= CRYPTO_IMAGES_CERT_PKG_SIZE;
-	data += CRYPTO_IMAGES_CERT_PKG_SIZE;
-
-	/* Sending the fw image */
-	LOG_INFO("Sending the image (%zu bytes)\n", size);
-	LOG_DBG("Sending a chunk (%zu bytes cksum 0x%08x)\n",
-		MIN(MAX_CHUNK_SIZE, size), *cksum);
-	prepare_hstc(hstc_current, data, MIN(MAX_CHUNK_SIZE, size));
-	size -= hstc_current->len - CKSUM_SIZE;
-	data += hstc_current->len - CKSUM_SIZE;
-	do {
-		rc = xfer_payload_prep_next(handle, "data chunk", hstc_current,
-					    sstc, hstc_next, &data, &size);
-		if (rc)
-			goto exit;
-		chunk_nr++;
-		/* swap hstcs */
-		hstc = hstc_current;
-		hstc_current = hstc_next;
-		hstc_next = hstc;
-	} while (size);
-
-	/* Sends the last now */
-	rc = xfer_payload_prep_next(handle, "data chunk", hstc_current, sstc,
-				    NULL, NULL, NULL);
-
-exit:
-	// tries to get the flashing status anyway...
-	rc = run_fwupdater_get_status(handle, hstc, sstc, &status);
-	if (!rc) {
-		if (status.status) {
-			LOG_ERR("Flashing failed, fw updater status %#x (errors: sub %#x, cksum %u, rram %u, crypto %d)\n",
-				status.status, status.suberror,
-				status.cksum_errors, status.rram_errors,
-				status.crypto_errors);
-			rc = status.status;
-		} else {
-			if (gstats_ss_rdy_timeouts + gstats_spi_errors +
-			    status.cksum_errors + status.rram_errors +
-			    status.crypto_errors) {
-				LOG_WARN(
-					"Flashing succeeded with errors (host %u, ss_rdy_timeout %u, QM %u, cksum %u, rram %u, crypto %d)\n",
-					gstats_spi_errors,
-					gstats_ss_rdy_timeouts,
-					status.spi_errors, status.cksum_errors,
-					status.rram_errors,
-					status.crypto_errors);
-			} else {
-				LOG_INFO(
-					"Flashing succeeded without any errors\n");
-			}
-		}
-	} else {
-		LOG_ERR("run_fwupdater_get_status returned %d\n", rc);
-	}
-exit_nomem:
-	if (rx)
-		qmrom_free(rx);
-	if (tx)
-		qmrom_free(tx);
-	return rc;
-}
diff --git a/libfwupdater/tests/comms_tests.c b/libfwupdater/tests/comms_tests.c
deleted file mode 100644
index 6ce3333..0000000
--- a/libfwupdater/tests/comms_tests.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#include <stddef.h>
-#include <qmrom_spi.h>
-#include <qmrom_log.h>
-#include <qmrom_utils.h>
-
-#include "unit_tests.h"
-
-void run_fwupdater_read_test(void *spi_handle)
-{
-	u_int8_t rx[MESSAGE_LEN];
-	u_int8_t tx_poll[STC_LEN] = { 0 };
-	u_int8_t tx[MESSAGE_LEN] = { 0x80, 0x00, MESSAGE_LEN - 4,
-				     0x00, 0x01, 0x02,
-				     0x03, 0x4,	 0x5,
-				     0x6,  0x7,	 0x8 };
-	qmrom_msleep(100);
-
-	qmrom_spi_wait_for_ready_line(spi_handle, 100);
-	qmrom_spi_transfer(spi_handle, rx, tx_poll, sizeof(tx_poll));
-	memset(rx, 0, sizeof(tx_poll));
-
-	for (int i = 0; i < NB_RX_MESSAGES; i++) {
-		qmrom_spi_wait_for_ready_line(spi_handle, 100);
-		qmrom_spi_transfer(spi_handle, rx, tx, sizeof(tx));
-		tx[4]++;
-		LOG_INFO("received:\n");
-		hexdump(LOG_INFO, rx, sizeof(rx));
-		memset(rx, 0, sizeof(rx));
-	}
-
-	LOG_INFO("%s done\n", __func__);
-}
-
-void run_fwupdater_write_test(void *spi_handle)
-{
-	u_int8_t rx[MESSAGE_LEN];
-	u_int8_t tx_prd[STC_LEN] = { 0x40, 0x00, 0x00, 0x00 };
-	u_int8_t tx[MESSAGE_LEN] = { 0x20, 0x00, MESSAGE_LEN - 4,
-				     0x00, 0x01, 0x02,
-				     0x03, 0x4,	 0x5,
-				     0x6,  0x7,	 0x8 };
-
-	for (int i = 0; i < NB_TX_MESSAGES; i++) {
-		qmrom_spi_wait_for_ready_line(spi_handle, 100);
-		qmrom_spi_transfer(spi_handle, rx, tx_prd, sizeof(tx_prd));
-		qmrom_spi_wait_for_ready_line(spi_handle, 100);
-		qmrom_spi_transfer(spi_handle, rx, tx, sizeof(tx));
-		tx[4]++;
-		LOG_INFO("received:\n");
-		hexdump(LOG_INFO, rx, sizeof(rx));
-		memset(rx, 0, sizeof(rx));
-	}
-
-	LOG_INFO("%s done\n", __func__);
-}
diff --git a/libfwupdater/tests/fwpkg_tests.c b/libfwupdater/tests/fwpkg_tests.c
deleted file mode 100644
index 035668a..0000000
--- a/libfwupdater/tests/fwpkg_tests.c
+++ /dev/null
@@ -1,94 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#include <stddef.h>
-#include <qmrom_spi.h>
-#include <qmrom_log.h>
-#include <qmrom_utils.h>
-
-#include <fwupdater.h>
-
-#include "unit_tests.h"
-
-#define PLD_CHK_PLD_SIZE 16
-#define PLD_CHK_TOTAL_SIZE \
-	(sizeof(struct fw_pkg_payload_chunk_t) + PLD_CHK_PLD_SIZE)
-
-void run_fwupdater_download_fwpkg_test(void *spi_handle)
-{
-	uint8_t rx[STC_LEN + sizeof(struct fw_pkg_hdr_t)] = { 0 };
-	uint8_t tx[STC_LEN + sizeof(struct fw_pkg_hdr_t)] = {
-		0x80, 0x00, sizeof(struct fw_pkg_hdr_t), 0x00
-	};
-	struct fw_pkg_hdr_t *fwpkg = (struct fw_pkg_hdr_t *)&tx[STC_LEN];
-
-	/* Setup the expected fw package */
-	fwpkg->magic = CRYPTO_FIRMWARE_PACK_MAGIC_VALUE;
-	fwpkg->version = CRYPTO_FIRMWARE_PACK_VERSION;
-	fwpkg->enc_mode = CRYPTO_FIRMWARE_PACK_ENC_MODE_ENCRYPTED;
-	fwpkg->package_type = CRYPTO_FIRMWARE_PACK_PACKAGE_TYPE_ICV;
-	fwpkg->enc_mode = CRYPTO_FIRMWARE_PACK_ENC_MODE_ENCRYPTED;
-	fwpkg->enc_algo = CRYPTO_FIRMWARE_PACK_ENC_ALGO_128BIT_AES_CTR;
-	strcpy((char *)fwpkg->enc_data, "encrypted data");
-	strcpy((char *)fwpkg->fw_version, "firmware version");
-	fwpkg->payload_len = 0xDEADBEEF;
-	strcpy((char *)fwpkg->tag, "AES-CMAC Tag");
-
-	qmrom_spi_wait_for_ready_line(spi_handle, 100);
-	qmrom_spi_transfer(spi_handle, (char *)rx, (char *)tx, sizeof(tx));
-	LOG_INFO("received:\n");
-	hexdump(LOG_INFO, rx, sizeof(tx));
-
-	LOG_INFO("%s done\n", __func__);
-}
-
-void run_fwupdater_download_img_hdr_test(void *spi_handle)
-{
-	char rx[STC_LEN + CRYPTO_FIRMWARE_IMAGE_HDR_TOTAL_SIZE] = { 0 };
-	char tx[STC_LEN + CRYPTO_FIRMWARE_IMAGE_HDR_TOTAL_SIZE] = {
-		(char)0x80, 0x00, CRYPTO_FIRMWARE_IMAGE_HDR_TOTAL_SIZE, 0x00
-	};
-	struct fw_pkg_img_hdr_t *imghdr =
-		(struct fw_pkg_img_hdr_t *)&tx[STC_LEN];
-
-	/* Setup the expected fw package */
-	imghdr->magic = CRYPTO_FIRMWARE_IMAGE_MAGIC_VALUE;
-	imghdr->version = CRYPTO_FIRMWARE_IMAGE_VERSION;
-	imghdr->cert_chain_length = CRYPTO_IMAGES_CERT_PKG_SIZE;
-	imghdr->cert_chain_offset = 0xDEADBEEF;
-	imghdr->num_descs = 1;
-	imghdr->descs[0].offset = 0xDEADBEEF;
-	imghdr->descs[0].length = 0xDEADBEEF;
-
-	qmrom_spi_wait_for_ready_line(spi_handle, 100);
-	qmrom_spi_transfer(spi_handle, rx, tx, sizeof(tx));
-	LOG_INFO("received:\n");
-	hexdump(LOG_INFO, rx, sizeof(tx));
-
-	LOG_INFO("%s done\n", __func__);
-}
-
-void run_fwupdater_download_pld_chk_test(void *spi_handle)
-{
-	char rx[STC_LEN + PLD_CHK_TOTAL_SIZE] = { 0 };
-	char tx[STC_LEN + PLD_CHK_TOTAL_SIZE] = { (char)0x80, 0x00,
-						  PLD_CHK_TOTAL_SIZE, 0x00 };
-	struct fw_pkg_payload_chunk_t *pldchk =
-		(struct fw_pkg_payload_chunk_t *)&tx[STC_LEN];
-
-	/* Setup the expected fw package */
-	pldchk->magic = CRYPTO_FIRMWARE_CHUNK_MAGIC_VALUE;
-	pldchk->version = CRYPTO_FIRMWARE_CHUNK_VERSION;
-	pldchk->length = PLD_CHK_PLD_SIZE;
-	strcpy((char *)pldchk->payload, "payload");
-
-	qmrom_spi_wait_for_ready_line(spi_handle, 100);
-	qmrom_spi_transfer(spi_handle, rx, tx, sizeof(tx));
-	LOG_INFO("received:\n");
-	hexdump(LOG_INFO, rx, sizeof(tx));
-
-	LOG_INFO("%s done\n", __func__);
-}
diff --git a/libfwupdater/tests/fwupdater_unit_tests.c b/libfwupdater/tests/fwupdater_unit_tests.c
deleted file mode 100644
index b17f4ac..0000000
--- a/libfwupdater/tests/fwupdater_unit_tests.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#include "unit_tests.h"
-
-void run_fwupdater_unit_tests(void *spi_handle)
-{
-	run_fwupdater_download_fwpkg_test(spi_handle);
-	run_fwupdater_download_img_hdr_test(spi_handle);
-	run_fwupdater_download_pld_chk_test(spi_handle);
-	run_fwupdater_read_test(spi_handle);
-	run_fwupdater_write_test(spi_handle);
-}
diff --git a/libfwupdater/tests/unit_tests.h b/libfwupdater/tests/unit_tests.h
deleted file mode 100644
index 78d0729..0000000
--- a/libfwupdater/tests/unit_tests.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2023 Qorvo US, Inc.
- *
- */
-
-#ifndef __UNITTESTS_H__
-#define __UNITTESTS_H__
-
-#define NB_RX_MESSAGES 5
-#define NB_TX_MESSAGES 5
-#define MESSAGE_LEN 16
-#define STC_LEN 4
-
-void run_fwupdater_read_test(void *spi_handle);
-void run_fwupdater_write_test(void *spi_handle);
-
-void run_fwupdater_download_fwpkg_test(void *spi_handle);
-void run_fwupdater_download_img_hdr_test(void *spi_handle);
-void run_fwupdater_download_pld_chk_test(void *spi_handle);
-
-#endif /* __UNITTESTS_H__ */
diff --git a/libqmrom/CMakeLists.txt b/libqmrom/CMakeLists.txt
index 7227f2d..3e11781 100644
--- a/libqmrom/CMakeLists.txt
+++ b/libqmrom/CMakeLists.txt
@@ -1,8 +1,8 @@
 set(SOURCES
-    src/qm357xx_rom_b0.c
-    src/qm357xx_rom_c0.c
-    src/qm357xx_rom_common.c
     src/qmrom_common.c
+    src/qmrom_a0.c
+    src/qmrom_b0.c
+    src/qmrom_c0.c
     src/qmrom_log.c
 )
 
diff --git a/libqmrom/include/qm357xx_fwpkg.h b/libqmrom/include/qm357xx_fwpkg.h
deleted file mode 100644
index 213baa0..0000000
--- a/libqmrom/include/qm357xx_fwpkg.h
+++ /dev/null
@@ -1,132 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2021 Qorvo US, Inc.
- *
- */
-
-#ifndef __QM357XX_FWPKG_H__
-#define __QM357XX_FWPKG_H__
-
-/* Pkg version word conversion macro */
-#define PKG_VER_TO_U32(maj, min) (((maj) << 16) | ((min) << 24))
-
-/* Pkg magic word conversion macro */
-#define MAGIC_STR_TO_U32(x) \
-	((uint32_t)(((x)[3]) | ((x)[2] << 8) | ((x)[1] << 16) | ((x)[0] << 24)))
-
-/* Package size defines */
-#define CRYPTO_FIRMWARE_PACK_ENC_DATA_SIZE 16
-#define CRYPTO_FIRMWARE_PACK_FW_VERSION_SIZE 32
-#define CRYPTO_FIRMWARE_PACK_TAG_SIZE 16
-
-/* Firmware image size define */
-#define CRYPTO_FW_PKG_IMG_HDR_IMG_NUM_MAX 8
-
-/* Field values for macro firmware package */
-#define CRYPTO_MACRO_FIRMWARE_PACK_MAGIC_VALUE MAGIC_STR_TO_U32("FWMP")
-
-/* Field values for firmware package */
-#define CRYPTO_FIRMWARE_PACK_MAGIC_VALUE MAGIC_STR_TO_U32("CFWP")
-#define CRYPTO_FIRMWARE_PACK_VERSION PKG_VER_TO_U32(1, 0)
-#define CRYPTO_FIRMWARE_PACK_ENC_MODE_NOT_ENCRYPTED 0x0
-#define CRYPTO_FIRMWARE_PACK_ENC_ALGO_128BIT_AES_CTR 0x00
-#define CRYPTO_FIRMWARE_PACK_ENC_KEY_L2_SIZE 64
-
-/* Field values for firmware image */
-#define CRYPTO_FIRMWARE_IMAGE_MAGIC_VALUE MAGIC_STR_TO_U32("IMGS")
-#define CRYPTO_FIRMWARE_IMAGE_VERSION PKG_VER_TO_U32(1, 0)
-
-/* Field values for firmware chunks */
-#define CRYPTO_FIRMWARE_CHUNK_MAGIC_VALUE MAGIC_STR_TO_U32("CFWC")
-#define CRYPTO_FIRMWARE_CHUNK_VERSION PKG_VER_TO_U32(1, 0)
-#define CRYPTO_FIRMWARE_CHUNK_MIN_SIZE 16
-
-/* fw certificate sizes */
-#define CRYPTO_IMAGES_CERT_KEY_SIZE 840
-#define CRYPTO_IMAGES_CERT_CONTENT_SIZE 868
-#define CRYPTO_IMAGES_CERT_PKG_SIZE \
-	(2 * CRYPTO_IMAGES_CERT_KEY_SIZE + CRYPTO_IMAGES_CERT_CONTENT_SIZE)
-#define CRYPTO_IMAGES_NB_CERTS 3
-#define CRYPTO_IMAGES_MAX_NB_IMAGES 8
-
-#define CRYPTO_FIRMWARE_IMAGE_HDR_TOTAL_SIZE \
-	(sizeof(struct fw_pkg_img_hdr_t) +   \
-	 CRYPTO_IMAGES_NB_CERTS * sizeof(struct fw_img_desc_t))
-
-/* Encryption mode enum. */
-enum fw_pkg_enc_mode_e {
-	CRYPTO_FIRMWARE_PACK_ENC_MODE_NONE,
-	CRYPTO_FIRMWARE_PACK_ENC_MODE_ENCRYPTED
-};
-
-/* Package type enum. */
-enum fw_pkg_package_type_e {
-	CRYPTO_FIRMWARE_PACK_PACKAGE_TYPE_ICV = 0x01,
-	CRYPTO_FIRMWARE_PACK_PACKAGE_TYPE_OEM = 0x02
-};
-
-/* IV type enum. */
-enum fw_pkg_iv_type_e {
-	CRYPTO_FIRMWARE_PACK_IV_TYPE_HDR,
-	CRYPTO_FIRMWARE_PACK_IV_TYPE_IMG
-};
-
-/* Firmware Package Header fields */
-struct fw_pkg_hdr_t {
-	uint32_t magic; /**< Magic number. */
-	uint32_t version; /**< Version. */
-	uint8_t package_type; /**< Package type. */
-	uint8_t enc_mode; /**< Encryption mode. */
-	uint8_t enc_algo; /**< Encryption algorithm. */
-	uint8_t reserved; /**< Reserved for alignment. */
-	uint8_t enc_data
-		[CRYPTO_FIRMWARE_PACK_ENC_DATA_SIZE]; /**< Encryption data. */
-	uint8_t enc_key_l2
-		[CRYPTO_FIRMWARE_PACK_ENC_KEY_L2_SIZE]; /**< Code encryption L2 key data. */
-	uint8_t fw_version
-		[CRYPTO_FIRMWARE_PACK_FW_VERSION_SIZE]; /**< Firmware version included in the package. */
-	uint32_t payload_len; /**< Payload length. */
-	uint8_t tag[CRYPTO_FIRMWARE_PACK_TAG_SIZE]; /**< AES-CMAC Tag. */
-} __attribute__((packed));
-
-/* Firmware Image Metadata fields */
-struct fw_img_desc_t {
-	uint32_t offset; /**< Offset. */
-	uint32_t length; /**< Length. */
-} __attribute__((packed));
-
-/* Firmware Image Header fields */
-struct fw_pkg_img_hdr_t {
-	uint32_t magic; /**< Magic number. */
-	uint32_t version; /**< Version number. */
-	uint32_t cert_chain_offset; /**< Certificate chain offset. */
-	uint16_t cert_chain_length; /**< Certificate chain length. */
-	uint8_t num_descs; /**< Number of images descriptors. */
-	uint8_t reserved; /**< Reserved data. */
-	struct fw_img_desc_t descs
-		[CRYPTO_FW_PKG_IMG_HDR_IMG_NUM_MAX]; /**< Firmware image metadata. */
-} __attribute__((packed));
-
-/* Firmware Chunk fields */
-struct fw_pkg_payload_chunk_t {
-	uint32_t magic; /**< Magic number. */
-	uint32_t version; /**< Version number. */
-	uint32_t length; /**< Length. */
-	uint8_t payload[]; /**< Payload data pointer. */
-} __attribute__((packed));
-
-/* Firmware Macro Package Header fields */
-struct fw_macro_pkg_hdr_t {
-	uint32_t magic; /**< Magic number. */
-	uint32_t version; /**< Version. */
-	uint8_t nb_descriptors;
-	uint8_t reserved[3];
-	struct fw_img_desc_t img_desc[];
-} __attribute__((packed));
-
-#define MACRO_PKG_HASH_SIZE (32)
-#define COMPUTE_FW_MACRO_PKG_HDR_SIZE(ndescs) \
-	(sizeof(struct fw_macro_pkg_hdr_t) +  \
-	 ndescs * sizeof(struct fw_img_desc_t) + MACRO_PKG_HASH_SIZE)
-
-#endif /* __QM357XX_FWPKG_H__ */
diff --git a/libqmrom/include/qm357xx_rom.h b/libqmrom/include/qm357xx_rom.h
deleted file mode 100644
index 9592004..0000000
--- a/libqmrom/include/qm357xx_rom.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2021 Qorvo US, Inc.
- *
- */
-
-#ifndef __QM357XX_ROM_H__
-#define __QM357XX_ROM_H__
-
-#define PEG_ERR_TIMEOUT PEG_ERR_BASE - 1
-#define PEG_ERR_ROM_NOT_READY PEG_ERR_BASE - 2
-#define PEG_ERR_SEND_CERT_WRITE PEG_ERR_BASE - 3
-#define PEG_ERR_WRONG_REVISION PEG_ERR_BASE - 4
-#define PEG_ERR_FIRST_KEY_CERT_OR_FW_VER PEG_ERR_BASE - 5
-
-#define HBK_LOC 12
-typedef enum {
-	HBK_2E_ICV,
-	HBK_2E_OEM,
-	HBK_1E_ICV_OEM,
-} hbk_t;
-
-#define ROM_VERSION_A0 0x01a0
-#define ROM_VERSION_B0 0xb000
-
-#define QM357XX_ROM_SOC_ID_LEN 0x20
-#define QM357XX_ROM_UUID_LEN 0x10
-
-/* Life cycle state definitions. */
-
-/*! Defines the CM life-cycle state value. */
-#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0
-/*! Defines the DM life-cycle state value. */
-#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1
-/*! Defines the Secure life-cycle state value. */
-#define CC_BSV_SECURE_LCS 0x5
-/*! Defines the RMA life-cycle state value. */
-#define CC_BSV_RMA_LCS 0x7
-
-struct unstitched_firmware {
-	struct firmware *fw_img;
-	struct firmware *fw_crt;
-	struct firmware *key1_crt;
-	struct firmware *key2_crt;
-};
-
-/* Those functions allow the libqmrom to call
- * revision specific functions
- */
-typedef int (*flash_fw_fn)(struct qmrom_handle *handle,
-			   const struct firmware *fw);
-typedef int (*flash_unstitched_fw_fn)(struct qmrom_handle *handle,
-				      const struct unstitched_firmware *fw);
-typedef int (*flash_debug_cert_fn)(struct qmrom_handle *handle,
-				   struct firmware *dbg_cert);
-typedef int (*erase_debug_cert_fn)(struct qmrom_handle *handle);
-
-struct qm357xx_rom_code_ops {
-	flash_fw_fn flash_fw;
-	flash_unstitched_fw_fn flash_unstitched_fw;
-	flash_debug_cert_fn flash_debug_cert;
-	erase_debug_cert_fn erase_debug_cert;
-};
-
-struct qm357xx_soc_infos {
-	uint8_t soc_id[QM357XX_ROM_SOC_ID_LEN];
-	uint8_t uuid[QM357XX_ROM_UUID_LEN];
-	uint32_t lcs_state;
-};
-
-int qm357xx_rom_unstitch_fw(const struct firmware *fw,
-			    struct unstitched_firmware *unstitched_fw,
-			    enum chip_revision_e revision);
-int qm357xx_rom_fw_macro_pkg_get_fw_idx(const struct firmware *fw, int idx,
-					uint32_t *fw_size, char **fw_fata);
-int qm357xx_rom_unpack_fw_macro_pkg(const struct firmware *fw,
-				    struct unstitched_firmware *all_fws);
-int qm357xx_rom_unpack_fw_pkg(const struct firmware *fw_pkg,
-			      struct unstitched_firmware *all_fws);
-int qm357xx_rom_flash_dbg_cert(struct qmrom_handle *handle,
-			       struct firmware *dbg_cert);
-int qm357xx_rom_erase_dbg_cert(struct qmrom_handle *handle);
-int qm357xx_rom_flash_fw(struct qmrom_handle *handle,
-			 const struct firmware *fw);
-int qm357xx_rom_flash_unstitched_fw(struct qmrom_handle *handle,
-				    const struct unstitched_firmware *fw);
-
-int qm357xx_rom_write_cmd(struct qmrom_handle *handle, uint8_t cmd);
-int qm357xx_rom_write_cmd32(struct qmrom_handle *handle, uint32_t cmd);
-int qm357xx_rom_write_size_cmd(struct qmrom_handle *handle, uint8_t cmd,
-			       uint16_t data_size, const char *data);
-int qm357xx_rom_write_size_cmd32(struct qmrom_handle *handle, uint32_t cmd,
-				 uint16_t data_size, const char *data);
-
-#endif /* __QM357XX_ROM_H__ */
diff --git a/libqmrom/include/qmrom.h b/libqmrom/include/qmrom.h
index 226b7f4..c403ed1 100644
--- a/libqmrom/include/qmrom.h
+++ b/libqmrom/include/qmrom.h
@@ -28,19 +28,54 @@
 
 #undef CHECK_STCS
 
+#define PEG_ERR_TIMEOUT PEG_ERR_BASE - 1
+#define PEG_ERR_ROM_NOT_READY PEG_ERR_BASE - 2
+#define PEG_ERR_SEND_CERT_WRITE PEG_ERR_BASE - 3
+#define PEG_ERR_WRONG_REVISION PEG_ERR_BASE - 4
+#define PEG_ERR_FIRST_KEY_CERT_OR_FW_VER PEG_ERR_BASE - 5
+
 enum chip_revision_e {
 	CHIP_REVISION_A0 = 0xA0,
 	CHIP_REVISION_B0 = 0xB0,
 	CHIP_REVISION_C0 = 0xC0,
-	CHIP_REVISION_C2 = 0xC2,
 	CHIP_REVISION_UNKNOWN = 0xFF
 };
 
-enum device_generation_e { DEVICE_GEN_QM357XX, DEVICE_GEN_UNKNOWN = 0xFF };
+#define HBK_LOC 12
+typedef enum {
+	HBK_2E_ICV = 0,
+	HBK_2E_OEM = 1,
+	HBK_1E_ICV_OEM = 2,
+} hbk_t;
+
+#define ROM_VERSION_A0 0x01a0
+#define ROM_VERSION_B0 0xb000
+
+#define ROM_SOC_ID_LEN 0x20
+#define ROM_UUID_LEN 0x10
+
+/* Life cycle state definitions. */
+
+/*! Defines the CM life-cycle state value. */
+#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0
+/*! Defines the DM life-cycle state value. */
+#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1
+/*! Defines the Secure life-cycle state value. */
+#define CC_BSV_SECURE_LCS 0x5
+/*! Defines the RMA life-cycle state value. */
+#define CC_BSV_RMA_LCS 0x7
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
 
 struct qmrom_handle;
 
-#include <qm357xx_rom.h>
+struct unstitched_firmware {
+	struct firmware *fw_img;
+	struct firmware *fw_crt;
+	struct firmware *key1_crt;
+	struct firmware *key2_crt;
+};
 
 #define SSTC2UINT32(handle, offset)                                      \
 	({                                                               \
@@ -61,6 +96,24 @@
 	})
 
 /* Those functions allow the libqmrom to call
+ * revision specific functions
+ */
+typedef int (*flash_fw_fn)(struct qmrom_handle *handle,
+			   const struct firmware *fw);
+typedef int (*flash_unstitched_fw_fn)(struct qmrom_handle *handle,
+				      const struct unstitched_firmware *fw);
+typedef int (*flash_debug_cert_fn)(struct qmrom_handle *handle,
+				   struct firmware *dbg_cert);
+typedef int (*erase_debug_cert_fn)(struct qmrom_handle *handle);
+
+struct rom_code_ops {
+	flash_fw_fn flash_fw;
+	flash_unstitched_fw_fn flash_unstitched_fw;
+	flash_debug_cert_fn flash_debug_cert;
+	erase_debug_cert_fn erase_debug_cert;
+};
+
+/* Those functions allow the libqmrom to call
  * device specific functions
  */
 typedef int (*reset_device_fn)(void *handle);
@@ -73,30 +126,42 @@
 	void *spi_handle;
 	void *reset_handle;
 	void *ss_rdy_handle;
-	void *ss_irq_handle;
 	int comms_retries;
-	enum device_generation_e dev_gen;
 	enum chip_revision_e chip_rev;
 	uint16_t device_version;
 	struct device_ops dev_ops;
-	int spi_speed;
-	struct qm357xx_rom_code_ops qm357xx_rom_ops;
+	struct rom_code_ops rom_ops;
+	uint32_t lcs_state;
 	struct stc *hstc;
 	struct stc *sstc;
-	struct qm357xx_soc_infos qm357xx_soc_info;
+	uint8_t soc_id[ROM_SOC_ID_LEN];
+	uint8_t uuid[ROM_UUID_LEN];
 	bool is_be;
 };
 
+int qmrom_unstitch_fw(const struct firmware *fw,
+		      struct unstitched_firmware *unstitched_fw,
+		      enum chip_revision_e revision);
 struct qmrom_handle *qmrom_init(void *spi_handle, void *reset_handle,
-				void *ss_rdy_handle, void *ss_irq_handle,
-				int spi_speed, int comms_retries,
-				reset_device_fn reset,
-				enum device_generation_e dev_gen_hint);
+				void *ss_rdy_handle, int comms_retries,
+				reset_device_fn reset);
 void qmrom_deinit(struct qmrom_handle *handle);
 int qmrom_reboot_bootloader(struct qmrom_handle *handle);
+int qmrom_flash_dbg_cert(struct qmrom_handle *handle,
+			 struct firmware *dbg_cert);
+int qmrom_erase_dbg_cert(struct qmrom_handle *handle);
+int qmrom_flash_fw(struct qmrom_handle *handle, const struct firmware *fw);
+int qmrom_flash_unstitched_fw(struct qmrom_handle *handle,
+			      const struct unstitched_firmware *fw);
 
 int qmrom_pre_read(struct qmrom_handle *handle);
 int qmrom_read(struct qmrom_handle *handle);
+int qmrom_write_cmd(struct qmrom_handle *handle, uint8_t cmd);
+int qmrom_write_cmd32(struct qmrom_handle *handle, uint32_t cmd);
+int qmrom_write_size_cmd(struct qmrom_handle *handle, uint8_t cmd,
+			 uint16_t data_size, const char *data);
+int qmrom_write_size_cmd32(struct qmrom_handle *handle, uint32_t cmd,
+			   uint16_t data_size, const char *data);
 
 #ifdef CHECK_STCS
 void check_stcs(const char *func, int line, struct qmrom_handle *h);
diff --git a/libqmrom/include/qmrom_spi.h b/libqmrom/include/qmrom_spi.h
index c94e544..c3d8c92 100644
--- a/libqmrom/include/qmrom_spi.h
+++ b/libqmrom/include/qmrom_spi.h
@@ -50,13 +50,9 @@
 int qmrom_spi_reset_device(void *reset_handle);
 const struct firmware *qmrom_spi_get_firmware(void *handle,
 					      struct qmrom_handle *qmrom_h,
-					      bool *is_fw_updater,
 					      bool use_prod_fw);
-const struct firmware *qmrom_spi_get_firmware_package(void *handle,
-						      int lcs_state);
 void qmrom_spi_release_firmware(const struct firmware *fw);
 int qmrom_spi_wait_for_ready_line(void *handle, unsigned int timeout_ms);
-int qmrom_spi_read_irq_line(void *handle);
 void qmrom_spi_set_freq(unsigned int freq);
 unsigned int qmrom_spi_get_freq(void);
 
diff --git a/libqmrom/include/qmrom_utils.h b/libqmrom/include/qmrom_utils.h
index 7533194..06ece2a 100644
--- a/libqmrom/include/qmrom_utils.h
+++ b/libqmrom/include/qmrom_utils.h
@@ -31,26 +31,21 @@
 	} while (0)
 
 #define qmrom_free free
-
-#define qmrom_data_dma_able(d) true
 #else
 
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/mm.h>
 
 #define qmrom_msleep(ms)                            \
 	do {                                        \
 		usleep_range(ms * 1000, ms * 1000); \
 	} while (0)
 
-#define qmrom_alloc(ptr, size)                             \
-	do {                                               \
-		ptr = kzalloc(size, GFP_KERNEL | GFP_DMA); \
+#define qmrom_alloc(ptr, size)                   \
+	do {                                     \
+		ptr = kzalloc(size, GFP_KERNEL); \
 	} while (0)
 
 #define qmrom_free kfree
-
-#define qmrom_data_dma_able(d) !is_vmalloc_addr(d)
 #endif
 #endif /* __QMROM_UTILS_H__ */
diff --git a/libqmrom/src/qm357xx_rom_common.c b/libqmrom/src/qm357xx_rom_common.c
deleted file mode 100644
index 051cc3d..0000000
--- a/libqmrom/src/qm357xx_rom_common.c
+++ /dev/null
@@ -1,414 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
-/*
- * Copyright 2022 Qorvo US, Inc.
- *
- */
-
-#include <qmrom_utils.h>
-#include <qmrom_log.h>
-#include <qmrom_spi.h>
-#include <qmrom.h>
-#include <spi_rom_protocol.h>
-
-#include <qm357xx_fwpkg.h>
-
-int qm357xx_rom_b0_probe_device(struct qmrom_handle *handle);
-int qm357xx_rom_c0_probe_device(struct qmrom_handle *handle);
-
-int qm357xx_rom_write_cmd(struct qmrom_handle *handle, uint8_t cmd)
-{
-	handle->hstc->all = 0;
-	handle->hstc->host_flags.write = 1;
-	handle->hstc->ul = 1;
-	handle->hstc->len = 1;
-	handle->hstc->payload[0] = cmd;
-
-	return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
-				  (const char *)handle->hstc,
-				  sizeof(struct stc) + handle->hstc->len);
-}
-
-int qm357xx_rom_write_cmd32(struct qmrom_handle *handle, uint32_t cmd)
-{
-	handle->hstc->all = 0;
-	handle->hstc->host_flags.write = 1;
-	handle->hstc->ul = 1;
-	handle->hstc->len = sizeof(cmd);
-	memcpy(handle->hstc->payload, &cmd, sizeof(cmd));
-
-	return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
-				  (const char *)handle->hstc,
-				  sizeof(struct stc) + handle->hstc->len);
-}
-
-int qm357xx_rom_write_size_cmd(struct qmrom_handle *handle, uint8_t cmd,
-			       uint16_t data_size, const char *data)
-{
-	handle->hstc->all = 0;
-	handle->hstc->host_flags.write = 1;
-	handle->hstc->ul = 1;
-	handle->hstc->len = data_size + 1;
-	handle->hstc->payload[0] = cmd;
-	memcpy(&handle->hstc->payload[1], data, data_size);
-
-	return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
-				  (const char *)handle->hstc,
-				  sizeof(struct stc) + handle->hstc->len);
-}
-
-int qm357xx_rom_write_size_cmd32(struct qmrom_handle *handle, uint32_t cmd,
-				 uint16_t data_size, const char *data)
-{
-	handle->hstc->all = 0;
-	handle->hstc->host_flags.write = 1;
-	handle->hstc->ul = 1;
-	handle->hstc->len = data_size + sizeof(cmd);
-	memcpy(handle->hstc->payload, &cmd, sizeof(cmd));
-	memcpy(&handle->hstc->payload[sizeof(cmd)], data, data_size);
-
-	return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
-				  (const char *)handle->hstc,
-				  sizeof(struct stc) + handle->hstc->len);
-}
-
-/*
- * Unfortunately, B0 and C0 have different
- * APIs to get the chip version...
- *
- */
-int qm357xx_rom_probe_device(struct qmrom_handle *handle)
-{
-	int rc;
-
-	/* Test C0 first */
-	rc = qm357xx_rom_c0_probe_device(handle);
-	if (!rc)
-		return rc;
-
-	/* Test B0 next */
-	rc = qm357xx_rom_b0_probe_device(handle);
-	if (!rc)
-		return rc;
-
-	/* None matched!!! */
-	return -1;
-}
-
-int qm357xx_rom_flash_dbg_cert(struct qmrom_handle *handle,
-			       struct firmware *dbg_cert)
-{
-	if (!handle->qm357xx_rom_ops.flash_debug_cert) {
-		LOG_ERR("%s: flash debug certificate not support on this device\n",
-			__func__);
-		return -EINVAL;
-	}
-	return handle->qm357xx_rom_ops.flash_debug_cert(handle, dbg_cert);
-}
-
-int qm357xx_rom_erase_dbg_cert(struct qmrom_handle *handle)
-{
-	if (!handle->qm357xx_rom_ops.erase_debug_cert) {
-		LOG_ERR("%s: erase debug certificate not support on this device\n",
-			__func__);
-		return -EINVAL;
-	}
-	return handle->qm357xx_rom_ops.erase_debug_cert(handle);
-}
-
-int qm357xx_rom_flash_fw(struct qmrom_handle *handle, const struct firmware *fw)
-{
-	int rc = 0;
-	struct unstitched_firmware all_fws = { 0 };
-
-	if (*(uint32_t *)&fw->data[0] ==
-	    CRYPTO_MACRO_FIRMWARE_PACK_MAGIC_VALUE) {
-		//macro package detected
-		//write the FW UPDATER
-		rc = qm357xx_rom_unpack_fw_macro_pkg(fw, &all_fws);
-		if (rc) {
-			LOG_ERR("%s: Unpack macro FW package unsuccessful!\n",
-				__func__);
-			return rc;
-		}
-	} else {
-		rc = qm357xx_rom_unstitch_fw(fw, &all_fws, handle->chip_rev);
-		if (rc) {
-			LOG_ERR("%s: Unstitched fw flashing not supported yet\n",
-				__func__);
-			return rc;
-		}
-	}
-	rc = qm357xx_rom_flash_unstitched_fw(handle, &all_fws);
-	return rc;
-}
-
-int qm357xx_rom_flash_unstitched_fw(struct qmrom_handle *handle,
-				    const struct unstitched_firmware *fw)
-{
-	if (!handle->qm357xx_rom_ops.flash_unstitched_fw) {
-		LOG_ERR("%s: flash un-stitched firmware not supported on this device\n",
-			__func__);
-		return -EINVAL;
-	}
-	return handle->qm357xx_rom_ops.flash_unstitched_fw(handle, fw);
-}
-
-int qm357xx_rom_unstitch_fw(const struct firmware *fw,
-			    struct unstitched_firmware *unstitched_fw,
-			    enum chip_revision_e revision)
-{
-	uint32_t tot_len = 0;
-	uint32_t fw_img_sz = 0;
-	uint32_t fw_crt_sz = 0;
-	uint32_t key1_crt_sz = 0;
-	uint32_t key2_crt_sz = 0;
-	uint8_t *p_key1;
-	uint8_t *p_key2;
-	uint8_t *p_crt;
-	uint8_t *p_fw;
-	int ret = 0;
-
-	if (fw->size < 2 * sizeof(key1_crt_sz)) {
-		LOG_ERR("%s: Not enough data (%zu) to unstitch\n", __func__,
-			fw->size);
-		return -EINVAL;
-	}
-	LOG_INFO("%s: Unstitching %zu bytes\n", __func__, fw->size);
-
-	/* key1 */
-	key1_crt_sz = *(uint32_t *)&fw->data[tot_len];
-	if (tot_len + key1_crt_sz + sizeof(key1_crt_sz) + sizeof(key2_crt_sz) >
-	    fw->size) {
-		LOG_ERR("%s: Invalid or corrupted stitched file at offset \
-				%" PRIu32 " (key1)\n",
-			__func__, tot_len);
-		ret = -EINVAL;
-		goto out;
-	}
-	tot_len += sizeof(key1_crt_sz);
-	p_key1 = (uint8_t *)&fw->data[tot_len];
-	tot_len += key1_crt_sz;
-
-	/* key2 */
-	key2_crt_sz = *(uint32_t *)&fw->data[tot_len];
-	if (tot_len + key2_crt_sz + sizeof(key2_crt_sz) + sizeof(fw_crt_sz) >
-	    fw->size) {
-		LOG_ERR("%s: Invalid or corrupted stitched file at offset \
-				%" PRIu32 " (key2)\n",
-			__func__, tot_len);
-		ret = -EINVAL;
-		goto out;
-	}
-	tot_len += sizeof(key2_crt_sz);
-	p_key2 = (uint8_t *)&fw->data[tot_len];
-	tot_len += key2_crt_sz;
-
-	/* cert */
-	fw_crt_sz = *(uint32_t *)&fw->data[tot_len];
-	if (tot_len + fw_crt_sz + sizeof(fw_crt_sz) + sizeof(fw_img_sz) >
-	    fw->size) {
-		LOG_ERR("%s: Invalid or corrupted stitched file at offset \
-				%" PRIu32 " (content cert)\n",
-			__func__, tot_len);
-		ret = -EINVAL;
-		goto out;
-	}
-	tot_len += sizeof(fw_crt_sz);
-	p_crt = (uint8_t *)&fw->data[tot_len];
-	tot_len += fw_crt_sz;
-
-	/* fw */
-	fw_img_sz = *(uint32_t *)&fw->data[tot_len];
-	if (tot_len + fw_img_sz + sizeof(fw_img_sz) != fw->size) {
-		LOG_ERR("%s: Invalid or corrupted stitched file at offset \
-				%" PRIu32 " (firmware)\n",
-			__func__, tot_len);
-		ret = -EINVAL;
-		goto out;
-	}
-	tot_len += sizeof(fw_img_sz);
-	p_fw = (uint8_t *)&fw->data[tot_len];
-
-	qmrom_alloc(unstitched_fw->fw_img, fw_img_sz + sizeof(struct firmware));
-	if (unstitched_fw->fw_img == NULL) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	qmrom_alloc(unstitched_fw->fw_crt, fw_crt_sz + sizeof(struct firmware));
-	if (unstitched_fw->fw_crt == NULL) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	qmrom_alloc(unstitched_fw->key1_crt,
-		    key1_crt_sz + sizeof(struct firmware));
-	if (unstitched_fw->key1_crt == NULL) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	qmrom_alloc(unstitched_fw->key2_crt,
-		    key2_crt_sz + sizeof(struct firmware));
-	if (unstitched_fw->key2_crt == NULL) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	unstitched_fw->key1_crt->data =
-		(const uint8_t *)(unstitched_fw->key1_crt + 1);
-	unstitched_fw->key2_crt->data =
-		(const uint8_t *)(unstitched_fw->key2_crt + 1);
-	unstitched_fw->fw_crt->data =
-		(const uint8_t *)(unstitched_fw->fw_crt + 1);
-	unstitched_fw->fw_img->data =
-		(const uint8_t *)(unstitched_fw->fw_img + 1);
-	unstitched_fw->key1_crt->size = key1_crt_sz;
-	unstitched_fw->key2_crt->size = key2_crt_sz;
-	unstitched_fw->fw_crt->size = fw_crt_sz;
-	unstitched_fw->fw_img->size = fw_img_sz;
-
-	memcpy((void *)unstitched_fw->key1_crt->data, p_key1, key1_crt_sz);
-	memcpy((void *)unstitched_fw->key2_crt->data, p_key2, key2_crt_sz);
-	memcpy((void *)unstitched_fw->fw_crt->data, p_crt, fw_crt_sz);
-	memcpy((void *)unstitched_fw->fw_img->data, p_fw, fw_img_sz);
-	return 0;
-
-err:
-	if (unstitched_fw->fw_img)
-		qmrom_free(unstitched_fw->fw_img);
-	if (unstitched_fw->fw_crt)
-		qmrom_free(unstitched_fw->fw_crt);
-	if (unstitched_fw->key1_crt)
-		qmrom_free(unstitched_fw->key1_crt);
-	if (unstitched_fw->key2_crt)
-		qmrom_free(unstitched_fw->key2_crt);
-
-out:
-	return ret;
-}
-
-int qm357xx_rom_fw_macro_pkg_get_fw_idx(const struct firmware *fw, int idx,
-					uint32_t *fw_size, char **fw_data)
-{
-	struct fw_macro_pkg_hdr_t *fw_macro_pkg_hdr =
-		(struct fw_macro_pkg_hdr_t *)fw->data;
-	struct fw_img_desc_t *fw_pkg;
-
-	if (fw_macro_pkg_hdr->nb_descriptors >= 1 &&
-	    idx < fw_macro_pkg_hdr->nb_descriptors) {
-		fw_pkg = &fw_macro_pkg_hdr->img_desc[idx];
-		if (fw_pkg->offset + fw_pkg->length > fw->size) {
-			LOG_ERR("Wrong FW PKG offset = %04x; len = %04x; idx = %d!\n",
-				fw_pkg->offset, fw_pkg->length, idx);
-			return -EINVAL;
-		}
-	} else {
-		LOG_ERR("%s: No FW pkg found in macro package! nb_descriptors = %d\n",
-			__func__, fw_macro_pkg_hdr->nb_descriptors);
-		return -EINVAL;
-	}
-	*fw_size = fw_pkg->length;
-	*fw_data = (char *)&fw->data[fw_pkg->offset];
-	return 0;
-}
-
-int qm357xx_rom_unpack_fw_macro_pkg(const struct firmware *fw,
-				    struct unstitched_firmware *all_fws)
-{
-	int rc = 0;
-	char *fw_data;
-	uint32_t fw_size;
-	struct firmware fw_pkg;
-
-	rc = qm357xx_rom_fw_macro_pkg_get_fw_idx(fw, 0, &fw_size, &fw_data);
-	if (rc) {
-		LOG_ERR("%s: FW MACRO PACKAGE corrupted = %d\n", __func__, rc);
-		return rc;
-	}
-
-	fw_pkg.data = (const uint8_t *)fw_data;
-	fw_pkg.size = fw_size;
-	return qm357xx_rom_unpack_fw_pkg(&fw_pkg, all_fws);
-}
-
-int qm357xx_rom_unpack_fw_pkg(const struct firmware *fw_pkg,
-			      struct unstitched_firmware *all_fws)
-{
-	int rc = 0;
-	uint8_t *p_key1;
-	uint8_t *p_key2;
-	uint8_t *p_crt;
-	uint8_t *p_fw;
-	struct fw_pkg_img_hdr_t *fw_pkg_img_hdr;
-
-	fw_pkg_img_hdr =
-		(struct fw_pkg_img_hdr_t *)(fw_pkg->data +
-					    sizeof(struct fw_pkg_hdr_t));
-
-	if (fw_pkg_img_hdr->magic != CRYPTO_FIRMWARE_IMAGE_MAGIC_VALUE) {
-		LOG_ERR("%s: Invalid or corrupted file! magic = %04x\n",
-			__func__, fw_pkg_img_hdr->magic);
-		return -EINVAL;
-	}
-	qmrom_alloc(all_fws->fw_img,
-		    fw_pkg_img_hdr->descs[0].length + sizeof(struct firmware));
-	if (all_fws->fw_img == NULL) {
-		rc = -ENOMEM;
-		goto err;
-	}
-	qmrom_alloc(all_fws->key1_crt,
-		    CRYPTO_IMAGES_CERT_KEY_SIZE + sizeof(struct firmware));
-	if (all_fws->key1_crt == NULL) {
-		rc = -ENOMEM;
-		goto err;
-	}
-
-	qmrom_alloc(all_fws->key2_crt,
-		    CRYPTO_IMAGES_CERT_KEY_SIZE + sizeof(struct firmware));
-	if (all_fws->key2_crt == NULL) {
-		rc = -ENOMEM;
-		goto err;
-	}
-
-	qmrom_alloc(all_fws->fw_crt,
-		    CRYPTO_IMAGES_CERT_CONTENT_SIZE + sizeof(struct firmware));
-	if (all_fws->fw_crt == NULL) {
-		rc = -ENOMEM;
-		goto err;
-	}
-
-	all_fws->key1_crt->data = (const uint8_t *)(all_fws->key1_crt + 1);
-	all_fws->key2_crt->data = (const uint8_t *)(all_fws->key2_crt + 1);
-	all_fws->fw_crt->data = (const uint8_t *)(all_fws->fw_crt + 1);
-	all_fws->fw_img->data = (const uint8_t *)(all_fws->fw_img + 1);
-	all_fws->key1_crt->size = CRYPTO_IMAGES_CERT_KEY_SIZE;
-	all_fws->key2_crt->size = CRYPTO_IMAGES_CERT_KEY_SIZE;
-	all_fws->fw_crt->size = CRYPTO_IMAGES_CERT_CONTENT_SIZE;
-	all_fws->fw_img->size = fw_pkg_img_hdr->descs[0].length;
-
-	p_key1 = (uint8_t *)fw_pkg_img_hdr + fw_pkg_img_hdr->cert_chain_offset;
-	p_key2 = p_key1 + CRYPTO_IMAGES_CERT_KEY_SIZE;
-	p_crt = p_key2 + CRYPTO_IMAGES_CERT_KEY_SIZE;
-	p_fw = (uint8_t *)fw_pkg_img_hdr + fw_pkg_img_hdr->descs[0].offset;
-
-	memcpy((void *)all_fws->key1_crt->data, p_key1,
-	       all_fws->key1_crt->size);
-	memcpy((void *)all_fws->key2_crt->data, p_key2,
-	       all_fws->key2_crt->size);
-	memcpy((void *)all_fws->fw_crt->data, p_crt, all_fws->fw_crt->size);
-	memcpy((void *)all_fws->fw_img->data, p_fw, all_fws->fw_img->size);
-	return 0;
-
-err:
-	if (all_fws->fw_img)
-		qmrom_free(all_fws->fw_img);
-	if (all_fws->fw_crt)
-		qmrom_free(all_fws->fw_crt);
-	if (all_fws->key1_crt)
-		qmrom_free(all_fws->key1_crt);
-	if (all_fws->key2_crt)
-		qmrom_free(all_fws->key2_crt);
-
-	return rc;
-}
diff --git a/libqmrom/src/qmrom_a0.c b/libqmrom/src/qmrom_a0.c
new file mode 100644
index 0000000..ce75612
--- /dev/null
+++ b/libqmrom/src/qmrom_a0.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0 OR Apache-2.0
+/*
+ * Copyright 2022 Qorvo US, Inc.
+ *
+ */
+
+#include <qmrom.h>
+#include <qmrom_spi.h>
+#include <qmrom_log.h>
+#include <qmrom_utils.h>
+#include <spi_rom_protocol.h>
+
+#define DEFAULT_SPI_CLOCKRATE 750000
+#define CHIP_VERSION_CHIP_REV_PAYLOAD_OFFSET 1
+#define CHUNK_SIZE_A0 1016
+
+enum A0_CMD {
+	ROM_CMD_A0_GET_CHIP_VER = 0x0,
+	ROM_CMD_A0_DOWNLOAD_RRAM_CMD = 0x40,
+};
+
+enum A0_RESP {
+	/* Waiting for download command */
+	SPI_RSP_WAIT_DOWNLOAD_MODE = 1,
+	SPI_RSP_WAIT_FOR_KEY1_CERT,
+	SPI_RSP_WAIT_FOR_KEY2_CERT,
+	SPI_RSP_WAIT_FOR_IMAGE_CERT,
+	SPI_RSP_WAIT_IMAGE_SIZE,
+	SPI_RSP_WAIT_FOR_IMAGE,
+	SPI_RSP_DOWNLOAD_OK,
+	SPI_RSP_BOOT_OK,
+	/* Checksum/CRC error */
+	SPI_RSP_ERROR_CS,
+	/* Got error certificate RSA/FW ver. Didn't get
+	 * all the data before switching to image...
+	 */
+	SPI_RSP_ERROR_CERTIFICATE,
+	/* Got command smaller than SPI_HEADER_SIZE.
+	 * Each command must be at least this size.
+	 */
+	SPI_RSP_CMD_TOO_SHORT,
+	/* Error checking certificates or image, going
+	 * to download mode.
+	 */
+	SPI_RSP_ERROR_LOADING_IN_DOWNLOAD,
+};
+
+static int qmrom_a0_flash_fw(struct qmrom_handle *handle,
+			     const struct firmware *fw);
+
+void qmrom_a0_poll_soc(struct qmrom_handle *handle)
+{
+	int retries = handle->comms_retries;
+	handle->hstc->all = 0;
+	qmrom_msleep(SPI_READY_TIMEOUT_MS);
+	do {
+		qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+				   (const char *)handle->hstc, 1);
+	} while (retries-- && handle->sstc->raw_flags == 0);
+}
+
+int qmrom_a0_wait_ready(struct qmrom_handle *handle)
+{
+	int retries = handle->comms_retries;
+	qmrom_a0_poll_soc(handle);
+
+	while (retries-- && !handle->sstc->soc_flags.out_waiting) {
+		qmrom_a0_poll_soc(handle);
+	}
+	return handle->sstc->soc_flags.out_waiting ? 0 :
+						     SPI_ERR_WAIT_READY_TIMEOUT;
+}
+
+int qmrom_a0_probe_device(struct qmrom_handle *handle)
+{
+	int rc;
+	LOG_DBG("%s: enters...\n", __func__);
+	handle->is_be = true;
+
+	qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
+
+	rc = qmrom_reboot_bootloader(handle);
+	if (rc) {
+		LOG_ERR("%s: cannot reset the device...\n", __func__);
+		return rc;
+	}
+
+	rc = qmrom_a0_wait_ready(handle);
+	if (rc) {
+		LOG_INFO("%s: maybe not a A0 device\n", __func__);
+		return rc;
+	}
+	qmrom_pre_read(handle);
+	handle->sstc->len = bswap_16(handle->sstc->len);
+	if (handle->sstc->len > 0xff) {
+		/* likely the wrong endianness, B0 or C0? */
+		return -1;
+	}
+	qmrom_read(handle);
+
+	LOG_DBG("%s: Set the chip_rev/device_version\n", __func__);
+	handle->chip_rev =
+		bswap_16(SSTC2UINT16(handle,
+				     CHIP_VERSION_CHIP_REV_PAYLOAD_OFFSET)) &
+		0xFF;
+
+	if (handle->chip_rev != CHIP_REVISION_A0) {
+		LOG_ERR("%s: wrong chip revision %#x\n", __func__,
+			handle->chip_rev);
+		handle->chip_rev = -1;
+		return -1;
+	}
+
+	/* Set rom ops */
+	handle->rom_ops.flash_fw = qmrom_a0_flash_fw;
+	handle->rom_ops.flash_debug_cert = NULL;
+	handle->rom_ops.erase_debug_cert = NULL;
+	return 0;
+}
+
+int qmrom_a0_write_data(struct qmrom_handle *handle, uint16_t data_size,
+			const char *data)
+{
+	handle->hstc->all = 0;
+	handle->hstc->host_flags.write = 1;
+	handle->hstc->ul = 1;
+	handle->hstc->len = data_size;
+	memcpy(handle->hstc->payload, data, data_size);
+
+	return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+				  (const char *)handle->hstc,
+				  sizeof(struct stc) + data_size);
+}
+
+static int qmrom_a0_write_chunks(struct qmrom_handle *handle,
+				 const struct firmware *fw)
+{
+	int rc, sent = 0;
+	const char *bin_data = (const char *)fw->data;
+
+	check_stcs(__func__, __LINE__, handle);
+	while (sent < fw->size) {
+		uint32_t tx_bytes = fw->size - sent;
+		if (tx_bytes > CHUNK_SIZE_A0)
+			tx_bytes = CHUNK_SIZE_A0;
+
+		LOG_DBG("%s: poll soc...\n", __func__);
+		check_stcs(__func__, __LINE__, handle);
+		qmrom_a0_poll_soc(handle);
+		qmrom_pre_read(handle);
+		handle->sstc->len = bswap_16(handle->sstc->len);
+		qmrom_read(handle);
+		if (handle->sstc->payload[0] != SPI_RSP_WAIT_FOR_IMAGE) {
+			LOG_ERR("%s: wrong data result (%#x vs %#x)!!!\n",
+				__func__, handle->sstc->payload[0] & 0xff,
+				SPI_RSP_WAIT_FOR_IMAGE);
+			return SPI_PROTO_WRONG_RESP;
+		}
+
+		LOG_DBG("%s: sending %" PRIu32 " bytes of data\n", __func__,
+			tx_bytes);
+		rc = qmrom_a0_write_data(handle, tx_bytes, bin_data);
+		if (rc)
+			return rc;
+		sent += tx_bytes;
+		bin_data += tx_bytes;
+		check_stcs(__func__, __LINE__, handle);
+	}
+	return 0;
+}
+
+static int qmrom_a0_flash_fw(struct qmrom_handle *handle,
+			     const struct firmware *fw)
+{
+	int rc = 0, resp;
+
+	LOG_DBG("%s: starting...\n", __func__);
+
+	/* Reboot since the rom code on A0 seems
+	 * to have issues when starting flashing
+	 * after some prior interaction (like GET_CHIP_VERSION)
+	 */
+	rc = qmrom_reboot_bootloader(handle);
+	if (rc) {
+		LOG_ERR("%s: cannot reset the device...\n", __func__);
+		return rc;
+	}
+
+	rc = qmrom_a0_wait_ready(handle);
+	if (rc) {
+		LOG_ERR("%s: timedout waiting for the device to be ready\n",
+			__func__);
+		return rc;
+	}
+	qmrom_pre_read(handle);
+	handle->sstc->len = bswap_16(handle->sstc->len);
+	qmrom_read(handle);
+	if (handle->sstc->payload[0] != SPI_RSP_WAIT_DOWNLOAD_MODE) {
+		LOG_ERR("%s: wrong data result (%#x vs %#x)!!!\n", __func__,
+			handle->sstc->payload[0] & 0xff,
+			SPI_RSP_WAIT_DOWNLOAD_MODE);
+		return SPI_PROTO_WRONG_RESP;
+	}
+
+	check_stcs(__func__, __LINE__, handle);
+	LOG_DBG("%s: sending ROM_CMD_A0_DOWNLOAD_RRAM_CMD command\n", __func__);
+	rc = qmrom_write_cmd(handle, ROM_CMD_A0_DOWNLOAD_RRAM_CMD);
+	if (rc)
+		return rc;
+
+	for (resp = SPI_RSP_WAIT_FOR_KEY1_CERT; resp < SPI_RSP_WAIT_FOR_IMAGE;
+	     resp++) {
+		qmrom_a0_poll_soc(handle);
+		qmrom_pre_read(handle);
+		handle->sstc->len = bswap_16(handle->sstc->len);
+		qmrom_read(handle);
+		if (handle->sstc->payload[0] != resp) {
+			LOG_ERR("%s: wrong data result (%#x vs %#x)!!!\n",
+				__func__, handle->sstc->payload[0] & 0xff,
+				resp);
+			return SPI_PROTO_WRONG_RESP;
+		}
+		if (resp < SPI_RSP_WAIT_IMAGE_SIZE) {
+			rc = qmrom_write_cmd(handle, 0);
+			if (rc)
+				return rc;
+		}
+	}
+
+	LOG_DBG("%s: sending fw size\n", __func__);
+	rc = qmrom_a0_write_data(handle, sizeof(uint32_t),
+				 (const char *)&fw->size);
+	if (rc)
+		return rc;
+
+	check_stcs(__func__, __LINE__, handle);
+	rc = qmrom_a0_write_chunks(handle, fw);
+	check_stcs(__func__, __LINE__, handle);
+	return rc;
+}
diff --git a/libqmrom/src/qm357xx_rom_b0.c b/libqmrom/src/qmrom_b0.c
similarity index 67%
rename from libqmrom/src/qm357xx_rom_b0.c
rename to libqmrom/src/qmrom_b0.c
index fe2c637..9b23cff 100644
--- a/libqmrom/src/qm357xx_rom_b0.c
+++ b/libqmrom/src/qmrom_b0.c
@@ -67,14 +67,16 @@
 	ERR_DEBUG_CERT_SIZE = 0x1F,
 };
 
-static int qm357xx_rom_b0_flash_debug_cert(struct qmrom_handle *handle,
-					   struct firmware *dbg_cert);
-static int qm357xx_rom_b0_erase_debug_cert(struct qmrom_handle *handle);
+static int qmrom_b0_flash_fw(struct qmrom_handle *handle,
+			     const struct firmware *fw);
+static int qmrom_b0_flash_debug_cert(struct qmrom_handle *handle,
+				     struct firmware *dbg_cert);
+static int qmrom_b0_erase_debug_cert(struct qmrom_handle *handle);
 static int
-qm357xx_rom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
-				   const struct unstitched_firmware *all_fws);
+qmrom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
+			     const struct unstitched_firmware *all_fws);
 
-static void qm357xx_rom_b0_poll_soc(struct qmrom_handle *handle)
+static void qmrom_b0_poll_soc(struct qmrom_handle *handle)
 {
 	int retries = handle->comms_retries;
 	memset(handle->hstc, 0, sizeof(struct stc));
@@ -86,12 +88,12 @@
 	} while (retries-- && handle->sstc->raw_flags == 0);
 }
 
-static int qm357xx_rom_b0_wait_ready(struct qmrom_handle *handle)
+static int qmrom_b0_wait_ready(struct qmrom_handle *handle)
 {
 	int retries = handle->comms_retries;
 	int rc;
 
-	qm357xx_rom_b0_poll_soc(handle);
+	qmrom_b0_poll_soc(handle);
 
 	/* handle->sstc has been updated */
 	while (retries-- &&
@@ -104,7 +106,7 @@
 				return rc;
 		} else {
 			/* error? */
-			qm357xx_rom_b0_poll_soc(handle);
+			qmrom_b0_poll_soc(handle);
 		}
 	}
 
@@ -113,11 +115,11 @@
 		       SPI_ERR_WAIT_READY_TIMEOUT;
 }
 
-static int qm357xx_rom_b0_poll_cmd_resp(struct qmrom_handle *handle)
+static int qmrom_b0_poll_cmd_resp(struct qmrom_handle *handle)
 {
 	int retries = handle->comms_retries;
 
-	qm357xx_rom_b0_poll_soc(handle);
+	qmrom_b0_poll_soc(handle);
 	do {
 		if (handle->sstc->soc_flags.out_waiting) {
 			qmrom_pre_read(handle);
@@ -128,23 +130,20 @@
 			qmrom_read(handle);
 			break;
 		} else
-			qm357xx_rom_b0_poll_soc(handle);
+			qmrom_b0_poll_soc(handle);
 	} while (retries--);
 
 	return retries > 0 ? 0 : -1;
 }
 
-int qm357xx_rom_b0_probe_device(struct qmrom_handle *handle)
+int qmrom_b0_probe_device(struct qmrom_handle *handle)
 {
 	int rc, i;
 	uint8_t *soc_lcs_uuid;
 	handle->is_be = false;
 	check_stcs(__func__, __LINE__, handle);
 
-	if (handle->spi_speed == 0)
-		qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
-	else
-		qmrom_spi_set_freq(handle->spi_speed);
+	qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
 
 	rc = qmrom_reboot_bootloader(handle);
 	if (rc) {
@@ -152,17 +151,17 @@
 		return rc;
 	}
 
-	rc = qm357xx_rom_b0_wait_ready(handle);
+	rc = qmrom_b0_wait_ready(handle);
 	if (rc) {
 		LOG_INFO("%s: maybe not a B0 device\n", __func__);
 		return rc;
 	}
 
-	rc = qm357xx_rom_write_cmd(handle, ROM_CMD_B0_GET_CHIP_VER);
+	rc = qmrom_write_cmd(handle, ROM_CMD_B0_GET_CHIP_VER);
 	if (rc)
 		return rc;
 
-	rc = qm357xx_rom_b0_poll_cmd_resp(handle);
+	rc = qmrom_b0_poll_cmd_resp(handle);
 	if (rc)
 		return rc;
 
@@ -178,49 +177,42 @@
 		return -1;
 	}
 
-	rc = qm357xx_rom_b0_wait_ready(handle);
+	rc = qmrom_b0_wait_ready(handle);
 	if (rc) {
 		LOG_ERR("%s: hmm something went wrong!!!\n", __func__);
 		return rc;
 	}
 
-	rc = qm357xx_rom_write_cmd(handle, ROM_CMD_B0_GET_SOC_INFO);
+	rc = qmrom_write_cmd(handle, ROM_CMD_B0_GET_SOC_INFO);
 	if (rc)
 		return rc;
 
-	rc = qm357xx_rom_b0_poll_cmd_resp(handle);
+	rc = qmrom_b0_poll_cmd_resp(handle);
 	if (rc)
 		return rc;
 
 	/* skip the first byte */
 	soc_lcs_uuid = &(handle->sstc->payload[1]);
-	for (i = 0; i < QM357XX_ROM_SOC_ID_LEN; i++)
-		handle->qm357xx_soc_info.soc_id[i] =
-			soc_lcs_uuid[QM357XX_ROM_SOC_ID_LEN - i - 1];
-	soc_lcs_uuid += QM357XX_ROM_SOC_ID_LEN;
-	handle->qm357xx_soc_info.lcs_state = soc_lcs_uuid[0];
+	for (i = 0; i < ROM_SOC_ID_LEN; i++)
+		handle->soc_id[i] = soc_lcs_uuid[ROM_SOC_ID_LEN - i - 1];
+	soc_lcs_uuid += ROM_SOC_ID_LEN;
+	handle->lcs_state = soc_lcs_uuid[0];
 	soc_lcs_uuid += 1;
-	for (i = 0; i < QM357XX_ROM_UUID_LEN; i++)
-		handle->qm357xx_soc_info.uuid[i] =
-			soc_lcs_uuid[QM357XX_ROM_UUID_LEN - i - 1];
+	for (i = 0; i < ROM_UUID_LEN; i++)
+		handle->uuid[i] = soc_lcs_uuid[ROM_UUID_LEN - i - 1];
 
-	/* Set device type */
-	handle->dev_gen = DEVICE_GEN_QM357XX;
 	/* Set rom ops */
-	handle->qm357xx_rom_ops.flash_unstitched_fw =
-		qm357xx_rom_b0_flash_unstitched_fw;
-	handle->qm357xx_rom_ops.flash_debug_cert =
-		qm357xx_rom_b0_flash_debug_cert;
-	handle->qm357xx_rom_ops.erase_debug_cert =
-		qm357xx_rom_b0_erase_debug_cert;
+	handle->rom_ops.flash_fw = qmrom_b0_flash_fw;
+	handle->rom_ops.flash_unstitched_fw = qmrom_b0_flash_unstitched_fw;
+	handle->rom_ops.flash_debug_cert = qmrom_b0_flash_debug_cert;
+	handle->rom_ops.erase_debug_cert = qmrom_b0_erase_debug_cert;
 
 	check_stcs(__func__, __LINE__, handle);
 	return 0;
 }
 
-static int qm357xx_rom_b0_flash_data(struct qmrom_handle *handle,
-				     struct firmware *fw, uint8_t cmd,
-				     uint8_t exp)
+static int qmrom_b0_flash_data(struct qmrom_handle *handle, struct firmware *fw,
+			       uint8_t cmd, uint8_t exp)
 {
 	int rc, sent = 0;
 	const char *bin_data = (const char *)fw->data;
@@ -233,7 +225,7 @@
 
 		LOG_DBG("%s: poll soc...\n", __func__);
 		check_stcs(__func__, __LINE__, handle);
-		qm357xx_rom_b0_poll_soc(handle);
+		qmrom_b0_poll_soc(handle);
 		qmrom_pre_read(handle);
 		qmrom_read(handle);
 		if (handle->sstc->payload[0] != exp) {
@@ -248,8 +240,7 @@
 
 		LOG_DBG("%s: sending %d command with %" PRIu32 " bytes\n",
 			__func__, cmd, tx_bytes);
-		rc = qm357xx_rom_write_size_cmd(handle, cmd, tx_bytes,
-						bin_data);
+		rc = qmrom_write_size_cmd(handle, cmd, tx_bytes, bin_data);
 		if (rc)
 			return rc;
 		sent += tx_bytes;
@@ -259,18 +250,33 @@
 	return 0;
 }
 
-static int
-qm357xx_rom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
-				   const struct unstitched_firmware *all_fws)
+static int qmrom_b0_flash_fw(struct qmrom_handle *handle,
+			     const struct firmware *fw)
 {
 	int rc = 0;
-	uint8_t flash_cmd = handle->qm357xx_soc_info.lcs_state ==
-					    CC_BSV_SECURE_LCS ?
+	struct unstitched_firmware all_fws = { 0 };
+
+	rc = qmrom_unstitch_fw(fw, &all_fws, handle->chip_rev);
+	if (rc) {
+		LOG_ERR("%s: Unstitched fw flashing not supported yet\n",
+			__func__);
+		return rc;
+	}
+	rc = qmrom_b0_flash_unstitched_fw(handle, &all_fws);
+	return rc;
+}
+
+static int
+qmrom_b0_flash_unstitched_fw(struct qmrom_handle *handle,
+			     const struct unstitched_firmware *all_fws)
+{
+	int rc = 0;
+	uint8_t flash_cmd = handle->lcs_state == CC_BSV_SECURE_LCS ?
 				    ROM_CMD_B0_SEC_LOAD_OEM_IMG_TO_RRAM :
 				    ROM_CMD_B0_SEC_LOAD_ICV_IMG_TO_RRAM;
 
 	if (all_fws->key1_crt->data[HBK_LOC] == HBK_2E_ICV &&
-	    handle->qm357xx_soc_info.lcs_state != CC_BSV_CHIP_MANUFACTURE_LCS) {
+	    handle->lcs_state != CC_BSV_CHIP_MANUFACTURE_LCS) {
 		LOG_ERR("%s: Trying to flash an ICV fw on a non ICV platform\n",
 			__func__);
 		rc = -EINVAL;
@@ -278,7 +284,7 @@
 	}
 
 	if (all_fws->key1_crt->data[HBK_LOC] == HBK_2E_OEM &&
-	    handle->qm357xx_soc_info.lcs_state != CC_BSV_SECURE_LCS) {
+	    handle->lcs_state != CC_BSV_SECURE_LCS) {
 		LOG_ERR("%s: Trying to flash an OEM fw on a non OEM platform\n",
 			__func__);
 		rc = -EINVAL;
@@ -288,41 +294,40 @@
 	LOG_DBG("%s: starting...\n", __func__);
 	check_stcs(__func__, __LINE__, handle);
 
-	rc = qm357xx_rom_b0_wait_ready(handle);
+	rc = qmrom_b0_wait_ready(handle);
 	if (rc)
 		goto end;
 
 	check_stcs(__func__, __LINE__, handle);
 	LOG_DBG("%s: sending flash_cmd %u command\n", __func__, flash_cmd);
-	rc = qm357xx_rom_write_cmd(handle, flash_cmd);
+	rc = qmrom_write_cmd(handle, flash_cmd);
 	if (rc)
 		goto end;
 
 	check_stcs(__func__, __LINE__, handle);
-	rc = qm357xx_rom_b0_flash_data(handle, all_fws->key1_crt,
-				       ROM_CMD_B0_CERT_DATA,
-				       WAITING_FOR_FIRST_KEY_CERT);
+	rc = qmrom_b0_flash_data(handle, all_fws->key1_crt,
+				 ROM_CMD_B0_CERT_DATA,
+				 WAITING_FOR_FIRST_KEY_CERT);
 	if (rc)
 		goto end;
 
 	check_stcs(__func__, __LINE__, handle);
-	rc = qm357xx_rom_b0_flash_data(handle, all_fws->key2_crt,
-				       ROM_CMD_B0_CERT_DATA,
-				       WAITING_FOR_SECOND_KEY_CERT);
+	rc = qmrom_b0_flash_data(handle, all_fws->key2_crt,
+				 ROM_CMD_B0_CERT_DATA,
+				 WAITING_FOR_SECOND_KEY_CERT);
 	if (rc)
 		goto end;
 
 	check_stcs(__func__, __LINE__, handle);
-	rc = qm357xx_rom_b0_flash_data(handle, all_fws->fw_crt,
-				       ROM_CMD_B0_CERT_DATA,
-				       WAITING_FOR_CONTENT_CERT);
+	rc = qmrom_b0_flash_data(handle, all_fws->fw_crt, ROM_CMD_B0_CERT_DATA,
+				 WAITING_FOR_CONTENT_CERT);
 	if (rc)
 		goto end;
 
 	check_stcs(__func__, __LINE__, handle);
-	rc = qm357xx_rom_b0_flash_data(handle, all_fws->fw_img,
-				       ROM_CMD_B0_SEC_IMAGE_DATA,
-				       WAITING_FOR_SEC_FILE_DATA);
+	rc = qmrom_b0_flash_data(handle, all_fws->fw_img,
+				 ROM_CMD_B0_SEC_IMAGE_DATA,
+				 WAITING_FOR_SEC_FILE_DATA);
 
 	if (!rc)
 		qmrom_msleep(SPI_READY_TIMEOUT_MS);
@@ -336,35 +341,35 @@
 	return rc;
 }
 
-static int qm357xx_rom_b0_flash_debug_cert(struct qmrom_handle *handle,
-					   struct firmware *dbg_cert)
+static int qmrom_b0_flash_debug_cert(struct qmrom_handle *handle,
+				     struct firmware *dbg_cert)
 {
 	int rc;
 
 	LOG_DBG("%s: starting...\n", __func__);
 	check_stcs(__func__, __LINE__, handle);
 
-	rc = qm357xx_rom_b0_wait_ready(handle);
+	rc = qmrom_b0_wait_ready(handle);
 	if (rc)
 		return rc;
 
 	check_stcs(__func__, __LINE__, handle);
 	LOG_DBG("%s: sending ROM_CMD_B0_WRITE_DBG_CERT command\n", __func__);
-	rc = qm357xx_rom_write_cmd(handle, ROM_CMD_B0_WRITE_DBG_CERT);
+	rc = qmrom_write_cmd(handle, ROM_CMD_B0_WRITE_DBG_CERT);
 	if (rc)
 		return rc;
 
 	check_stcs(__func__, __LINE__, handle);
 	LOG_DBG("%s: poll soc...\n", __func__);
-	qm357xx_rom_b0_poll_soc(handle);
+	qmrom_b0_poll_soc(handle);
 	qmrom_pre_read(handle);
 	qmrom_read(handle);
 
 	check_stcs(__func__, __LINE__, handle);
 	LOG_DBG("%s: sending ROM_CMD_B0_DEBUG_CERT_SIZE command\n", __func__);
-	rc = qm357xx_rom_write_size_cmd(handle, ROM_CMD_B0_DEBUG_CERT_SIZE,
-					sizeof(uint32_t),
-					(const char *)&dbg_cert->size);
+	rc = qmrom_write_size_cmd(handle, ROM_CMD_B0_DEBUG_CERT_SIZE,
+				  sizeof(uint32_t),
+				  (const char *)&dbg_cert->size);
 	if (handle->sstc->payload[0] != WAITING_TO_DEBUG_CERTIFICATE_SIZE) {
 		LOG_ERR("%s: wrong debug cert size result (0x%x vs 0x%x)!!!\n",
 			__func__, handle->sstc->payload[0] & 0xff,
@@ -374,26 +379,25 @@
 	if (rc)
 		return rc;
 
-	rc = qm357xx_rom_b0_flash_data(handle, dbg_cert, ROM_CMD_B0_CERT_DATA,
-				       WAITING_FOR_DEBUG_CERT_DATA);
+	rc = qmrom_b0_flash_data(handle, dbg_cert, ROM_CMD_B0_CERT_DATA,
+				 WAITING_FOR_DEBUG_CERT_DATA);
 	check_stcs(__func__, __LINE__, handle);
-	qmrom_msleep(SPI_READY_TIMEOUT_MS);
 	return 0;
 }
 
-static int qm357xx_rom_b0_erase_debug_cert(struct qmrom_handle *handle)
+static int qmrom_b0_erase_debug_cert(struct qmrom_handle *handle)
 {
 	int rc;
 
 	LOG_INFO("%s: starting...\n", __func__);
 	check_stcs(__func__, __LINE__, handle);
 
-	rc = qm357xx_rom_b0_wait_ready(handle);
+	rc = qmrom_b0_wait_ready(handle);
 	if (!rc)
 		return rc;
 
 	LOG_DBG("%s: sending ROM_CMD_B0_ERASE_DBG_CERT command\n", __func__);
-	rc = qm357xx_rom_write_cmd(handle, ROM_CMD_B0_ERASE_DBG_CERT);
+	rc = qmrom_write_cmd(handle, ROM_CMD_B0_ERASE_DBG_CERT);
 	if (rc)
 		return rc;
 
diff --git a/libqmrom/src/qm357xx_rom_c0.c b/libqmrom/src/qmrom_c0.c
similarity index 62%
rename from libqmrom/src/qm357xx_rom_c0.c
rename to libqmrom/src/qmrom_c0.c
index acd4d31..76a04f3 100644
--- a/libqmrom/src/qm357xx_rom_c0.c
+++ b/libqmrom/src/qmrom_c0.c
@@ -77,12 +77,11 @@
 	ERR_DEBUG_CERT_SIZE = 0x1F,
 };
 
-static int
-qm357xx_rom_c0_flash_unstitched_fw(struct qmrom_handle *handle,
-				   const struct unstitched_firmware *all_fws);
-static int qm357xx_rom_c0_flash_debug_cert(struct qmrom_handle *handle,
-					   struct firmware *dbg_cert);
-static int qm357xx_rom_c0_erase_debug_cert(struct qmrom_handle *handle);
+static int qmrom_c0_flash_fw(struct qmrom_handle *handle,
+			     const struct firmware *fw);
+static int qmrom_c0_flash_debug_cert(struct qmrom_handle *handle,
+				     struct firmware *dbg_cert);
+static int qmrom_c0_erase_debug_cert(struct qmrom_handle *handle);
 
 #define qmrom_pre_read_c0(h)                                            \
 	({                                                              \
@@ -100,40 +99,40 @@
 		rc = qmrom_read((h));                                   \
 		rc;                                                     \
 	})
-#define qm357xx_rom_write_cmd_c0(h, cmd)                                \
+#define qmrom_write_cmd_c0(h, cmd)                                      \
 	({                                                              \
 		int rc;                                                 \
 		qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle,       \
 					      SPI_READY_TIMEOUT_MS_C0); \
-		rc = qm357xx_rom_write_cmd((h), (cmd));                 \
+		rc = qmrom_write_cmd((h), (cmd));                       \
 		rc;                                                     \
 	})
-#define qm357xx_rom_write_cmd32_c0(h, cmd)                              \
+#define qmrom_write_cmd32_c0(h, cmd)                                    \
 	({                                                              \
 		int rc;                                                 \
 		qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle,       \
 					      SPI_READY_TIMEOUT_MS_C0); \
-		rc = qm357xx_rom_write_cmd32((h), (cmd));               \
+		rc = qmrom_write_cmd32((h), (cmd));                     \
 		rc;                                                     \
 	})
-#define qm357xx_rom_write_size_cmd_c0(h, cmd, ds, d)                    \
+#define qmrom_write_size_cmd_c0(h, cmd, ds, d)                          \
 	({                                                              \
 		int rc;                                                 \
 		qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle,       \
 					      SPI_READY_TIMEOUT_MS_C0); \
-		rc = qm357xx_rom_write_size_cmd((h), (cmd), (ds), (d)); \
+		rc = qmrom_write_size_cmd((h), (cmd), (ds), (d));       \
 		rc;                                                     \
 	})
-#define qm357xx_rom_write_size_cmd32_c0(h, cmd, ds, d)                    \
-	({                                                                \
-		int rc;                                                   \
-		qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle,         \
-					      SPI_READY_TIMEOUT_MS_C0);   \
-		rc = qm357xx_rom_write_size_cmd32((h), (cmd), (ds), (d)); \
-		rc;                                                       \
+#define qmrom_write_size_cmd32_c0(h, cmd, ds, d)                        \
+	({                                                              \
+		int rc;                                                 \
+		qmrom_spi_wait_for_ready_line((h)->ss_rdy_handle,       \
+					      SPI_READY_TIMEOUT_MS_C0); \
+		rc = qmrom_write_size_cmd32((h), (cmd), (ds), (d));     \
+		rc;                                                     \
 	})
 
-static void qm357xx_rom_c0_poll_soc(struct qmrom_handle *handle)
+static void qmrom_c0_poll_soc(struct qmrom_handle *handle)
 {
 	int retries = handle->comms_retries;
 	memset(handle->hstc, 0, sizeof(struct stc));
@@ -152,11 +151,11 @@
 	} while (retries-- && handle->sstc->raw_flags == 0);
 }
 
-static int qm357xx_rom_c0_wait_ready(struct qmrom_handle *handle)
+static int qmrom_c0_wait_ready(struct qmrom_handle *handle)
 {
 	int retries = handle->comms_retries;
 
-	qm357xx_rom_c0_poll_soc(handle);
+	qmrom_c0_poll_soc(handle);
 
 	/* handle->sstc has been updated */
 	while (retries-- &&
@@ -167,7 +166,7 @@
 		} else if (handle->sstc->soc_flags.out_active) {
 			return qmrom_read_c0(handle);
 		} else
-			qm357xx_rom_c0_poll_soc(handle);
+			qmrom_c0_poll_soc(handle);
 	}
 
 	return handle->sstc->raw_flags == SPI_SH_READY_CMD_BIT_MASK_C0 ?
@@ -175,17 +174,17 @@
 		       SPI_ERR_WAIT_READY_TIMEOUT;
 }
 
-static int qm357xx_rom_c0_poll_cmd_resp(struct qmrom_handle *handle)
+static int qmrom_c0_poll_cmd_resp(struct qmrom_handle *handle)
 {
 	int retries = handle->comms_retries;
 
-	qm357xx_rom_c0_poll_soc(handle);
+	qmrom_c0_poll_soc(handle);
 	do {
 		if (handle->sstc->soc_flags.out_waiting) {
 			qmrom_pre_read_c0(handle);
 			return qmrom_read_c0(handle);
 		} else
-			qm357xx_rom_c0_poll_soc(handle);
+			qmrom_c0_poll_soc(handle);
 	} while (retries--);
 	if (retries <= 0)
 		LOG_ERR("%s failed after %d replies\n", __func__,
@@ -194,17 +193,14 @@
 	return retries > 0 ? 0 : -1;
 }
 
-int qm357xx_rom_c0_probe_device(struct qmrom_handle *handle)
+int qmrom_c0_probe_device(struct qmrom_handle *handle)
 {
 	int rc, i;
 	uint8_t *soc_lcs_uuid;
 
 	handle->is_be = false;
 
-	if (handle->spi_speed == 0)
-		qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
-	else
-		qmrom_spi_set_freq(handle->spi_speed);
+	qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
 
 	rc = qmrom_reboot_bootloader(handle);
 	if (rc) {
@@ -212,17 +208,17 @@
 		return rc;
 	}
 
-	rc = qm357xx_rom_c0_wait_ready(handle);
+	rc = qmrom_c0_wait_ready(handle);
 	if (rc) {
 		LOG_INFO("%s: maybe not a C0 device\n", __func__);
 		return rc;
 	}
 
-	rc = qm357xx_rom_write_cmd32_c0(handle, ROM_CMD_C0_GET_CHIP_VER);
+	rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_GET_CHIP_VER);
 	if (rc)
 		return rc;
 
-	rc = qm357xx_rom_c0_poll_cmd_resp(handle);
+	rc = qmrom_c0_poll_cmd_resp(handle);
 	if (rc)
 		return rc;
 
@@ -231,50 +227,41 @@
 		0xFF;
 	handle->device_version = bswap_16(
 		SSTC2UINT16(handle, CHIP_VERSION_DEV_REV_PAYLOAD_OFFSET));
-	if ((handle->chip_rev != CHIP_REVISION_C0) &&
-	    ((handle->chip_rev != CHIP_REVISION_C2))) {
+	if (handle->chip_rev != CHIP_REVISION_C0) {
 		LOG_ERR("%s: wrong chip revision %#x\n", __func__,
 			handle->chip_rev);
 		handle->chip_rev = -1;
 		return -1;
 	}
 
-	rc = qm357xx_rom_c0_wait_ready(handle);
+	rc = qmrom_c0_wait_ready(handle);
 	if (rc) {
 		LOG_ERR("%s: hmm something went wrong!!!\n", __func__);
 		return rc;
 	}
 
-	rc = qm357xx_rom_write_cmd32_c0(handle, ROM_CMD_C0_GET_SOC_INFO);
+	rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_GET_SOC_INFO);
 	if (rc)
 		return rc;
 
-	rc = qm357xx_rom_c0_poll_cmd_resp(handle);
+	rc = qmrom_c0_poll_cmd_resp(handle);
 	if (rc)
 		return rc;
 
 	/* skip the first 4 bytes */
 	soc_lcs_uuid = &(handle->sstc->payload[4]);
-	for (i = 0; i < QM357XX_ROM_SOC_ID_LEN; i++)
-		handle->qm357xx_soc_info.soc_id[i] =
-			soc_lcs_uuid[QM357XX_ROM_SOC_ID_LEN - i - 1];
-	soc_lcs_uuid += QM357XX_ROM_SOC_ID_LEN;
-	memcpy(&handle->qm357xx_soc_info.lcs_state, soc_lcs_uuid,
-	       sizeof(uint32_t));
+	for (i = 0; i < ROM_SOC_ID_LEN; i++)
+		handle->soc_id[i] = soc_lcs_uuid[ROM_SOC_ID_LEN - i - 1];
+	soc_lcs_uuid += ROM_SOC_ID_LEN;
+	memcpy(&handle->lcs_state, soc_lcs_uuid, sizeof(uint32_t));
 	soc_lcs_uuid += 4;
-	for (i = 0; i < QM357XX_ROM_UUID_LEN; i++)
-		handle->qm357xx_soc_info.uuid[i] =
-			soc_lcs_uuid[QM357XX_ROM_UUID_LEN - i - 1];
+	for (i = 0; i < ROM_UUID_LEN; i++)
+		handle->uuid[i] = soc_lcs_uuid[ROM_UUID_LEN - i - 1];
 
-	/* Set device type */
-	handle->dev_gen = DEVICE_GEN_QM357XX;
 	/* Set rom ops */
-	handle->qm357xx_rom_ops.flash_unstitched_fw =
-		qm357xx_rom_c0_flash_unstitched_fw;
-	handle->qm357xx_rom_ops.flash_debug_cert =
-		qm357xx_rom_c0_flash_debug_cert;
-	handle->qm357xx_rom_ops.erase_debug_cert =
-		qm357xx_rom_c0_erase_debug_cert;
+	handle->rom_ops.flash_fw = qmrom_c0_flash_fw;
+	handle->rom_ops.flash_debug_cert = qmrom_c0_flash_debug_cert;
+	handle->rom_ops.erase_debug_cert = qmrom_c0_erase_debug_cert;
 
 	return 0;
 }
@@ -298,18 +285,17 @@
 
 static void dump_stats(void)
 {
-	uint32_t nb_chunks = div_u64(total_bytes, CHUNK_SIZE_C0);
+	uint32_t nb_chunks = total_bytes / CHUNK_SIZE_C0;
 	LOG_WARN(
 		"C0 flashing time stats: %llu bytes over %llu us (chunk size %u, write timings: mean %u us, min %u us, max %u us)\n",
-		total_bytes, div_u64(total_time_ns, 1000), CHUNK_SIZE_C0,
-		(uint32_t)(div_u64((div_u64(total_time_ns, nb_chunks)), 1000)),
+		total_bytes, total_time_ns / 1000, CHUNK_SIZE_C0,
+		(uint32_t)((total_time_ns / nb_chunks) / 1000),
 		min_write_time_ns / 1000, max_write_time_ns / 1000);
 }
 #endif
 
-static int qm357xx_rom_c0_flash_data(struct qmrom_handle *handle,
-				     struct firmware *fw, uint8_t cmd,
-				     uint8_t resp, bool skip_last_check)
+static int qmrom_c0_flash_data(struct qmrom_handle *handle, struct firmware *fw,
+			       uint8_t cmd, uint8_t resp, bool skip_last_check)
 {
 	int rc, sent = 0;
 	const char *bin_data = (const char *)fw->data;
@@ -327,8 +313,7 @@
 #ifdef C0_WRITE_STATS
 		start_time = ktime_get();
 #endif
-		rc = qm357xx_rom_write_size_cmd32_c0(handle, cmd, tx_bytes,
-						     bin_data);
+		rc = qmrom_write_size_cmd32_c0(handle, cmd, tx_bytes, bin_data);
 		if (rc)
 			return rc;
 		sent += tx_bytes;
@@ -337,7 +322,7 @@
 			LOG_INFO("%s: flashing done, quitting now\n", __func__);
 			break;
 		}
-		qm357xx_rom_c0_poll_soc(handle);
+		qmrom_c0_poll_soc(handle);
 #ifdef C0_WRITE_STATS
 		if (tx_bytes == CHUNK_SIZE_C0)
 			update_write_max_chunk_stats(start_time);
@@ -359,26 +344,34 @@
 	return 0;
 }
 
-static int
-qm357xx_rom_c0_flash_unstitched_fw(struct qmrom_handle *handle,
-				   const struct unstitched_firmware *all_fws)
+static int qmrom_c0_flash_fw(struct qmrom_handle *handle,
+			     const struct firmware *fw)
 {
 	int rc = 0;
-	uint8_t flash_cmd = handle->qm357xx_soc_info.lcs_state ==
-					    CC_BSV_SECURE_LCS ?
+	struct unstitched_firmware all_fws = { 0 };
+	uint8_t flash_cmd = handle->lcs_state == CC_BSV_SECURE_LCS ?
 				    ROM_CMD_C0_SEC_LOAD_OEM_IMG_TO_RRAM :
 				    ROM_CMD_C0_SEC_LOAD_ICV_IMG_TO_RRAM;
 
-	if (all_fws->key1_crt->data[HBK_LOC] == HBK_2E_ICV &&
-	    handle->qm357xx_soc_info.lcs_state != CC_BSV_CHIP_MANUFACTURE_LCS) {
+	LOG_INFO("Unstitching the fw %p->data %p\n", (void *)fw,
+		 (void *)fw->data);
+	rc = qmrom_unstitch_fw(fw, &all_fws, handle->chip_rev);
+	if (rc) {
+		LOG_ERR("%s: Unstitched fw flashing not supported yet\n",
+			__func__);
+		return rc;
+	}
+
+	if (all_fws.key1_crt->data[HBK_LOC] == HBK_2E_ICV &&
+	    handle->lcs_state != CC_BSV_CHIP_MANUFACTURE_LCS) {
 		LOG_ERR("%s: Trying to flash an ICV fw on a non ICV platform\n",
 			__func__);
 		rc = -EINVAL;
 		goto end;
 	}
 
-	if (all_fws->key1_crt->data[HBK_LOC] == HBK_2E_OEM &&
-	    handle->qm357xx_soc_info.lcs_state != CC_BSV_SECURE_LCS) {
+	if (all_fws.key1_crt->data[HBK_LOC] == HBK_2E_OEM &&
+	    handle->lcs_state != CC_BSV_SECURE_LCS) {
 		LOG_ERR("%s: Trying to flash an OEM fw on a non OEM platform\n",
 			__func__);
 		rc = -EINVAL;
@@ -388,30 +381,25 @@
 	LOG_DBG("%s: starting...\n", __func__);
 
 	/* Set RRAM write mode */
-	rc = qm357xx_rom_c0_wait_ready(handle);
+	rc = qmrom_c0_wait_ready(handle);
 	if (rc)
 		goto end;
 
-	if (handle->chip_rev != CHIP_REVISION_C2) {
-		LOG_DBG("%s: sending ROM_CMD_C0_USE_INDIRECT_RRAM_WR command (chip_rev %x)\n",
-			__func__, handle->chip_rev);
-		rc = qm357xx_rom_write_cmd32_c0(
-			handle, ROM_CMD_C0_USE_INDIRECT_RRAM_WR);
-		if (rc)
-			goto end;
-	}
+	rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_USE_INDIRECT_RRAM_WR);
+	if (rc)
+		goto end;
 
-	qm357xx_rom_c0_poll_soc(handle);
+	qmrom_c0_poll_soc(handle);
 	qmrom_pre_read_c0(handle);
 	qmrom_read_c0(handle);
-	qm357xx_rom_c0_poll_soc(handle);
+	qmrom_c0_poll_soc(handle);
 
 	LOG_DBG("%s: sending flash_cmd %u command\n", __func__, flash_cmd);
-	rc = qm357xx_rom_write_cmd32_c0(handle, flash_cmd);
+	rc = qmrom_write_cmd32_c0(handle, flash_cmd);
 	if (rc)
 		goto end;
 
-	qm357xx_rom_c0_poll_cmd_resp(handle);
+	qmrom_c0_poll_cmd_resp(handle);
 	if (handle->sstc->payload[0] != WAITING_FOR_FIRST_KEY_CERT) {
 		LOG_ERR("%s: Waiting for WAITING_FOR_FIRST_KEY_CERT(%#x) but got %#x\n",
 			__func__, WAITING_FOR_FIRST_KEY_CERT,
@@ -419,93 +407,65 @@
 		goto end;
 	}
 
-	qm357xx_rom_c0_poll_soc(handle);
+	qmrom_c0_poll_soc(handle);
 
-	rc = qm357xx_rom_c0_flash_data(handle, all_fws->key1_crt,
-				       ROM_CMD_C0_CERT_DATA,
-				       WAITING_FOR_SECOND_KEY_CERT, false);
+	rc = qmrom_c0_flash_data(handle, all_fws.key1_crt, ROM_CMD_C0_CERT_DATA,
+				 WAITING_FOR_SECOND_KEY_CERT, false);
 	if (rc)
 		goto end;
 
-	rc = qm357xx_rom_c0_flash_data(handle, all_fws->key2_crt,
-				       ROM_CMD_C0_CERT_DATA,
-				       WAITING_FOR_CONTENT_CERT, false);
+	rc = qmrom_c0_flash_data(handle, all_fws.key2_crt, ROM_CMD_C0_CERT_DATA,
+				 WAITING_FOR_CONTENT_CERT, false);
 	if (rc)
 		goto end;
 
-	rc = qm357xx_rom_c0_flash_data(handle, all_fws->fw_crt,
-				       ROM_CMD_C0_CERT_DATA,
-				       WAITING_FOR_SEC_FILE_DATA, false);
+	rc = qmrom_c0_flash_data(handle, all_fws.fw_crt, ROM_CMD_C0_CERT_DATA,
+				 WAITING_FOR_SEC_FILE_DATA, false);
 	if (rc)
 		goto end;
 
-	rc = qm357xx_rom_c0_flash_data(handle, all_fws->fw_img,
-				       ROM_CMD_C0_SEC_IMAGE_DATA,
-				       WAITING_FOR_SEC_FILE_DATA, true);
+	rc = qmrom_c0_flash_data(handle, all_fws.fw_img,
+				 ROM_CMD_C0_SEC_IMAGE_DATA,
+				 WAITING_FOR_SEC_FILE_DATA, true);
 
 #ifdef C0_WRITE_STATS
 	dump_stats();
 #endif
 
-	if (qmrom_spi_read_irq_line(handle->ss_irq_handle)) {
-		int retries = handle->comms_retries;
-
-		do {
-			/* A final product id error likely occurred */
-			qmrom_pre_read_c0(handle);
-			qmrom_read_c0(handle);
-			rc = handle->sstc->payload[0];
-			if (rc) {
-				LOG_ERR("%s: flashing error %d (0x%x) detected\n",
-					__func__, rc, rc);
-				break;
-			}
-		} while (--retries);
-
-		if (retries <= 0) {
-			LOG_ERR("%s: flashing error detected but couldn't be fetched\n",
-				__func__);
-			rc = -1;
-		}
-	}
-
 end:
-	qmrom_free(all_fws->fw_img);
-	qmrom_free(all_fws->fw_crt);
-	qmrom_free(all_fws->key1_crt);
-	qmrom_free(all_fws->key2_crt);
+	qmrom_free(all_fws.fw_img);
+	qmrom_free(all_fws.fw_crt);
+	qmrom_free(all_fws.key1_crt);
+	qmrom_free(all_fws.key2_crt);
 	return rc;
 }
 
-static int qm357xx_rom_c0_flash_debug_cert(struct qmrom_handle *handle,
-					   struct firmware *dbg_cert)
+static int qmrom_c0_flash_debug_cert(struct qmrom_handle *handle,
+				     struct firmware *dbg_cert)
 {
 	int rc;
 
 	LOG_DBG("%s: starting...\n", __func__);
-	rc = qm357xx_rom_c0_wait_ready(handle);
+	rc = qmrom_c0_wait_ready(handle);
 	if (rc)
 		return rc;
 
-	if (handle->chip_rev != CHIP_REVISION_C2) {
-		LOG_DBG("%s: using ROM_CMD_C0_USE_INDIRECT_RRAM_WR command\n",
-			__func__);
-		rc = qm357xx_rom_write_cmd32_c0(
-			handle, ROM_CMD_C0_USE_INDIRECT_RRAM_WR);
-		if (rc)
-			return rc;
-	}
+	LOG_DBG("%s: sending ROM_CMD_C0_USE_DIRECT_RRAM_WR command\n",
+		__func__);
+	rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_USE_INDIRECT_RRAM_WR);
+	if (rc)
+		return rc;
 
-	qm357xx_rom_c0_poll_soc(handle);
+	qmrom_c0_poll_soc(handle);
 	qmrom_pre_read_c0(handle);
 	qmrom_read_c0(handle);
-	qm357xx_rom_c0_poll_soc(handle);
+	qmrom_c0_poll_soc(handle);
 
 	LOG_DBG("%s: sending ROM_CMD_C0_WRITE_DBG_CERT command\n", __func__);
-	rc = qm357xx_rom_write_cmd32_c0(handle, ROM_CMD_C0_WRITE_DBG_CERT);
+	rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_WRITE_DBG_CERT);
 	if (rc)
 		return rc;
-	qm357xx_rom_c0_poll_cmd_resp(handle);
+	qmrom_c0_poll_cmd_resp(handle);
 	if (handle->sstc->payload[0] != WAITING_TO_DEBUG_CERTIFICATE_SIZE) {
 		LOG_ERR("%s: Waiting for WAITING_TO_DEBUG_CERTIFICATE_SIZE(%#x) but got %#x\n",
 			__func__, WAITING_TO_DEBUG_CERTIFICATE_SIZE,
@@ -514,10 +474,10 @@
 	}
 
 	LOG_DBG("%s: sending ROM_CMD_C0_DEBUG_CERT_SIZE command\n", __func__);
-	rc = qm357xx_rom_write_size_cmd32_c0(handle, ROM_CMD_C0_DEBUG_CERT_SIZE,
-					     sizeof(uint32_t),
-					     (const char *)&dbg_cert->size);
-	qm357xx_rom_c0_poll_cmd_resp(handle);
+	rc = qmrom_write_size_cmd32_c0(handle, ROM_CMD_C0_DEBUG_CERT_SIZE,
+				       sizeof(uint32_t),
+				       (const char *)&dbg_cert->size);
+	qmrom_c0_poll_cmd_resp(handle);
 	if (handle->sstc->payload[0] != WAITING_FOR_DEBUG_CERT_DATA) {
 		LOG_ERR("%s: Waiting for WAITING_FOR_DEBUG_CERT_DATA(%#x) but got %#x\n",
 			__func__, WAITING_FOR_DEBUG_CERT_DATA,
@@ -525,23 +485,23 @@
 		return rc;
 	}
 
-	rc = qm357xx_rom_c0_flash_data(handle, dbg_cert, ROM_CMD_C0_CERT_DATA,
-				       WAITING_FOR_DEBUG_CERT_DATA, true);
+	rc = qmrom_c0_flash_data(handle, dbg_cert, ROM_CMD_C0_CERT_DATA,
+				 WAITING_FOR_DEBUG_CERT_DATA, true);
 	return 0;
 }
 
-static int qm357xx_rom_c0_erase_debug_cert(struct qmrom_handle *handle)
+static int qmrom_c0_erase_debug_cert(struct qmrom_handle *handle)
 {
 	int rc;
 
 	LOG_DBG("%s: starting...\n", __func__);
 
-	rc = qm357xx_rom_c0_wait_ready(handle);
+	rc = qmrom_c0_wait_ready(handle);
 	if (rc)
 		return rc;
 
 	LOG_DBG("%s: sending ROM_CMD_C0_ERASE_DBG_CERT command\n", __func__);
-	rc = qm357xx_rom_write_cmd32_c0(handle, ROM_CMD_C0_ERASE_DBG_CERT);
+	rc = qmrom_write_cmd32_c0(handle, ROM_CMD_C0_ERASE_DBG_CERT);
 	if (rc)
 		return rc;
 
diff --git a/libqmrom/src/qmrom_common.c b/libqmrom/src/qmrom_common.c
index 017b346..58ca662 100644
--- a/libqmrom/src/qmrom_common.c
+++ b/libqmrom/src/qmrom_common.c
@@ -10,7 +10,9 @@
 #include <qmrom.h>
 #include <spi_rom_protocol.h>
 
-int qm357xx_rom_probe_device(struct qmrom_handle *handle);
+int qmrom_a0_probe_device(struct qmrom_handle *handle);
+int qmrom_b0_probe_device(struct qmrom_handle *handle);
+int qmrom_c0_probe_device(struct qmrom_handle *handle);
 
 static void qmrom_free_stcs(struct qmrom_handle *h)
 {
@@ -98,28 +100,93 @@
 				  sizeof(struct stc) + rd_size);
 }
 
+int qmrom_write_cmd(struct qmrom_handle *handle, uint8_t cmd)
+{
+	handle->hstc->all = 0;
+	handle->hstc->host_flags.write = 1;
+	handle->hstc->ul = 1;
+	handle->hstc->len = 1;
+	handle->hstc->payload[0] = cmd;
+
+	return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+				  (const char *)handle->hstc,
+				  sizeof(struct stc) + handle->hstc->len);
+}
+
+int qmrom_write_cmd32(struct qmrom_handle *handle, uint32_t cmd)
+{
+	handle->hstc->all = 0;
+	handle->hstc->host_flags.write = 1;
+	handle->hstc->ul = 1;
+	handle->hstc->len = sizeof(cmd);
+	memcpy(handle->hstc->payload, &cmd, sizeof(cmd));
+
+	return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+				  (const char *)handle->hstc,
+				  sizeof(struct stc) + handle->hstc->len);
+}
+
+int qmrom_write_size_cmd(struct qmrom_handle *handle, uint8_t cmd,
+			 uint16_t data_size, const char *data)
+{
+	handle->hstc->all = 0;
+	handle->hstc->host_flags.write = 1;
+	handle->hstc->ul = 1;
+	handle->hstc->len = data_size + 1;
+	handle->hstc->payload[0] = cmd;
+	memcpy(&handle->hstc->payload[1], data, data_size);
+
+	return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+				  (const char *)handle->hstc,
+				  sizeof(struct stc) + handle->hstc->len);
+}
+
+int qmrom_write_size_cmd32(struct qmrom_handle *handle, uint32_t cmd,
+			   uint16_t data_size, const char *data)
+{
+	handle->hstc->all = 0;
+	handle->hstc->host_flags.write = 1;
+	handle->hstc->ul = 1;
+	handle->hstc->len = data_size + sizeof(cmd);
+	memcpy(handle->hstc->payload, &cmd, sizeof(cmd));
+	memcpy(&handle->hstc->payload[sizeof(cmd)], data, data_size);
+
+	return qmrom_spi_transfer(handle->spi_handle, (char *)handle->sstc,
+				  (const char *)handle->hstc,
+				  sizeof(struct stc) + handle->hstc->len);
+}
+
 /*
  * Unfortunately, A0, B0 and C0 have different
  * APIs to get the chip version...
  *
  */
-int qmrom_probe_device(struct qmrom_handle *handle,
-		       enum device_generation_e dev_gen_hint)
+int qmrom_probe_device(struct qmrom_handle *handle)
 {
-	int rc = -1;
+	int rc;
 
-	if (dev_gen_hint == DEVICE_GEN_QM357XX ||
-	    dev_gen_hint == DEVICE_GEN_UNKNOWN)
-		rc = qm357xx_rom_probe_device(handle);
+	/* Test B0 first */
+	rc = qmrom_b0_probe_device(handle);
+	if (!rc)
+		return rc;
 
-	return rc;
+	/* Test C0 next */
+	rc = qmrom_c0_probe_device(handle);
+	if (!rc)
+		return rc;
+
+	/* Finally try A0 */
+	rc = qmrom_a0_probe_device(handle);
+	if (!rc)
+		return rc;
+
+	/* None matched!!! */
+	return -1;
 }
 
 struct qmrom_handle *qmrom_init(void *spi_handle, void *reset_handle,
-				void *ss_rdy_handle, void *ss_irq_handle,
-				int spi_speed, int comms_retries,
-				reset_device_fn reset,
-				enum device_generation_e dev_gen_hint)
+				void *ss_rdy_handle, int comms_retries,
+				reset_device_fn reset)
 {
 	struct qmrom_handle *handle;
 	int rc;
@@ -140,15 +207,14 @@
 	handle->spi_handle = spi_handle;
 	handle->reset_handle = reset_handle;
 	handle->ss_rdy_handle = ss_rdy_handle;
-	handle->ss_irq_handle = ss_irq_handle;
 	handle->comms_retries = comms_retries;
 	handle->chip_rev = CHIP_REVISION_UNKNOWN;
 	handle->device_version = -1;
-	handle->spi_speed = spi_speed;
+	handle->lcs_state = -1;
 
 	handle->dev_ops.reset = reset;
 
-	rc = qmrom_probe_device(handle, dev_gen_hint);
+	rc = qmrom_probe_device(handle);
 	if (rc) {
 		LOG_ERR("%s: qmrom_probe_device returned %d!\n", __func__, rc);
 		qmrom_free_stcs(handle);
@@ -167,6 +233,173 @@
 	qmrom_free(handle);
 }
 
+int qmrom_flash_dbg_cert(struct qmrom_handle *handle, struct firmware *dbg_cert)
+{
+	if (!handle->rom_ops.flash_debug_cert) {
+		LOG_ERR("%s: flash debug certificate not support on this device\n",
+			__func__);
+		return -EINVAL;
+	}
+	return handle->rom_ops.flash_debug_cert(handle, dbg_cert);
+}
+
+int qmrom_erase_dbg_cert(struct qmrom_handle *handle)
+{
+	if (!handle->rom_ops.erase_debug_cert) {
+		LOG_ERR("%s: erase debug certificate not support on this device\n",
+			__func__);
+		return -EINVAL;
+	}
+	return handle->rom_ops.erase_debug_cert(handle);
+}
+
+int qmrom_flash_fw(struct qmrom_handle *handle, const struct firmware *fw)
+{
+	return handle->rom_ops.flash_fw(handle, fw);
+}
+
+int qmrom_flash_unstitched_fw(struct qmrom_handle *handle,
+			      const struct unstitched_firmware *fw)
+{
+	return handle->rom_ops.flash_unstitched_fw(handle, fw);
+}
+
+int qmrom_unstitch_fw(const struct firmware *fw,
+		      struct unstitched_firmware *unstitched_fw,
+		      enum chip_revision_e revision)
+{
+	uint32_t tot_len = 0;
+	uint32_t fw_img_sz = 0;
+	uint32_t fw_crt_sz = 0;
+	uint32_t key1_crt_sz = 0;
+	uint32_t key2_crt_sz = 0;
+	uint8_t *p_key1;
+	uint8_t *p_key2;
+	uint8_t *p_crt;
+	uint8_t *p_fw;
+	int ret = 0;
+
+	if (revision == CHIP_REVISION_A0) {
+		LOG_ERR("%s: A0, no unstitching!!!\n", __func__);
+		return -EINVAL;
+	}
+	if (fw->size < 2 * sizeof(key1_crt_sz)) {
+		LOG_ERR("%s: Not enough data (%zu) to unstitch\n", __func__,
+			fw->size);
+		return -EINVAL;
+	}
+	LOG_INFO("%s: Unstitching %zu bytes\n", __func__, fw->size);
+
+	/* key1 */
+	key1_crt_sz = *(uint32_t *)&fw->data[tot_len];
+	if (tot_len + key1_crt_sz + sizeof(key1_crt_sz) > fw->size) {
+		LOG_ERR("%s: Invalid or corrupted stitched file at offset \
+				%" PRIu32 " (key1)\n",
+			__func__, tot_len);
+		ret = -EINVAL;
+		goto out;
+	}
+	tot_len += sizeof(key1_crt_sz);
+	p_key1 = (uint8_t *)&fw->data[tot_len];
+	tot_len += key1_crt_sz;
+
+	/* key2 */
+	key2_crt_sz = *(uint32_t *)&fw->data[tot_len];
+	if (tot_len + key2_crt_sz + sizeof(key2_crt_sz) > fw->size) {
+		LOG_ERR("%s: Invalid or corrupted stitched file at offset \
+				%" PRIu32 " (key2)\n",
+			__func__, tot_len);
+		ret = -EINVAL;
+		goto out;
+	}
+	tot_len += sizeof(key2_crt_sz);
+	p_key2 = (uint8_t *)&fw->data[tot_len];
+	tot_len += key2_crt_sz;
+
+	/* cert */
+	fw_crt_sz = *(uint32_t *)&fw->data[tot_len];
+	if (tot_len + fw_crt_sz + sizeof(fw_crt_sz) > fw->size) {
+		LOG_ERR("%s: Invalid or corrupted stitched file at offset \
+				%" PRIu32 " (content cert)\n",
+			__func__, tot_len);
+		ret = -EINVAL;
+		goto out;
+	}
+	tot_len += sizeof(fw_crt_sz);
+	p_crt = (uint8_t *)&fw->data[tot_len];
+	tot_len += fw_crt_sz;
+
+	/* fw */
+	fw_img_sz = *(uint32_t *)&fw->data[tot_len];
+	if (tot_len + fw_img_sz + sizeof(fw_img_sz) != fw->size) {
+		LOG_ERR("%s: Invalid or corrupted stitched file at offset \
+				%" PRIu32 " (firmnware)\n",
+			__func__, tot_len);
+		ret = -EINVAL;
+		goto out;
+	}
+	tot_len += sizeof(fw_img_sz);
+	p_fw = (uint8_t *)&fw->data[tot_len];
+
+	qmrom_alloc(unstitched_fw->fw_img, fw_img_sz + sizeof(struct firmware));
+	if (unstitched_fw->fw_img == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	qmrom_alloc(unstitched_fw->fw_crt, fw_crt_sz + sizeof(struct firmware));
+	if (unstitched_fw->fw_crt == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	qmrom_alloc(unstitched_fw->key1_crt,
+		    key1_crt_sz + sizeof(struct firmware));
+	if (unstitched_fw->key1_crt == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	qmrom_alloc(unstitched_fw->key2_crt,
+		    key2_crt_sz + sizeof(struct firmware));
+	if (unstitched_fw->key2_crt == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	unstitched_fw->key1_crt->data =
+		(const uint8_t *)(unstitched_fw->key1_crt + 1);
+	unstitched_fw->key2_crt->data =
+		(const uint8_t *)(unstitched_fw->key2_crt + 1);
+	unstitched_fw->fw_crt->data =
+		(const uint8_t *)(unstitched_fw->fw_crt + 1);
+	unstitched_fw->fw_img->data =
+		(const uint8_t *)(unstitched_fw->fw_img + 1);
+	unstitched_fw->key1_crt->size = key1_crt_sz;
+	unstitched_fw->key2_crt->size = key2_crt_sz;
+	unstitched_fw->fw_crt->size = fw_crt_sz;
+	unstitched_fw->fw_img->size = fw_img_sz;
+
+	memcpy((void *)unstitched_fw->key1_crt->data, p_key1, key1_crt_sz);
+	memcpy((void *)unstitched_fw->key2_crt->data, p_key2, key2_crt_sz);
+	memcpy((void *)unstitched_fw->fw_crt->data, p_crt, fw_crt_sz);
+	memcpy((void *)unstitched_fw->fw_img->data, p_fw, fw_img_sz);
+	return 0;
+
+err:
+	if (unstitched_fw->fw_img)
+		qmrom_free(unstitched_fw->fw_img);
+	if (unstitched_fw->fw_crt)
+		qmrom_free(unstitched_fw->fw_crt);
+	if (unstitched_fw->key1_crt)
+		qmrom_free(unstitched_fw->key1_crt);
+	if (unstitched_fw->key2_crt)
+		qmrom_free(unstitched_fw->key2_crt);
+
+out:
+	return ret;
+}
+
 int qmrom_reboot_bootloader(struct qmrom_handle *handle)
 {
 	int rc;
diff --git a/qm35-spi.c b/qm35-spi.c
index c39f944..054518f 100644
--- a/qm35-spi.c
+++ b/qm35-spi.c
@@ -26,7 +26,6 @@
  * QM35 UCI over HSSPI protocol
  */
 
-#include <linux/version.h>
 #include <linux/bitfield.h>
 #include <linux/interrupt.h>
 #include <linux/ioctl.h>
@@ -50,8 +49,6 @@
 #include <qmrom_log.h>
 #include <spi_rom_protocol.h>
 
-#include <fwupdater.h>
-
 #include "qm35.h"
 #include "uci_ioctls.h"
 #include "hsspi.h"
@@ -60,8 +57,6 @@
 
 #define QM35_REGULATOR_DELAY_US 1000
 #define QMROM_RETRIES 10
-#define FLASHING_RETRIES 10 /* Intentionaly high value */
-/* Redefine certificate error here since original definitions are separate */
 #define REGULATORS_ENABLED(x) (x->vdd1 || x->vdd2 || x->vdd3 || x->vdd4)
 
 #ifndef NO_UWB_HAL
@@ -83,8 +78,8 @@
 module_param(flash_on_probe, bool, 0444);
 MODULE_PARM_DESC(flash_on_probe, "Flash during the module probe");
 
-int spi_speed_hz;
-module_param(spi_speed_hz, int, 0644);
+static int spi_speed_hz;
+module_param(spi_speed_hz, int, 0444);
 MODULE_PARM_DESC(spi_speed_hz, "SPI speed (if not set use DTS's one)");
 
 static char *fwname = NULL;
@@ -92,11 +87,11 @@
 MODULE_PARM_DESC(fwname, "Use fwname as firmware binary to flash QM35");
 
 static bool wake_use_wakeup = true;
-module_param(wake_use_wakeup, bool, 0644);
+module_param(wake_use_wakeup, bool, 0444);
 MODULE_PARM_DESC(wake_use_wakeup, "Use wakeup pin to wake up QM35");
 
 static bool wake_use_csn = false;
-module_param(wake_use_csn, bool, 0644);
+module_param(wake_use_csn, bool, 0444);
 MODULE_PARM_DESC(wake_use_csn, "Use HSSPI CSn pin to wake up QM35");
 
 static bool wake_on_ssirq = true;
@@ -105,34 +100,22 @@
 		 "Allow QM35 to wakeup the platform using ss_irq");
 
 int trace_spi_xfers;
-module_param(trace_spi_xfers, int, 0644);
+module_param(trace_spi_xfers, int, 0444);
 MODULE_PARM_DESC(trace_spi_xfers, "Trace all the SPI transfers");
 
 int qmrom_retries = QMROM_RETRIES;
-module_param(qmrom_retries, int, 0644);
+module_param(qmrom_retries, int, 0444);
 MODULE_PARM_DESC(qmrom_retries, "QMROM retries");
 
-int flashing_retries = FLASHING_RETRIES;
-module_param(flashing_retries, int, 0644);
-MODULE_PARM_DESC(flashing_retries, "Flashing retries");
-
 int reset_on_error = 1;
-module_param(reset_on_error, int, 0644);
+module_param(reset_on_error, int, 0444);
 MODULE_PARM_DESC(reset_on_error, "Reset the QM35 on successive errors");
 
 int log_qm_traces = 1;
 module_param(log_qm_traces, int, 0444);
 MODULE_PARM_DESC(log_qm_traces, "Logs the QM35 traces in the kernel messages");
 
-int fu_spi_speed_hz;
-module_param(fu_spi_speed_hz, int, 0644);
-MODULE_PARM_DESC(fu_spi_speed_hz, "FW updater SPI speed");
-
-int qmrom_spi_speed_hz;
-module_param(qmrom_spi_speed_hz, int, 0644);
-MODULE_PARM_DESC(qmrom_spi_speed_hz, "FW updater SPI speed");
-
-static uint8_t qm_soc_id[QM357XX_ROM_SOC_ID_LEN];
+static uint8_t qm_soc_id[ROM_SOC_ID_LEN];
 static uint16_t qm_dev_id;
 
 /*
@@ -374,13 +357,8 @@
 	if (wake_use_wakeup)
 		gpiod_set_value(qm35_hdl->gpio_wakeup, 0);
 
-	if (!qm35_hdl->flashing) {
-		hsspi_clear_spi_slave_busy(&qm35_hdl->hsspi);
-		hsspi_set_spi_slave_ready(&qm35_hdl->hsspi);
-	} else {
-		qm35_hdl->qmrom_qm_ready = true;
-		wake_up_interruptible(&qm35_hdl->qmrom_wq_ready);
-	}
+	hsspi_clear_spi_slave_busy(&qm35_hdl->hsspi);
+	hsspi_set_spi_slave_ready(&qm35_hdl->hsspi);
 
 	return IRQ_HANDLED;
 }
@@ -478,133 +456,25 @@
 	return ret;
 }
 
-static int qm_firmware_flash_fw(struct qm35_ctx *qm35_hdl,
-				struct qmrom_handle *h,
-				const struct firmware *fw)
-{
-	int rc = 0, nb_retries = FLASHING_RETRIES;
-	do {
-		/* If the previous flashing failed, re-enter the QM
-		 * rom code so it will be in the same initial state
-		 */
-		if (rc)
-			qmrom_reboot_bootloader(h);
-
-		rc = qm357xx_rom_flash_fw(h, fw);
-		if (rc)
-			dev_err(&qm35_hdl->spi->dev,
-				"Attempt %d: flashing failed with %d!\n",
-				FLASHING_RETRIES - nb_retries, rc);
-		if (rc == PEG_ERR_FIRST_KEY_CERT_OR_FW_VER)
-			break;
-	} while (rc && --nb_retries > 0);
-	return rc;
-}
-
-static int qm_firmware_flash_macro_pkg(struct qm35_ctx *qm35_hdl,
-				       struct qmrom_handle *h,
-				       const struct firmware *fw)
-{
-	int rc, nb_retries = FLASHING_RETRIES;
-	char *fw_data;
-	uint32_t fw_size;
-
-	rc = qm357xx_rom_fw_macro_pkg_get_fw_idx(fw, 1, &fw_size, &fw_data);
-	if (rc) {
-		dev_err(&qm35_hdl->spi->dev,
-			"FW MACRO PACKAGE corrupted = %d\n", rc);
-		return rc;
-	}
-	if (*(uint32_t *)fw_data != CRYPTO_FIRMWARE_PACK_MAGIC_VALUE) {
-		rc = -EINVAL;
-		dev_err(&qm35_hdl->spi->dev,
-			"FW PACKAGE not found - magic is %04x, size is %d\n",
-			*(uint32_t *)fw_data, fw_size);
-		return rc;
-	}
-
-	do {
-		/* If the previous flashing failed, re-enter the QM
-		 * rom code so it will be in the same initial state
-		 */
-		if (spi_speed_hz)
-			qmrom_spi_set_freq(spi_speed_hz);
-		else
-			qmrom_spi_set_freq(DEFAULT_SPI_CLOCKRATE);
-
-		if (rc)
-			qmrom_reboot_bootloader(h);
-
-		/* The Macro Package contain the fw updater and the package
-		 * simply flash the first and provide the second to
-		 * the updater lib
-		 */
-		rc = qm357xx_rom_flash_fw(h, fw);
-		if (rc) {
-			dev_err(&qm35_hdl->spi->dev,
-				"Attempt %d: fw updater flashing failed with %d!\n",
-				FLASHING_RETRIES - nb_retries, rc);
-			if (rc == PEG_ERR_FIRST_KEY_CERT_OR_FW_VER)
-				break;
-			continue;
-		}
-
-		/* Now flash the firmware proper */
-		if (fu_spi_speed_hz)
-			qmrom_spi_set_freq(fu_spi_speed_hz);
-		else
-			qmrom_spi_set_freq(FWUPDATER_SPI_SPEED_HZ);
-		rc = run_fwupdater(h, fw_data, fw_size);
-		if (rc) {
-			dev_err(&qm35_hdl->spi->dev,
-				"Attempt %d: fw app flashing failed with %d!\n",
-				FLASHING_RETRIES - nb_retries, rc);
-		}
-	} while (rc && --nb_retries > 0);
-	return rc;
-}
-
 static int qm_firmware_flashing(void *handle, struct qmrom_handle *h,
-				bool *is_macro_pkg, bool use_prod_fw)
+				bool use_prod_fw)
 {
 	struct qm35_ctx *qm35_hdl = (struct qm35_ctx *)handle;
 	struct spi_device *spi = qm35_hdl->spi;
-	int rc = 0;
 	const struct firmware *fw;
-#ifdef C0_WRITE_STATS
-	uint64_t elapsed_time_ns;
-	ktime_t start_time;
-#endif
+	int ret = 0;
 
-	fw = qmrom_spi_get_firmware(&spi->dev, h, is_macro_pkg, use_prod_fw);
+	fw = qmrom_spi_get_firmware(&spi->dev, h, use_prod_fw);
 	if (fw == NULL) {
 		dev_err(&spi->dev, "Firmware file not present!\n");
 		return -1;
 	}
 
-#ifdef C0_WRITE_STATS
-	start_time = ktime_get();
-#endif
-
-	qm35_hdl->flashing = true;
-	if (!*is_macro_pkg)
-		rc = qm_firmware_flash_fw(qm35_hdl, h, fw);
-	else
-		rc = qm_firmware_flash_macro_pkg(qm35_hdl, h, fw);
-
-#ifdef C0_WRITE_STATS
-	elapsed_time_ns = ktime_to_ns(ktime_sub(ktime_get(), start_time));
-	if (!rc)
-		dev_warn(&spi->dev, "Fw_updater flashed in %llu us\n",
-			 div_u64(elapsed_time_ns, 1000));
-#endif
+	ret = qmrom_flash_fw(h, fw);
+	dev_dbg(&spi->dev, "Return qmrom_flash_fw = %d!\n", ret);
 
 	qmrom_spi_release_firmware(fw);
-	qm35_hdl->flashing = false;
-
-	/* Reset the device anyway */
-	qmrom_spi_reset_device(qm35_hdl);
-	return rc;
+	return ret;
 }
 
 static int qm_firmware_load(struct qm35_ctx *qm35_hdl)
@@ -612,19 +482,14 @@
 	struct spi_device *spi = qm35_hdl->spi;
 	unsigned int state = qm35_get_state(qm35_hdl);
 	struct qmrom_handle *h;
-	bool is_macro_pkg = false;
-	int ret, irq = gpiod_to_irq(qm35_hdl->gpio_ss_rdy);
+	int ret;
 
 	qm35_set_state(qm35_hdl, QM35_CTRL_STATE_FW_DOWNLOADING);
 
 	qmrom_set_log_device(&spi->dev, LOG_WARN);
 
-	if (irq >= 0)
-		enable_irq(irq);
-
-	h = qmrom_init(&spi->dev, qm35_hdl, qm35_hdl, qm35_hdl->gpio_ss_irq,
-		       qmrom_spi_speed_hz, qmrom_retries,
-		       qmrom_spi_reset_device, DEVICE_GEN_QM357XX);
+	h = qmrom_init(&spi->dev, qm35_hdl, qm35_hdl->gpio_ss_rdy,
+		       qmrom_retries, qmrom_spi_reset_device);
 	if (!h) {
 		pr_err("qmrom_init failed\n");
 		ret = -1;
@@ -635,16 +500,14 @@
 	dev_info(&spi->dev, "    dev_id:    deca%04x\n", h->device_version);
 
 	if (h->chip_rev != CHIP_REVISION_A0) {
-		dev_info(&spi->dev, "    soc_id:    %*phN\n",
-			 QM357XX_ROM_SOC_ID_LEN, h->qm357xx_soc_info.soc_id);
-		dev_info(&spi->dev, "    uuid:      %*phN\n",
-			 QM357XX_ROM_UUID_LEN, h->qm357xx_soc_info.uuid);
-		dev_info(&spi->dev, "    lcs_state: %u\n",
-			 h->qm357xx_soc_info.lcs_state);
+		dev_info(&spi->dev, "    soc_id:    %*phN\n", ROM_SOC_ID_LEN,
+			 h->soc_id);
+		dev_info(&spi->dev, "    uuid:      %*phN\n", ROM_UUID_LEN,
+			 h->uuid);
+		dev_info(&spi->dev, "    lcs_state: %u\n", h->lcs_state);
 
 		memcpy(&qm_dev_id, &h->device_version, sizeof(qm_dev_id));
-		memcpy(qm_soc_id, h->qm357xx_soc_info.soc_id,
-		       QM357XX_ROM_SOC_ID_LEN);
+		memcpy(qm_soc_id, h->soc_id, ROM_SOC_ID_LEN);
 
 		debug_soc_info_available(&qm35_hdl->debug);
 	} else {
@@ -653,21 +516,18 @@
 	}
 
 	dev_dbg(&spi->dev, "Starting device flashing!\n");
-	ret = qm_firmware_flashing(qm35_hdl, h, &is_macro_pkg, true);
+	ret = qm_firmware_flashing(qm35_hdl, h, true);
 	if (ret) {
 		qmrom_reboot_bootloader(h);
-		ret = qm_firmware_flashing(qm35_hdl, h, &is_macro_pkg, false);
+		ret = qm_firmware_flashing(qm35_hdl, h, false);
 	}
 
 	if (ret)
 		dev_err(&spi->dev, "Firmware download failed with %d!\n", ret);
 	else
-		dev_info(&spi->dev, "Device flashing succeeded!\n");
+		dev_info(&spi->dev, "Device flashing completed!\n");
 
 out:
-	if (irq >= 0)
-		disable_irq_nosync(irq);
-
 	qm35_set_state(qm35_hdl, state);
 
 	return ret;
@@ -682,7 +542,7 @@
 
 int qm_get_soc_id(struct qm35_ctx *qm35_hdl, uint8_t *soc_id)
 {
-	memcpy(soc_id, qm_soc_id, QM357XX_ROM_SOC_ID_LEN);
+	memcpy(soc_id, qm_soc_id, ROM_SOC_ID_LEN);
 
 	return 0;
 }
@@ -707,7 +567,8 @@
  */
 static int hsspi_irqs_setup(struct qm35_ctx *qm35_ctx)
 {
-	int ret, irq;
+	int ret;
+	unsigned long ss_irqflags;
 
 	/* Get READY GPIO */
 	qm35_ctx->gpio_ss_rdy =
@@ -715,47 +576,25 @@
 	if (IS_ERR(qm35_ctx->gpio_ss_rdy))
 		return PTR_ERR(qm35_ctx->gpio_ss_rdy);
 
-	irq = gpiod_to_irq(qm35_ctx->gpio_ss_rdy);
-	if (irq < 0) {
-		dev_err(&qm35_ctx->spi->dev,
-			"%s: gpiod_to_irq(ss-ready) returns %d", __func__, irq);
-		return irq;
-	}
-	ret = devm_request_irq(&qm35_ctx->spi->dev, irq, &qm35_ss_rdy_handler,
-			       IRQF_TRIGGER_RISING, "hsspi-ss-rdy", qm35_ctx);
-	if (ret) {
-		dev_err(&qm35_ctx->spi->dev, "%s: devm_request_irq returned %d",
-			__func__, ret);
+	ret = devm_request_irq(&qm35_ctx->spi->dev,
+			       gpiod_to_irq(qm35_ctx->gpio_ss_rdy),
+			       &qm35_ss_rdy_handler, IRQF_TRIGGER_RISING,
+			       "hsspi-ss-rdy", qm35_ctx);
+	if (ret)
 		return ret;
-	}
-	/* devm_request_irq enables the interrupt. On probe, the hsspi is in
-	 * HSSPI_STOPPED state by default. In this state, the interrupt is
-	 * expected to be disabled. */
-	disable_irq(irq);
 
 	/* get SS_IRQ GPIO */
-	qm35_ctx->gpio_ss_irq =
-		devm_gpiod_get(&qm35_ctx->spi->dev, "ss-irq", GPIOD_IN);
-	if (IS_ERR(qm35_ctx->gpio_ss_irq)) {
-		dev_err(&qm35_ctx->spi->dev,
-			"%s: gpiod_get_index(ss-irq) returned %pK", __func__,
-			qm35_ctx->gpio_ss_irq);
-	}
+	qm35_ctx->gpio_ss_irq = devm_gpiod_get_optional(&qm35_ctx->spi->dev,
+							"ss-irq", GPIOD_IN);
 
-	qm35_ctx->spi->irq = gpiod_to_irq(qm35_ctx->gpio_ss_irq);
-	if (qm35_ctx->spi->irq < 0) {
-		dev_err(&qm35_ctx->spi->dev,
-			"%s: gpiod_to_irq(ss-irq) returned %d", __func__,
-			qm35_ctx->spi->irq);
-		return qm35_ctx->spi->irq;
-	}
-	ret = devm_request_irq(&qm35_ctx->spi->dev, qm35_ctx->spi->irq,
-			       &qm35_irq_handler, IRQF_TRIGGER_HIGH,
-			       "hsspi-ss-irq", qm35_ctx);
-	if (ret) {
-		dev_err(&qm35_ctx->spi->dev, "%s: devm_request_irq returned %d",
-			__func__, ret);
-		return ret;
+	if (qm35_ctx->gpio_ss_irq) {
+		if (IS_ERR(qm35_ctx->gpio_ss_irq))
+			return PTR_ERR(qm35_ctx->gpio_ss_irq);
+
+		qm35_ctx->spi->irq = gpiod_to_irq(qm35_ctx->gpio_ss_irq);
+		ss_irqflags = IRQF_TRIGGER_HIGH;
+	} else {
+		ss_irqflags = irq_get_trigger_type(qm35_ctx->spi->irq);
 	}
 
 	if (wake_on_ssirq) {
@@ -769,6 +608,12 @@
 	qm35_ctx->hsspi.wakeup = qm35_wakeup;
 	qm35_ctx->hsspi.reset_qm35 = qm35_reset_hook;
 
+	ret = devm_request_irq(&qm35_ctx->spi->dev, qm35_ctx->spi->irq,
+			       &qm35_irq_handler, ss_irqflags, "hsspi-ss-irq",
+			       qm35_ctx);
+	if (ret)
+		return ret;
+
 	/* Get exton */
 	qm35_ctx->gpio_exton =
 		devm_gpiod_get_optional(&qm35_ctx->spi->dev, "exton", GPIOD_IN);
@@ -916,7 +761,6 @@
 	qm35_ctx->spi = spi;
 	qm35_ctx->log_qm_traces = log_qm_traces;
 	spin_lock_init(&qm35_ctx->lock);
-	init_waitqueue_head(&qm35_ctx->qmrom_wq_ready);
 
 	spi_set_drvdata(spi, qm35_ctx);
 
@@ -998,11 +842,11 @@
 	if (!NO_UWB_HAL) {
 		/* If regulators not available, QM is powered on */
 		if (!REGULATORS_ENABLED(qm35_ctx))
-			qm35_hsspi_start(qm35_ctx);
+			hsspi_start(&qm35_ctx->hsspi);
 	} else {
 		qm35_regulators_set(qm35_ctx, true);
 		usleep_range(100000, 100000);
-		qm35_hsspi_start(qm35_ctx);
+		hsspi_start(&qm35_ctx->hsspi);
 	}
 
 	ret = misc_register(&qm35_ctx->uci_dev);
@@ -1043,7 +887,7 @@
 
 	misc_deregister(&qm35_hdl->uci_dev);
 
-	qm35_hsspi_stop(qm35_hdl);
+	hsspi_stop(&qm35_hdl->hsspi);
 
 	hsspi_unregister(&qm35_hdl->hsspi, &qm35_hdl->log_layer.hlayer);
 	hsspi_unregister(&qm35_hdl->hsspi, &qm35_hdl->coredump_layer.hlayer);
diff --git a/qm35.h b/qm35.h
index 7bc3d70..59cf825 100644
--- a/qm35.h
+++ b/qm35.h
@@ -4,7 +4,6 @@
 #define __QM35_H___
 
 #include <linux/gpio.h>
-#include <linux/wait.h>
 #include <linux/delay.h>
 #include <linux/spi/spi.h>
 #include <linux/spinlock.h>
@@ -17,9 +16,6 @@
 #include "hsspi_log.h"
 #include "debug.h"
 
-#define FWUPDATER_SPI_SPEED_HZ 20000000
-#define DEFAULT_SPI_CLOCKRATE 3000000
-
 #define DEBUG_CERTIFICATE_SIZE 2560
 #define QM_RESET_LOW_MS 2
 /*
@@ -28,7 +24,7 @@
 #define QM_BOOT_MS 450
 #define QM_BEFORE_RESET_MS 450
 
-#define DRV_VERSION "7.2.0-rc6"
+#define DRV_VERSION "6.3.8-rc1"
 
 struct regulator;
 
@@ -61,11 +57,6 @@
 	struct regulator *vdd4;
 	bool regulators_enabled;
 	bool log_qm_traces;
-
-	/* qmrom support */
-	struct wait_queue_head qmrom_wq_ready;
-	bool qmrom_qm_ready;
-	bool flashing;
 };
 
 static inline unsigned int qm35_get_state(struct qm35_ctx *qm35_hdl)
diff --git a/qmrom_spi.c b/qmrom_spi.c
index 76ce52e..0592d2f 100644
--- a/qmrom_spi.c
+++ b/qmrom_spi.c
@@ -26,7 +26,6 @@
  * QM35 FW ROM protocol SPI ops
  */
 
-#include <linux/interrupt.h>
 #include <linux/spi/spi.h>
 
 #include <qmrom_spi.h>
@@ -34,12 +33,6 @@
 
 #include "qm35.h"
 
-/* TODO Compile QM358XX code */
-int qm358xx_rom_probe_device(struct qmrom_handle *handle)
-{
-	return -1;
-}
-
 static const char *fwname = NULL;
 static unsigned int speed_hz;
 extern int trace_spi_xfers;
@@ -52,7 +45,6 @@
 int qmrom_spi_transfer(void *handle, char *rbuf, const char *wbuf, size_t size)
 {
 	struct spi_device *spi = (struct spi_device *)handle;
-	struct qm35_ctx *qm35_ctx = spi_get_drvdata(spi);
 	int rc;
 
 	struct spi_transfer xfer[] = {
@@ -64,14 +56,13 @@
 		},
 	};
 
-	qm35_ctx->qmrom_qm_ready = false;
 	rc = spi_sync_transfer(spi, xfer, ARRAY_SIZE(xfer));
 
 	if (trace_spi_xfers) {
-		print_hex_dump(KERN_DEBUG, "qm35 tx:", DUMP_PREFIX_NONE, 16, 1,
-			       wbuf, size, false);
-		print_hex_dump(KERN_DEBUG, "qm35 rx:", DUMP_PREFIX_NONE, 16, 1,
-			       rbuf, size, false);
+		print_hex_dump(KERN_DEBUG, "tx:", DUMP_PREFIX_NONE, 16, 1, wbuf,
+			       size, false);
+		print_hex_dump(KERN_DEBUG, "rx:", DUMP_PREFIX_NONE, 16, 1, rbuf,
+			       size, false);
 	}
 
 	return rc;
@@ -103,25 +94,26 @@
 
 const struct firmware *qmrom_spi_get_firmware(void *handle,
 					      struct qmrom_handle *qmrom_h,
-					      bool *is_macro_pkg,
 					      bool use_prod_fw)
 {
 	const struct firmware *fw;
 	struct spi_device *spi = handle;
-	const char *fw_name;
+	char _fw_name[16]; /* enough room to store "qm35_xx_xxx.bin" */
+	const char *fw_name = _fw_name;
 	int ret;
-	uint32_t lcs_state = qmrom_h->qm357xx_soc_info.lcs_state;
+	enum chip_revision_e revision = qmrom_h->chip_rev;
+	int lcs_state = qmrom_h->lcs_state;
 
 	if (!fwname) {
-		if (lcs_state != CC_BSV_SECURE_LCS) {
-			dev_warn(&spi->dev, "LCS state is not secure.");
-		}
-
-		if (use_prod_fw)
-			fw_name = "qm35_fw_pkg_prod.bin";
-		else
-			fw_name = "qm35_fw_pkg.bin";
-		*is_macro_pkg = true;
+		if (revision == CHIP_REVISION_A0)
+			fw_name = "qm35_a0.bin";
+		else if (lcs_state == CC_BSV_SECURE_LCS) {
+			if (use_prod_fw)
+				fw_name = "qm35_b0_oem_prod.bin";
+			else
+				fw_name = "qm35_b0_oem.bin";
+		} else
+			fw_name = "qm35_b0_icv.bin";
 	} else {
 		fw_name = fwname;
 	}
@@ -129,24 +121,6 @@
 
 	ret = request_firmware(&fw, fw_name, &spi->dev);
 	if (ret) {
-		if (lcs_state != CC_BSV_SECURE_LCS) {
-			dev_warn(&spi->dev, "LCS state is not secure.");
-		}
-
-		/* Didn't get the macro package, try the stitched image */
-		*is_macro_pkg = false;
-		if (use_prod_fw)
-			fw_name = "qm35_oem_prod.bin";
-		else
-			fw_name = "qm35_oem.bin";
-		dev_info(&spi->dev, "Requesting fw %s!\n", fw_name);
-		ret = request_firmware(&fw, fw_name, &spi->dev);
-		if (!ret) {
-			dev_info(&spi->dev, "Firmware size is %zu!\n",
-				 fw->size);
-			return fw;
-		}
-
 		release_firmware(fw);
 		dev_err(&spi->dev,
 			"request_firmware failed (ret=%d) for '%s'\n", ret,
@@ -166,17 +140,11 @@
 
 int qmrom_spi_wait_for_ready_line(void *handle, unsigned int timeout_ms)
 {
-	struct qm35_ctx *qm35_ctx = (struct qm35_ctx *)handle;
-
-	wait_event_interruptible_timeout(qm35_ctx->qmrom_wq_ready,
-					 qm35_ctx->qmrom_qm_ready,
-					 msecs_to_jiffies(timeout_ms));
-	return gpiod_get_value(qm35_ctx->gpio_ss_rdy) > 0 ? 0 : -1;
-}
-
-int qmrom_spi_read_irq_line(void *handle)
-{
-	return gpiod_get_value(handle);
+	int count_down = (int)timeout_ms;
+	while (!gpiod_get_value(handle) && (--count_down >= 0)) {
+		usleep_range(1000, 1100);
+	}
+	return gpiod_get_value(handle) ? 0 : -1;
 }
 
 void qmrom_spi_set_freq(unsigned int freq)
@@ -184,7 +152,7 @@
 	speed_hz = freq;
 }
 
-unsigned int qmrom_spi_get_freq(void)
+unsigned int qmrom_spi_get_freq()
 {
 	return speed_hz;
 }