Commit a9e1383d authored by Federico Vaga's avatar Federico Vaga

kernel:[vmebus] use vme_register_device to declare devices

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent d9c5b4e3
......@@ -793,16 +793,34 @@ static void svec_destroy_misc_device(struct svec_dev *svec)
}
/* * * * * * END MISC DEVICE * * * * */
static inline int svec_find_param(unsigned int slot_n)
{
int i;
for (i = 0; i < slot_num; i++) {
if (slot_n == slot[i])
return i;
}
return -ENODEV;
}
static int svec_probe(struct device *pdev, unsigned int ndev)
{
struct vme_dev *vme_dev = to_vme_dev(pdev);
struct svec_dev *svec;
const char *name;
int error = 0;
int error = 0, idx;
idx = svec_find_param(vme_dev->slot);
if (idx < 0) {
dev_err(pdev, "Missing LUN,SLOT mapping\n");
return idx;
}
if (lun[ndev] < 0 || lun[ndev] >= SVEC_MAX_DEVICES) {
if (lun[idx] < 0 || lun[idx] >= SVEC_MAX_DEVICES) {
dev_err(pdev, "Card lun %d out of range [0..%d]\n",
lun[ndev], SVEC_MAX_DEVICES - 1);
lun[idx], SVEC_MAX_DEVICES - 1);
return -EINVAL;
}
......@@ -816,18 +834,18 @@ static int svec_probe(struct device *pdev, unsigned int ndev)
/* Initialize struct fields */
svec->verbose = verbose;
svec->lun = lun[ndev];
svec->slot = slot[ndev];
svec->lun = lun[idx];
svec->slot = vme_dev->slot;
svec->fmcs_n = SVEC_N_SLOTS; /* FIXME: Two mezzanines */
svec->dev = pdev;
svec->cfg_cur.use_vic = 1;
svec->cfg_cur.use_fmc = 1;
svec->cfg_cur.vme_base = vme_base[ndev];
svec->cfg_cur.vme_am = vme_am[ndev];
svec->cfg_cur.vme_size = vme_size[ndev];
svec->cfg_cur.interrupt_vector = vector[ndev];
svec->cfg_cur.interrupt_level = level[ndev];
svec->cfg_cur.vme_base = vme_dev->base_address;
svec->cfg_cur.vme_am = vme_dev->am;
svec->cfg_cur.vme_size = vme_dev->size;
svec->cfg_cur.interrupt_vector = vme_dev->irq_vector;
svec->cfg_cur.interrupt_level = vme_dev->irq_level;
svec->cfg_cur.configured = 1;
svec->cfg_cur.configured =
svec_validate_configuration(pdev, &svec->cfg_cur);
......@@ -844,8 +862,8 @@ static int svec_probe(struct device *pdev, unsigned int ndev)
}
/* Get firmware name */
if (ndev < fw_name_num)
svec->fw_name = fw_name[ndev];
if (idx < fw_name_num)
svec->fw_name = fw_name[idx];
else
svec->fw_name = svec_fw_name; /* Default value */
......@@ -894,10 +912,58 @@ static struct vme_driver svec_driver = {
.probe = svec_probe,
.remove = svec_remove,
.driver = {
.name = KBUILD_MODNAME,
.name = KBUILD_MODNAME,
},
};
static struct vme_dev *vme_dev_tbl[SVEC_MAX_DEVICES];
static int __init svec_register_devices(void)
{
int err, i;
for (i = 0; i< lun_num; i++) {
vme_dev_tbl[i] = kzalloc(sizeof(struct vme_dev), GFP_KERNEL);
if (!vme_dev_tbl[i]) {
err = -ENOMEM;
goto out_all;
}
vme_dev_tbl[i]->base_address = vme_base[i];
vme_dev_tbl[i]->size = vme_size[i];
vme_dev_tbl[i]->am = vme_am[i];
vme_dev_tbl[i]->slot = slot[i];
vme_dev_tbl[i]->irq_vector = vector[i];
vme_dev_tbl[i]->irq_level = level[i];
err = vme_register_device(vme_dev_tbl[i], &svec_driver);
if (err)
goto out_reg;
}
return 0;
out_reg:
kfree(vme_dev_tbl[i]);
vme_dev_tbl[i] = NULL;
out_all:
while (--i >= 0) {
vme_unregister_device(vme_dev_tbl[i]);
kfree(vme_dev_tbl[i]);
vme_dev_tbl[i] = NULL;
}
return err;
}
static void svec_unregister_devices(void)
{
int i;
for (i = 0; i< lun_num; i++) {
vme_unregister_device(vme_dev_tbl[i]);
kfree(vme_dev_tbl[i]);
vme_dev_tbl[i] = NULL;
}
}
static int __init svec_init(void)
{
int error = 0;
......@@ -919,6 +985,7 @@ static int __init svec_init(void)
error |= (vme_size_num && vme_size_num != slot_num);
error |= (level_num && level_num != slot_num);
error |= (vector_num && vector_num != slot_num);
error |= (fw_name_num && fw_name_num != slot_num);
if (error) {
......@@ -927,17 +994,26 @@ static int __init svec_init(void)
return -EINVAL;
}
error = vme_register_driver(&svec_driver, lun_num);
/* Just register the driver, we register devices our selfs */
error = vme_register_driver(&svec_driver, 0);
if (error) {
pr_err("%s: Cannot register vme driver - lun [%d]\n", __func__,
lun_num);
}
return error;
error = svec_register_devices();
if (error) {
pr_err("%s: Cannot register vme devices\n", __func__);
vme_unregister_driver(&svec_driver);
return error;
}
return 0;
}
static void __exit svec_exit(void)
{
svec_unregister_devices();
vme_unregister_driver(&svec_driver);
}
......
......@@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/fmc-sdb.h>
#include <linux/platform_device.h>
#include "svec.h"
static int svec_show_sdb;
......
......@@ -135,13 +135,6 @@ ATTR_SHOW_CALLBACK(dummy_attr)
return snprintf(buf, PAGE_SIZE, "0");
}
ATTR_SHOW_CALLBACK(interrupt_vector)
{
struct svec_dev *card = dev_get_drvdata(pdev);
return snprintf(buf, PAGE_SIZE, "0x%x\n",
card->cfg_cur.interrupt_vector);
}
ATTR_SHOW_CALLBACK(interrupt_level)
{
......@@ -164,19 +157,6 @@ ATTR_STORE_CALLBACK(interrupt_level)
return count;
}
ATTR_STORE_CALLBACK(interrupt_vector)
{
int vec;
struct svec_dev *card = dev_get_drvdata(pdev);
if (sscanf(buf, "%i", &vec) != 1)
return -EINVAL;
if (vec < 0 || vec > 255)
return -EINVAL;
card->cfg_new.interrupt_vector = vec;
return count;
}
ATTR_SHOW_CALLBACK(vme_am)
{
......@@ -197,46 +177,6 @@ ATTR_STORE_CALLBACK(vme_am)
return count;
}
ATTR_SHOW_CALLBACK(vme_base)
{
struct svec_dev *card = dev_get_drvdata(pdev);
return snprintf(buf, PAGE_SIZE, "0x%x\n", card->cfg_cur.vme_base);
}
ATTR_STORE_CALLBACK(vme_base)
{
uint32_t base;
struct svec_dev *card = dev_get_drvdata(pdev);
if (sscanf(buf, "%i", &base) != 1)
return -EINVAL;
card->cfg_new.vme_base = base; /* will be verified on commit */
return count;
}
ATTR_SHOW_CALLBACK(vme_size)
{
struct svec_dev *card = dev_get_drvdata(pdev);
return snprintf(buf, PAGE_SIZE, "0x%x\n", card->cfg_cur.vme_size);
}
ATTR_STORE_CALLBACK(vme_size)
{
struct svec_dev *card = dev_get_drvdata(pdev);
uint32_t size;
if (sscanf(buf, "%i", &size) != 1)
return -EINVAL;
card->cfg_new.vme_size = size; /* will be verified on commit */
return count;
}
ATTR_SHOW_CALLBACK(vme_addr)
{
struct svec_dev *card = dev_get_drvdata(pdev);
......@@ -394,13 +334,6 @@ ATTR_STORE_CALLBACK(configured)
return count;
}
ATTR_SHOW_CALLBACK(slot)
{
struct svec_dev *card = dev_get_drvdata(pdev);
return snprintf(buf, PAGE_SIZE, "%d\n", card->slot);
}
static DEVICE_ATTR(firmware_name,
S_IWUSR | S_IRUGO,
svec_show_firmware_name, svec_store_firmware_name);
......@@ -410,26 +343,12 @@ static DEVICE_ATTR(firmware_cmd,
svec_show_dummy_attr, svec_store_firmware_cmd);
/* Helper attribute to find the physical slot for a given VME LUN. Used by
the userspace tools. */
static DEVICE_ATTR(slot, S_IRUGO, svec_show_slot, NULL);
/* Standard VME configuration attributes. Committed in atomic way by
writing 1 to 1 to 'configured' attribute. */
static DEVICE_ATTR(interrupt_vector,
S_IWUSR | S_IRUGO,
svec_show_interrupt_vector, svec_store_interrupt_vector);
static DEVICE_ATTR(interrupt_level,
S_IWUSR | S_IRUGO,
svec_show_interrupt_level, svec_store_interrupt_level);
static DEVICE_ATTR(vme_base,
S_IWUSR | S_IRUGO, svec_show_vme_base, svec_store_vme_base);
static DEVICE_ATTR(vme_size,
S_IWUSR | S_IRUGO, svec_show_vme_size, svec_store_vme_size);
static DEVICE_ATTR(vme_am,
S_IWUSR | S_IRUGO, svec_show_vme_am, svec_store_vme_am);
......@@ -476,17 +395,13 @@ static DEVICE_ATTR(vme_data,
static struct attribute *svec_attrs[] = {
&dev_attr_firmware_name.attr,
&dev_attr_firmware_cmd.attr,
&dev_attr_interrupt_vector.attr,
&dev_attr_interrupt_level.attr,
&dev_attr_vme_base.attr,
&dev_attr_vme_size.attr,
&dev_attr_vme_am.attr,
&dev_attr_use_vic.attr,
&dev_attr_use_fmc.attr,
&dev_attr_configured.attr,
&dev_attr_vme_addr.attr,
&dev_attr_vme_data.attr,
&dev_attr_slot.attr,
NULL,
};
......
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