Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751445AbdGRGdG (ORCPT ); Tue, 18 Jul 2017 02:33:06 -0400 Received: from mail.gnudd.com ([77.43.112.34]:45025 "EHLO mail.gnudd.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751398AbdGRGdC (ORCPT ); Tue, 18 Jul 2017 02:33:02 -0400 Date: Tue, 18 Jul 2017 08:32:53 +0200 From: Alessandro Rubini To: linux-kernel@vger.kernel.org Cc: riehecky@fnal.gov, federico.vaga@cern.ch, gregkh@linuxfoundation.org Subject: [PATCH V3 2/5] drivers/fmc: hide fmc operations behind helpers Message-ID: <20170718063253.GA23443@mail.gnudd.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Organization: GnuDD, Device Drivers, Embedded Systems, Courses Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7462 Lines: 236 From: Federico Vaga 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 Tested-by: Pat Riehecky Acked-by: Alessandro Rubini --- V3 (Alessandro): fixed From line in patch, added alessandro's acked-by V2 (Pat): added Tested-by and incorrect From line V1 (Pat): picked from ohwr.org repo, where most fmc users pick from. drivers/fmc/fmc-chardev.c | 3 +-- drivers/fmc/fmc-core.c | 55 ++++++++++++++++++++++++++++++++++++++++++ drivers/fmc/fmc-match.c | 2 +- drivers/fmc/fmc-trivial.c | 20 ++++++--------- drivers/fmc/fmc-write-eeprom.c | 8 +++--- 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 ace6ef2..5ecf409 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 353fc54..5263d06 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 104a5ef..a0956d1 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 6c590f5..8defdee 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 9bb2cbd..3eb81bb 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 a5f0aa5..8bb4a154 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__ */ -- 2.1.4