Loading drivers/spi/spi-bcm53xx.c +76 −2 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include "spi-bcm53xx.h" #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */ #define BCM53XXSPI_FLASH_WINDOW SZ_32M /* The longest observed required wait was 19 ms */ #define BCM53XXSPI_SPE_TIMEOUT_MS 80 Loading @@ -17,8 +18,10 @@ struct bcm53xxspi { struct bcma_device *core; struct spi_master *master; void __iomem *mmio_base; size_t read_offset; bool bspi; /* Boot SPI mode with memory mapping */ }; static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset) Loading @@ -32,6 +35,50 @@ static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset, bcma_write32(b53spi->core, offset, value); } static void bcm53xxspi_disable_bspi(struct bcm53xxspi *b53spi) { struct device *dev = &b53spi->core->dev; unsigned long deadline; u32 tmp; if (!b53spi->bspi) return; tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL); if (tmp & 0x1) return; deadline = jiffies + usecs_to_jiffies(200); do { tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_BUSY_STATUS); if (!(tmp & 0x1)) { bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x1); ndelay(200); b53spi->bspi = false; return; } udelay(1); } while (!time_after_eq(jiffies, deadline)); dev_warn(dev, "Timeout disabling BSPI\n"); } static void bcm53xxspi_enable_bspi(struct bcm53xxspi *b53spi) { u32 tmp; if (b53spi->bspi) return; tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL); if (!(tmp & 0x1)) return; bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x0); b53spi->bspi = true; } static inline unsigned int bcm53xxspi_calc_timeout(size_t len) { /* Do some magic calculation based on length and buad. Add 10% and 1. */ Loading Loading @@ -176,6 +223,8 @@ static int bcm53xxspi_transfer_one(struct spi_master *master, u8 *buf; size_t left; bcm53xxspi_disable_bspi(b53spi); if (t->tx_buf) { buf = (u8 *)t->tx_buf; left = t->len; Loading Loading @@ -206,6 +255,22 @@ static int bcm53xxspi_transfer_one(struct spi_master *master, return 0; } static int bcm53xxspi_flash_read(struct spi_device *spi, struct spi_flash_read_message *msg) { struct bcm53xxspi *b53spi = spi_master_get_devdata(spi->master); int ret = 0; if (msg->from + msg->len > BCM53XXSPI_FLASH_WINDOW) return -EINVAL; bcm53xxspi_enable_bspi(b53spi); memcpy_fromio(msg->buf, b53spi->mmio_base + msg->from, msg->len); msg->retlen = msg->len; return ret; } /************************************************** * BCMA **************************************************/ Loading @@ -222,6 +287,7 @@ MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl); static int bcm53xxspi_bcma_probe(struct bcma_device *core) { struct device *dev = &core->dev; struct bcm53xxspi *b53spi; struct spi_master *master; int err; Loading @@ -231,7 +297,7 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) return -ENOTSUPP; } master = spi_alloc_master(&core->dev, sizeof(*b53spi)); master = spi_alloc_master(dev, sizeof(*b53spi)); if (!master) return -ENOMEM; Loading @@ -239,11 +305,19 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) b53spi->master = master; b53spi->core = core; if (core->addr_s[0]) b53spi->mmio_base = devm_ioremap(dev, core->addr_s[0], BCM53XXSPI_FLASH_WINDOW); b53spi->bspi = true; bcm53xxspi_disable_bspi(b53spi); master->transfer_one = bcm53xxspi_transfer_one; if (b53spi->mmio_base) master->spi_flash_read = bcm53xxspi_flash_read; bcma_set_drvdata(core, b53spi); err = devm_spi_register_master(&core->dev, master); err = devm_spi_register_master(dev, master); if (err) { spi_master_put(master); bcma_set_drvdata(core, NULL); Loading Loading
drivers/spi/spi-bcm53xx.c +76 −2 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ #include "spi-bcm53xx.h" #define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */ #define BCM53XXSPI_FLASH_WINDOW SZ_32M /* The longest observed required wait was 19 ms */ #define BCM53XXSPI_SPE_TIMEOUT_MS 80 Loading @@ -17,8 +18,10 @@ struct bcm53xxspi { struct bcma_device *core; struct spi_master *master; void __iomem *mmio_base; size_t read_offset; bool bspi; /* Boot SPI mode with memory mapping */ }; static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset) Loading @@ -32,6 +35,50 @@ static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset, bcma_write32(b53spi->core, offset, value); } static void bcm53xxspi_disable_bspi(struct bcm53xxspi *b53spi) { struct device *dev = &b53spi->core->dev; unsigned long deadline; u32 tmp; if (!b53spi->bspi) return; tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL); if (tmp & 0x1) return; deadline = jiffies + usecs_to_jiffies(200); do { tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_BUSY_STATUS); if (!(tmp & 0x1)) { bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x1); ndelay(200); b53spi->bspi = false; return; } udelay(1); } while (!time_after_eq(jiffies, deadline)); dev_warn(dev, "Timeout disabling BSPI\n"); } static void bcm53xxspi_enable_bspi(struct bcm53xxspi *b53spi) { u32 tmp; if (b53spi->bspi) return; tmp = bcm53xxspi_read(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL); if (!(tmp & 0x1)) return; bcm53xxspi_write(b53spi, B53SPI_BSPI_MAST_N_BOOT_CTRL, 0x0); b53spi->bspi = true; } static inline unsigned int bcm53xxspi_calc_timeout(size_t len) { /* Do some magic calculation based on length and buad. Add 10% and 1. */ Loading Loading @@ -176,6 +223,8 @@ static int bcm53xxspi_transfer_one(struct spi_master *master, u8 *buf; size_t left; bcm53xxspi_disable_bspi(b53spi); if (t->tx_buf) { buf = (u8 *)t->tx_buf; left = t->len; Loading Loading @@ -206,6 +255,22 @@ static int bcm53xxspi_transfer_one(struct spi_master *master, return 0; } static int bcm53xxspi_flash_read(struct spi_device *spi, struct spi_flash_read_message *msg) { struct bcm53xxspi *b53spi = spi_master_get_devdata(spi->master); int ret = 0; if (msg->from + msg->len > BCM53XXSPI_FLASH_WINDOW) return -EINVAL; bcm53xxspi_enable_bspi(b53spi); memcpy_fromio(msg->buf, b53spi->mmio_base + msg->from, msg->len); msg->retlen = msg->len; return ret; } /************************************************** * BCMA **************************************************/ Loading @@ -222,6 +287,7 @@ MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl); static int bcm53xxspi_bcma_probe(struct bcma_device *core) { struct device *dev = &core->dev; struct bcm53xxspi *b53spi; struct spi_master *master; int err; Loading @@ -231,7 +297,7 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) return -ENOTSUPP; } master = spi_alloc_master(&core->dev, sizeof(*b53spi)); master = spi_alloc_master(dev, sizeof(*b53spi)); if (!master) return -ENOMEM; Loading @@ -239,11 +305,19 @@ static int bcm53xxspi_bcma_probe(struct bcma_device *core) b53spi->master = master; b53spi->core = core; if (core->addr_s[0]) b53spi->mmio_base = devm_ioremap(dev, core->addr_s[0], BCM53XXSPI_FLASH_WINDOW); b53spi->bspi = true; bcm53xxspi_disable_bspi(b53spi); master->transfer_one = bcm53xxspi_transfer_one; if (b53spi->mmio_base) master->spi_flash_read = bcm53xxspi_flash_read; bcma_set_drvdata(core, b53spi); err = devm_spi_register_master(&core->dev, master); err = devm_spi_register_master(dev, master); if (err) { spi_master_put(master); bcma_set_drvdata(core, NULL); Loading