On Tue, 14 Jan 2020 at 10:46, Ard Biesheuvel <ardb@xxxxxxxxxx> wrote: > > When fitted, the SynQuacer platform exposes its SPI TPM via a MMIO > window that is backed by the SPI command sequencer in the SPI bus > controller. This arrangement has the limitation that only byte size > accesses are supported, and so we'll need to provide a separate set > of read and write accessors that take this into account. > > Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx> > --- > drivers/char/tpm/tpm_tis.c | 31 ++++++++++++++++++-- > 1 file changed, 29 insertions(+), 2 deletions(-) > > diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c > index e7df342a317d..693e48096035 100644 > --- a/drivers/char/tpm/tpm_tis.c > +++ b/drivers/char/tpm/tpm_tis.c > @@ -32,6 +32,7 @@ > > struct tpm_info { > struct resource res; > + const struct tpm_tis_phy_ops *ops; > /* irq > 0 means: use irq $irq; > * irq = 0 means: autoprobe for an irq; > * irq = -1 means: no irq support > @@ -186,6 +187,29 @@ static const struct tpm_tis_phy_ops tpm_tcg = { > .write32 = tpm_tcg_write32, > }; > > +static int tpm_tcg_read16_bw(struct tpm_tis_data *data, u32 addr, u16 *result) > +{ > + return tpm_tcg_read_bytes(data, addr, 2, (u8 *)result); > +} > + > +static int tpm_tcg_read32_bw(struct tpm_tis_data *data, u32 addr, u32 *result) > +{ > + return tpm_tcg_read_bytes(data, addr, 4, (u8 *)result); > +} > + > +static int tpm_tcg_write32_bw(struct tpm_tis_data *data, u32 addr, u32 value) > +{ > + return tpm_tcg_write_bytes(data, addr, 4, (u8 *)&value); > +} > + These are wrong - I'll need to respin. Apologies for the noise. > +static const struct tpm_tis_phy_ops tpm_tcg_bw = { > + .read_bytes = tpm_tcg_read_bytes, > + .write_bytes = tpm_tcg_write_bytes, > + .read16 = tpm_tcg_read16_bw, > + .read32 = tpm_tcg_read32_bw, > + .write32 = tpm_tcg_write32_bw, > +}; > + > static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info) > { > struct tpm_tis_tcg_phy *phy; > @@ -210,7 +234,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info) > if (itpm || is_itpm(ACPI_COMPANION(dev))) > phy->priv.flags |= TPM_TIS_ITPM_WORKAROUND; > > - return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg, > + return tpm_tis_core_init(dev, &phy->priv, irq, tpm_info->ops, > ACPI_HANDLE(dev)); > } > > @@ -219,7 +243,7 @@ static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); > static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, > const struct pnp_device_id *pnp_id) > { > - struct tpm_info tpm_info = {}; > + struct tpm_info tpm_info = { .ops = &tpm_tcg }; > struct resource *res; > > res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0); > @@ -295,6 +319,8 @@ static int tpm_tis_plat_probe(struct platform_device *pdev) > tpm_info.irq = 0; > } > > + tpm_info.ops = of_device_get_match_data(&pdev->dev) ?: &tpm_tcg; > + > return tpm_tis_init(&pdev->dev, &tpm_info); > } > > @@ -311,6 +337,7 @@ static int tpm_tis_plat_remove(struct platform_device *pdev) > #ifdef CONFIG_OF > static const struct of_device_id tis_of_platform_match[] = { > {.compatible = "tcg,tpm-tis-mmio"}, > + {.compatible = "socionext,synquacer-tpm-mmio", .data = &tpm_tcg_bw}, > {}, > }; > MODULE_DEVICE_TABLE(of, tis_of_platform_match); > -- > 2.20.1 >