forked from mirrors/linux
		
	spi: bcm-qspi: Handle lack of MSPI_REV offset
Older MIPS chips have a QSPI/MSPI controller that does not have the MSPI_REV offset, reading from that offset will cause a bus error. Match their compatible string and do not perform a read from that register in that case. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com> Link: https://lore.kernel.org/r/20200420190853.45614-4-kdasu.kdev@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
		
							parent
							
								
									66eb228988
								
							
						
					
					
						commit
						3a01f04d74
					
				
					 1 changed files with 48 additions and 2 deletions
				
			
		| 
						 | 
					@ -91,6 +91,7 @@
 | 
				
			||||||
#define MSPI_MSPI_STATUS			0x020
 | 
					#define MSPI_MSPI_STATUS			0x020
 | 
				
			||||||
#define MSPI_CPTQP				0x024
 | 
					#define MSPI_CPTQP				0x024
 | 
				
			||||||
#define MSPI_SPCR3				0x028
 | 
					#define MSPI_SPCR3				0x028
 | 
				
			||||||
 | 
					#define MSPI_REV				0x02c
 | 
				
			||||||
#define MSPI_TXRAM				0x040
 | 
					#define MSPI_TXRAM				0x040
 | 
				
			||||||
#define MSPI_RXRAM				0x0c0
 | 
					#define MSPI_RXRAM				0x0c0
 | 
				
			||||||
#define MSPI_CDRAM				0x140
 | 
					#define MSPI_CDRAM				0x140
 | 
				
			||||||
| 
						 | 
					@ -217,6 +218,8 @@ struct bcm_qspi {
 | 
				
			||||||
	struct bcm_qspi_dev_id *dev_ids;
 | 
						struct bcm_qspi_dev_id *dev_ids;
 | 
				
			||||||
	struct completion mspi_done;
 | 
						struct completion mspi_done;
 | 
				
			||||||
	struct completion bspi_done;
 | 
						struct completion bspi_done;
 | 
				
			||||||
 | 
						u8 mspi_maj_rev;
 | 
				
			||||||
 | 
						u8 mspi_min_rev;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool has_bspi(struct bcm_qspi *qspi)
 | 
					static inline bool has_bspi(struct bcm_qspi *qspi)
 | 
				
			||||||
| 
						 | 
					@ -1190,8 +1193,35 @@ static const struct spi_controller_mem_ops bcm_qspi_mem_ops = {
 | 
				
			||||||
	.exec_op = bcm_qspi_exec_mem_op,
 | 
						.exec_op = bcm_qspi_exec_mem_op,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bcm_qspi_data {
 | 
				
			||||||
 | 
						bool	has_mspi_rev;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct bcm_qspi_data bcm_qspi_no_rev_data = {
 | 
				
			||||||
 | 
						.has_mspi_rev	= false,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct bcm_qspi_data bcm_qspi_rev_data = {
 | 
				
			||||||
 | 
						.has_mspi_rev	= true,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct of_device_id bcm_qspi_of_match[] = {
 | 
					static const struct of_device_id bcm_qspi_of_match[] = {
 | 
				
			||||||
	{ .compatible = "brcm,spi-bcm-qspi" },
 | 
						{
 | 
				
			||||||
 | 
							.compatible = "brcm,spi-bcm7425-qspi",
 | 
				
			||||||
 | 
							.data = &bcm_qspi_no_rev_data,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.compatible = "brcm,spi-bcm7429-qspi",
 | 
				
			||||||
 | 
							.data = &bcm_qspi_no_rev_data,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.compatible = "brcm,spi-bcm7435-qspi",
 | 
				
			||||||
 | 
							.data = &bcm_qspi_no_rev_data,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.compatible = "brcm,spi-bcm-qspi",
 | 
				
			||||||
 | 
							.data = &bcm_qspi_rev_data,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	{},
 | 
						{},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
MODULE_DEVICE_TABLE(of, bcm_qspi_of_match);
 | 
					MODULE_DEVICE_TABLE(of, bcm_qspi_of_match);
 | 
				
			||||||
| 
						 | 
					@ -1199,12 +1229,15 @@ MODULE_DEVICE_TABLE(of, bcm_qspi_of_match);
 | 
				
			||||||
int bcm_qspi_probe(struct platform_device *pdev,
 | 
					int bcm_qspi_probe(struct platform_device *pdev,
 | 
				
			||||||
		   struct bcm_qspi_soc_intc *soc_intc)
 | 
							   struct bcm_qspi_soc_intc *soc_intc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						const struct of_device_id *of_id = NULL;
 | 
				
			||||||
 | 
						const struct bcm_qspi_data *data;
 | 
				
			||||||
	struct device *dev = &pdev->dev;
 | 
						struct device *dev = &pdev->dev;
 | 
				
			||||||
	struct bcm_qspi *qspi;
 | 
						struct bcm_qspi *qspi;
 | 
				
			||||||
	struct spi_master *master;
 | 
						struct spi_master *master;
 | 
				
			||||||
	struct resource *res;
 | 
						struct resource *res;
 | 
				
			||||||
	int irq, ret = 0, num_ints = 0;
 | 
						int irq, ret = 0, num_ints = 0;
 | 
				
			||||||
	u32 val;
 | 
						u32 val;
 | 
				
			||||||
 | 
						u32 rev = 0;
 | 
				
			||||||
	const char *name = NULL;
 | 
						const char *name = NULL;
 | 
				
			||||||
	int num_irqs = ARRAY_SIZE(qspi_irq_tab);
 | 
						int num_irqs = ARRAY_SIZE(qspi_irq_tab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1212,9 +1245,12 @@ int bcm_qspi_probe(struct platform_device *pdev,
 | 
				
			||||||
	if (!dev->of_node)
 | 
						if (!dev->of_node)
 | 
				
			||||||
		return -ENODEV;
 | 
							return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!of_match_node(bcm_qspi_of_match, dev->of_node))
 | 
						of_id = of_match_node(bcm_qspi_of_match, dev->of_node);
 | 
				
			||||||
 | 
						if (!of_id)
 | 
				
			||||||
		return -ENODEV;
 | 
							return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data = of_id->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	master = spi_alloc_master(dev, sizeof(struct bcm_qspi));
 | 
						master = spi_alloc_master(dev, sizeof(struct bcm_qspi));
 | 
				
			||||||
	if (!master) {
 | 
						if (!master) {
 | 
				
			||||||
		dev_err(dev, "error allocating spi_master\n");
 | 
							dev_err(dev, "error allocating spi_master\n");
 | 
				
			||||||
| 
						 | 
					@ -1351,6 +1387,16 @@ int bcm_qspi_probe(struct platform_device *pdev,
 | 
				
			||||||
	qspi->base_clk = clk_get_rate(qspi->clk);
 | 
						qspi->base_clk = clk_get_rate(qspi->clk);
 | 
				
			||||||
	qspi->max_speed_hz = qspi->base_clk / (QSPI_SPBR_MIN * 2);
 | 
						qspi->max_speed_hz = qspi->base_clk / (QSPI_SPBR_MIN * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (data->has_mspi_rev) {
 | 
				
			||||||
 | 
							rev = bcm_qspi_read(qspi, MSPI, MSPI_REV);
 | 
				
			||||||
 | 
							/* some older revs do not have a MSPI_REV register */
 | 
				
			||||||
 | 
							if ((rev & 0xff) == 0xff)
 | 
				
			||||||
 | 
								rev = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qspi->mspi_maj_rev = (rev >> 4) & 0xf;
 | 
				
			||||||
 | 
						qspi->mspi_min_rev = rev & 0xf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bcm_qspi_hw_init(qspi);
 | 
						bcm_qspi_hw_init(qspi);
 | 
				
			||||||
	init_completion(&qspi->mspi_done);
 | 
						init_completion(&qspi->mspi_done);
 | 
				
			||||||
	init_completion(&qspi->bspi_done);
 | 
						init_completion(&qspi->bspi_done);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue