On Tue, Aug 07, 2018 at 06:43:38PM +0800, Baolin Wang wrote: > From: Lanqing Liu <lanqing.liu@xxxxxxxxxxxxxx> > > This patch adds the SPI controller driver for Spreadtrum SC9860 platform. This all looks pretty clean, a few comments below but nothing too major: > +static void sprd_spi_chipselect(struct spi_device *sdev, bool cs) > +{ > + struct spi_controller *sctlr = sdev->controller; > + struct sprd_spi *ss = spi_controller_get_devdata(sctlr); > + u32 val; > + int ret; > + > + ret = pm_runtime_get_sync(ss->dev); > + if (ret < 0) { > + dev_err(ss->dev, "failed to resume SPI controller\n"); > + return; > + } Something else further up the stack should probably have runtime PM enabled already - we should only be changing chip select as part of a bigger operation. If you use the core auto_runtime_pm feature this will definitely happen. > + bits_per_word = bits_per_word > 16 ? round_up(bits_per_word, 16) : > + round_up(bits_per_word, 8); Please > + switch (bits_per_word) { > + case 8: > + case 16: > + case 32: It'd be nice to have a default case, the core should check for you but it's nice to have defensive programming here. > +static int sprd_spi_transfer_one(struct spi_controller *sctlr, > + struct spi_device *sdev, > + struct spi_transfer *t) > +{ > + struct sprd_spi *ss = spi_controller_get_devdata(sctlr); > + int ret; > + > + ret = pm_runtime_get_sync(ss->dev); > + if (ret < 0) { > + dev_err(ss->dev, "failed to resume SPI controller\n"); > + goto rpm_err; > + } Same thing with runtime PM here - the core can do this for you. > +static int sprd_spi_setup(struct spi_device *spi_dev) > +{ > + struct spi_controller *sctlr = spi_dev->controller; > + struct sprd_spi *ss = spi_controller_get_devdata(sctlr); > + int ret; > + > + ret = pm_runtime_get_sync(ss->dev); > + if (ret < 0) { > + dev_err(ss->dev, "failed to resume SPI controller\n"); > + return ret; > + } > + > + ss->hw_mode = spi_dev->mode; > + sprd_spi_init_hw(ss); This can be called for one chip select while another is in progress so it's not good to actually configure the hardware here unless the configuration is in a chip select specific set of registers. Instead you should defer to when the transfer is being set up. > +static int sprd_spi_clk_init(struct platform_device *pdev, struct sprd_spi *ss) > +{ > + struct clk *clk_spi, *clk_parent; > + > + clk_spi = devm_clk_get(&pdev->dev, "spi"); > + if (IS_ERR(clk_spi)) { > + dev_warn(&pdev->dev, "can't get the spi clock\n"); > + clk_spi = NULL; > + } I suspect some of these clocks are essential and you should probably return an error if you can't get them (especially if probe deferral becomes a factor). > + if (!clk_set_parent(clk_spi, clk_parent)) > + ss->src_clk = clk_get_rate(clk_spi); > + else > + ss->src_clk = SPRD_SPI_DEFAULT_SOURCE; Are upstream DTs going to be missing the clock setup needed here?
Attachment:
signature.asc
Description: PGP signature