aboutsummaryrefslogtreecommitdiff
path: root/drivers/spi/spi-fsl-espi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-fsl-espi.c')
-rw-r--r--drivers/spi/spi-fsl-espi.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 428dc7a6b62..8ebd724e4c5 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -219,13 +219,8 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
struct fsl_espi_reg *reg_base = mpc8xxx_spi->reg_base;
unsigned int len = t->len;
- u8 bits_per_word;
int ret;
- bits_per_word = spi->bits_per_word;
- if (t->bits_per_word)
- bits_per_word = t->bits_per_word;
-
mpc8xxx_spi->len = t->len;
len = roundup(len, 4) / 4;
@@ -353,7 +348,7 @@ static void fsl_espi_cmd_trans(struct spi_message *m,
}
espi_trans->tx_buf = local_buf;
- espi_trans->rx_buf = local_buf + espi_trans->n_tx;
+ espi_trans->rx_buf = local_buf;
fsl_espi_do_trans(m, espi_trans);
espi_trans->actual_length = espi_trans->len;
@@ -402,7 +397,7 @@ static void fsl_espi_rw_trans(struct spi_message *m,
espi_trans->n_rx = trans_len;
espi_trans->len = trans_len + n_tx;
espi_trans->tx_buf = local_buf;
- espi_trans->rx_buf = local_buf + n_tx;
+ espi_trans->rx_buf = local_buf;
fsl_espi_do_trans(m, espi_trans);
memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len);
@@ -446,7 +441,8 @@ static void fsl_espi_do_one_msg(struct spi_message *m)
m->actual_length = espi_trans.actual_length;
m->status = espi_trans.status;
- m->complete(m->context);
+ if (m->complete)
+ m->complete(m->context);
}
static int fsl_espi_setup(struct spi_device *spi)
@@ -462,7 +458,7 @@ static int fsl_espi_setup(struct spi_device *spi)
return -EINVAL;
if (!cs) {
- cs = kzalloc(sizeof *cs, GFP_KERNEL);
+ cs = devm_kzalloc(&spi->dev, sizeof(*cs), GFP_KERNEL);
if (!cs)
return -ENOMEM;
spi->controller_state = cs;
@@ -590,8 +586,10 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
struct spi_master *master;
struct mpc8xxx_spi *mpc8xxx_spi;
struct fsl_espi_reg *reg_base;
- u32 regval;
- int i, ret = 0;
+ struct device_node *nc;
+ const __be32 *prop;
+ u32 regval, csmode;
+ int i, len, ret = 0;
master = spi_alloc_master(dev, sizeof(struct mpc8xxx_spi));
if (!master) {
@@ -638,8 +636,32 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
mpc8xxx_spi_write_reg(&reg_base->event, 0xffffffff);
/* Init eSPI CS mode register */
- for (i = 0; i < pdata->max_chipselect; i++)
- mpc8xxx_spi_write_reg(&reg_base->csmode[i], CSMODE_INIT_VAL);
+ for_each_available_child_of_node(master->dev.of_node, nc) {
+ /* get chip select */
+ prop = of_get_property(nc, "reg", &len);
+ if (!prop || len < sizeof(*prop))
+ continue;
+ i = be32_to_cpup(prop);
+ if (i < 0 || i >= pdata->max_chipselect)
+ continue;
+
+ csmode = CSMODE_INIT_VAL;
+ /* check if CSBEF is set in device tree */
+ prop = of_get_property(nc, "fsl,csbef", &len);
+ if (prop && len >= sizeof(*prop)) {
+ csmode &= ~(CSMODE_BEF(0xf));
+ csmode |= CSMODE_BEF(be32_to_cpup(prop));
+ }
+ /* check if CSAFT is set in device tree */
+ prop = of_get_property(nc, "fsl,csaft", &len);
+ if (prop && len >= sizeof(*prop)) {
+ csmode &= ~(CSMODE_AFT(0xf));
+ csmode |= CSMODE_AFT(be32_to_cpup(prop));
+ }
+ mpc8xxx_spi_write_reg(&reg_base->csmode[i], csmode);
+
+ dev_info(dev, "cs=%d, init_csmode=0x%x\n", i, csmode);
+ }
/* Enable SPI interface */
regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;