Commit da4085d5 authored by Federico Vaga's avatar Federico Vaga

sw:drv: move spec-core-fpga device register where it belongs

The SPEC is made of its PCI bridge (GN4124) and a set of FPGA
devices that enables some carrier feature. The first one is handled
by the Linux pci_dev, the second set of devices have a commond parent
that I am moving into the spec-core-fpga.c file so that all FPGA related
code is in one place
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 292e1bd7
......@@ -490,14 +490,14 @@ static void spec_fpga_app_exit(struct spec_dev *spec)
static bool spec_fpga_is_valid(struct spec_dev *spec)
{
if ((spec->meta->bom & SPEC_META_BOM_END_MASK) != SPEC_META_BOM_LE) {
dev_err(spec->dev.parent,
dev_err(&spec->pdev->dev,
"Expected Little Endian devices BOM: 0x%x\n",
spec->meta->bom);
return false;
}
if ((spec->meta->bom & SPEC_META_BOM_VER_MASK) != 0) {
dev_err(spec->dev.parent,
dev_err(&spec->pdev->dev,
"Unknow Metadata specification version BOM: 0x%x\n",
spec->meta->bom);
return false;
......@@ -505,14 +505,14 @@ static bool spec_fpga_is_valid(struct spec_dev *spec)
if (spec->meta->vendor != SPEC_META_VENDOR_ID ||
spec->meta->device != SPEC_META_DEVICE_ID) {
dev_err(spec->dev.parent,
dev_err(&spec->pdev->dev,
"Unknow vendor/device ID: %08x:%08x\n",
spec->meta->vendor, spec->meta->device);
return false;
}
if (spec->meta->version != SPEC_META_VERSION_1_4) {
dev_err(spec->dev.parent,
dev_err(&spec->pdev->dev,
"Unknow version: %08x\n", spec->meta->version);
return false;
}
......@@ -521,6 +521,22 @@ static bool spec_fpga_is_valid(struct spec_dev *spec)
}
static void spec_release(struct device *dev)
{
}
static int spec_uevent(struct device *dev, struct kobj_uevent_env *env)
{
return 0;
}
static const struct device_type spec_dev_type = {
.name = "spec",
.release = spec_release,
.uevent = spec_uevent,
};
/**
* Initialize carrier devices on FPGA
*/
......@@ -534,6 +550,22 @@ int spec_fpga_init(struct spec_dev *spec)
if (!spec_fpga_is_valid(spec))
return -EINVAL;
memset(&spec->dev, 0, sizeof(spec->dev));
spec->dev.parent = &spec->pdev->dev;
spec->dev.driver = spec->pdev->dev.driver;
spec->dev.type = &spec_dev_type;
err = dev_set_name(&spec->dev, "spec-%s", dev_name(&spec->pdev->dev));
if (err)
goto err_name;
err = device_register(&spec->dev);
if (err) {
dev_err(&spec->pdev->dev, "Failed to register '%s'\n",
dev_name(&spec->dev));
goto err_dev;
}
err = spec_fpga_therm_init(spec);
if (err)
goto err_therm;
......@@ -542,7 +574,7 @@ int spec_fpga_init(struct spec_dev *spec)
goto err_vic;
err = spec_fpga_devices_init(spec);
if (err)
goto err_dev;
goto err_devs;
err = spec_fmc_init(spec);
if (err)
goto err_fmc;
......@@ -556,11 +588,14 @@ err_app:
spec_fmc_exit(spec);
err_fmc:
spec_fpga_devices_exit(spec);
err_dev:
err_devs:
spec_fpga_vic_exit(spec);
err_vic:
spec_fpga_therm_exit(spec);
err_therm:
device_unregister(&spec->dev);
err_dev:
err_name:
return err;
}
......@@ -571,6 +606,7 @@ int spec_fpga_exit(struct spec_dev *spec)
spec_fpga_devices_exit(spec);
spec_fpga_vic_exit(spec);
spec_fpga_therm_exit(spec);
device_unregister(&spec->dev);
return 0;
}
......@@ -92,12 +92,10 @@ static const struct mfd_cell spec_mfd_devs[] = {
*/
static const char *spec_fw_name_init_get(struct spec_dev *spec)
{
struct pci_dev *pdev = to_pci_dev(spec->dev.parent);
if (strlen(spec_fw_name) > 0)
return spec_fw_name;
switch (pdev->device) {
switch (spec->pdev->device) {
case PCI_DEVICE_ID_SPEC_45T:
return spec_fw_name_45t;
case PCI_DEVICE_ID_SPEC_100T:
......@@ -123,7 +121,7 @@ int spec_fw_load(struct spec_dev *spec, const char *name)
err = spec_fpga_exit(spec);
if (err) {
dev_err(&spec->dev,
dev_err(&spec->pdev->dev,
"Cannot remove FPGA device instances. Try to remove them manually and to reload this device instance\n");
return err;
}
......@@ -140,7 +138,7 @@ int spec_fw_load(struct spec_dev *spec, const char *name)
err = spec_fpga_init(spec);
if (err)
dev_warn(&spec->dev, "FPGA incorrectly programmed\n");
dev_warn(&spec->pdev->dev, "FPGA incorrectly programmed\n");
out:
spec_gpio_fpga_select_set(spec, sel);
......@@ -149,22 +147,12 @@ out:
return err;
}
static void spec_release(struct device *dev)
{
}
static int spec_uevent(struct device *dev, struct kobj_uevent_env *env)
{
return 0;
}
static ssize_t bootselect_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct spec_dev *spec = to_spec_dev(dev);
struct pci_dev *pdev = to_pci_dev(dev);
struct spec_dev *spec = pci_get_drvdata(pdev);
enum spec_fpga_select sel;
if (strncmp("fpga-flash", buf, 8) == 0) {
......@@ -190,7 +178,8 @@ static ssize_t bootselect_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct spec_dev *spec = to_spec_dev(dev);
struct pci_dev *pdev = to_pci_dev(dev);
struct spec_dev *spec = pci_get_drvdata(pdev);
enum spec_fpga_select sel;
sel = spec_gpio_fpga_select_get(spec);
......@@ -216,7 +205,8 @@ static ssize_t load_golden_fpga_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct spec_dev *spec = to_spec_dev(dev);
struct pci_dev *pdev = to_pci_dev(dev);
struct spec_dev *spec = pci_get_drvdata(pdev);
int err;
err = spec_fw_load(spec, spec_fw_name_init_get(spec));
......@@ -225,29 +215,17 @@ static ssize_t load_golden_fpga_store(struct device *dev,
}
static DEVICE_ATTR_WO(load_golden_fpga);
static struct attribute *spec_type_attrs[] = {
static struct attribute *gn412x_fpga_attrs[] = {
&dev_attr_load_golden_fpga.attr,
&dev_attr_bootselect.attr,
NULL,
};
static const struct attribute_group spec_type_group = {
.attrs = spec_type_attrs,
static const struct attribute_group gn412x_fpga_group = {
.name = "fpga-options",
.attrs = gn412x_fpga_attrs,
};
static const struct attribute_group *spec_type_groups[] = {
&spec_type_group,
NULL,
};
static const struct device_type spec_dev_type = {
.name = "spec",
.release = spec_release,
.uevent = spec_uevent,
.groups = spec_type_groups,
};
static int spec_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
......@@ -260,11 +238,11 @@ static int spec_probe(struct pci_dev *pdev,
mutex_init(&spec->mtx);
pci_set_drvdata(pdev, spec);
spec->pdev = pdev;
err = pci_enable_device(pdev);
if (err) {
dev_err(spec->dev.parent,
"Failed to enable PCI device (%d)\n",
dev_err(&pdev->dev, "Failed to enable PCI device (%d)\n",
err);
goto err_enable;
}
......@@ -285,7 +263,7 @@ static int spec_probe(struct pci_dev *pdev,
}
}
if (err) {
dev_err(spec->dev.parent, "Failed to remap memory (%d)\n",
dev_err(&pdev->dev, "Failed to remap memory (%d)\n",
err);
goto err_remap;
}
......@@ -295,35 +273,25 @@ static int spec_probe(struct pci_dev *pdev,
ARRAY_SIZE(spec_mfd_devs),
&pdev->resource[4], pdev->irq, NULL);
if (err) {
dev_err(&spec->dev, "Failed to add MFD devices (%d)\n", err);
dev_err(&spec->pdev->dev, "Failed to add MFD devices (%d)\n",
err);
goto err_mfd;
}
spec->dev.parent = &pdev->dev;
spec->dev.type = &spec_dev_type;
err = dev_set_name(&spec->dev, "spec-%s", dev_name(&pdev->dev));
if (err)
goto err_name;
err = device_register(&spec->dev);
if (err) {
dev_err(spec->dev.parent, "Failed to register '%s'\n",
dev_name(&spec->dev));
goto err_dev;
}
/* This virtual device is assciated with this driver */
spec->dev.driver = pdev->dev.driver;
err = spec_gpio_init(spec);
if (err) {
dev_err(&spec->dev, "Failed to get GPIOs (%d)\n", err);
dev_err(&pdev->dev, "Failed to get GPIOs (%d)\n", err);
goto err_sgpio;
}
err = sysfs_create_group(&pdev->dev.kobj, &gn412x_fpga_group);
if (err)
goto err_sysfs;
mutex_lock(&spec->mtx);
err = spec_fpga_init(spec);
if (err)
dev_warn(&spec->dev,
dev_warn(&pdev->dev,
"FPGA incorrectly programmed or empty (%d)\n", err);
mutex_unlock(&spec->mtx);
......@@ -331,10 +299,9 @@ static int spec_probe(struct pci_dev *pdev,
return 0;
err_sysfs:
spec_gpio_exit(spec);
err_sgpio:
device_unregister(&spec->dev);
err_dev:
err_name:
mfd_remove_devices(&pdev->dev);
err_mfd:
for (i = 0; i < 3; i++) {
......@@ -356,8 +323,8 @@ static void spec_remove(struct pci_dev *pdev)
spec_dbg_exit(spec);
spec_fpga_exit(spec);
sysfs_remove_group(&pdev->dev.kobj, &gn412x_fpga_group);
spec_gpio_exit(spec);
device_unregister(&spec->dev);
mfd_remove_devices(&pdev->dev);
for (i = 0; i < 3; i++)
......
......@@ -15,9 +15,9 @@ static int spec_irq_dbg_info(struct seq_file *s, void *offset)
{
struct spec_dev *spec = s->private;
seq_printf(s, "'%s':\n", dev_name(spec->dev.parent));
seq_printf(s, "'%s':\n", dev_name(&spec->pdev->dev));
seq_printf(s, " redirect: %d\n", to_pci_dev(spec->dev.parent)->irq);
seq_printf(s, " redirect: %d\n", to_pci_dev(&spec->pdev->dev)->irq);
seq_puts(s, " irq-mapping:\n");
seq_puts(s, " - hardware: 8\n");
seq_printf(s, " linux: %d\n",
......@@ -75,7 +75,7 @@ static int spec_dbg_meta(struct seq_file *s, void *offset)
{
struct spec_dev *spec = s->private;
seq_printf(s, "'%s':\n", dev_name(spec->dev.parent));
seq_printf(s, "'%s':\n", dev_name(&spec->pdev->dev));
seq_puts(s, "Metadata:\n");
seq_printf(s, " - Vendor: 0x%08x\n", spec->meta->vendor);
seq_printf(s, " - Device: 0x%08x\n", spec->meta->device);
......@@ -119,7 +119,7 @@ static const struct file_operations spec_dbg_meta_ops = {
*/
int spec_dbg_init(struct spec_dev *spec)
{
spec->dbg_dir = debugfs_create_dir(dev_name(&spec->dev), NULL);
spec->dbg_dir = debugfs_create_dir(dev_name(&spec->pdev->dev), NULL);
if (IS_ERR_OR_NULL(spec->dbg_dir)) {
dev_err(&spec->dev,
"Cannot create debugfs directory (%ld)\n",
......
......@@ -78,7 +78,7 @@ int spec_gpio_init(struct spec_dev *spec)
struct gpiod_lookup_table *lookup;
int err = 0;
lookup = devm_kzalloc(spec->dev.parent,
lookup = devm_kzalloc(&spec->pdev->dev,
spec_gpiod_table_size(),
GFP_KERNEL);
if (!lookup) {
......@@ -88,7 +88,7 @@ int spec_gpio_init(struct spec_dev *spec)
memcpy(lookup, &spec_gpiod_table, spec_gpiod_table_size());
lookup->dev_id = kstrdup(dev_name(spec->dev.parent), GFP_KERNEL);
lookup->dev_id = kstrdup(dev_name(&spec->pdev->dev), GFP_KERNEL);
if (!lookup->dev_id)
goto err_dup;
......@@ -97,14 +97,14 @@ int spec_gpio_init(struct spec_dev *spec)
if (err)
goto err_lookup;
gpiod = gpiod_get_index(spec->dev.parent, "bootsel", 0, GPIOD_OUT_HIGH);
gpiod = gpiod_get_index(&spec->pdev->dev, "bootsel", 0, GPIOD_OUT_HIGH);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto err_sel0;
}
spec->gpiod[GN4124_GPIO_BOOTSEL0] = gpiod;
gpiod = gpiod_get_index(spec->dev.parent, "bootsel", 1, GPIOD_OUT_HIGH);
gpiod = gpiod_get_index(&spec->pdev->dev, "bootsel", 1, GPIOD_OUT_HIGH);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto err_sel1;
......@@ -120,14 +120,14 @@ int spec_gpio_init(struct spec_dev *spec)
goto err_out1;
gpiod = gpiod_get_index(spec->dev.parent, "irq", 0, GPIOD_IN);
gpiod = gpiod_get_index(&spec->pdev->dev, "irq", 0, GPIOD_IN);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto err_irq0;
}
spec->gpiod[GN4124_GPIO_IRQ0] = gpiod;
gpiod = gpiod_get_index(spec->dev.parent, "irq", 1, GPIOD_IN);
gpiod = gpiod_get_index(&spec->pdev->dev, "irq", 1, GPIOD_IN);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto err_irq1;
......@@ -160,7 +160,7 @@ err_sel0:
err_lookup:
kfree(lookup->dev_id);
err_dup:
devm_kfree(spec->dev.parent, lookup);
devm_kfree(&spec->pdev->dev, lookup);
spec->gpiod_table = NULL;
err_alloc:
......
......@@ -110,6 +110,7 @@ struct spec_meta_id {
* @i2c_adapter: the I2C master device to be used
*/
struct spec_dev {
struct pci_dev *pdev;
struct device dev;
DECLARE_BITMAP(flags, SPEC_FLAG_BITS);
......
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