/* * AMD Platform Security Processor (PSP) interface * * Copyright (C) 2016-2017 Advanced Micro Devices, Inc. * * Author: Brijesh Singh * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "sp-dev.h" #include "psp-dev.h" static struct psp_device *psp_alloc_struct(struct sp_device *sp) { struct device *dev = sp->dev; struct psp_device *psp; psp = devm_kzalloc(dev, sizeof(*psp), GFP_KERNEL); if (!psp) return NULL; psp->dev = dev; psp->sp = sp; snprintf(psp->name, sizeof(psp->name), "psp-%u", sp->ord); return psp; } static irqreturn_t psp_irq_handler(int irq, void *data) { return IRQ_HANDLED; } int psp_dev_init(struct sp_device *sp) { struct device *dev = sp->dev; struct psp_device *psp; int ret; ret = -ENOMEM; psp = psp_alloc_struct(sp); if (!psp) goto e_err; sp->psp_data = psp; psp->vdata = (struct psp_vdata *)sp->dev_vdata->psp_vdata; if (!psp->vdata) { ret = -ENODEV; dev_err(dev, "missing driver data\n"); goto e_err; } psp->io_regs = sp->io_map + psp->vdata->offset; /* Disable and clear interrupts until ready */ iowrite32(0, psp->io_regs + PSP_P2CMSG_INTEN); iowrite32(-1, psp->io_regs + PSP_P2CMSG_INTSTS); /* Request an irq */ ret = sp_request_psp_irq(psp->sp, psp_irq_handler, psp->name, psp); if (ret) { dev_err(dev, "psp: unable to allocate an IRQ\n"); goto e_err; } if (sp->set_psp_master_device) sp->set_psp_master_device(sp); /* Enable interrupt */ iowrite32(-1, psp->io_regs + PSP_P2CMSG_INTEN); return 0; e_err: sp->psp_data = NULL; dev_notice(dev, "psp initialization failed\n"); return ret; } void psp_dev_destroy(struct sp_device *sp) { struct psp_device *psp = sp->psp_data; sp_free_psp_irq(sp, psp); }