* struct pcc_chan_info - PCC channel specific information
  *
  * @chan: PCC channel information with Shared Memory Region info
- * @db_vaddr: cached virtual address for doorbell register
- * @plat_irq_ack_vaddr: cached virtual address for platform interrupt
- *     acknowledge register
+ * @db: PCC register bundle for the doorbell register
+ * @plat_irq_ack: PCC register bundle for the platform interrupt acknowledge
+ *     register
  * @plat_irq: platform interrupt
  */
 struct pcc_chan_info {
        struct pcc_mbox_chan chan;
-       void __iomem *db_vaddr;
-       void __iomem *plat_irq_ack_vaddr;
+       struct pcc_chan_reg db;
+       struct pcc_chan_reg plat_irq_ack;
        int plat_irq;
 };
 
  */
 static irqreturn_t pcc_mbox_irq(int irq, void *p)
 {
-       struct acpi_generic_address *doorbell_ack;
-       struct acpi_pcct_hw_reduced *pcct_ss;
        struct pcc_chan_info *pchan;
        struct mbox_chan *chan = p;
-       u64 doorbell_ack_preserve;
-       u64 doorbell_ack_write;
-       u64 doorbell_ack_val;
-       int ret;
 
-       pcct_ss = chan->con_priv;
+       pchan = chan->con_priv;
 
-       mbox_chan_received_data(chan, NULL);
+       if (pcc_chan_reg_read_modify_write(&pchan->plat_irq_ack))
+               return IRQ_NONE;
 
-       if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
-               struct acpi_pcct_hw_reduced_type2 *pcct2_ss = chan->con_priv;
-               u32 id = chan - pcc_mbox_channels;
-
-               pchan = chan_info + id;
-               doorbell_ack = &pcct2_ss->platform_ack_register;
-               doorbell_ack_preserve = pcct2_ss->ack_preserve_mask;
-               doorbell_ack_write = pcct2_ss->ack_write_mask;
-
-               ret = read_register(pchan->plat_irq_ack_vaddr,
-                                   &doorbell_ack_val, doorbell_ack->bit_width);
-               if (ret)
-                       return IRQ_NONE;
-
-               ret = write_register(pchan->plat_irq_ack_vaddr,
-                                    (doorbell_ack_val & doorbell_ack_preserve)
-                                       | doorbell_ack_write,
-                                    doorbell_ack->bit_width);
-               if (ret)
-                       return IRQ_NONE;
-       }
+       mbox_chan_received_data(chan, NULL);
 
        return IRQ_HANDLED;
 }
  */
 static int pcc_send_data(struct mbox_chan *chan, void *data)
 {
-       struct acpi_pcct_hw_reduced *pcct_ss = chan->con_priv;
-       struct acpi_generic_address *doorbell;
-       struct pcc_chan_info *pchan;
-       u64 doorbell_preserve;
-       u64 doorbell_val;
-       u64 doorbell_write;
-       u32 id = chan - pcc_mbox_channels;
-       int ret = 0;
+       struct pcc_chan_info *pchan = chan->con_priv;
 
-       if (id >= pcc_mbox_ctrl.num_chans) {
-               pr_debug("pcc_send_data: Invalid mbox_chan passed\n");
-               return -ENOENT;
-       }
-
-       pchan = chan_info + id;
-       doorbell = &pcct_ss->doorbell_register;
-       doorbell_preserve = pcct_ss->preserve_mask;
-       doorbell_write = pcct_ss->write_mask;
-
-       /* Sync notification from OS to Platform. */
-       if (pchan->db_vaddr) {
-               ret = read_register(pchan->db_vaddr, &doorbell_val,
-                                   doorbell->bit_width);
-               if (ret)
-                       return ret;
-               ret = write_register(pchan->db_vaddr,
-                                    (doorbell_val & doorbell_preserve)
-                                     | doorbell_write, doorbell->bit_width);
-       } else {
-               ret = acpi_read(&doorbell_val, doorbell);
-               if (ret)
-                       return ret;
-               ret = acpi_write((doorbell_val & doorbell_preserve) | doorbell_write,
-                       doorbell);
-       }
-       return ret;
+       return pcc_chan_reg_read_modify_write(&pchan->db);
 }
 
 static const struct mbox_chan_ops pcc_chan_ops = {
 static int pcc_parse_subspace_irq(struct pcc_chan_info *pchan,
                                  struct acpi_subtable_header *pcct_entry)
 {
+       int ret = 0;
        struct acpi_pcct_hw_reduced *pcct_ss;
 
        if (pcct_entry->type < ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
        if (pcct_ss->header.type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
                struct acpi_pcct_hw_reduced_type2 *pcct2_ss = (void *)pcct_ss;
 
-               pchan->plat_irq_ack_vaddr =
-                       acpi_os_ioremap(pcct2_ss->platform_ack_register.address,
-                                       pcct2_ss->platform_ack_register.bit_width / 8);
-               if (!pchan->plat_irq_ack_vaddr) {
-                       pr_err("Failed to ioremap PCC ACK register\n");
-                       return -ENOMEM;
-               }
+               ret = pcc_chan_reg_init(&pchan->plat_irq_ack,
+                                       &pcct2_ss->platform_ack_register,
+                                       pcct2_ss->ack_preserve_mask,
+                                       pcct2_ss->ack_write_mask, 0,
+                                       "PLAT IRQ ACK");
        }
 
-       return 0;
+       return ret;
 }
 
 /**
  * @pchan: Pointer to the PCC channel info structure.
  * @pcct_entry: Pointer to the ACPI subtable header.
  *
+ * Return: 0 for Success, else errno.
  */
-static void pcc_parse_subspace_db_reg(struct pcc_chan_info *pchan,
-                                     struct acpi_subtable_header *pcct_entry)
+static int pcc_parse_subspace_db_reg(struct pcc_chan_info *pchan,
+                                    struct acpi_subtable_header *pcct_entry)
 {
+       int ret = 0;
+
        struct acpi_pcct_subspace *pcct_ss;
-       struct acpi_generic_address *db_reg;
 
        pcct_ss = (struct acpi_pcct_subspace *)pcct_entry;
 
-       /* If doorbell is in system memory cache the virt address */
-       db_reg = &pcct_ss->doorbell_register;
-       if (db_reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
-               pchan->db_vaddr = acpi_os_ioremap(db_reg->address,
-                                                 db_reg->bit_width / 8);
+       ret = pcc_chan_reg_init(&pchan->db,
+                               &pcct_ss->doorbell_register,
+                               pcct_ss->preserve_mask,
+                               pcct_ss->write_mask, 0, "Doorbell");
+       return ret;
 }
 
 /**
 
        for (i = 0; i < count; i++) {
                struct pcc_chan_info *pchan = chan_info + i;
-               pcc_mbox_channels[i].con_priv = pcct_entry;
 
+               pcc_mbox_channels[i].con_priv = pchan;
                pchan->chan.mchan = &pcc_mbox_channels[i];
 
                if (pcc_mbox_ctrl.txdone_irq) {
                        if (rc < 0)
                                goto err;
                }
-               pcc_parse_subspace_db_reg(pchan, pcct_entry);
+               rc = pcc_parse_subspace_db_reg(pchan, pcct_entry);
+               if (rc < 0)
+                       goto err;
 
                pcc_parse_subspace_shmem(pchan, pcct_entry);