Add channel information private struct

This commit is contained in:
Sven Schnelle
2015-10-26 20:49:22 +01:00
parent 01ace6554c
commit a3f7381da8
5 changed files with 87 additions and 5 deletions

View File

@@ -32,6 +32,14 @@ struct bcwc_reg {
u32 value; u32 value;
}; };
struct fw_channel {
char *name;
u32 offset;
u32 size;
u32 source;
u32 type;
};
struct bcwc_private { struct bcwc_private {
struct pci_dev *pdev; struct pci_dev *pdev;
unsigned int dma_mask; unsigned int dma_mask;
@@ -65,6 +73,10 @@ struct bcwc_private {
struct isp_mem_obj *firmware; struct isp_mem_obj *firmware;
struct isp_mem_obj *ipc_queue; struct isp_mem_obj *ipc_queue;
struct isp_mem_obj *heap; struct isp_mem_obj *heap;
/* Firmware channels */
int num_channels;
struct fw_channel **channels;
}; };
#endif #endif

View File

@@ -670,7 +670,6 @@ static int bcwc_hw_irq_disable(struct bcwc_private *dev_priv)
int bcwc_hw_init(struct bcwc_private *dev_priv) int bcwc_hw_init(struct bcwc_private *dev_priv)
{ {
u32 val;
int ret, i; int ret, i;
ret = bcwc_hw_s2_init_pcie_link(dev_priv); ret = bcwc_hw_s2_init_pcie_link(dev_priv);

View File

@@ -160,6 +160,7 @@
#define ISP_REG_40004 0x40004 #define ISP_REG_40004 0x40004
#define ISP_REG_40008 0x40008 #define ISP_REG_40008 0x40008
#define ISP_REG_41000 0x41000 #define ISP_REG_41000 0x41000
#define ISP_REG_41020 0x41020
#define ISP_REG_41024 0x41024 #define ISP_REG_41024 0x41024
#define ISP_IPC_CHAN_START 0x0128 #define ISP_IPC_CHAN_START 0x0128

69
isp.c
View File

@@ -175,14 +175,71 @@ static int isp_load_firmware(struct bcwc_private *dev_priv)
return ret; return ret;
} }
static void isp_free_channel_info(struct bcwc_private *priv)
{
struct fw_channel *chan;
int i;
for(i = 0; i < priv->num_channels; i++) {
chan = priv->channels[i];
if (!chan)
continue;
kfree(chan->name);
kfree(chan);
priv->channels[i] = NULL;
}
kfree(priv->channels);
priv->channels = NULL;
}
static int isp_fill_channel_info(struct bcwc_private *priv, int offset, int num_channels)
{
struct isp_channel_info *info;
struct fw_channel *chan;
int i;
if (!num_channels)
return 0;
priv->num_channels = num_channels;
priv->channels = kzalloc(num_channels * sizeof(struct fw_channel *), GFP_KERNEL);
if (!priv->channels)
goto out;
for(i = 0; i < num_channels; i++) {
info = (struct isp_channel_info *)(priv->s2_mem + offset + i * 256);
chan = kzalloc(sizeof(struct fw_channel), GFP_KERNEL);
if (!chan)
goto out;
priv->channels[i] = chan;
dev_info(&priv->pdev->dev, "Channel %d: %s, type %d, source %d, size %d, offset %x\n",
i, info->name, info->type, info->source, info->size, info->offset);
chan->name = kstrdup(info->name, GFP_KERNEL);
if (!chan->name)
goto out;
chan->type = info->type;
chan->source = info->source;
chan->size = info->size;
chan->offset = info->offset;
}
return 0;
out:
isp_free_channel_info(priv);
return -ENOMEM;
}
int isp_init(struct bcwc_private *dev_priv) int isp_init(struct bcwc_private *dev_priv)
{ {
struct isp_mem_obj *ipc_queue, *heap, *fw_args; struct isp_mem_obj *ipc_queue, *heap, *fw_args;
u32 num_channels, queue_size, heap_size;
u32 reg;
int i, retries, ret;
unsigned char *p;
struct isp_fw_args *fw_args_data; struct isp_fw_args *fw_args_data;
u32 num_channels, queue_size, heap_size, reg, offset;
int i, retries, ret;
ret = isp_mem_init(dev_priv); ret = isp_mem_init(dev_priv);
if (ret) if (ret)
@@ -330,6 +387,9 @@ int isp_init(struct bcwc_private *dev_priv)
dev_info(&dev_priv->pdev->dev, "ISP second int after %dms\n", dev_info(&dev_priv->pdev->dev, "ISP second int after %dms\n",
(retries - 1) * 10); (retries - 1) * 10);
offset = BCWC_ISP_REG_READ(ISP_IPC_NUM_CHAN);
dev_info(&dev_priv->pdev->dev, "Channel description table at %08x\n", offset);
isp_fill_channel_info(dev_priv, offset, num_channels);
} }
return 0; return 0;
@@ -337,6 +397,7 @@ int isp_init(struct bcwc_private *dev_priv)
int isp_uninit(struct bcwc_private *dev_priv) int isp_uninit(struct bcwc_private *dev_priv)
{ {
isp_free_channel_info(dev_priv);
kfree(dev_priv->mem); kfree(dev_priv->mem);
return 0; return 0;
} }

9
isp.h
View File

@@ -42,6 +42,15 @@ struct isp_fw_args {
u32 fw_arg; u32 fw_arg;
u32 full_stats_mode; u32 full_stats_mode;
}; };
struct isp_channel_info {
char name[64]; /* really that big? */
u32 type;
u32 source;
u32 size;
u32 offset;
};
#define to_isp_mem_obj(x) container_of((x), struct isp_mem_obj, base) #define to_isp_mem_obj(x) container_of((x), struct isp_mem_obj, base)
extern int isp_init(struct bcwc_private *dev_priv); extern int isp_init(struct bcwc_private *dev_priv);