Re: [PATCH v2 7/7] spi: spi-fsl-spi: Add support for gpio chipselects for GRLIB type cores
On 2013-02-07 17:08, Anton Vorontsov wrote: > On Thu, Feb 07, 2013 at 02:12:11PM +0100, Andreas Larsson wrote: >> struct fsl_spi_reg *reg_base; >> -int retval; >> +int retval, desel; > > We don't usually place variable declarations on the same line, unless the > variables are closely related. > >> u32 hw_mode; >> struct spi_mpc8xxx_cs *cs = spi->controller_state; >> >> @@ -456,12 +456,45 @@ static int fsl_spi_setup(struct spi_device *spi) >> return retval; >> } >> >> +if (mpc8xxx_spi->type == TYPE_GRLIB) { >> +if (gpio_is_valid(spi->cs_gpio)) { > > <- You can place the 'int desel;' here, limiting the visibility for it. Thanks for the feedback! I'll put that in v3. This last patch needs to wait for the other patchset I mentioned anyway. Cheers, Andreas -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 1/4] spi: s3c64xx: modified error interrupt handling and init
On Wed, Feb 6, 2013 at 3:48 PM, Grant Likely wrote: > On Wed, Feb 6, 2013 at 8:12 PM, Girish KS wrote: >> On Wed, Feb 6, 2013 at 2:26 AM, Grant Likely >> wrote: >>> On Tue, 5 Feb 2013 15:09:41 -0800, Girish K S >>> wrote: The status of the interrupt is available in the status register, so reading the clear pending register and writing back the same value will not actually clear the pending interrupts. This patch modifies the interrupt handler to read the status register and clear the corresponding pending bit in the clear pending register. Modified the hwInit function to clear all the pending interrupts. Signed-off-by: Girish K S --- drivers/spi/spi-s3c64xx.c | 41 + 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index ad93231..b770f88 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -997,25 +997,30 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data) { struct s3c64xx_spi_driver_data *sdd = data; struct spi_master *spi = sdd->master; - unsigned int val; + unsigned int val, clr = 0; - val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); + val = readl(sdd->regs + S3C64XX_SPI_STATUS); - val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | - S3C64XX_SPI_PND_RX_UNDERRUN_CLR | - S3C64XX_SPI_PND_TX_OVERRUN_CLR | - S3C64XX_SPI_PND_TX_UNDERRUN_CLR; - - writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); - - if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) + if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) { + clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR; dev_err(&spi->dev, "RX overrun\n"); - if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) + } + if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) { + clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR; dev_err(&spi->dev, "RX underrun\n"); - if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) + } + if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) { + clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR; dev_err(&spi->dev, "TX overrun\n"); - if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) + } + if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) { + clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR; dev_err(&spi->dev, "TX underrun\n"); + } + + /* Clear the pending irq by setting and then clearing it */ + writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); + writel(clr & ~clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); >>> >>> Wait, what? clr & ~clr == 0 Always. What are you actually trying to do >>> here? >> The user manual says, wirting 1 to the pending clear register clears >> the interrupt (its not auto clear to 0). so i need to explicitly reset >> those bits thats what the 2nd write does > > Then write 0. That's the result of what the code does anyway, but the > code as-written is nonsensical. i cannot write 0. because the 0th bit is trailing byte interrupt clear pending bit, which is not being handled in the handler. > > g. -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 2/5] spi: pl022: use generic DMA slave configuration if possible
On Thursday 07 February 2013 21:19:04 Linus Walleij wrote: > On Thu, Feb 7, 2013 at 8:42 PM, Arnd Bergmann wrote: > > On Thursday 07 February 2013, Linus Walleij wrote: > > >> Actually I once read about a feature where the kernel provides > >> a static page full of zeroes or something like this, that would be > >> ideal to use in cases like this, then all of this dummy page > >> allocation and freeing can be deleted. > > > > You mean empty_zero_page? That only works if this page is > > read-only from the perspective of the DMA controller, but > > then it would be a good fit, yes. > > That's actually how it's used. > > SPI is symmetric, and in the DMA case we're not poking > data into the buffers from the CPU so the controller need > something - anything - to stream to the block. > > If we can use that page we'll even save a few remaps. I'm slightly worried about the caching effects though. The idea of the empty-zero page is that all user processes get it when they read a page before they write to it, so the data in it can essentially always be cache-hot. If we do DMA from that page to a device what would be the overhead of flushing the (clean) cache lines? Arnd -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 2/5] spi: pl022: use generic DMA slave configuration if possible
On Thu, Feb 7, 2013 at 8:42 PM, Arnd Bergmann wrote: > On Thursday 07 February 2013, Linus Walleij wrote: >> Actually I once read about a feature where the kernel provides >> a static page full of zeroes or something like this, that would be >> ideal to use in cases like this, then all of this dummy page >> allocation and freeing can be deleted. > > You mean empty_zero_page? That only works if this page is > read-only from the perspective of the DMA controller, but > then it would be a good fit, yes. That's actually how it's used. SPI is symmetric, and in the DMA case we're not poking data into the buffers from the CPU so the controller need something - anything - to stream to the block. If we can use that page we'll even save a few remaps. Yours, Linus Walleij -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 2/5] spi: pl022: use generic DMA slave configuration if possible
On Thursday 07 February 2013, Linus Walleij wrote: > On Tue, Jan 29, 2013 at 2:13 PM, Arnd Bergmann wrote: > > On Tuesday 29 January 2013, Andy Shevchenko wrote: > > >> > + pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL); > >> > >> Where this memory will be freed? > >> In dependence of the answer could you consider to use > >> devm_kmalloc or __get_free_page? > > > > There is another function like this called pl022_dma_probe() > > that has the same allocation, and it gets freed in the same place. > > > > It's probably worth changing this into something different, but > > I felt that it didn't belong into this patch. I was also not > > sure if the best option would be dmam_alloc_coherent, dev_kzalloc, > > or __get_free_page. > > Actually I once read about a feature where the kernel provides > a static page full of zeroes or something like this, that would be > ideal to use in cases like this, then all of this dummy page > allocation and freeing can be deleted. You mean empty_zero_page? That only works if this page is read-only from the perspective of the DMA controller, but then it would be a good fit, yes. Arnd -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 3/4] spi: s3c64xx: add gpio quirk for controller
On Thu, Feb 7, 2013 at 3:55 AM, Mark Brown wrote: > On Tue, Feb 05, 2013 at 03:09:43PM -0800, Girish K S wrote: >> This patch adds support for spi controllers with >> dedicated clk/miso/mosi/cs pins. It skips the gpio >> parsing and initialization for controllers that >> have dedicated pins. > >> if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ >> /* Deselect the last toggled device */ >> cs = sdd->tgl_spi->controller_data; >> - gpio_set_value(cs->line, >> - spi->mode & SPI_CS_HIGH ? 0 : 1); >> + if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_GPIO)) >> + gpio_set_value(cs->line, >> + spi->mode & SPI_CS_HIGH ? 0 : 1); >> } > > This isn't going to work with system designs which ignore the /CS line > the controller has and just use a GPIO instead. This is very common, > for example when connecting multiple devices to the same SPI bus. As per grant's comment i would remove the quirk option and check for "cs-gpio" property to handle /CS. When multiple devices are connected to the same spi bus, "cs-gpio" entry would exist in the dts file, and works with /CS gpio lines. > > It seems like there's really two changes here. One change is making the > provision of pinmux information optional, the other is allowing the user > to use the controller /CS management rather than using GPIO. As suggested i would make two changes. 1. would parse the "gpios" property and make decision whether to use gpios/dedicated pins for miso/miso/clk. 2.would parse "cs-gpio" property from dts node to handle the chip select correct me if my understanding is wrong -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 2/5] spi: pl022: use generic DMA slave configuration if possible
On Tue, Jan 29, 2013 at 2:13 PM, Arnd Bergmann wrote: > On Tuesday 29 January 2013, Andy Shevchenko wrote: >> > + pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL); >> >> Where this memory will be freed? >> In dependence of the answer could you consider to use >> devm_kmalloc or __get_free_page? > > There is another function like this called pl022_dma_probe() > that has the same allocation, and it gets freed in the same place. > > It's probably worth changing this into something different, but > I felt that it didn't belong into this patch. I was also not > sure if the best option would be dmam_alloc_coherent, dev_kzalloc, > or __get_free_page. Actually I once read about a feature where the kernel provides a static page full of zeroes or something like this, that would be ideal to use in cases like this, then all of this dummy page allocation and freeing can be deleted. Yours, Linus Walleij -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 2/5] spi: pl022: use generic DMA slave configuration if possible
On Mon, Jan 28, 2013 at 6:57 PM, Arnd Bergmann wrote: > With the new OF DMA binding, it is possible to completely avoid the > need for platform_data for configuring a DMA channel. In cases where the > platform has already been converted, calling dma_request_slave_channel > should get all the necessary information from the device tree. > > Like the patch that converts the dw_dma controller, this is completely > untested and is looking for someone to try it out. > > Signed-off-by: Arnd Bergmann This looks correct to me atleast: Acked-by: Linus Walleij Yours, Linus Walleij -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 1/4] spi: s3c64xx: modified error interrupt handling and init
On Thu, Feb 7, 2013 at 3:09 AM, Tomasz Figa wrote: > Hi Girish, > > On Wednesday 06 of February 2013 12:12:29 Girish KS wrote: >> On Wed, Feb 6, 2013 at 2:26 AM, Grant Likely > wrote: >> > On Tue, 5 Feb 2013 15:09:41 -0800, Girish K S > wrote: >> >> The status of the interrupt is available in the status register, >> >> so reading the clear pending register and writing back the same >> >> value will not actually clear the pending interrupts. This patch >> >> modifies the interrupt handler to read the status register and >> >> clear the corresponding pending bit in the clear pending register. >> >> >> >> Modified the hwInit function to clear all the pending interrupts. >> >> >> >> Signed-off-by: Girish K S >> >> --- >> >> >> >> drivers/spi/spi-s3c64xx.c | 41 >> >> + 1 file changed, 25 >> >> insertions(+), 16 deletions(-) >> >> >> >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c >> >> index ad93231..b770f88 100644 >> >> --- a/drivers/spi/spi-s3c64xx.c >> >> +++ b/drivers/spi/spi-s3c64xx.c >> >> @@ -997,25 +997,30 @@ static irqreturn_t s3c64xx_spi_irq(int irq, >> >> void *data)>> >> >> { >> >> >> >> struct s3c64xx_spi_driver_data *sdd = data; >> >> struct spi_master *spi = sdd->master; >> >> >> >> - unsigned int val; >> >> + unsigned int val, clr = 0; >> >> >> >> - val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); >> >> + val = readl(sdd->regs + S3C64XX_SPI_STATUS); >> >> >> >> - val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | >> >> - S3C64XX_SPI_PND_RX_UNDERRUN_CLR | >> >> - S3C64XX_SPI_PND_TX_OVERRUN_CLR | >> >> - S3C64XX_SPI_PND_TX_UNDERRUN_CLR; >> >> - >> >> - writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); >> >> - >> >> - if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) >> >> + if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) { >> >> + clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR; >> >> >> >> dev_err(&spi->dev, "RX overrun\n"); >> >> >> >> - if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) >> >> + } >> >> + if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) { >> >> + clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR; >> >> >> >> dev_err(&spi->dev, "RX underrun\n"); >> >> >> >> - if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) >> >> + } >> >> + if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) { >> >> + clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR; >> >> >> >> dev_err(&spi->dev, "TX overrun\n"); >> >> >> >> - if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) >> >> + } >> >> + if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) { >> >> + clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR; >> >> >> >> dev_err(&spi->dev, "TX underrun\n"); >> >> >> >> + } >> >> + >> >> + /* Clear the pending irq by setting and then clearing it */ >> >> + writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); >> >> + writel(clr & ~clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); >> > >> > Wait, what? clr & ~clr == 0 Always. What are you actually trying >> > to do here? >> The user manual says, wirting 1 to the pending clear register clears >> the interrupt (its not auto clear to 0). so i need to explicitly reset >> those bits thats what the 2nd write does > > I have looked through user's manuals of different Samsung SoCs. All of > them said that writing 1 to a bit clears the corresponding interrupt, but > none of them contain any note that it must be manually cleared to 0. What i meant was the clear pending bit will not clear automatically. When I set the clear pending bit, it remains set. This is a problem for the next interrupt cycle. > In addition the expression > > clr & ~clr > > makes no sense, because it is equal to 0. It makes sense, because we are not disturbing the interrupt pending bit at position 0, which is a trailing clr bit. > > If you really need to clear those bits manually (and I don't think so), > you should replace this expression with 0. since we are not enabling (was not enabled in previous implementation) trailing byte interrupt, and not handling the same in handler we cannot write 0. > > Best regards, > -- > Tomasz Figa > Samsung Poland R&D Center > SW Solution Development, Linux Platform > -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH v2 7/7] spi: spi-fsl-spi: Add support for gpio chipselects for GRLIB type cores
On Thu, Feb 07, 2013 at 02:12:11PM +0100, Andreas Larsson wrote: > This relies upon of_spi_register_master to find out which gpios to use. > > Signed-off-by: Andreas Larsson > --- > drivers/spi/spi-fsl-lib.h |1 + > drivers/spi/spi-fsl-spi.c | 53 +++- > 2 files changed, 48 insertions(+), 6 deletions(-) Just a couple of minor nits... > diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h > index d5c788b..52db693 100644 > --- a/drivers/spi/spi-fsl-lib.h > +++ b/drivers/spi/spi-fsl-lib.h > @@ -71,6 +71,7 @@ struct mpc8xxx_spi { > > #ifdef CONFIG_SPI_FSL_SPI > int type; > + int native_chipselects; > u8 max_bits_per_word; > > void (*set_shifts)(u32 *rx_shift, u32 *tx_shift, > diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c > index 55652e6..2befe16 100644 > --- a/drivers/spi/spi-fsl-spi.c > +++ b/drivers/spi/spi-fsl-spi.c > @@ -418,7 +418,7 @@ static int fsl_spi_setup(struct spi_device *spi) > { > struct mpc8xxx_spi *mpc8xxx_spi; > struct fsl_spi_reg *reg_base; > - int retval; > + int retval, desel; We don't usually place variable declarations on the same line, unless the variables are closely related. > u32 hw_mode; > struct spi_mpc8xxx_cs *cs = spi->controller_state; > > @@ -456,12 +456,45 @@ static int fsl_spi_setup(struct spi_device *spi) > return retval; > } > > + if (mpc8xxx_spi->type == TYPE_GRLIB) { > + if (gpio_is_valid(spi->cs_gpio)) { <- You can place the 'int desel;' here, limiting the visibility for it. > + retval = gpio_request(spi->cs_gpio, > + dev_name(&spi->dev)); > + if (retval) > + return retval; > + > + desel = !(spi->mode & SPI_CS_HIGH); > + desel ^= !!(spi->cs_gpio_flags & OF_GPIO_ACTIVE_LOW); > + retval = gpio_direction_output(spi->cs_gpio, desel); > + if (retval) { > + gpio_free(spi->cs_gpio); > + return retval; > + } Thanks, Anton -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH v2 0/7] spi: spi-fsl-spi: Make spi-fsl-spi usable in cpu mode outside of FSL SOC environments and add a grlib variant normally running on sparc
On Thu, Feb 07, 2013 at 02:12:04PM +0100, Andreas Larsson wrote: > This makes the cpu mode of the driver available outside of an FSL SOC > and even powerpc environment. Furthermore, this adds support for the > mostly register-compatible SPICTRL core from the GRLIB VHDL IP core > library normally running on SPARC. The patches look clean and neat, I don't see anything obviously wrong with them... so, Acked-by: Anton Vorontsov Thanks! Anton -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2 4/7] spi: spi-fsl-spi: Introduce a type for the driver
For being able to distinguishing between the regular type of cores and others with different entries in of_fsl_spi_match. Signed-off-by: Andreas Larsson --- drivers/spi/spi-fsl-lib.h |2 ++ drivers/spi/spi-fsl-spi.c | 39 --- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index eae54b6..5a9c36c 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h @@ -70,6 +70,8 @@ struct mpc8xxx_spi { unsigned int flags; #ifdef CONFIG_SPI_FSL_SPI + int type; + void (*set_shifts)(u32 *rx_shift, u32 *tx_shift, int bits_per_word, int msb_first); #endif diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 128f7b3..c018e1c 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -39,6 +39,37 @@ #include "spi-fsl-cpm.h" #include "spi-fsl-spi.h" +#define TYPE_FSL 0 + +struct fsl_spi_match_data { + int type; +}; + +static struct fsl_spi_match_data of_fsl_spi_fsl_config = { + .type = TYPE_FSL, +}; + +static struct of_device_id of_fsl_spi_match[] = { + { + .compatible = "fsl,spi", + .data = &of_fsl_spi_fsl_config, + }, + {} +}; +MODULE_DEVICE_TABLE(of, of_fsl_spi_match); + +static int fsl_spi_get_type(struct device *dev) +{ + const struct of_device_id *match; + + if (dev->of_node) { + match = of_match_node(of_fsl_spi_match, dev->of_node); + if (match && match->data) + return ((struct fsl_spi_match_data *)match->data)->type; + } + return TYPE_FSL; +} + static void fsl_spi_change_mode(struct spi_device *spi) { struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); @@ -489,7 +520,7 @@ static struct spi_master * fsl_spi_probe(struct device *dev, mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->spi_do_one_msg = fsl_spi_do_one_msg; mpc8xxx_spi->spi_remove = fsl_spi_remove; - + mpc8xxx_spi->type = fsl_spi_get_type(dev); ret = fsl_spi_cpm_init(mpc8xxx_spi); if (ret) @@ -716,12 +747,6 @@ static int of_fsl_spi_remove(struct platform_device *ofdev) return 0; } -static const struct of_device_id of_fsl_spi_match[] = { - { .compatible = "fsl,spi" }, - {} -}; -MODULE_DEVICE_TABLE(of, of_fsl_spi_match); - static struct platform_driver of_fsl_spi_driver = { .driver = { .name = "fsl_spi", -- 1.7.0.4 -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2 4/7 RESEND] spi: spi-fsl-spi: Introduce a type for the driver
For being able to distinguishing between the regular type of cores and others with different entries in of_fsl_spi_match. Signed-off-by: Andreas Larsson --- [Resent, as the mail for patch 4 seems to have been lost somehow] drivers/spi/spi-fsl-lib.h |2 ++ drivers/spi/spi-fsl-spi.c | 39 --- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index eae54b6..5a9c36c 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h @@ -70,6 +70,8 @@ struct mpc8xxx_spi { unsigned int flags; #ifdef CONFIG_SPI_FSL_SPI + int type; + void (*set_shifts)(u32 *rx_shift, u32 *tx_shift, int bits_per_word, int msb_first); #endif diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 128f7b3..c018e1c 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -39,6 +39,37 @@ #include "spi-fsl-cpm.h" #include "spi-fsl-spi.h" +#define TYPE_FSL 0 + +struct fsl_spi_match_data { + int type; +}; + +static struct fsl_spi_match_data of_fsl_spi_fsl_config = { + .type = TYPE_FSL, +}; + +static struct of_device_id of_fsl_spi_match[] = { + { + .compatible = "fsl,spi", + .data = &of_fsl_spi_fsl_config, + }, + {} +}; +MODULE_DEVICE_TABLE(of, of_fsl_spi_match); + +static int fsl_spi_get_type(struct device *dev) +{ + const struct of_device_id *match; + + if (dev->of_node) { + match = of_match_node(of_fsl_spi_match, dev->of_node); + if (match && match->data) + return ((struct fsl_spi_match_data *)match->data)->type; + } + return TYPE_FSL; +} + static void fsl_spi_change_mode(struct spi_device *spi) { struct mpc8xxx_spi *mspi = spi_master_get_devdata(spi->master); @@ -489,7 +520,7 @@ static struct spi_master * fsl_spi_probe(struct device *dev, mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->spi_do_one_msg = fsl_spi_do_one_msg; mpc8xxx_spi->spi_remove = fsl_spi_remove; - + mpc8xxx_spi->type = fsl_spi_get_type(dev); ret = fsl_spi_cpm_init(mpc8xxx_spi); if (ret) @@ -716,12 +747,6 @@ static int of_fsl_spi_remove(struct platform_device *ofdev) return 0; } -static const struct of_device_id of_fsl_spi_match[] = { - { .compatible = "fsl,spi" }, - {} -}; -MODULE_DEVICE_TABLE(of, of_fsl_spi_match); - static struct platform_driver of_fsl_spi_driver = { .driver = { .name = "fsl_spi", -- 1.7.0.4 -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2 7/7] spi: spi-fsl-spi: Add support for gpio chipselects for GRLIB type cores
This relies upon of_spi_register_master to find out which gpios to use. Signed-off-by: Andreas Larsson --- drivers/spi/spi-fsl-lib.h |1 + drivers/spi/spi-fsl-spi.c | 53 +++- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index d5c788b..52db693 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h @@ -71,6 +71,7 @@ struct mpc8xxx_spi { #ifdef CONFIG_SPI_FSL_SPI int type; + int native_chipselects; u8 max_bits_per_word; void (*set_shifts)(u32 *rx_shift, u32 *tx_shift, diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 55652e6..2befe16 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -418,7 +418,7 @@ static int fsl_spi_setup(struct spi_device *spi) { struct mpc8xxx_spi *mpc8xxx_spi; struct fsl_spi_reg *reg_base; - int retval; + int retval, desel; u32 hw_mode; struct spi_mpc8xxx_cs *cs = spi->controller_state; @@ -456,12 +456,45 @@ static int fsl_spi_setup(struct spi_device *spi) return retval; } + if (mpc8xxx_spi->type == TYPE_GRLIB) { + if (gpio_is_valid(spi->cs_gpio)) { + retval = gpio_request(spi->cs_gpio, + dev_name(&spi->dev)); + if (retval) + return retval; + + desel = !(spi->mode & SPI_CS_HIGH); + desel ^= !!(spi->cs_gpio_flags & OF_GPIO_ACTIVE_LOW); + retval = gpio_direction_output(spi->cs_gpio, desel); + if (retval) { + gpio_free(spi->cs_gpio); + return retval; + } + } else if (spi->cs_gpio != -EEXIST) { + if (spi->cs_gpio < 0) + return spi->cs_gpio; + return -EINVAL; + } + /* When spi->cs_gpio == -EEXIST, a hole in the phandle list +* indicates to use native chipselect if present, or allow for +* an always selected chip +*/ + } + /* Initialize chipselect - might be active for SPI_CS_HIGH mode */ fsl_spi_chipselect(spi, BITBANG_CS_INACTIVE); return 0; } +static void fsl_spi_cleanup(struct spi_device *spi) +{ + struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master); + + if (mpc8xxx_spi->type == TYPE_GRLIB && gpio_is_valid(spi->cs_gpio)) + gpio_free(spi->cs_gpio); +} + static void fsl_spi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) { struct fsl_spi_reg *reg_base = mspi->reg_base; @@ -529,9 +562,15 @@ static void fsl_spi_grlib_cs_control(struct spi_device *spi, bool on) u32 slvsel; u16 cs = spi->chip_select; - slvsel = mpc8xxx_spi_read_reg(®_base->slvsel); - slvsel = on ? (slvsel | (1 << cs)) : (slvsel & ~(1 << cs)); - mpc8xxx_spi_write_reg(®_base->slvsel, slvsel); + if (gpio_is_valid(spi->cs_gpio)) { + if (spi->cs_gpio_flags & OF_GPIO_ACTIVE_LOW) + on = !on; + gpio_set_value(spi->cs_gpio, on); + } else if (cs < mpc8xxx_spi->native_chipselects) { + slvsel = mpc8xxx_spi_read_reg(®_base->slvsel); + slvsel = on ? (slvsel | (1 << cs)) : (slvsel & ~(1 << cs)); + mpc8xxx_spi_write_reg(®_base->slvsel, slvsel); + } } static void fsl_spi_grlib_probe(struct device *dev) @@ -550,11 +589,12 @@ static void fsl_spi_grlib_probe(struct device *dev) if (mbits) mpc8xxx_spi->max_bits_per_word = mbits + 1; - master->num_chipselect = 1; /* Allow for an always selected chip */ + mpc8xxx_spi->native_chipselects = 0; if (SPCAP_SSEN(capabilities)) { - master->num_chipselect = SPCAP_SSSZ(capabilities); + mpc8xxx_spi->native_chipselects = SPCAP_SSSZ(capabilities); mpc8xxx_spi_write_reg(®_base->slvsel, 0x); } + master->num_chipselect = mpc8xxx_spi->native_chipselects; pdata->cs_control = fsl_spi_grlib_cs_control; } @@ -581,6 +621,7 @@ static struct spi_master * fsl_spi_probe(struct device *dev, goto err_probe; master->setup = fsl_spi_setup; + master->cleanup = fsl_spi_cleanup; mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->spi_do_one_msg = fsl_spi_do_one_msg; -- 1.7.0.4 -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb __
[PATCH v2 3/7] spi: spi-fsl-spi: Move setting non-zero tx and rx shifts to a function accessed by a function pointer
Signed-off-by: Andreas Larsson --- drivers/spi/spi-fsl-lib.h |5 drivers/spi/spi-fsl-spi.c | 51 +++- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index d785595..eae54b6 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h @@ -69,6 +69,11 @@ struct mpc8xxx_spi { unsigned int flags; +#ifdef CONFIG_SPI_FSL_SPI + void (*set_shifts)(u32 *rx_shift, u32 *tx_shift, + int bits_per_word, int msb_first); +#endif + struct workqueue_struct *workqueue; struct work_struct work; diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index b63ce63..128f7b3 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -91,6 +91,25 @@ static void fsl_spi_chipselect(struct spi_device *spi, int value) } } +static void fsl_spi_qe_cpu_set_shifts(u32 *rx_shift, u32 *tx_shift, + int bits_per_word, int msb_first) +{ + *rx_shift = 0; + *tx_shift = 0; + if (msb_first) { + if (bits_per_word <= 8) { + *rx_shift = 16; + *tx_shift = 24; + } else if (bits_per_word <= 16) { + *rx_shift = 16; + *tx_shift = 16; + } + } else { + if (bits_per_word <= 8) + *rx_shift = 8; + } +} + static int mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs, struct spi_device *spi, struct mpc8xxx_spi *mpc8xxx_spi, @@ -101,31 +120,20 @@ static int mspi_apply_cpu_mode_quirks(struct spi_mpc8xxx_cs *cs, if (bits_per_word <= 8) { cs->get_rx = mpc8xxx_spi_rx_buf_u8; cs->get_tx = mpc8xxx_spi_tx_buf_u8; - if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { - cs->rx_shift = 16; - cs->tx_shift = 24; - } } else if (bits_per_word <= 16) { cs->get_rx = mpc8xxx_spi_rx_buf_u16; cs->get_tx = mpc8xxx_spi_tx_buf_u16; - if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { - cs->rx_shift = 16; - cs->tx_shift = 16; - } } else if (bits_per_word <= 32) { cs->get_rx = mpc8xxx_spi_rx_buf_u32; cs->get_tx = mpc8xxx_spi_tx_buf_u32; } else return -EINVAL; - if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE && - spi->mode & SPI_LSB_FIRST) { - cs->tx_shift = 0; - if (bits_per_word <= 8) - cs->rx_shift = 8; - else - cs->rx_shift = 0; - } + if (mpc8xxx_spi->set_shifts) + mpc8xxx_spi->set_shifts(&cs->rx_shift, &cs->tx_shift, + bits_per_word, + !(spi->mode & SPI_LSB_FIRST)); + mpc8xxx_spi->rx_shift = cs->rx_shift; mpc8xxx_spi->tx_shift = cs->tx_shift; mpc8xxx_spi->get_rx = cs->get_rx; @@ -487,10 +495,13 @@ static struct spi_master * fsl_spi_probe(struct device *dev, if (ret) goto err_cpm_init; - if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) { - mpc8xxx_spi->rx_shift = 16; - mpc8xxx_spi->tx_shift = 24; - } + if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) + mpc8xxx_spi->set_shifts = fsl_spi_qe_cpu_set_shifts; + + if (mpc8xxx_spi->set_shifts) + /* 8 bits per word and MSB first */ + mpc8xxx_spi->set_shifts(&mpc8xxx_spi->rx_shift, + &mpc8xxx_spi->tx_shift, 8, 1); mpc8xxx_spi->reg_base = ioremap(mem->start, resource_size(mem)); if (mpc8xxx_spi->reg_base == NULL) { -- 1.7.0.4 -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2 1/7] spi: spi-fsl-spi: Make driver usable in CPU mode outside of an FSL_SOC environment
This makes the spi-fsl-spi driver usable in CPU mode outside of an FSL_SOC and even an powerpc environment by moving CPM mode functionality to a separate file that is only compiled and linked in an FSL_SOC environment and adding some ifdefs to hide types and functions or provide alternatives. For devicetree probing a "clock-frequency" property is used for clock frequency instead of calls to FSL_SOC-specific functions. Signed-off-by: Andreas Larsson --- This introduces a lot of line changes, but to illustrate that large parts of is just moving between files you can run the following script at this commit standing in the source root directory: #!/bin/bash ORIG=$(mktemp) CPM=$(mktemp) git show HEAD~:drivers/spi/spi-fsl-spi.c > $ORIG sed -n "42,+8 p" $ORIG >> $CPM sed -n "90,+12 p" $ORIG >> $CPM sed -n "122,+12 p" $ORIG | sed 's/^\t//' >> $CPM sed -n "298,+105 p" $ORIG >> $CPM sed -n "571,+23 p" $ORIG >> $CPM sed -n "649,+190 p" $ORIG >> $CPM diff -u $CPM drivers/spi/spi-fsl-cpm.c sed -n "51,+38 p" $ORIG | diff -u -- - drivers/spi/spi-fsl-spi.h rm $ORIG $CPM Documentation/devicetree/bindings/spi/fsl-spi.txt |1 + drivers/spi/Kconfig |7 +- drivers/spi/Makefile |1 + drivers/spi/spi-fsl-cpm.c | 387 +++ drivers/spi/spi-fsl-cpm.h | 43 +++ drivers/spi/spi-fsl-lib.c |8 + drivers/spi/spi-fsl-lib.h |6 +- drivers/spi/spi-fsl-spi.c | 411 + drivers/spi/spi-fsl-spi.h | 61 +++ 9 files changed, 520 insertions(+), 405 deletions(-) create mode 100644 drivers/spi/spi-fsl-cpm.c create mode 100644 drivers/spi/spi-fsl-cpm.h create mode 100644 drivers/spi/spi-fsl-spi.h diff --git a/Documentation/devicetree/bindings/spi/fsl-spi.txt b/Documentation/devicetree/bindings/spi/fsl-spi.txt index 777abd7..4f2ea94 100644 --- a/Documentation/devicetree/bindings/spi/fsl-spi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-spi.txt @@ -14,6 +14,7 @@ Required properties: controller you have. - interrupt-parent : the phandle for the interrupt controller that services interrupts for this device. +- clock-frequency : input clock frequency to non FSL_SOC cores Optional properties: - gpios : specifies the gpio pins to be used for chipselects. diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a90393d..da5968e 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -218,12 +218,17 @@ config SPI_MPC512x_PSC config SPI_FSL_LIB tristate + depends on OF + +config SPI_FSL_CPM + tristate depends on FSL_SOC config SPI_FSL_SPI bool "Freescale SPI controller" - depends on FSL_SOC + depends on OF select SPI_FSL_LIB + select SPI_FSL_CPM if FSL_SOC help This enables using the Freescale SPI controllers in master mode. MPC83xx platform uses the controller in cpu mode or CPM/QE mode. diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 64e970b..818d5c1 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_SPI_DW_PCI) += spi-dw-midpci.o spi-dw-midpci-objs := spi-dw-pci.o spi-dw-mid.o obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o obj-$(CONFIG_SPI_FALCON) += spi-falcon.o +obj-$(CONFIG_SPI_FSL_CPM) += spi-fsl-cpm.o obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c new file mode 100644 index 000..a39fda4 --- /dev/null +++ b/drivers/spi/spi-fsl-cpm.c @@ -0,0 +1,387 @@ +/* + * Freescale SPI controller driver cpm functions. + * + * Maintainer: Kumar Gala + * + * Copyright (C) 2006 Polycom, Inc. + * Copyright 2010 Freescale Semiconductor, Inc. + * + * CPM SPI and QE buffer descriptors mode support: + * Copyright (c) 2009 MontaVista Software, Inc. + * Author: Anton Vorontsov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "spi-fsl-lib.h" +#include "spi-fsl-cpm.h" +#include "spi-fsl-spi.h" + +/* CPM1 and CPM2 are mutually exclusive. */ +#ifdef CONFIG_CPM1 +#include +#define CPM_SPI_CMD mk_cr_cmd(CPM_CR_CH_SPI, 0) +#else +#include +#define CPM_SPI_CMD mk_cr_cmd(CPM_CR_SPI_PAGE, CPM_CR_SPI_SBLOCK, 0, 0) +#endif + +#defineSPIE_TXB0x0200 /* Last char is written to tx fifo */ +#defineSPIE_RXB0x0100 /* La
[PATCH v2 6/7] spi: spi-fsl-spi: Add support for Aeroflex Gaisler GRLIB cores normally running on SPARC
This adds support for the mostly register-compatible SPICTRL cores from the GRLIB VHDL IP core library from Aeroflex Gaisler. They are normally running on SPARC. A different entry in of_fsl_spi_match matches this core and indicates a different hardware type that is used to set up different function pointers and special cases. The GRLIB core operates in cpu mode. The number of bits per word might be limited. There might be native chipselects selected via a slave select register. These differences to the FSL type cores, if present, are indicated by a capabilities register. Other register and function differences exists but are not relevant to the driver. Signed-off-by: Andreas Larsson --- Documentation/devicetree/bindings/spi/fsl-spi.txt |2 +- .../devicetree/bindings/vendor-prefixes.txt|1 + drivers/spi/Kconfig|4 +- drivers/spi/spi-fsl-spi.c | 98 +--- drivers/spi/spi-fsl-spi.h | 13 +++- 5 files changed, 103 insertions(+), 15 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/fsl-spi.txt b/Documentation/devicetree/bindings/spi/fsl-spi.txt index 4f2ea94..b032dd7 100644 --- a/Documentation/devicetree/bindings/spi/fsl-spi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-spi.txt @@ -4,7 +4,7 @@ Required properties: - cell-index : QE SPI subblock index. 0: QE subblock SPI1 1: QE subblock SPI2 -- compatible : should be "fsl,spi". +- compatible : should be "fsl,spi" or "aeroflexgaisler,spictrl". - mode : the SPI operation mode, it can be "cpu" or "cpu-qe". - reg : Offset and length of the register set for the device - interrupts : where a is the interrupt number and b is a diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 902b1b1..fee5232 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -5,6 +5,7 @@ using them to avoid name-space collisions. ad Avionic Design GmbH adiAnalog Devices, Inc. +aeroflexgaislerAeroflex Gaisler AB ak Asahi Kasei Corp. amcc Applied Micro Circuits Corporation (APM, formally AMCC) apmApplied Micro Circuits Corporation (APM) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index da5968e..3b5b928 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -225,7 +225,7 @@ config SPI_FSL_CPM depends on FSL_SOC config SPI_FSL_SPI - bool "Freescale SPI controller" + bool "Freescale SPI controller and Aeroflex Gaisler GRLIB SPI controller" depends on OF select SPI_FSL_LIB select SPI_FSL_CPM if FSL_SOC @@ -233,6 +233,8 @@ config SPI_FSL_SPI This enables using the Freescale SPI controllers in master mode. MPC83xx platform uses the controller in cpu mode or CPM/QE mode. MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. + This also enables using the Aeroflex Gaisler GRLIB SPI controller in + master mode. config SPI_FSL_ESPI bool "Freescale eSPI controller" diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 437319f..55652e6 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -10,6 +10,10 @@ * Copyright (c) 2009 MontaVista Software, Inc. * Author: Anton Vorontsov * + * GRLIB support: + * Copyright (c) 2012 Aeroflex Gaisler AB. + * Author: Andreas Larsson + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -40,6 +44,7 @@ #include "spi-fsl-spi.h" #define TYPE_FSL 0 +#define TYPE_GRLIB 1 struct fsl_spi_match_data { int type; @@ -49,11 +54,19 @@ static struct fsl_spi_match_data of_fsl_spi_fsl_config = { .type = TYPE_FSL, }; +static struct fsl_spi_match_data of_fsl_spi_grlib_config = { + .type = TYPE_GRLIB, +}; + static struct of_device_id of_fsl_spi_match[] = { { .compatible = "fsl,spi", .data = &of_fsl_spi_fsl_config, }, + { + .compatible = "aeroflexgaisler,spictrl", + .data = &of_fsl_spi_grlib_config, + }, {} }; MODULE_DEVICE_TABLE(of, of_fsl_spi_match); @@ -141,6 +154,21 @@ static void fsl_spi_qe_cpu_set_shifts(u32 *rx_shift, u32 *tx_shift, } } +static void fsl_spi_grlib_set_shifts(u32 *rx_shift, u32 *tx_shift, +int bits_per_word, int msb_first) +{ + *rx_shift = 0; + *tx_shift = 0; + if (bits_per_word <= 16) { + if (msb_first) { + *rx_shift = 16; /* LSB in bit 16 */ + *tx_shift = 32 - bits_per_word; /* MSB in bit 31 *
[PATCH v2 5/7] spi: spi-fsl-spi: Add support for setting a maximum number of bits per word
Signed-off-by: Andreas Larsson --- drivers/spi/spi-fsl-lib.h |1 + drivers/spi/spi-fsl-spi.c |8 +++- 2 files changed, 8 insertions(+), 1 deletions(-) diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index 5a9c36c..d5c788b 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h @@ -71,6 +71,7 @@ struct mpc8xxx_spi { #ifdef CONFIG_SPI_FSL_SPI int type; + u8 max_bits_per_word; void (*set_shifts)(u32 *rx_shift, u32 *tx_shift, int bits_per_word, int msb_first); diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index c018e1c..437319f 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -213,7 +213,8 @@ static int fsl_spi_setup_transfer(struct spi_device *spi, /* Make sure its a bit width we support [4..16, 32] */ if ((bits_per_word < 4) - || ((bits_per_word > 16) && (bits_per_word != 32))) + || ((bits_per_word > 16) && (bits_per_word != 32)) + || (bits_per_word > mpc8xxx_spi->max_bits_per_word)) return -EINVAL; if (!hz) @@ -520,6 +521,7 @@ static struct spi_master * fsl_spi_probe(struct device *dev, mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->spi_do_one_msg = fsl_spi_do_one_msg; mpc8xxx_spi->spi_remove = fsl_spi_remove; + mpc8xxx_spi->max_bits_per_word = 32; mpc8xxx_spi->type = fsl_spi_get_type(dev); ret = fsl_spi_cpm_init(mpc8xxx_spi); @@ -557,6 +559,10 @@ static struct spi_master * fsl_spi_probe(struct device *dev, /* Enable SPI interface */ regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE; + if (mpc8xxx_spi->max_bits_per_word < 8) { + regval &= ~SPMODE_LEN(0xF); + regval |= SPMODE_LEN(mpc8xxx_spi->max_bits_per_word - 1); + } if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) regval |= SPMODE_OP; -- 1.7.0.4 -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2 2/7] spi: spi-fsl-spi: Make sure in spi_fsl_setup that chipselect becomes inactive
This is needed for a device in SPI_CS_HIGH mode that otherwise could start out active for the first transaction. Signed-off-by: Andreas Larsson --- drivers/spi/spi-fsl-spi.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index e9ae1d8..b63ce63 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -387,6 +387,10 @@ static int fsl_spi_setup(struct spi_device *spi) cs->hw_mode = hw_mode; /* Restore settings */ return retval; } + + /* Initialize chipselect - might be active for SPI_CS_HIGH mode */ + fsl_spi_chipselect(spi, BITBANG_CS_INACTIVE); + return 0; } -- 1.7.0.4 -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2 0/7] spi: spi-fsl-spi: Make spi-fsl-spi usable in cpu mode outside of FSL SOC environments and add a grlib variant normally running on sparc
This makes the cpu mode of the driver available outside of an FSL SOC and even powerpc environment. Furthermore, this adds support for the mostly register-compatible SPICTRL core from the GRLIB VHDL IP core library normally running on SPARC. This effort is split up in several patches for clarity of what is being changed. Patches 3-5 prepares for the introduction of the GRLIB SPICTRL functionality in patch 6. To use what is introduced right away they could eventually be merged: Patch A: patch 1 Patch B: patch 2 Patch C: patches 3-6 merged Patch D: patch 7 Patch 1 makes the driver compileable and presumably useable outside of FSL SOC and powerpc environments (SPARC in particular) Patch 2 fixes a bug that can happen when a device uses SPI_CS_HIGH Patches 3-6 makes the driver working for GRLIB SPICTRL cores that has the built in slave select register and that uses that exclusively for chipselects. Patch 7 introduces gpio support for GRLIB SPICTRL cores. That patch (and that patch only) relies upon the "of, of_gpio, of_spi: Fix and improve of_parse_phandle_with_args, of_gpio_named_count and of_spi_register_master" patchset - https://lkml.org/lkml/2013/1/29/308 The GRLIB type has been tested under sparc. The FSL type has been compile tested in powerpc, arm and x86 environments. It would be great if someone with an FSL board could test this out. One could argue that it would be better to add the GRLIB variant as a mode flag in of_mpc8xxx_spi_probe instead of using a new type field, but that would require to add a flag for this core in include/linux/fsl_devices.h which does not feel right given that this core is not part of an FSL device. Signed-off-by: Andreas Larsson Andreas Larsson (7): spi: spi-fsl-spi: Make driver usable in CPU mode outside of an FSL_SOC environment spi: spi-fsl-spi: Make sure in spi_fsl_setup that chipselect becomes inactive spi: spi-fsl-spi: Move setting non-zero tx and rx shifts to a function accessed by a function pointer spi: spi-fsl-spi: Introduce a type for the driver spi: spi-fsl-spi: Add support for setting a maximum number of bits per word spi: spi-fsl-spi: Add support for Aeroflex Gaisler GRLIB cores normally running on SPARC spi: spi-fsl-spi: Add support for gpio chipselects for GRLIB type cores Documentation/devicetree/bindings/spi/fsl-spi.txt |3 +- .../devicetree/bindings/vendor-prefixes.txt|1 + drivers/spi/Kconfig| 11 +- drivers/spi/Makefile |1 + drivers/spi/spi-fsl-cpm.c | 387 + drivers/spi/spi-fsl-cpm.h | 43 ++ drivers/spi/spi-fsl-lib.c |8 + drivers/spi/spi-fsl-lib.h | 15 +- drivers/spi/spi-fsl-spi.c | 610 ++-- drivers/spi/spi-fsl-spi.h | 72 +++ 10 files changed, 725 insertions(+), 426 deletions(-) create mode 100644 drivers/spi/spi-fsl-cpm.c create mode 100644 drivers/spi/spi-fsl-cpm.h create mode 100644 drivers/spi/spi-fsl-spi.h -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 3/4] spi: s3c64xx: add gpio quirk for controller
On Tue, Feb 05, 2013 at 03:09:43PM -0800, Girish K S wrote: > This patch adds support for spi controllers with > dedicated clk/miso/mosi/cs pins. It skips the gpio > parsing and initialization for controllers that > have dedicated pins. > if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ > /* Deselect the last toggled device */ > cs = sdd->tgl_spi->controller_data; > - gpio_set_value(cs->line, > - spi->mode & SPI_CS_HIGH ? 0 : 1); > + if (!(sdd->port_conf->quirks & S3C64XX_SPI_QUIRK_GPIO)) > + gpio_set_value(cs->line, > + spi->mode & SPI_CS_HIGH ? 0 : 1); > } This isn't going to work with system designs which ignore the /CS line the controller has and just use a GPIO instead. This is very common, for example when connecting multiple devices to the same SPI bus. It seems like there's really two changes here. One change is making the provision of pinmux information optional, the other is allowing the user to use the controller /CS management rather than using GPIO. -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 1/4] spi: s3c64xx: modified error interrupt handling and init
Hi Girish, On Wednesday 06 of February 2013 12:12:29 Girish KS wrote: > On Wed, Feb 6, 2013 at 2:26 AM, Grant Likely wrote: > > On Tue, 5 Feb 2013 15:09:41 -0800, Girish K S wrote: > >> The status of the interrupt is available in the status register, > >> so reading the clear pending register and writing back the same > >> value will not actually clear the pending interrupts. This patch > >> modifies the interrupt handler to read the status register and > >> clear the corresponding pending bit in the clear pending register. > >> > >> Modified the hwInit function to clear all the pending interrupts. > >> > >> Signed-off-by: Girish K S > >> --- > >> > >> drivers/spi/spi-s3c64xx.c | 41 > >> + 1 file changed, 25 > >> insertions(+), 16 deletions(-) > >> > >> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c > >> index ad93231..b770f88 100644 > >> --- a/drivers/spi/spi-s3c64xx.c > >> +++ b/drivers/spi/spi-s3c64xx.c > >> @@ -997,25 +997,30 @@ static irqreturn_t s3c64xx_spi_irq(int irq, > >> void *data)>> > >> { > >> > >> struct s3c64xx_spi_driver_data *sdd = data; > >> struct spi_master *spi = sdd->master; > >> > >> - unsigned int val; > >> + unsigned int val, clr = 0; > >> > >> - val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); > >> + val = readl(sdd->regs + S3C64XX_SPI_STATUS); > >> > >> - val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | > >> - S3C64XX_SPI_PND_RX_UNDERRUN_CLR | > >> - S3C64XX_SPI_PND_TX_OVERRUN_CLR | > >> - S3C64XX_SPI_PND_TX_UNDERRUN_CLR; > >> - > >> - writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); > >> - > >> - if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) > >> + if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) { > >> + clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR; > >> > >> dev_err(&spi->dev, "RX overrun\n"); > >> > >> - if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) > >> + } > >> + if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) { > >> + clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR; > >> > >> dev_err(&spi->dev, "RX underrun\n"); > >> > >> - if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) > >> + } > >> + if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) { > >> + clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR; > >> > >> dev_err(&spi->dev, "TX overrun\n"); > >> > >> - if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) > >> + } > >> + if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) { > >> + clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR; > >> > >> dev_err(&spi->dev, "TX underrun\n"); > >> > >> + } > >> + > >> + /* Clear the pending irq by setting and then clearing it */ > >> + writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); > >> + writel(clr & ~clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); > > > > Wait, what? clr & ~clr == 0 Always. What are you actually trying > > to do here? > The user manual says, wirting 1 to the pending clear register clears > the interrupt (its not auto clear to 0). so i need to explicitly reset > those bits thats what the 2nd write does I have looked through user's manuals of different Samsung SoCs. All of them said that writing 1 to a bit clears the corresponding interrupt, but none of them contain any note that it must be manually cleared to 0. In addition the expression clr & ~clr makes no sense, because it is equal to 0. If you really need to clear those bits manually (and I don't think so), you should replace this expression with 0. Best regards, -- Tomasz Figa Samsung Poland R&D Center SW Solution Development, Linux Platform -- Free Next-Gen Firewall Hardware Offer Buy your Sophos next-gen firewall before the end March 2013 and get the hardware for free! Learn more. http://p.sf.net/sfu/sophos-d2d-feb ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general