Commit f5423aec authored by Federico Vaga's avatar Federico Vaga

sw:drv: split the device in two parts

Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 5f7187a0
......@@ -124,13 +124,13 @@ static struct platform_device *mfd_find_device(struct device *parent,
return to_platform_device(dev);
}
int compat_spec_fw_load(struct spec_dev *spec, const char *name)
int compat_spec_fw_load(struct spec_gn412x *spec_gn412x, const char *name)
{
struct fpga_manager *mgr;
struct platform_device *fpga_pdev;
int err;
fpga_pdev = mfd_find_device(spec->dev.parent, "gn412x-fcl", -1);
fpga_pdev = mfd_find_device(&spec_gn412x->pdev->dev, "gn412x-fcl", -1);
if (!fpga_pdev)
return -ENODEV;
mgr = fpga_mgr_get(&fpga_pdev->dev);
......
......@@ -49,7 +49,7 @@ int compat_spec_fpga_write_complete(struct fpga_manager *mgr,
#endif
int compat_get_fpga_last_word_size(struct fpga_image_info *info,
size_t count);
int compat_spec_fw_load(struct spec_dev *spec, const char *name);
int compat_spec_fw_load(struct spec_gn412x *spec_gn412x, const char *name);
#if KERNEL_VERSION(3, 11, 0) > LINUX_VERSION_CODE
#define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \
......
This diff is collapsed.
......@@ -90,12 +90,12 @@ static const struct mfd_cell spec_mfd_devs[] = {
*
* Return: FPGA firmware name
*/
static const char *spec_fw_name_init_get(struct spec_dev *spec)
static const char *spec_fw_name_init_get(struct spec_gn412x *spec_gn412x)
{
if (strlen(spec_fw_name) > 0)
return spec_fw_name;
switch (spec->pdev->device) {
switch (spec_gn412x->pdev->device) {
case PCI_DEVICE_ID_SPEC_45T:
return spec_fw_name_45t;
case PCI_DEVICE_ID_SPEC_100T:
......@@ -114,35 +114,36 @@ static const char *spec_fw_name_init_get(struct spec_dev *spec)
*
* Return: 0 on success, otherwise a negative error number
*/
int spec_fw_load(struct spec_dev *spec, const char *name)
int spec_fw_load(struct spec_gn412x *spec_gn412x, const char *name)
{
enum spec_fpga_select sel;
int err;
err = spec_fpga_exit(spec);
err = spec_fpga_exit(spec_gn412x);
if (err) {
dev_err(&spec->pdev->dev,
dev_err(&spec_gn412x->pdev->dev,
"Cannot remove FPGA device instances. Try to remove them manually and to reload this device instance\n");
return err;
}
mutex_lock(&spec->mtx);
sel = spec_gpio_fpga_select_get(spec);
mutex_lock(&spec_gn412x->mtx);
sel = spec_gpio_fpga_select_get(spec_gn412x);
spec_gpio_fpga_select_set(spec, SPEC_FPGA_SELECT_GN4124_FPGA);
spec_gpio_fpga_select_set(spec_gn412x, SPEC_FPGA_SELECT_GN4124_FPGA);
err = compat_spec_fw_load(spec, name);
err = compat_spec_fw_load(spec_gn412x, name);
if (err)
goto out;
err = spec_fpga_init(spec);
err = spec_fpga_init(spec_gn412x);
if (err)
dev_warn(&spec->pdev->dev, "FPGA incorrectly programmed\n");
dev_warn(&spec_gn412x->pdev->dev,
"FPGA incorrectly programmed\n");
out:
spec_gpio_fpga_select_set(spec, sel);
mutex_unlock(&spec->mtx);
spec_gpio_fpga_select_set(spec_gn412x, sel);
mutex_unlock(&spec_gn412x->mtx);
return err;
}
......@@ -152,7 +153,7 @@ static ssize_t bootselect_store(struct device *dev,
const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct spec_dev *spec = pci_get_drvdata(pdev);
struct spec_gn412x *spec_gn412x = pci_get_drvdata(pdev);
enum spec_fpga_select sel;
if (strncmp("fpga-flash", buf, 8) == 0) {
......@@ -167,9 +168,9 @@ static ssize_t bootselect_store(struct device *dev,
return -EINVAL;
}
mutex_lock(&spec->mtx);
spec_gpio_fpga_select_set(spec, sel);
mutex_unlock(&spec->mtx);
mutex_lock(&spec_gn412x->mtx);
spec_gpio_fpga_select_set(spec_gn412x, sel);
mutex_unlock(&spec_gn412x->mtx);
return count;
......@@ -179,10 +180,10 @@ static ssize_t bootselect_show(struct device *dev,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct spec_dev *spec = pci_get_drvdata(pdev);
struct spec_gn412x *spec_gn412x = pci_get_drvdata(pdev);
enum spec_fpga_select sel;
sel = spec_gpio_fpga_select_get(spec);
sel = spec_gpio_fpga_select_get(spec_gn412x);
switch (sel) {
case SPEC_FPGA_SELECT_FPGA_FLASH:
return snprintf(buf, PAGE_SIZE, "fpga-flash\n");
......@@ -206,10 +207,10 @@ static ssize_t load_golden_fpga_store(struct device *dev,
const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct spec_dev *spec = pci_get_drvdata(pdev);
struct spec_gn412x *spec_gn412x = pci_get_drvdata(pdev);
int err;
err = spec_fw_load(spec, spec_fw_name_init_get(spec));
err = spec_fw_load(spec_gn412x, spec_fw_name_init_get(spec_gn412x));
return err < 0 ? err : count;
}
......@@ -229,16 +230,16 @@ static const struct attribute_group gn412x_fpga_group = {
static int spec_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct spec_dev *spec;
struct spec_gn412x *spec_gn412x;
int err;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (!spec)
spec_gn412x = kzalloc(sizeof(*spec_gn412x), GFP_KERNEL);
if (!spec_gn412x)
return -ENOMEM;
mutex_init(&spec->mtx);
pci_set_drvdata(pdev, spec);
spec->pdev = pdev;
mutex_init(&spec_gn412x->mtx);
pci_set_drvdata(pdev, spec_gn412x);
spec_gn412x->pdev = pdev;
err = pci_enable_device(pdev);
if (err) {
......@@ -253,12 +254,13 @@ static int spec_probe(struct pci_dev *pdev,
ARRAY_SIZE(spec_mfd_devs),
&pdev->resource[4], pdev->irq, NULL);
if (err) {
dev_err(&spec->pdev->dev, "Failed to add MFD devices (%d)\n",
dev_err(&spec_gn412x->pdev->dev,
"Failed to add MFD devices (%d)\n",
err);
goto err_mfd;
}
err = spec_gpio_init(spec);
err = spec_gpio_init(spec_gn412x);
if (err) {
dev_err(&pdev->dev, "Failed to get GPIOs (%d)\n", err);
goto err_sgpio;
......@@ -268,41 +270,41 @@ static int spec_probe(struct pci_dev *pdev,
if (err)
goto err_sysfs;
spec_dbg_init(spec);
spec_dbg_init(spec_gn412x);
mutex_lock(&spec->mtx);
err = spec_fpga_init(spec);
mutex_lock(&spec_gn412x->mtx);
err = spec_fpga_init(spec_gn412x);
if (err)
dev_warn(&pdev->dev,
"FPGA incorrectly programmed or empty (%d)\n", err);
mutex_unlock(&spec->mtx);
mutex_unlock(&spec_gn412x->mtx);
return 0;
err_sysfs:
spec_gpio_exit(spec);
spec_gpio_exit(spec_gn412x);
err_sgpio:
mfd_remove_devices(&pdev->dev);
err_mfd:
pci_disable_device(pdev);
err_enable:
kfree(spec);
kfree(spec_gn412x);
return err;
}
static void spec_remove(struct pci_dev *pdev)
{
struct spec_dev *spec = pci_get_drvdata(pdev);
struct spec_gn412x *spec_gn412x = pci_get_drvdata(pdev);
spec_dbg_exit(spec);
spec_fpga_exit(spec);
spec_dbg_exit(spec_gn412x);
spec_fpga_exit(spec_gn412x);
sysfs_remove_group(&pdev->dev.kobj, &gn412x_fpga_group);
spec_gpio_exit(spec);
spec_gpio_exit(spec_gn412x);
mfd_remove_devices(&pdev->dev);
pci_disable_device(pdev);
kfree(spec);
kfree(spec_gn412x);
}
......
......@@ -13,25 +13,25 @@
static int spec_irq_dbg_info(struct seq_file *s, void *offset)
{
struct spec_dev *spec = s->private;
struct spec_gn412x *spec_gn412x = s->private;
seq_printf(s, "'%s':\n", dev_name(&spec->pdev->dev));
seq_printf(s, "'%s':\n", dev_name(&spec_gn412x->pdev->dev));
seq_printf(s, " redirect: %d\n", to_pci_dev(&spec->pdev->dev)->irq);
seq_printf(s, " redirect: %d\n", to_pci_dev(&spec_gn412x->pdev->dev)->irq);
seq_puts(s, " irq-mapping:\n");
seq_puts(s, " - hardware: 8\n");
seq_printf(s, " linux: %d\n",
gpiod_to_irq(spec->gpiod[GN4124_GPIO_IRQ0]));
gpiod_to_irq(spec_gn412x->gpiod[GN4124_GPIO_IRQ0]));
seq_puts(s, " - hardware: 9\n");
seq_printf(s, " linux: %d\n",
gpiod_to_irq(spec->gpiod[GN4124_GPIO_IRQ1]));
gpiod_to_irq(spec_gn412x->gpiod[GN4124_GPIO_IRQ1]));
return 0;
}
static int spec_irq_dbg_info_open(struct inode *inode, struct file *file)
{
struct spec_dev *spec = inode->i_private;
struct spec_gn412x *spec = inode->i_private;
return single_open(file, spec_irq_dbg_info, spec);
}
......@@ -48,10 +48,10 @@ static ssize_t spec_dbg_fw_write(struct file *file,
const char __user *buf,
size_t count, loff_t *ppos)
{
struct spec_dev *spec = file->private_data;
struct spec_gn412x *spec_gn412x = file->private_data;
int err;
err = spec_fw_load(spec, buf);
err = spec_fw_load(spec_gn412x, buf);
if (err)
return err;
return count;
......@@ -73,32 +73,32 @@ static const struct file_operations spec_dbg_fw_ops = {
static int spec_dbg_meta(struct seq_file *s, void *offset)
{
struct spec_dev *spec = s->private;
struct spec_gn412x *spec_gn412x = s->private;
seq_printf(s, "'%s':\n", dev_name(&spec->pdev->dev));
seq_printf(s, "'%s':\n", dev_name(&spec_gn412x->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);
seq_printf(s, " - Version: 0x%08x\n", spec->meta->version);
seq_printf(s, " - BOM: 0x%08x\n", spec->meta->bom);
seq_printf(s, " - Vendor: 0x%08x\n", spec_gn412x->meta->vendor);
seq_printf(s, " - Device: 0x%08x\n", spec_gn412x->meta->device);
seq_printf(s, " - Version: 0x%08x\n", spec_gn412x->meta->version);
seq_printf(s, " - BOM: 0x%08x\n", spec_gn412x->meta->bom);
seq_printf(s, " - SourceID: 0x%08x%08x%08x%08x\n",
spec->meta->src[0],
spec->meta->src[1],
spec->meta->src[2],
spec->meta->src[3]);
seq_printf(s, " - CapabilityMask: 0x%08x\n", spec->meta->cap);
spec_gn412x->meta->src[0],
spec_gn412x->meta->src[1],
spec_gn412x->meta->src[2],
spec_gn412x->meta->src[3]);
seq_printf(s, " - CapabilityMask: 0x%08x\n", spec_gn412x->meta->cap);
seq_printf(s, " - VendorUUID: 0x%08x%08x%08x%08x\n",
spec->meta->uuid[0],
spec->meta->uuid[1],
spec->meta->uuid[2],
spec->meta->uuid[3]);
spec_gn412x->meta->uuid[0],
spec_gn412x->meta->uuid[1],
spec_gn412x->meta->uuid[2],
spec_gn412x->meta->uuid[3]);
return 0;
}
static int spec_dbg_meta_open(struct inode *inode, struct file *file)
{
struct spec_dev *spec = inode->i_private;
struct spec_gn412x *spec = inode->i_private;
return single_open(file, spec_dbg_meta, spec);
}
......@@ -117,44 +117,48 @@ static const struct file_operations spec_dbg_meta_ops = {
*
* Return: 0 on success, otherwise a negative error number
*/
int spec_dbg_init(struct spec_dev *spec)
int spec_dbg_init(struct spec_gn412x *spec_gn412x)
{
spec->dbg_dir = debugfs_create_dir(dev_name(&spec->pdev->dev), NULL);
if (IS_ERR_OR_NULL(spec->dbg_dir)) {
dev_err(&spec->dev,
spec_gn412x->dbg_dir = debugfs_create_dir(dev_name(&spec_gn412x->pdev->dev),
NULL);
if (IS_ERR_OR_NULL(spec_gn412x->dbg_dir)) {
dev_err(&spec_gn412x->pdev->dev,
"Cannot create debugfs directory (%ld)\n",
PTR_ERR(spec->dbg_dir));
return PTR_ERR(spec->dbg_dir);
PTR_ERR(spec_gn412x->dbg_dir));
return PTR_ERR(spec_gn412x->dbg_dir);
}
spec->dbg_info = debugfs_create_file(SPEC_DBG_INFO_NAME, 0444,
spec->dbg_dir, spec,
&spec_irq_dbg_info_ops);
if (IS_ERR_OR_NULL(spec->dbg_info)) {
dev_err(&spec->dev,
spec_gn412x->dbg_info = debugfs_create_file(SPEC_DBG_INFO_NAME, 0444,
spec_gn412x->dbg_dir,
spec_gn412x,
&spec_irq_dbg_info_ops);
if (IS_ERR_OR_NULL(spec_gn412x->dbg_info)) {
dev_err(&spec_gn412x->pdev->dev,
"Cannot create debugfs file \"%s\" (%ld)\n",
SPEC_DBG_INFO_NAME, PTR_ERR(spec->dbg_info));
return PTR_ERR(spec->dbg_info);
SPEC_DBG_INFO_NAME, PTR_ERR(spec_gn412x->dbg_info));
return PTR_ERR(spec_gn412x->dbg_info);
}
spec->dbg_fw = debugfs_create_file(SPEC_DBG_FW_NAME, 0200,
spec->dbg_dir, spec,
&spec_dbg_fw_ops);
if (IS_ERR_OR_NULL(spec->dbg_fw)) {
dev_err(&spec->dev,
spec_gn412x->dbg_fw = debugfs_create_file(SPEC_DBG_FW_NAME, 0200,
spec_gn412x->dbg_dir,
spec_gn412x,
&spec_dbg_fw_ops);
if (IS_ERR_OR_NULL(spec_gn412x->dbg_fw)) {
dev_err(&spec_gn412x->pdev->dev,
"Cannot create debugfs file \"%s\" (%ld)\n",
SPEC_DBG_FW_NAME, PTR_ERR(spec->dbg_fw));
return PTR_ERR(spec->dbg_fw);
SPEC_DBG_FW_NAME, PTR_ERR(spec_gn412x->dbg_fw));
return PTR_ERR(spec_gn412x->dbg_fw);
}
spec->dbg_meta = debugfs_create_file(SPEC_DBG_META_NAME, 0200,
spec->dbg_dir, spec,
&spec_dbg_meta_ops);
if (IS_ERR_OR_NULL(spec->dbg_meta)) {
dev_err(&spec->dev,
spec_gn412x->dbg_meta = debugfs_create_file(SPEC_DBG_META_NAME, 0200,
spec_gn412x->dbg_dir,
spec_gn412x,
&spec_dbg_meta_ops);
if (IS_ERR_OR_NULL(spec_gn412x->dbg_meta)) {
dev_err(&spec_gn412x->pdev->dev,
"Cannot create debugfs file \"%s\" (%ld)\n",
SPEC_DBG_META_NAME, PTR_ERR(spec->dbg_meta));
return PTR_ERR(spec->dbg_meta);
SPEC_DBG_META_NAME, PTR_ERR(spec_gn412x->dbg_meta));
return PTR_ERR(spec_gn412x->dbg_meta);
}
return 0;
......@@ -164,7 +168,7 @@ int spec_dbg_init(struct spec_dev *spec)
* It removes the debugfs interface
* @spec: SPEC device instance
*/
void spec_dbg_exit(struct spec_dev *spec)
void spec_dbg_exit(struct spec_gn412x *spec_gn412x)
{
debugfs_remove_recursive(spec->dbg_dir);
debugfs_remove_recursive(spec_gn412x->dbg_dir);
}
......@@ -8,16 +8,16 @@
#include "spec.h"
#include "spec-compat.h"
void spec_gpio_fpga_select_set(struct spec_dev *spec,
void spec_gpio_fpga_select_set(struct spec_gn412x *spec_gn412x,
enum spec_fpga_select sel)
{
switch (sel) {
case SPEC_FPGA_SELECT_FPGA_FLASH:
case SPEC_FPGA_SELECT_GN4124_FPGA:
case SPEC_FPGA_SELECT_GN4124_FLASH:
gpiod_set_value(spec->gpiod[GN4124_GPIO_BOOTSEL0],
gpiod_set_value(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL0],
!!(sel & 0x1));
gpiod_set_value(spec->gpiod[GN4124_GPIO_BOOTSEL1],
gpiod_set_value(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL1],
!!(sel & 0x2));
break;
default:
......@@ -25,12 +25,12 @@ void spec_gpio_fpga_select_set(struct spec_dev *spec,
}
}
enum spec_fpga_select spec_gpio_fpga_select_get(struct spec_dev *spec)
enum spec_fpga_select spec_gpio_fpga_select_get(struct spec_gn412x *spec_gn412x)
{
enum spec_fpga_select sel = 0;
sel |= !!gpiod_get_value(spec->gpiod[GN4124_GPIO_BOOTSEL1]) << 1;
sel |= !!gpiod_get_value(spec->gpiod[GN4124_GPIO_BOOTSEL0]) << 0;
sel |= !!gpiod_get_value(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL1]) << 1;
sel |= !!gpiod_get_value(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL0]) << 0;
return sel;
}
......@@ -72,13 +72,13 @@ static inline size_t spec_gpiod_table_size(void)
(sizeof(struct gpiod_lookup) * 9);
}
int spec_gpio_init(struct spec_dev *spec)
int spec_gpio_init(struct spec_gn412x *spec_gn412x)
{
struct gpio_desc *gpiod;
struct gpiod_lookup_table *lookup;
int err = 0;
lookup = devm_kzalloc(&spec->pdev->dev,
lookup = devm_kzalloc(&spec_gn412x->pdev->dev,
spec_gpiod_table_size(),
GFP_KERNEL);
if (!lookup) {
......@@ -88,57 +88,57 @@ int spec_gpio_init(struct spec_dev *spec)
memcpy(lookup, &spec_gpiod_table, spec_gpiod_table_size());
lookup->dev_id = kstrdup(dev_name(&spec->pdev->dev), GFP_KERNEL);
lookup->dev_id = kstrdup(dev_name(&spec_gn412x->pdev->dev), GFP_KERNEL);
if (!lookup->dev_id)
goto err_dup;
spec->gpiod_table = lookup;
err = compat_gpiod_add_lookup_table(spec->gpiod_table);
spec_gn412x->gpiod_table = lookup;
err = compat_gpiod_add_lookup_table(spec_gn412x->gpiod_table);
if (err)
goto err_lookup;
gpiod = gpiod_get_index(&spec->pdev->dev, "bootsel", 0, GPIOD_OUT_HIGH);
gpiod = gpiod_get_index(&spec_gn412x->pdev->dev, "bootsel", 0, GPIOD_OUT_HIGH);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto err_sel0;
}
spec->gpiod[GN4124_GPIO_BOOTSEL0] = gpiod;
spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL0] = gpiod;
gpiod = gpiod_get_index(&spec->pdev->dev, "bootsel", 1, GPIOD_OUT_HIGH);
gpiod = gpiod_get_index(&spec_gn412x->pdev->dev, "bootsel", 1, GPIOD_OUT_HIGH);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto err_sel1;
}
spec->gpiod[GN4124_GPIO_BOOTSEL1] = gpiod;
spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL1] = gpiod;
/* Because of a BUG in RedHat kernel 3.10 we re-set direction */
err = gpiod_direction_output(spec->gpiod[GN4124_GPIO_BOOTSEL0], 1);
err = gpiod_direction_output(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL0], 1);
if (err)
goto err_out0;
err = gpiod_direction_output(spec->gpiod[GN4124_GPIO_BOOTSEL1], 1);
err = gpiod_direction_output(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL1], 1);
if (err)
goto err_out1;
gpiod = gpiod_get_index(&spec->pdev->dev, "irq", 0, GPIOD_IN);
gpiod = gpiod_get_index(&spec_gn412x->pdev->dev, "irq", 0, GPIOD_IN);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto err_irq0;
}
spec->gpiod[GN4124_GPIO_IRQ0] = gpiod;
spec_gn412x->gpiod[GN4124_GPIO_IRQ0] = gpiod;
gpiod = gpiod_get_index(&spec->pdev->dev, "irq", 1, GPIOD_IN);
gpiod = gpiod_get_index(&spec_gn412x->pdev->dev, "irq", 1, GPIOD_IN);
if (IS_ERR(gpiod)) {
err = PTR_ERR(gpiod);
goto err_irq1;
}
spec->gpiod[GN4124_GPIO_IRQ1] = gpiod;
spec_gn412x->gpiod[GN4124_GPIO_IRQ1] = gpiod;
/* Because of a BUG in RedHat kernel 3.10 we re-set direction */
err = gpiod_direction_input(spec->gpiod[GN4124_GPIO_IRQ0]);
err = gpiod_direction_input(spec_gn412x->gpiod[GN4124_GPIO_IRQ0]);
if (err)
goto err_in0;
err = gpiod_direction_input(spec->gpiod[GN4124_GPIO_IRQ1]);
err = gpiod_direction_input(spec_gn412x->gpiod[GN4124_GPIO_IRQ1]);
if (err)
goto err_in1;
......@@ -146,33 +146,33 @@ int spec_gpio_init(struct spec_dev *spec)
err_in1:
err_in0:
gpiod_put(spec->gpiod[GN4124_GPIO_IRQ1]);
gpiod_put(spec_gn412x->gpiod[GN4124_GPIO_IRQ1]);
err_irq1:
gpiod_put(spec->gpiod[GN4124_GPIO_IRQ0]);
gpiod_put(spec_gn412x->gpiod[GN4124_GPIO_IRQ0]);
err_irq0:
err_out1:
err_out0:
gpiod_put(spec->gpiod[GN4124_GPIO_BOOTSEL1]);
gpiod_put(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL1]);
err_sel1:
gpiod_put(spec->gpiod[GN4124_GPIO_BOOTSEL0]);
gpiod_put(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL0]);
err_sel0:
gpiod_remove_lookup_table(spec->gpiod_table);
gpiod_remove_lookup_table(spec_gn412x->gpiod_table);
err_lookup:
kfree(lookup->dev_id);
err_dup:
devm_kfree(&spec->pdev->dev, lookup);
spec->gpiod_table = NULL;
devm_kfree(&spec_gn412x->pdev->dev, lookup);
spec_gn412x->gpiod_table = NULL;
err_alloc:
return err;
}
void spec_gpio_exit(struct spec_dev *spec)
void spec_gpio_exit(struct spec_gn412x *spec_gn412x)
{
gpiod_put(spec->gpiod[GN4124_GPIO_IRQ1]);
gpiod_put(spec->gpiod[GN4124_GPIO_IRQ0]);
gpiod_put(spec->gpiod[GN4124_GPIO_BOOTSEL1]);
gpiod_put(spec->gpiod[GN4124_GPIO_BOOTSEL0]);
gpiod_remove_lookup_table(spec->gpiod_table);
kfree(spec->gpiod_table->dev_id);
gpiod_put(spec_gn412x->gpiod[GN4124_GPIO_IRQ1]);
gpiod_put(spec_gn412x->gpiod[GN4124_GPIO_IRQ0]);
gpiod_put(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL1]);
gpiod_put(spec_gn412x->gpiod[GN4124_GPIO_BOOTSEL0]);
gpiod_remove_lookup_table(spec_gn412x->gpiod_table);
kfree(spec_gn412x->gpiod_table->dev_id);
}
......@@ -99,30 +99,42 @@ struct spec_meta_id {
};
/**
* struct spec_dev - SPEC instance
* It describes a SPEC device instance.
* @dev Linux device instance descriptor
* @mtx: protect bootselect usage, fpga device load
* @flags collection of bit flags
* @slot_info: information about FMC slot
* @i2c_pdev: platform device for I2C master
* @i2c_adapter: the I2C master device to be used
* struct spec_fpga - it contains data to handle the FPGA
*
* @pdev: pointer to the PCI device
* @fpga:
* @meta:
* @vic_pdev:
* @app_pdev:
* @slot_info:
* @dbg_dir_fpga:
* @dbg_csr:
* @dbg_csr_reg:
*/
struct spec_dev {
struct pci_dev *pdev;
struct spec_fpga {
struct device dev;
DECLARE_BITMAP(flags, SPEC_FLAG_BITS);
void __iomem *fpga;
struct spec_meta_id __iomem *meta;
struct mutex mtx;
struct platform_device *vic_pdev;
struct platform_device *app_pdev;
struct fmc_slot_info slot_info;
struct dentry *dbg_dir_fpga;
#define SPEC_DBG_CSR_NAME "csr_regs"
struct dentry *dbg_csr;
struct debugfs_regset32 dbg_csr_reg;
};
/**
* struct spec_gn412x - it contains data to handle the PCB
*
* @pdev: pointer to the PCI device
* @mtx: it protects FPGA device/configuration loading
*/
struct spec_gn412x {
struct pci_dev *pdev;
struct mutex mtx;
struct spec_meta_id __iomem *meta;
struct gpiod_lookup_table *gpiod_table;
struct gpio_desc *gpiod[GN4124_GPIO_MAX];
struct dentry *dbg_dir;
#define SPEC_DBG_INFO_NAME "info"
struct dentry *dbg_info;
......@@ -130,35 +142,27 @@ struct spec_dev {
struct dentry *dbg_fw;
#define SPEC_DBG_META_NAME "fpga_device_metadata"
struct dentry *dbg_meta;
struct dentry *dbg_dir_fpga;
#define SPEC_DBG_CSR_NAME "csr_regs"
struct dentry *dbg_csr;
struct debugfs_regset32 dbg_csr_reg;
struct gpiod_lookup_table *gpiod_table;
struct gpio_desc *gpiod[GN4124_GPIO_MAX];
struct spec_fpga *spec_fpga;
};
static inline struct spec_dev *to_spec_dev(struct device *_dev)
static inline struct spec_fpga *to_spec_fpga(struct device *_dev)
{
return container_of(_dev, struct spec_dev, dev);
return container_of(_dev, struct spec_fpga, dev);
}
extern int spec_fw_load(struct spec_dev *spec, const char *name);
extern int spec_fw_load(struct spec_gn412x *spec_gn412x, const char *name);
extern int spec_dbg_init(struct spec_dev *spec);
extern void spec_dbg_exit(struct spec_dev *spec);
extern int spec_dbg_init(struct spec_gn412x *spec_gn412x);
extern void spec_dbg_exit(struct spec_gn412x *spec_gn412x);
extern void spec_gpio_fpga_select_set(struct spec_dev *spec,
extern void spec_gpio_fpga_select_set(struct spec_gn412x *spec_gn412x,
enum spec_fpga_select sel);
extern enum spec_fpga_select spec_gpio_fpga_select_get(struct spec_dev *spec);
extern enum spec_fpga_select spec_gpio_fpga_select_get(struct spec_gn412x *spec_gn412x);
extern int spec_gpio_init(struct spec_dev *spec);
extern void spec_gpio_exit(struct spec_dev *spec);
extern int spec_gpio_init(struct spec_gn412x *spec_gn412x);
extern void spec_gpio_exit(struct spec_gn412x *spec_gn412x);
extern int spec_fpga_init(struct spec_dev *spec);
extern int spec_fpga_exit(struct spec_dev *spec);
extern int spec_fpga_init(struct spec_gn412x *spec_gn412x);
extern int spec_fpga_exit(struct spec_gn412x *spec_gn412x);
#endif /* __SPEC_H__ */
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