Move the getters/setters to sp-dev.c, so that they can be accessed from sp-pci.c and sp-platform.c. This makes it possible for the psp platform_device to set the function pointers and be assigned the role of master device by psp_dev_init(). While the case of a system having both a PCI and ACPI PSP is not supported (and not known to occur in the wild), it makes sense to have a single static global to assign to. Should such a system occur, the logic in psp_set_master() is that the pci device is preferred. Signed-off-by: Jeremi Piotrowski <jpiotrowski@xxxxxxxxxxxxxxxxxxx> --- drivers/crypto/ccp/sp-dev.c | 59 ++++++++++++++++++++++++++++++++ drivers/crypto/ccp/sp-dev.h | 4 +++ drivers/crypto/ccp/sp-pci.c | 48 -------------------------- drivers/crypto/ccp/sp-platform.c | 6 ++++ 4 files changed, 69 insertions(+), 48 deletions(-) diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c index 52b8d957d0f6..04b77d640f62 100644 --- a/drivers/crypto/ccp/sp-dev.c +++ b/drivers/crypto/ccp/sp-dev.c @@ -14,6 +14,8 @@ #include <linux/kthread.h> #include <linux/sched.h> #include <linux/interrupt.h> +#include <linux/pci.h> +#include <linux/platform_device.h> #include <linux/spinlock.h> #include <linux/spinlock_types.h> #include <linux/types.h> @@ -39,6 +41,8 @@ static LIST_HEAD(sp_units); /* Ever-increasing value to produce unique unit numbers */ static atomic_t sp_ordinal; +static struct sp_device *sp_dev_master; + static void sp_add_device(struct sp_device *sp) { unsigned long flags; @@ -250,6 +254,61 @@ struct sp_device *sp_get_psp_master_device(void) return ret; } +static bool sp_pci_is_master(struct sp_device *sp) +{ + struct device *dev_cur, *dev_new; + struct pci_dev *pdev_cur, *pdev_new; + + dev_new = sp->dev; + dev_cur = sp_dev_master->dev; + + pdev_new = to_pci_dev(dev_new); + pdev_cur = to_pci_dev(dev_cur); + + if (pdev_new->bus->number < pdev_cur->bus->number) + return true; + + if (PCI_SLOT(pdev_new->devfn) < PCI_SLOT(pdev_cur->devfn)) + return true; + + if (PCI_FUNC(pdev_new->devfn) < PCI_FUNC(pdev_cur->devfn)) + return true; + + return false; +} + +void psp_set_master(struct sp_device *sp) +{ + struct device *dev_cur, *dev_new; + + if (!sp_dev_master) { + sp_dev_master = sp; + return; + } + + dev_new = sp->dev; + dev_cur = sp_dev_master->dev; + + if (dev_is_pci(dev_new) && dev_is_pci(dev_cur) && sp_pci_is_master(sp)) + sp_dev_master = sp; + if (dev_is_pci(dev_new) && dev_is_platform(dev_cur)) + sp_dev_master = sp; +} + +struct sp_device *psp_get_master(void) +{ + return sp_dev_master; +} + +void psp_clear_master(struct sp_device *sp) +{ + if (sp == sp_dev_master) { + sp_dev_master = NULL; + dev_dbg(sp->dev, "Cleared sp_dev_master\n"); + } +} + + static int __init sp_mod_init(void) { #ifdef CONFIG_X86 diff --git a/drivers/crypto/ccp/sp-dev.h b/drivers/crypto/ccp/sp-dev.h index aaa651364425..083e57652c7b 100644 --- a/drivers/crypto/ccp/sp-dev.h +++ b/drivers/crypto/ccp/sp-dev.h @@ -129,6 +129,10 @@ int sp_request_psp_irq(struct sp_device *sp, irq_handler_t handler, void sp_free_psp_irq(struct sp_device *sp, void *data); struct sp_device *sp_get_psp_master_device(void); +void psp_set_master(struct sp_device *sp); +struct sp_device *psp_get_master(void); +void psp_clear_master(struct sp_device *sp); + #ifdef CONFIG_CRYPTO_DEV_SP_CCP int ccp_dev_init(struct sp_device *sp); diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c index 792d6da7f0c0..f9be8aba0acf 100644 --- a/drivers/crypto/ccp/sp-pci.c +++ b/drivers/crypto/ccp/sp-pci.c @@ -30,7 +30,6 @@ struct sp_pci { int msix_count; struct msix_entry msix_entry[MSIX_VECTORS]; }; -static struct sp_device *sp_dev_master; #define attribute_show(name, def) \ static ssize_t name##_show(struct device *d, struct device_attribute *attr, \ @@ -168,53 +167,6 @@ static void sp_free_irqs(struct sp_device *sp) sp->psp_irq = 0; } -static bool sp_pci_is_master(struct sp_device *sp) -{ - struct device *dev_cur, *dev_new; - struct pci_dev *pdev_cur, *pdev_new; - - dev_new = sp->dev; - dev_cur = sp_dev_master->dev; - - pdev_new = to_pci_dev(dev_new); - pdev_cur = to_pci_dev(dev_cur); - - if (pdev_new->bus->number < pdev_cur->bus->number) - return true; - - if (PCI_SLOT(pdev_new->devfn) < PCI_SLOT(pdev_cur->devfn)) - return true; - - if (PCI_FUNC(pdev_new->devfn) < PCI_FUNC(pdev_cur->devfn)) - return true; - - return false; -} - -static void psp_set_master(struct sp_device *sp) -{ - if (!sp_dev_master) { - sp_dev_master = sp; - return; - } - - if (sp_pci_is_master(sp)) - sp_dev_master = sp; -} - -static struct sp_device *psp_get_master(void) -{ - return sp_dev_master; -} - -static void psp_clear_master(struct sp_device *sp) -{ - if (sp == sp_dev_master) { - sp_dev_master = NULL; - dev_dbg(sp->dev, "Cleared sp_dev_master\n"); - } -} - static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct sp_device *sp; diff --git a/drivers/crypto/ccp/sp-platform.c b/drivers/crypto/ccp/sp-platform.c index b74f16e0e963..d56b34255b97 100644 --- a/drivers/crypto/ccp/sp-platform.c +++ b/drivers/crypto/ccp/sp-platform.c @@ -231,6 +231,12 @@ static int sp_platform_probe(struct platform_device *pdev) dev_set_drvdata(dev, sp); + if (sp_platform->is_platform) { + sp->set_psp_master_device = psp_set_master; + sp->get_psp_master_device = psp_get_master; + sp->clear_psp_master_device = psp_clear_master; + } + ret = sp_init(sp); if (ret) goto e_err; -- 2.25.1