[U-Boot] [PATCH 3/5] x86: ich-spi: Don't read cached lock status
Stefan Roese
sr at denx.de
Wed Aug 16 06:19:09 UTC 2017
On 16.08.2017 07:38, Bin Meng wrote:
> At present the ICH SPI controller driver reads the controller lock
> status from its register in the probe routine and saves the lock
> status to a member of priv. Later the driver uses the cached status
> from priv to judge whether the controller setting is locked and do
> different setup.
>
> But such logic is only valid when there is only the SPI controller
> driver that touches the SPI hardware. In fact the lock status change
> can be trigged outside the driver, eg: during the fsp_notify() call
> when Intel FSP is used.
>
> This changes the driver to read the lock status every time when an
> SPI transfer is initiated instead of reading the cached one.
>
> Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
> ---
>
> drivers/spi/ich.c | 29 +++++++++++++++++++++++------
> drivers/spi/ich.h | 2 --
> 2 files changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
> index 909eefc..d4888f5 100644
> --- a/drivers/spi/ich.c
> +++ b/drivers/spi/ich.c
> @@ -126,7 +126,6 @@ static int ich_init_controller(struct udevice *dev,
> if (plat->ich_version == ICHV_7) {
> struct ich7_spi_regs *ich7_spi = sbase;
>
> - ctlr->ichspi_lock = readw(&ich7_spi->spis) & SPIS_LOCK;
> ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu);
> ctlr->menubytes = sizeof(ich7_spi->opmenu);
> ctlr->optype = offsetof(struct ich7_spi_regs, optype);
> @@ -141,7 +140,6 @@ static int ich_init_controller(struct udevice *dev,
> } else if (plat->ich_version == ICHV_9) {
> struct ich9_spi_regs *ich9_spi = sbase;
>
> - ctlr->ichspi_lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
> ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu);
> ctlr->menubytes = sizeof(ich9_spi->opmenu);
> ctlr->optype = offsetof(struct ich9_spi_regs, optype);
> @@ -186,6 +184,23 @@ static inline void spi_use_in(struct spi_trans *trans, unsigned bytes)
> trans->bytesin -= bytes;
> }
>
> +static bool spi_lock_status(struct ich_spi_platdata *plat, void *sbase)
> +{
> + int lock = 0;
> +
> + if (plat->ich_version == ICHV_7) {
> + struct ich7_spi_regs *ich7_spi = sbase;
> +
> + lock = readw(&ich7_spi->spis) & SPIS_LOCK;
> + } else if (plat->ich_version == ICHV_9) {
> + struct ich9_spi_regs *ich9_spi = sbase;
> +
> + lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
> + }
> +
> + return lock != 0;
> +}
> +
> static void spi_setup_type(struct spi_trans *trans, int data_bytes)
> {
> trans->type = 0xFF;
> @@ -219,14 +234,15 @@ static void spi_setup_type(struct spi_trans *trans, int data_bytes)
> }
> }
>
> -static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans)
> +static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
> + bool lock)
> {
> uint16_t optypes;
> uint8_t opmenu[ctlr->menubytes];
>
> trans->opcode = trans->out[0];
> spi_use_out(trans, 1);
> - if (!ctlr->ichspi_lock) {
> + if (!lock) {
> /* The lock is off, so just use index 0. */
> ich_writeb(ctlr, trans->opcode, ctlr->opmenu);
> optypes = ich_readw(ctlr, ctlr->optype);
> @@ -336,6 +352,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
> struct spi_trans *trans = &ctlr->trans;
> unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END);
> int using_cmd = 0;
> + bool lock = spi_lock_status(plat, ctlr->base);
> int ret;
>
> /* We don't support writing partial bytes */
> @@ -399,7 +416,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
> ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
>
> spi_setup_type(trans, using_cmd ? bytes : 0);
> - opcode_index = spi_setup_opcode(ctlr, trans);
> + opcode_index = spi_setup_opcode(ctlr, trans, lock);
> if (opcode_index < 0)
> return -EINVAL;
> with_address = spi_setup_offset(trans);
> @@ -412,7 +429,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
> * in order to prevent the Management Engine from
> * issuing a transaction between WREN and DATA.
> */
> - if (!ctlr->ichspi_lock)
> + if (!lock)
> ich_writew(ctlr, trans->opcode, ctlr->preop);
> return 0;
> }
> diff --git a/drivers/spi/ich.h b/drivers/spi/ich.h
> index dcb8a90..c867c57 100644
> --- a/drivers/spi/ich.h
> +++ b/drivers/spi/ich.h
> @@ -177,8 +177,6 @@ struct ich_spi_platdata {
> };
>
> struct ich_spi_priv {
> - int ichspi_lock;
> - int locked;
> int opmenu;
> int menubytes;
> void *base; /* Base of register set */
>
Reviewed-by: Stefan Roese <sr at denx.de>
Thanks,
Stefan
More information about the U-Boot
mailing list