diff options
author | Federico Vaga <federico.vaga@cern.ch> | 2017-07-18 09:32:53 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-08-28 17:24:21 +0300 |
commit | 9f757f415210a7c85e2784e4a1733ea78b2e4e88 (patch) | |
tree | c29a08c4ead881258606731c66129aa0d3272771 | |
parent | 8e12381bd7637dcf61a0503b566d5d9ab5b5e1b3 (diff) | |
download | linux-9f757f415210a7c85e2784e4a1733ea78b2e4e88.tar.xz |
drivers/fmc: hide fmc operations behind helpers
This gave us more freedom to change/add/remove operations without
recompiling all device driver.
Typically, Carrier board implement the fmc operations, so they will not
use these helpers.
Signed-off-by: Federico Vaga <federico.vaga@cern.ch>
Tested-by: Pat Riehecky <riehecky@fnal.gov>
Acked-by: Alessandro Rubini <rubini@gnudd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/fmc/fmc-chardev.c | 3 | ||||
-rw-r--r-- | drivers/fmc/fmc-core.c | 55 | ||||
-rw-r--r-- | drivers/fmc/fmc-match.c | 2 | ||||
-rw-r--r-- | drivers/fmc/fmc-trivial.c | 20 | ||||
-rw-r--r-- | drivers/fmc/fmc-write-eeprom.c | 8 | ||||
-rw-r--r-- | include/linux/fmc.h | 18 |
6 files changed, 87 insertions, 19 deletions
diff --git a/drivers/fmc/fmc-chardev.c b/drivers/fmc/fmc-chardev.c index ace6ef24d15e..5ecf4090a610 100644 --- a/drivers/fmc/fmc-chardev.c +++ b/drivers/fmc/fmc-chardev.c @@ -129,8 +129,7 @@ static int fc_probe(struct fmc_device *fmc) struct fc_instance *fc; - if (fmc->op->validate) - index = fmc->op->validate(fmc, &fc_drv); + index = fmc_validate(fmc, &fc_drv); if (index < 0) return -EINVAL; /* not our device: invalid */ diff --git a/drivers/fmc/fmc-core.c b/drivers/fmc/fmc-core.c index 353fc546fb08..5263d0607b64 100644 --- a/drivers/fmc/fmc-core.c +++ b/drivers/fmc/fmc-core.c @@ -118,6 +118,61 @@ static struct bin_attribute fmc_eeprom_attr = { .write = fmc_write_eeprom, }; +int fmc_irq_request(struct fmc_device *fmc, irq_handler_t h, + char *name, int flags) +{ + if (fmc->op->irq_request) + return fmc->op->irq_request(fmc, h, name, flags); + return -EPERM; +} +EXPORT_SYMBOL(fmc_irq_request); + +void fmc_irq_free(struct fmc_device *fmc) +{ + if (fmc->op->irq_free) + fmc->op->irq_free(fmc); +} +EXPORT_SYMBOL(fmc_irq_free); + +void fmc_irq_ack(struct fmc_device *fmc) +{ + if (likely(fmc->op->irq_ack)) + fmc->op->irq_ack(fmc); +} +EXPORT_SYMBOL(fmc_irq_ack); + +int fmc_validate(struct fmc_device *fmc, struct fmc_driver *drv) +{ + if (fmc->op->validate) + return fmc->op->validate(fmc, drv); + return -EPERM; +} +EXPORT_SYMBOL(fmc_validate); + +int fmc_gpio_config(struct fmc_device *fmc, struct fmc_gpio *gpio, int ngpio) +{ + if (fmc->op->gpio_config) + return fmc->op->gpio_config(fmc, gpio, ngpio); + return -EPERM; +} +EXPORT_SYMBOL(fmc_gpio_config); + +int fmc_read_ee(struct fmc_device *fmc, int pos, void *d, int l) +{ + if (fmc->op->read_ee) + return fmc->op->read_ee(fmc, pos, d, l); + return -EPERM; +} +EXPORT_SYMBOL(fmc_read_ee); + +int fmc_write_ee(struct fmc_device *fmc, int pos, const void *d, int l) +{ + if (fmc->op->write_ee) + return fmc->op->write_ee(fmc, pos, d, l); + return -EPERM; +} +EXPORT_SYMBOL(fmc_write_ee); + /* * Functions for client modules follow */ diff --git a/drivers/fmc/fmc-match.c b/drivers/fmc/fmc-match.c index 104a5efc2207..a0956d1f7550 100644 --- a/drivers/fmc/fmc-match.c +++ b/drivers/fmc/fmc-match.c @@ -63,7 +63,7 @@ int fmc_fill_id_info(struct fmc_device *fmc) if (!fmc->eeprom) return -ENOMEM; allocated = 1; - ret = fmc->op->read_ee(fmc, 0, fmc->eeprom, fmc->eeprom_len); + ret = fmc_read_ee(fmc, 0, fmc->eeprom, fmc->eeprom_len); if (ret < 0) goto out; } diff --git a/drivers/fmc/fmc-trivial.c b/drivers/fmc/fmc-trivial.c index 6c590f54c79d..8defdee3e3a3 100644 --- a/drivers/fmc/fmc-trivial.c +++ b/drivers/fmc/fmc-trivial.c @@ -24,7 +24,7 @@ static irqreturn_t t_handler(int irq, void *dev_id) { struct fmc_device *fmc = dev_id; - fmc->op->irq_ack(fmc); + fmc_irq_ack(fmc); dev_info(&fmc->dev, "received irq %i\n", irq); return IRQ_HANDLED; } @@ -46,25 +46,21 @@ static int t_probe(struct fmc_device *fmc) int ret; int index = 0; - if (fmc->op->validate) - index = fmc->op->validate(fmc, &t_drv); + index = fmc_validate(fmc, &t_drv); if (index < 0) return -EINVAL; /* not our device: invalid */ - ret = fmc->op->irq_request(fmc, t_handler, "fmc-trivial", IRQF_SHARED); + ret = fmc_irq_request(fmc, t_handler, "fmc-trivial", IRQF_SHARED); if (ret < 0) return ret; /* ignore error code of call below, we really don't care */ - fmc->op->gpio_config(fmc, t_gpio, ARRAY_SIZE(t_gpio)); + fmc_gpio_config(fmc, t_gpio, ARRAY_SIZE(t_gpio)); - /* Reprogram, if asked to. ESRCH == no filename specified */ - ret = -ESRCH; - if (fmc->op->reprogram) - ret = fmc->op->reprogram(fmc, &t_drv, ""); - if (ret == -ESRCH) + ret = fmc_reprogram(fmc, &t_drv, "", 0); + if (ret == -EPERM) /* programming not supported */ ret = 0; if (ret < 0) - fmc->op->irq_free(fmc); + fmc_irq_free(fmc); /* FIXME: reprogram LM32 too */ return ret; @@ -72,7 +68,7 @@ static int t_probe(struct fmc_device *fmc) static int t_remove(struct fmc_device *fmc) { - fmc->op->irq_free(fmc); + fmc_irq_free(fmc); return 0; } diff --git a/drivers/fmc/fmc-write-eeprom.c b/drivers/fmc/fmc-write-eeprom.c index 9bb2cbd5c9f2..3eb81bb1f1fc 100644 --- a/drivers/fmc/fmc-write-eeprom.c +++ b/drivers/fmc/fmc-write-eeprom.c @@ -50,7 +50,7 @@ static int fwe_run_tlv(struct fmc_device *fmc, const struct firmware *fw, if (write) { dev_info(&fmc->dev, "write %i bytes at 0x%04x\n", thislen, thisaddr); - err = fmc->op->write_ee(fmc, thisaddr, p + 5, thislen); + err = fmc_write_ee(fmc, thisaddr, p + 5, thislen); } if (err < 0) { dev_err(&fmc->dev, "write failure @0x%04x\n", @@ -70,7 +70,7 @@ static int fwe_run_bin(struct fmc_device *fmc, const struct firmware *fw) int ret; dev_info(&fmc->dev, "programming %zi bytes\n", fw->size); - ret = fmc->op->write_ee(fmc, 0, (void *)fw->data, fw->size); + ret = fmc_write_ee(fmc, 0, (void *)fw->data, fw->size); if (ret < 0) { dev_info(&fmc->dev, "write_eeprom: error %i\n", ret); return ret; @@ -115,8 +115,8 @@ static int fwe_probe(struct fmc_device *fmc) KBUILD_MODNAME); return -ENODEV; } - if (fmc->op->validate) - index = fmc->op->validate(fmc, &fwe_drv); + + index = fmc_validate(fmc, &fwe_drv); if (index < 0) { pr_err("%s: refusing device \"%s\"\n", KBUILD_MODNAME, dev_name(dev)); diff --git a/include/linux/fmc.h b/include/linux/fmc.h index a5f0aa5c2a8d..8bb4a154bbdc 100644 --- a/include/linux/fmc.h +++ b/include/linux/fmc.h @@ -234,4 +234,22 @@ extern void fmc_free_id_info(struct fmc_device *fmc); extern void fmc_dump_eeprom(const struct fmc_device *fmc); extern void fmc_dump_sdb(const struct fmc_device *fmc); +/* helpers for FMC operations */ +extern int fmc_irq_request(struct fmc_device *fmc, irq_handler_t h, + char *name, int flags); +extern void fmc_irq_free(struct fmc_device *fmc); +extern void fmc_irq_ack(struct fmc_device *fmc); +extern int fmc_validate(struct fmc_device *fmc, struct fmc_driver *drv); +extern int fmc_gpio_config(struct fmc_device *fmc, struct fmc_gpio *gpio, + int ngpio); +extern int fmc_read_ee(struct fmc_device *fmc, int pos, void *d, int l); +extern int fmc_write_ee(struct fmc_device *fmc, int pos, const void *d, int l); + +/* helpers for FMC operations */ +extern int fmc_irq_request(struct fmc_device *fmc, irq_handler_t h, + char *name, int flags); +extern void fmc_irq_free(struct fmc_device *fmc); +extern void fmc_irq_ack(struct fmc_device *fmc); +extern int fmc_validate(struct fmc_device *fmc, struct fmc_driver *drv); + #endif /* __LINUX_FMC_H__ */ |