Commit 33f81009 authored by AnilKumar Ch's avatar AnilKumar Ch Committed by Marc Kleine-Budde

can: c_can: Move overlay structure to array with offset as index

c_can uses overlay structure for accessing c_can module registers.
With this kind of implementation it is difficult to add one more ip
which is similar to c_can in functionality but different register
offsets.

This patch changes the overlay structure implementation to an array
with register offset as index. This way we can overcome the above
limitation.
Signed-off-by: default avatarAnilKumar Ch <anilkumar@ti.com>
Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent c1864cfb
This diff is collapsed.
......@@ -22,43 +22,84 @@
#ifndef C_CAN_H
#define C_CAN_H
/* c_can IF registers */
struct c_can_if_regs {
u16 com_req;
u16 com_mask;
u16 mask1;
u16 mask2;
u16 arb1;
u16 arb2;
u16 msg_cntrl;
u16 data[4];
u16 _reserved[13];
enum reg {
C_CAN_CTRL_REG = 0,
C_CAN_STS_REG,
C_CAN_ERR_CNT_REG,
C_CAN_BTR_REG,
C_CAN_INT_REG,
C_CAN_TEST_REG,
C_CAN_BRPEXT_REG,
C_CAN_IF1_COMREQ_REG,
C_CAN_IF1_COMMSK_REG,
C_CAN_IF1_MASK1_REG,
C_CAN_IF1_MASK2_REG,
C_CAN_IF1_ARB1_REG,
C_CAN_IF1_ARB2_REG,
C_CAN_IF1_MSGCTRL_REG,
C_CAN_IF1_DATA1_REG,
C_CAN_IF1_DATA2_REG,
C_CAN_IF1_DATA3_REG,
C_CAN_IF1_DATA4_REG,
C_CAN_IF2_COMREQ_REG,
C_CAN_IF2_COMMSK_REG,
C_CAN_IF2_MASK1_REG,
C_CAN_IF2_MASK2_REG,
C_CAN_IF2_ARB1_REG,
C_CAN_IF2_ARB2_REG,
C_CAN_IF2_MSGCTRL_REG,
C_CAN_IF2_DATA1_REG,
C_CAN_IF2_DATA2_REG,
C_CAN_IF2_DATA3_REG,
C_CAN_IF2_DATA4_REG,
C_CAN_TXRQST1_REG,
C_CAN_TXRQST2_REG,
C_CAN_NEWDAT1_REG,
C_CAN_NEWDAT2_REG,
C_CAN_INTPND1_REG,
C_CAN_INTPND2_REG,
C_CAN_MSGVAL1_REG,
C_CAN_MSGVAL2_REG,
};
/* c_can hardware registers */
struct c_can_regs {
u16 control;
u16 status;
u16 err_cnt;
u16 btr;
u16 interrupt;
u16 test;
u16 brp_ext;
u16 _reserved1;
struct c_can_if_regs ifregs[2]; /* [0] = IF1 and [1] = IF2 */
u16 _reserved2[8];
u16 txrqst1;
u16 txrqst2;
u16 _reserved3[6];
u16 newdat1;
u16 newdat2;
u16 _reserved4[6];
u16 intpnd1;
u16 intpnd2;
u16 _reserved5[6];
u16 msgval1;
u16 msgval2;
u16 _reserved6[6];
static const u16 reg_map_c_can[] = {
[C_CAN_CTRL_REG] = 0x00,
[C_CAN_STS_REG] = 0x02,
[C_CAN_ERR_CNT_REG] = 0x04,
[C_CAN_BTR_REG] = 0x06,
[C_CAN_INT_REG] = 0x08,
[C_CAN_TEST_REG] = 0x0A,
[C_CAN_BRPEXT_REG] = 0x0C,
[C_CAN_IF1_COMREQ_REG] = 0x10,
[C_CAN_IF1_COMMSK_REG] = 0x12,
[C_CAN_IF1_MASK1_REG] = 0x14,
[C_CAN_IF1_MASK2_REG] = 0x16,
[C_CAN_IF1_ARB1_REG] = 0x18,
[C_CAN_IF1_ARB2_REG] = 0x1A,
[C_CAN_IF1_MSGCTRL_REG] = 0x1C,
[C_CAN_IF1_DATA1_REG] = 0x1E,
[C_CAN_IF1_DATA2_REG] = 0x20,
[C_CAN_IF1_DATA3_REG] = 0x22,
[C_CAN_IF1_DATA4_REG] = 0x24,
[C_CAN_IF2_COMREQ_REG] = 0x40,
[C_CAN_IF2_COMMSK_REG] = 0x42,
[C_CAN_IF2_MASK1_REG] = 0x44,
[C_CAN_IF2_MASK2_REG] = 0x46,
[C_CAN_IF2_ARB1_REG] = 0x48,
[C_CAN_IF2_ARB2_REG] = 0x4A,
[C_CAN_IF2_MSGCTRL_REG] = 0x4C,
[C_CAN_IF2_DATA1_REG] = 0x4E,
[C_CAN_IF2_DATA2_REG] = 0x50,
[C_CAN_IF2_DATA3_REG] = 0x52,
[C_CAN_IF2_DATA4_REG] = 0x54,
[C_CAN_TXRQST1_REG] = 0x80,
[C_CAN_TXRQST2_REG] = 0x82,
[C_CAN_NEWDAT1_REG] = 0x90,
[C_CAN_NEWDAT2_REG] = 0x92,
[C_CAN_INTPND1_REG] = 0xA0,
[C_CAN_INTPND2_REG] = 0xA2,
[C_CAN_MSGVAL1_REG] = 0xB0,
[C_CAN_MSGVAL2_REG] = 0xB2,
};
/* c_can private data structure */
......@@ -69,9 +110,10 @@ struct c_can_priv {
int tx_object;
int current_status;
int last_status;
u16 (*read_reg) (struct c_can_priv *priv, void *reg);
void (*write_reg) (struct c_can_priv *priv, void *reg, u16 val);
struct c_can_regs __iomem *regs;
u16 (*read_reg) (struct c_can_priv *priv, enum reg index);
void (*write_reg) (struct c_can_priv *priv, enum reg index, u16 val);
void __iomem *base;
const u16 *regs;
unsigned long irq_flags; /* for request_irq() */
unsigned int tx_next;
unsigned int tx_echo;
......
......@@ -42,27 +42,27 @@
* Handle the same by providing a common read/write interface.
*/
static u16 c_can_plat_read_reg_aligned_to_16bit(struct c_can_priv *priv,
void *reg)
enum reg index)
{
return readw(reg);
return readw(priv->base + priv->regs[index]);
}
static void c_can_plat_write_reg_aligned_to_16bit(struct c_can_priv *priv,
void *reg, u16 val)
enum reg index, u16 val)
{
writew(val, reg);
writew(val, priv->base + priv->regs[index]);
}
static u16 c_can_plat_read_reg_aligned_to_32bit(struct c_can_priv *priv,
void *reg)
enum reg index)
{
return readw(reg + (long)reg - (long)priv->regs);
return readw(priv->base + 2 * priv->regs[index]);
}
static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv,
void *reg, u16 val)
enum reg index, u16 val)
{
writew(val, reg + (long)reg - (long)priv->regs);
writew(val, priv->base + 2 * priv->regs[index]);
}
static int __devinit c_can_plat_probe(struct platform_device *pdev)
......@@ -115,9 +115,10 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
}
priv = netdev_priv(dev);
priv->regs = reg_map_c_can;
dev->irq = irq;
priv->regs = addr;
priv->base = addr;
#ifdef CONFIG_HAVE_CLK
priv->can.clock.freq = clk_get_rate(clk);
priv->priv = clk;
......@@ -146,7 +147,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
}
dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n",
KBUILD_MODNAME, priv->regs, dev->irq);
KBUILD_MODNAME, priv->base, dev->irq);
return 0;
exit_free_device:
......@@ -176,7 +177,7 @@ static int __devexit c_can_plat_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
free_c_can_dev(dev);
iounmap(priv->regs);
iounmap(priv->base);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, resource_size(mem));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment