struct c_can_priv *priv = netdev_priv(dev);
        int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface);
 
-       priv->write_reg(priv, reg + 1, cmd);
-       priv->write_reg(priv, reg, obj);
+       priv->write_reg32(priv, reg, (cmd << 16) | obj);
 
        for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) {
                if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY))
                change_bit(idx, &priv->tx_dir);
        }
 
-       priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), arb);
-       priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), arb >> 16);
+       priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), arb);
 
        priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
 
 
        frame->can_dlc = get_can_dlc(ctrl & 0x0F);
 
-       arb = priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface));
-       arb |= priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface)) << 16;
+       arb = priv->read_reg32(priv, C_CAN_IFACE(ARB1_REG, iface));
 
        if (arb & IF_ARB_MSGXTD)
                frame->can_id = (arb & CAN_EFF_MASK) | CAN_EFF_FLAG;
        struct c_can_priv *priv = netdev_priv(dev);
 
        mask |= BIT(29);
-       priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), mask);
-       priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), mask >> 16);
+       priv->write_reg32(priv, C_CAN_IFACE(MASK1_REG, iface), mask);
 
        id |= IF_ARB_MSGVAL;
-       priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), id);
-       priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), id >> 16);
+       priv->write_reg32(priv, C_CAN_IFACE(ARB1_REG, iface), id);
 
        priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont);
        c_can_object_put(dev, iface, obj, IF_COMM_RCV_SETUP);
 
        int last_status;
        u16 (*read_reg) (const struct c_can_priv *priv, enum reg index);
        void (*write_reg) (const struct c_can_priv *priv, enum reg index, u16 val);
+       u32 (*read_reg32) (const struct c_can_priv *priv, enum reg index);
+       void (*write_reg32) (const struct c_can_priv *priv, enum reg index, u32 val);
        void __iomem *base;
        const u16 *regs;
        void *priv;             /* for board-specific data */
 
        iowrite32((u32)val, priv->base + 2 * priv->regs[index]);
 }
 
+static u32 c_can_pci_read_reg32(const struct c_can_priv *priv, enum reg index)
+{
+       u32 val;
+
+       val = priv->read_reg(priv, index);
+       val |= ((u32) priv->read_reg(priv, index + 1)) << 16;
+
+       return val;
+}
+
+static void c_can_pci_write_reg32(const struct c_can_priv *priv, enum reg index,
+               u32 val)
+{
+       priv->write_reg(priv, index + 1, val >> 16);
+       priv->write_reg(priv, index, val);
+}
+
 static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable)
 {
        if (enable) {
                ret = -EINVAL;
                goto out_free_c_can;
        }
+       priv->read_reg32 = c_can_pci_read_reg32;
+       priv->write_reg32 = c_can_pci_write_reg32;
 
        priv->raminit = c_can_pci_data->init;
 
 
        spin_unlock(&raminit_lock);
 }
 
+static u32 c_can_plat_read_reg32(const struct c_can_priv *priv, enum reg index)
+{
+       u32 val;
+
+       val = priv->read_reg(priv, index);
+       val |= ((u32) priv->read_reg(priv, index + 1)) << 16;
+
+       return val;
+}
+
+static void c_can_plat_write_reg32(const struct c_can_priv *priv, enum reg index,
+               u32 val)
+{
+       priv->write_reg(priv, index + 1, val >> 16);
+       priv->write_reg(priv, index, val);
+}
+
+static u32 d_can_plat_read_reg32(const struct c_can_priv *priv, enum reg index)
+{
+       return readl(priv->base + priv->regs[index]);
+}
+
+static void d_can_plat_write_reg32(const struct c_can_priv *priv, enum reg index,
+               u32 val)
+{
+       writel(val, priv->base + priv->regs[index]);
+}
+
 static struct platform_device_id c_can_id_table[] = {
        [BOSCH_C_CAN_PLATFORM] = {
                .name = KBUILD_MODNAME,
                case IORESOURCE_MEM_32BIT:
                        priv->read_reg = c_can_plat_read_reg_aligned_to_32bit;
                        priv->write_reg = c_can_plat_write_reg_aligned_to_32bit;
+                       priv->read_reg32 = c_can_plat_read_reg32;
+                       priv->write_reg32 = c_can_plat_write_reg32;
                        break;
                case IORESOURCE_MEM_16BIT:
                default:
                        priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
                        priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
+                       priv->read_reg32 = c_can_plat_read_reg32;
+                       priv->write_reg32 = c_can_plat_write_reg32;
                        break;
                }
                break;
                priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
                priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
                priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
+               priv->read_reg32 = d_can_plat_read_reg32;
+               priv->write_reg32 = d_can_plat_write_reg32;
 
                if (pdev->dev.of_node)
                        priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");