Re: [PATCH v2 RESEND] spi: spi-mpc512x-psc: add support for gpio chip selects
On Tue, 9 Apr 2013 17:53:22 +0100 Mark Brown wrote: > On Mon, Apr 01, 2013 at 05:29:21PM +0200, Anatolij Gustschin wrote: > > Currently the driver only uses one internal chip select. > > Add support for gpio chip selects configured by cs-gpios > > DT binding. > > Applied, thanks - I'm assuming the binding is already covered in the > generic SPI DT coverage? yes, this DT binding and documentation already exists. Thanks, Anatolij -- Precog is a next-generation analytics platform capable of advanced analytics on semi-structured data. The platform includes APIs for building apps and a phenomenal toolset for data science. Developers can use our toolset for easy data analysis & visualization. Get a free account! http://www2.precog.com/precogplatform/slashdotnewsletter ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH] spi: spi-mpc512x-psc: let transmiter/receiver enabled when in xfer loop
There is no need to disable transmitter/receiver after each loop iteration and re-enable it for next loop iteration. Enable the transmitter/receiver before xfer loop starts and disable it when the whole transfer is done. Signed-off-by: Anatolij Gustschin --- drivers/spi/spi-mpc512x-psc.c | 10 +++--- 1 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 3e490ee..0ea7c81 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -148,6 +148,9 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, in_8(&psc->mode); out_8(&psc->mode, 0x0); + /* enable transmiter/receiver */ + out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); + while (len) { int count; int i; @@ -176,10 +179,6 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, out_be32(&fifo->txisr, MPC512x_PSC_FIFO_EMPTY); out_be32(&fifo->tximr, MPC512x_PSC_FIFO_EMPTY); - /* enable transmiter/receiver */ - out_8(&psc->command, - MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); - wait_for_completion(&mps->done); mdelay(1); @@ -204,9 +203,6 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, while (in_be32(&fifo->rxcnt)) { in_8(&fifo->rxdata_8); } - - out_8(&psc->command, - MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE); } /* disable transmiter/receiver and fifo interrupt */ out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE); -- 1.7.5.4 -- Own the Future-Intel® Level Up Game Demo Contest 2013 Rise to greatness in Intel's independent game demo contest. Compete for recognition, cash, and the chance to get your game on Steam. $5K grand prize plus 10 genre and skill prizes. Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2 RESEND] spi: spi-mpc512x-psc: add support for gpio chip selects
Currently the driver only uses one internal chip select. Add support for gpio chip selects configured by cs-gpios DT binding. Signed-off-by: Anatolij Gustschin --- v2 resend: - no changes, resend to Mark v2: - do not parse GPIO chip selects manually drivers/spi/spi-mpc512x-psc.c | 31 +-- 1 files changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 3e490ee..da60f26 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include struct mpc512x_psc_spi { @@ -113,7 +114,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) out_be32(&psc->ccr, ccr); mps->bits_per_word = cs->bits_per_word; - if (mps->cs_control) + if (mps->cs_control && gpio_is_valid(spi->cs_gpio)) mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0); } @@ -121,7 +122,7 @@ static void mpc512x_psc_spi_deactivate_cs(struct spi_device *spi) { struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); - if (mps->cs_control) + if (mps->cs_control && gpio_is_valid(spi->cs_gpio)) mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1); } @@ -278,6 +279,7 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi) struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); struct mpc512x_psc_spi_cs *cs = spi->controller_state; unsigned long flags; + int ret; if (spi->bits_per_word % 8) return -EINVAL; @@ -286,6 +288,19 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi) cs = kzalloc(sizeof *cs, GFP_KERNEL); if (!cs) return -ENOMEM; + + if (gpio_is_valid(spi->cs_gpio)) { + ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev)); + if (ret) { + dev_err(&spi->dev, "can't get CS gpio: %d\n", + ret); + kfree(cs); + return ret; + } + gpio_direction_output(spi->cs_gpio, + spi->mode & SPI_CS_HIGH ? 0 : 1); + } + spi->controller_state = cs; } @@ -319,6 +334,8 @@ static int mpc512x_psc_spi_transfer(struct spi_device *spi, static void mpc512x_psc_spi_cleanup(struct spi_device *spi) { + if (gpio_is_valid(spi->cs_gpio)) + gpio_free(spi->cs_gpio); kfree(spi->controller_state); } @@ -405,6 +422,11 @@ static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) return IRQ_NONE; } +static void mpc512x_spi_cs_control(struct spi_device *spi, bool onoff) +{ + gpio_set_value(spi->cs_gpio, onoff); +} + /* bus_num is used only for the case dev->platform_data == NULL */ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, u32 size, unsigned int irq, @@ -425,12 +447,9 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, mps->irq = irq; if (pdata == NULL) { - dev_err(dev, "probe called without platform data, no " - "cs_control function will be called\n"); - mps->cs_control = NULL; + mps->cs_control = mpc512x_spi_cs_control; mps->sysclk = 0; master->bus_num = bus_num; - master->num_chipselect = 255; } else { mps->cs_control = pdata->cs_control; mps->sysclk = pdata->sysclk; -- 1.7.5.4 -- Own the Future-Intel® Level Up Game Demo Contest 2013 Rise to greatness in Intel's independent game demo contest. Compete for recognition, cash, and the chance to get your game on Steam. $5K grand prize plus 10 genre and skill prizes. Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH] spi: mpc512x-psc: optionally keep PSC SS asserted across xfer segmensts
On Mon, 1 Apr 2013 14:30:17 +0100 Mark Brown wrote: > On Wed, Mar 13, 2013 at 02:57:43PM +0100, Anatolij Gustschin wrote: > > Some SPI slave devices require asserted chip select signal across > > multiple transfer segments of an SPI message. Currently the driver > > This isn't some devices, it's the standard behaviour for the API - > drivers and frameworks can split up a SPI transfer into as many pieces > as amuses them. > > Anyway, applied. Thanks! Could you also apply this one ? https://patchwork.kernel.org/patch/2251911 Thanks, Anatolij -- Own the Future-Intel® Level Up Game Demo Contest 2013 Rise to greatness in Intel's independent game demo contest. Compete for recognition, cash, and the chance to get your game on Steam. $5K grand prize plus 10 genre and skill prizes. Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH] spi: mpc512x-psc: optionally keep PSC SS asserted across xfer segmensts
Some SPI slave devices require asserted chip select signal across multiple transfer segments of an SPI message. Currently the driver always de-asserts the internal SS signal for every single transfer segment of the message and ignores the 'cs_change' flag of the transfer description. Disable the internal chip select (SS) only if this is needed and indicated by the 'cs_change' flag. Without this change, each partial transfer of a surrounding multi-part SPI transaction might erroneously change the SS signal, which might prevent slaves from answering the request that was sent in a previous transfer segment because the transaction could be considered aborted (SS was de-asserted before reading the response). Reported-by: Gerhard Sittig Signed-off-by: Anatolij Gustschin --- drivers/spi/spi-mpc512x-psc.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 6b600a2..dfddf33 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -168,7 +168,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, for (i = count; i > 0; i--) { data = tx_buf ? *tx_buf++ : 0; - if (len == EOFBYTE) + if (len == EOFBYTE && t->cs_change) setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF); out_8(&fifo->txdata_8, data); len--; -- 1.7.5.4 -- Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_d2d_mar ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2] spi: spi-mpc512x-psc: add support for gpio chip selects
Currently the driver only uses one internal chip select. Add support for gpio chip selects configured by cs-gpios DT binding. Signed-off-by: Anatolij Gustschin --- v2: - do not parse GPIO chip selects manually drivers/spi/spi-mpc512x-psc.c | 31 +-- 1 files changed, 25 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 89480b2..4263ed4 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include struct mpc512x_psc_spi { @@ -113,7 +114,7 @@ static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) out_be32(&psc->ccr, ccr); mps->bits_per_word = cs->bits_per_word; - if (mps->cs_control) + if (mps->cs_control && gpio_is_valid(spi->cs_gpio)) mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0); } @@ -121,7 +122,7 @@ static void mpc512x_psc_spi_deactivate_cs(struct spi_device *spi) { struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); - if (mps->cs_control) + if (mps->cs_control && gpio_is_valid(spi->cs_gpio)) mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1); } @@ -278,6 +279,7 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi) struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); struct mpc512x_psc_spi_cs *cs = spi->controller_state; unsigned long flags; + int ret; if (spi->bits_per_word % 8) return -EINVAL; @@ -286,6 +288,19 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi) cs = kzalloc(sizeof *cs, GFP_KERNEL); if (!cs) return -ENOMEM; + + if (gpio_is_valid(spi->cs_gpio)) { + ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev)); + if (ret) { + dev_err(&spi->dev, "can't get CS gpio: %d\n", + ret); + kfree(cs); + return ret; + } + gpio_direction_output(spi->cs_gpio, + spi->mode & SPI_CS_HIGH ? 0 : 1); + } + spi->controller_state = cs; } @@ -319,6 +334,8 @@ static int mpc512x_psc_spi_transfer(struct spi_device *spi, static void mpc512x_psc_spi_cleanup(struct spi_device *spi) { + if (gpio_is_valid(spi->cs_gpio)) + gpio_free(spi->cs_gpio); kfree(spi->controller_state); } @@ -405,6 +422,11 @@ static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) return IRQ_NONE; } +static void mpc512x_spi_cs_control(struct spi_device *spi, bool onoff) +{ + gpio_set_value(spi->cs_gpio, onoff); +} + /* bus_num is used only for the case dev->platform_data == NULL */ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, u32 size, unsigned int irq, @@ -425,12 +447,9 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, mps->irq = irq; if (pdata == NULL) { - dev_err(dev, "probe called without platform data, no " - "cs_control function will be called\n"); - mps->cs_control = NULL; + mps->cs_control = mpc512x_spi_cs_control; mps->sysclk = 0; master->bus_num = bus_num; - master->num_chipselect = 255; } else { mps->cs_control = pdata->cs_control; mps->sysclk = pdata->sysclk; -- 1.7.5.4 -- Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the endpoint security space. For insight on selecting the right partner to tackle endpoint security challenges, access the full report. http://p.sf.net/sfu/symantec-dev2dev ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH 2/2] spi: spi-mpc512x-psc: add support for gpio chip selects
On Tue, 05 Feb 2013 14:18:46 + Grant Likely wrote: > On Mon, 14 Jan 2013 21:27:01 +0100, Anatolij Gustschin wrote: > > Currently the driver only uses one internal chip select. Add support > > for gpio chip selects configured by gpio specifiers in the device tree. > > > > Signed-off-by: Anatolij Gustschin > > GPIO chip selects are now in the core spi library. Take a look at > master->cs_gpios and Documentation/devicetree/bindings/spi/spi-bus.txt. > You don't need to parse them manually. Thanks for the hint! I'll rework the patch and resubmit. Anatolij -- Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the endpoint security space. For insight on selecting the right partner to tackle endpoint security challenges, access the full report. http://p.sf.net/sfu/symantec-dev2dev ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH 2/2] spi: spi-mpc512x-psc: add support for gpio chip selects
Currently the driver only uses one internal chip select. Add support for gpio chip selects configured by gpio specifiers in the device tree. Signed-off-by: Anatolij Gustschin --- drivers/spi/spi-mpc512x-psc.c | 80 ++--- 1 files changed, 75 insertions(+), 5 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 89480b2..4b2f391 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,8 @@ struct mpc512x_psc_spi { spinlock_t lock;/* Message queue lock */ struct completion done; + int num_cs; + int chipselects[0]; }; /* controller state */ @@ -277,6 +280,7 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi) { struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); struct mpc512x_psc_spi_cs *cs = spi->controller_state; + int gpio = mps->chipselects[spi->chip_select]; unsigned long flags; if (spi->bits_per_word % 8) @@ -292,6 +296,9 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi) cs->bits_per_word = spi->bits_per_word; cs->speed_hz = spi->max_speed_hz; + if (gpio_is_valid(gpio)) + gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); + spin_lock_irqsave(&mps->lock, flags); if (!mps->busy) mpc512x_psc_spi_deactivate_cs(spi); @@ -405,6 +412,27 @@ static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) return IRQ_NONE; } +static void mpc512x_spi_cs_control(struct spi_device *spi, bool on) +{ + struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); + int gpio = mps->chipselects[spi->chip_select]; + + gpio_set_value(gpio, on); +} + +static int mpc512x_spi_cs_num(struct device *dev) +{ + int num_cs, ret; + + ret = of_property_read_u32(dev->of_node, "num-cs", &num_cs); + if (ret < 0) { + dev_warn(dev, "no num-cs property\n"); + return of_gpio_named_count(dev->of_node, "cs-gpios"); + } + + return num_cs; +} + /* bus_num is used only for the case dev->platform_data == NULL */ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, u32 size, unsigned int irq, @@ -415,8 +443,17 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, struct spi_master *master; int ret; void *tempp; + int i = 0, max_cs_num = 0; + int use_internal_cs = 0; + int num_cs; + + num_cs = mpc512x_spi_cs_num(dev); + if (!num_cs) + use_internal_cs = 1; - master = spi_alloc_master(dev, sizeof *mps); + dev_dbg(dev, "using %d gpio chipselects\n", num_cs); + + master = spi_alloc_master(dev, sizeof(*mps) + sizeof(int) * num_cs); if (master == NULL) return -ENOMEM; @@ -425,12 +462,14 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, mps->irq = irq; if (pdata == NULL) { - dev_err(dev, "probe called without platform data, no " - "cs_control function will be called\n"); - mps->cs_control = NULL; mps->sysclk = 0; master->bus_num = bus_num; - master->num_chipselect = 255; + if (use_internal_cs) { + mps->cs_control = NULL; + master->num_chipselect = 1; + } else { + mps->cs_control = mpc512x_spi_cs_control; + } } else { mps->cs_control = pdata->cs_control; mps->sysclk = pdata->sysclk; @@ -438,6 +477,28 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, master->num_chipselect = pdata->max_chipselect; } + if (!pdata && !use_internal_cs) { + for (i = 0; i < num_cs; i++) { + int cs_gpio = of_get_named_gpio(dev->of_node, + "cs-gpios", i); + + dev_dbg(dev, "cs %d: gpio %d\n", i, cs_gpio); + mps->chipselects[i] = cs_gpio; + if (!gpio_is_valid(cs_gpio)) + continue; + + max_cs_num = max(max_cs_num, cs_gpio); + ret = gpio_request(mps->chipselects[i], + "psc-spi cs"); + if (ret) { + dev_err(de
[PATCH 1/2] spi: spi-mpc512x-psc: init mode bits supported by the driver
The driver should setup mode bits it supports, otherwise adding an SPI device might fail even if the driver supports the requested SPI mode. Signed-off-by: Anatolij Gustschin --- drivers/spi/spi-mpc512x-psc.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 88e5441..89480b2 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -438,6 +438,7 @@ static int mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, master->num_chipselect = pdata->max_chipselect; } + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; master->setup = mpc512x_psc_spi_setup; master->transfer = mpc512x_psc_spi_transfer; master->cleanup = mpc512x_psc_spi_cleanup; -- 1.7.5.4 -- Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. SALE $99.99 this month only -- learn more at: http://p.sf.net/sfu/learnmore_122412 ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2] spi: spi-mpc512x-psc: don't use obsolet cell-index property
Remove deprecated cell-index property and use spi alias to obtain the SPI PSC number used for SPI bus id. Signed-off-by: Anatolij Gustschin --- v2: - use of_alias_get_id() to get spi bus number drivers/spi/spi-mpc512x-psc.c | 16 +--- 1 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index cb3a310..88e5441 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -522,17 +522,11 @@ static int mpc512x_psc_spi_of_probe(struct platform_device *op) regaddr64 = of_translate_address(op->dev.of_node, regaddr_p); /* get PSC id (0..11, used by port_config) */ - if (op->dev.platform_data == NULL) { - const u32 *psc_nump; - - psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL); - if (!psc_nump || *psc_nump > 11) { - dev_err(&op->dev, "mpc512x_psc_spi: Device node %s " - "has invalid cell-index property\n", - op->dev.of_node->full_name); - return -EINVAL; - } - id = *psc_nump; + id = of_alias_get_id(op->dev.of_node, "spi"); + if (id < 0) { + dev_err(&op->dev, "no alias id for %s\n", + op->dev.of_node->full_name); + return id; } return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, -- 1.7.5.4 -- Master HTML5, CSS3, ASP.NET, MVC, AJAX, Knockout.js, Web API and much more. Get web development skills now with LearnDevNow - 350+ hours of step-by-step video tutorials by Microsoft MVPs and experts. SALE $99.99 this month only -- learn more at: http://p.sf.net/sfu/learnmore_122812 ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH v2] spi: spi-mpc512x-psc: don't use obsolet cell-index property
Remove deprecated cell-index property and use spi alias to obtain the SPI PSC number used for SPI bus id. Signed-off-by: Anatolij Gustschin --- v2: - use of_alias_get_id() to get spi bus number drivers/spi/spi-mpc512x-psc.c | 16 +--- 1 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index cb3a310..88e5441 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -522,17 +522,11 @@ static int mpc512x_psc_spi_of_probe(struct platform_device *op) regaddr64 = of_translate_address(op->dev.of_node, regaddr_p); /* get PSC id (0..11, used by port_config) */ - if (op->dev.platform_data == NULL) { - const u32 *psc_nump; - - psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL); - if (!psc_nump || *psc_nump > 11) { - dev_err(&op->dev, "mpc512x_psc_spi: Device node %s " - "has invalid cell-index property\n", - op->dev.of_node->full_name); - return -EINVAL; - } - id = *psc_nump; + id = of_alias_get_id(op->dev.of_node, "spi"); + if (id < 0) { + dev_err(&op->dev, "no alias id for %s\n", + op->dev.of_node->full_name); + return id; } return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, -- 1.7.5.4 -- Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. ON SALE this month only -- learn more at: http://p.sf.net/sfu/learnmore_122712 ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
Re: [PATCH] spi: spi-mpc512x-psc: don't use obsolet cell-index property
Hi Grant, On Fri, 21 Dec 2012 19:29:14 + Grant Likely wrote: > On Fri, 21 Dec 2012 14:48:38 +, Grant Likely > wrote: > > On Fri, Dec 21, 2012 at 2:43 PM, Anatolij Gustschin wrote: > > > Use unique PSCx register base offset to obtain the > > > SPI PSC number used for SPI bus id. > > > > > > Signed-off-by: Anatolij Gustschin > > > > Don't do this. If you really want to assign a specific bus number, > > then use a property in /aliases. cell-index has been deprecated a very > > long time ago now. > > Ummm.. I really should read patches before I reply to them. I see you're > removing cell-index, not adding it back in. It is fine. > > Aliases would be a more generic solution though. Would this following > change work for you? Try it out and let me know. Sorry for delay. I've tried it now, it doesn't work. The mpc5121 psc spi driver also needs to get/enable psc clock of the used psc controller. It uses psc bus number to generate psc clock name string and to get and enable this clock, so I need to set the bus number in the driver. I'll use of_alias_get_id() in the the psc spi driver. Thanks, Anatolij -- Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. ON SALE this month only -- learn more at: http://p.sf.net/sfu/learnmore_122712 ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH] spi: spi-mpc512x-psc: don't use obsolet cell-index property
Use unique PSCx register base offset to obtain the SPI PSC number used for SPI bus id. Signed-off-by: Anatolij Gustschin --- drivers/spi/spi-mpc512x-psc.c | 17 +++-- 1 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 0a1e39e..844d68f 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -523,16 +523,21 @@ static int __devinit mpc512x_psc_spi_of_probe(struct platform_device *op) /* get PSC id (0..11, used by port_config) */ if (op->dev.platform_data == NULL) { - const u32 *psc_nump; + u32 reg; + int err; - psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL); - if (!psc_nump || *psc_nump > 11) { - dev_err(&op->dev, "mpc512x_psc_spi: Device node %s " - "has invalid cell-index property\n", + err = of_property_read_u32(op->dev.of_node, "reg", ®); + if (err) { + dev_err(&op->dev, "Can't read reg property: %d\n", err); + return err; + } + + id = (reg & 0xf00) >> 8; + if (id > 11) { + dev_err(&op->dev, "node %s has invalid reg property\n", op->dev.of_node->full_name); return -EINVAL; } - id = *psc_nump; } return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, -- 1.7.7.6 -- LogMeIn Rescue: Anywhere, Anytime Remote support for IT. Free Trial Remotely access PCs and mobile devices and provide instant support Improve your efficiency, and focus on delivering more value-add services Discover what IT Professionals Know. Rescue delivers http://p.sf.net/sfu/logmein_12329d2d ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[PATCH] spi: bitbang: initialize bits_per_word as specified by spi message
SPI protocol drivers can submit messages specifying needed bits_per_word parameter for a message transfer. The bitbang driver currently ignores bits_per_word given by a singe message and always uses master's bits_per_word parameter. Only use master's bits_per_word when a message didn't specify needed bits_per_word for ongoing transfer. Signed-off-by: Anatolij Gustschin --- drivers/spi/spi_bitbang.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index 14a63f6..bb38c83 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -68,7 +68,7 @@ static unsigned bitbang_txrx_8( unsignedns, struct spi_transfer *t ) { - unsignedbits = spi->bits_per_word; + unsignedbits = t->bits_per_word ? : spi->bits_per_word; unsignedcount = t->len; const u8*tx = t->tx_buf; u8 *rx = t->rx_buf; @@ -94,7 +94,7 @@ static unsigned bitbang_txrx_16( unsignedns, struct spi_transfer *t ) { - unsignedbits = spi->bits_per_word; + unsignedbits = t->bits_per_word ? : spi->bits_per_word; unsignedcount = t->len; const u16 *tx = t->tx_buf; u16 *rx = t->rx_buf; @@ -120,7 +120,7 @@ static unsigned bitbang_txrx_32( unsignedns, struct spi_transfer *t ) { - unsignedbits = spi->bits_per_word; + unsignedbits = t->bits_per_word ? : spi->bits_per_word; unsignedcount = t->len; const u32 *tx = t->tx_buf; u32 *rx = t->rx_buf; -- 1.7.1 -- Simplify data backup and recovery for your virtual environment with vRanger. Installation's a snap, and flexible recovery options mean your data is safe, secure and there when you need it. Data protection magic? Nope - It's vRanger. Get your free trial download today. http://p.sf.net/sfu/quest-sfdev2dev ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[spi-devel-general] [PATCH v2] of/spi: call of_register_spi_devices() from spi core code
Move of_register_spi_devices() call from drivers to spi_register_master(). Also change the function to use the struct device_node pointer from master spi device instead of passing it as function argument. Signed-off-by: Anatolij Gustschin Cc: David Brownell Cc: Grant Likely Cc: devicetree-disc...@lists.ozlabs.org --- Changes in v2 as requested by Grant: - check master->dev.of_node to prevent potential null pointer dereference - set master->dev.of_node in OF-aware SPI bus drivers - also drop of_register_spi_devices() in xilinx_spi_of.c and spi_ppc4xx.c drivers drivers/of/of_spi.c | 10 ++ drivers/spi/mpc512x_psc_spi.c |1 + drivers/spi/mpc52xx_psc_spi.c | 10 ++ drivers/spi/mpc52xx_spi.c |3 +-- drivers/spi/spi.c |4 drivers/spi/spi_mpc8xxx.c |4 +--- drivers/spi/spi_ppc4xx.c |2 +- drivers/spi/xilinx_spi.c |1 + drivers/spi/xilinx_spi_of.c |3 --- include/linux/of_spi.h| 11 --- 10 files changed, 25 insertions(+), 24 deletions(-) diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index d504f1d..1dbce58 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -15,12 +15,11 @@ /** * of_register_spi_devices - Register child devices onto the SPI bus * @master:Pointer to spi_master device - * @np:parent node of SPI device nodes * - * Registers an spi_device for each child node of 'np' which has a 'reg' + * Registers an spi_device for each child node of master node which has a 'reg' * property. */ -void of_register_spi_devices(struct spi_master *master, struct device_node *np) +void of_register_spi_devices(struct spi_master *master) { struct spi_device *spi; struct device_node *nc; @@ -28,7 +27,10 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) int rc; int len; - for_each_child_of_node(np, nc) { + if (!master->dev.of_node) + return; + + for_each_child_of_node(master->dev.of_node, nc) { /* Alloc an spi_device */ spi = spi_alloc_device(master); if (!spi) { diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c index c8d69fc..b5539d3 100644 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c @@ -440,6 +440,7 @@ static int __devinit mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, master->setup = mpc512x_psc_spi_setup; master->transfer = mpc512x_psc_spi_transfer; master->cleanup = mpc512x_psc_spi_cleanup; + master->dev.of_node = dev->of_node; tempp = ioremap(regaddr, size); if (!tempp) { diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 7104cb7..bd81ff9 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -398,6 +397,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr, master->setup = mpc52xx_psc_spi_setup; master->transfer = mpc52xx_psc_spi_transfer; master->cleanup = mpc52xx_psc_spi_cleanup; + master->dev.of_node = dev->of_node; mps->psc = ioremap(regaddr, size); if (!mps->psc) { @@ -470,7 +470,6 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, const u32 *regaddr_p; u64 regaddr64, size64; s16 id = -1; - int rc; regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { @@ -491,13 +490,8 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, id = *psc_nump + 1; } - rc = mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, + return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, irq_of_parse_and_map(op->dev.of_node, 0), id); - if (rc == 0) - of_register_spi_devices(dev_get_drvdata(&op->dev), - op->dev.of_node); - - return rc; } static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op) diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index b1a76bf..56136ff 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -439,6 +438,7 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, master->setup = mpc52xx_spi_setup; master->transfer = mpc52xx_spi_transfer; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; + master->dev.of_node = op->dev.of_node; dev_set_drvdata(&op->dev, master)
[spi-devel-general] [PATCH] of/spi: call of_register_spi_devices() from spi core code
Move of_register_spi_devices() call from some drivers to spi_register_master(). Also change the function to use the struct device_node pointer from master spi device instead of passing it as function argument. Since xilinx_spi_of.c and spi_ppc4xx.c drivers do not use spi_register_master(), they still call of_register_spi_devices() directly. Maybe these drivers should be reworked later. Signed-off-by: Anatolij Gustschin Cc: David Brownell Cc: Grant Likely Cc: devicetree-disc...@lists.ozlabs.org --- drivers/of/of_spi.c |7 +++ drivers/spi/mpc52xx_psc_spi.c |9 + drivers/spi/mpc52xx_spi.c |2 -- drivers/spi/spi.c |5 + drivers/spi/spi_mpc8xxx.c |3 --- drivers/spi/spi_ppc4xx.c |3 ++- drivers/spi/xilinx_spi.c |1 + drivers/spi/xilinx_spi_of.c |2 +- include/linux/of_spi.h| 11 --- 9 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index d504f1d..76a0529 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -15,12 +15,11 @@ /** * of_register_spi_devices - Register child devices onto the SPI bus * @master:Pointer to spi_master device - * @np:parent node of SPI device nodes * - * Registers an spi_device for each child node of 'np' which has a 'reg' + * Registers an spi_device for each child node of master node which has a 'reg' * property. */ -void of_register_spi_devices(struct spi_master *master, struct device_node *np) +void of_register_spi_devices(struct spi_master *master) { struct spi_device *spi; struct device_node *nc; @@ -28,7 +27,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) int rc; int len; - for_each_child_of_node(np, nc) { + for_each_child_of_node(master->dev.of_node, nc) { /* Alloc an spi_device */ spi = spi_alloc_device(master); if (!spi) { diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c index 7104cb7..a6eb5d4 100644 --- a/drivers/spi/mpc52xx_psc_spi.c +++ b/drivers/spi/mpc52xx_psc_spi.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -470,7 +469,6 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, const u32 *regaddr_p; u64 regaddr64, size64; s16 id = -1; - int rc; regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { @@ -491,13 +489,8 @@ static int __init mpc52xx_psc_spi_of_probe(struct of_device *op, id = *psc_nump + 1; } - rc = mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, + return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64, irq_of_parse_and_map(op->dev.of_node, 0), id); - if (rc == 0) - of_register_spi_devices(dev_get_drvdata(&op->dev), - op->dev.of_node); - - return rc; } static int __exit mpc52xx_psc_spi_of_remove(struct of_device *op) diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index b1a76bf..18e1c86 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -512,7 +511,6 @@ static int __devinit mpc52xx_spi_probe(struct of_device *op, if (rc) goto err_register; - of_register_spi_devices(master, op->dev.of_node); dev_info(&ms->master->dev, "registered MPC5200 SPI bus\n"); return rc; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index fdde706..626fa48 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -26,6 +26,7 @@ #include #include #include +#include /* SPI bustype and spi_master class are registered after board init code @@ -544,6 +545,10 @@ int spi_register_master(struct spi_master *master) /* populate children from any spi device tables */ scan_boardinfo(master); status = 0; + + /* Register devices from the device tree */ + master->dev.of_node = dev->of_node; + of_register_spi_devices(master); done: return status; } diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c index 97ab0a8..89fea11 100644 --- a/drivers/spi/spi_mpc8xxx.c +++ b/drivers/spi/spi_mpc8xxx.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -1299,8 +1298,6 @@ static int __devinit of_mpc8xxx_spi_probe(struct of_device *ofdev, goto err; } - of_register_spi_devices(master, np); - return 0; err: diff --git a/drivers/spi/spi_ppc4xx.c b/drivers/spi/spi_ppc4xx.c index d53466a..0bcea55 100644 ---
[spi-devel-general] [PATCH] spi/mpc5121: register spi child devices of spi node
Signed-off-by: Anatolij Gustschin --- drivers/spi/mpc512x_psc_spi.c | 10 +- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c index c8d69fc..39e5faf 100644 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c @@ -27,6 +27,7 @@ #include #include #include +#include #include struct mpc512x_psc_spi { @@ -511,6 +512,7 @@ static int __devinit mpc512x_psc_spi_of_probe(struct of_device *op, const u32 *regaddr_p; u64 regaddr64, size64; s16 id = -1; + int ret; regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { @@ -533,8 +535,14 @@ static int __devinit mpc512x_psc_spi_of_probe(struct of_device *op, id = *psc_nump; } - return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, + ret = mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, irq_of_parse_and_map(op->dev.of_node, 0), id); + + if (!ret) + of_register_spi_devices(dev_get_drvdata(&op->dev), + op->dev.of_node); + + return ret; } static int __devexit mpc512x_psc_spi_of_remove(struct of_device *op) -- 1.7.0.4 -- The Palm PDK Hot Apps Program offers developers who use the Plug-In Development Kit to bring their C/C++ apps to Palm for a share of $1 Million in cash or HP Products. Visit us here for more details: http://ad.doubleclick.net/clk;226879339;13503038;l? http://clk.atdmt.com/CRS/go/247765532/direct/01/ ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[spi-devel-general] [PATCH] spi/mpc5121: change annotations for probe and remove functions
Change annotations from __init/__exit to __devinit/__devexit to get rid of section mismatch warning. Signed-off-by: Anatolij Gustschin --- drivers/spi/mpc512x_psc_spi.c | 16 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c index 2534b1e..c8d69fc 100644 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c @@ -405,9 +405,9 @@ static irqreturn_t mpc512x_psc_spi_isr(int irq, void *dev_id) } /* bus_num is used only for the case dev->platform_data == NULL */ -static int __init mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, - u32 size, unsigned int irq, - s16 bus_num) +static int __devinit mpc512x_psc_spi_do_probe(struct device *dev, u32 regaddr, + u32 size, unsigned int irq, + s16 bus_num) { struct fsl_spi_platform_data *pdata = dev->platform_data; struct mpc512x_psc_spi *mps; @@ -490,7 +490,7 @@ free_master: return ret; } -static int __exit mpc512x_psc_spi_do_remove(struct device *dev) +static int __devexit mpc512x_psc_spi_do_remove(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct mpc512x_psc_spi *mps = spi_master_get_devdata(master); @@ -505,8 +505,8 @@ static int __exit mpc512x_psc_spi_do_remove(struct device *dev) return 0; } -static int __init mpc512x_psc_spi_of_probe(struct of_device *op, - const struct of_device_id *match) +static int __devinit mpc512x_psc_spi_of_probe(struct of_device *op, + const struct of_device_id *match) { const u32 *regaddr_p; u64 regaddr64, size64; @@ -537,7 +537,7 @@ static int __init mpc512x_psc_spi_of_probe(struct of_device *op, irq_of_parse_and_map(op->dev.of_node, 0), id); } -static int __exit mpc512x_psc_spi_of_remove(struct of_device *op) +static int __devexit mpc512x_psc_spi_of_remove(struct of_device *op) { return mpc512x_psc_spi_do_remove(&op->dev); } @@ -551,7 +551,7 @@ MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match); static struct of_platform_driver mpc512x_psc_spi_of_driver = { .probe = mpc512x_psc_spi_of_probe, - .remove = __exit_p(mpc512x_psc_spi_of_remove), + .remove = __devexit_p(mpc512x_psc_spi_of_remove), .driver = { .name = "mpc512x-psc-spi", .owner = THIS_MODULE, -- 1.7.0.4 -- This SF.net email is sponsored by Sprint What will you do first with EVO, the first 4G phone? Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[spi-devel-general] [PATCH] spi: mpc512x_psc_spi.c: Fix build failures
Fixes build errors caused by the: - OF device_node pointer being moved into struct device - removal of the match_table field from struct of_platform_driver Signed-off-by: Anatolij Gustschin Cc: Grant Likely --- drivers/spi/mpc512x_psc_spi.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c index 28a126d..2534b1e 100644 --- a/drivers/spi/mpc512x_psc_spi.c +++ b/drivers/spi/mpc512x_psc_spi.c @@ -512,29 +512,29 @@ static int __init mpc512x_psc_spi_of_probe(struct of_device *op, u64 regaddr64, size64; s16 id = -1; - regaddr_p = of_get_address(op->node, 0, &size64, NULL); + regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL); if (!regaddr_p) { dev_err(&op->dev, "Invalid PSC address\n"); return -EINVAL; } - regaddr64 = of_translate_address(op->node, regaddr_p); + regaddr64 = of_translate_address(op->dev.of_node, regaddr_p); /* get PSC id (0..11, used by port_config) */ if (op->dev.platform_data == NULL) { const u32 *psc_nump; - psc_nump = of_get_property(op->node, "cell-index", NULL); + psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL); if (!psc_nump || *psc_nump > 11) { dev_err(&op->dev, "mpc512x_psc_spi: Device node %s " "has invalid cell-index property\n", - op->node->full_name); + op->dev.of_node->full_name); return -EINVAL; } id = *psc_nump; } return mpc512x_psc_spi_do_probe(&op->dev, (u32) regaddr64, (u32) size64, - irq_of_parse_and_map(op->node, 0), id); + irq_of_parse_and_map(op->dev.of_node, 0), id); } static int __exit mpc512x_psc_spi_of_remove(struct of_device *op) @@ -550,12 +550,12 @@ static struct of_device_id mpc512x_psc_spi_of_match[] = { MODULE_DEVICE_TABLE(of, mpc512x_psc_spi_of_match); static struct of_platform_driver mpc512x_psc_spi_of_driver = { - .match_table = mpc512x_psc_spi_of_match, .probe = mpc512x_psc_spi_of_probe, .remove = __exit_p(mpc512x_psc_spi_of_remove), .driver = { .name = "mpc512x-psc-spi", .owner = THIS_MODULE, + .of_match_table = mpc512x_psc_spi_of_match, }, }; -- 1.7.0.4 -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general
[spi-devel-general] [PATCH 2/2] spi: Add SPI master driver for MPC5121 PSC
Signed-off-by: John Rigby Signed-off-by: Anatolij Gustschin --- arch/powerpc/include/asm/mpc52xx_psc.h |1 + drivers/spi/Kconfig|7 + drivers/spi/Makefile |1 + drivers/spi/mpc512x_psc_spi.c | 576 4 files changed, 585 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/mpc512x_psc_spi.c diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h b/arch/powerpc/include/asm/mpc52xx_psc.h index 42561f4..ecc4fc6 100644 --- a/arch/powerpc/include/asm/mpc52xx_psc.h +++ b/arch/powerpc/include/asm/mpc52xx_psc.h @@ -248,6 +248,7 @@ struct mpc52xx_psc_fifo { u16 tflwfptr; /* PSC + 0x9e */ }; +#define MPC512x_PSC_FIFO_EOF 0x100 #define MPC512x_PSC_FIFO_RESET_SLICE 0x80 #define MPC512x_PSC_FIFO_ENABLE_SLICE 0x01 #define MPC512x_PSC_FIFO_ENABLE_DMA0x04 diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a191fa2..317bb01 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -165,6 +165,13 @@ config SPI_MPC52xx_PSC This enables using the Freescale MPC52xx Programmable Serial Controller in master SPI mode. +config SPI_MPC512x_PSC + tristate "Freescale MPC512x PSC SPI controller" + depends on SPI_MASTER && PPC_MPC512x + help + This enables using the Freescale MPC5121 Programmable Serial + Controller in SPI master mode. + config SPI_MPC8xxx tristate "Freescale MPC8xxx SPI controller" depends on FSL_SOC diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index d7d0f89..b989ffb 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_SPI_OMAP24XX)+= omap2_mcspi.o obj-$(CONFIG_SPI_OMAP_100K)+= omap_spi_100k.o obj-$(CONFIG_SPI_ORION)+= orion_spi.o obj-$(CONFIG_SPI_PL022)+= amba-pl022.o +obj-$(CONFIG_SPI_MPC512x_PSC) += mpc512x_psc_spi.o obj-$(CONFIG_SPI_MPC52xx_PSC) += mpc52xx_psc_spi.o obj-$(CONFIG_SPI_MPC52xx) += mpc52xx_spi.o obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o diff --git a/drivers/spi/mpc512x_psc_spi.c b/drivers/spi/mpc512x_psc_spi.c new file mode 100644 index 000..28a126d --- /dev/null +++ b/drivers/spi/mpc512x_psc_spi.c @@ -0,0 +1,576 @@ +/* + * MPC512x PSC in SPI mode driver. + * + * Copyright (C) 2007,2008 Freescale Semiconductor Inc. + * Original port from 52xx driver: + * Hongjun Chen + * + * Fork of mpc52xx_psc_spi.c: + * Copyright (C) 2006 TOPTICA Photonics AG., Dragos Carp + * + * 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 +#include +#include +#include +#include +#include +#include + +struct mpc512x_psc_spi { + void (*cs_control)(struct spi_device *spi, bool on); + u32 sysclk; + + /* driver internal data */ + struct mpc52xx_psc __iomem *psc; + struct mpc512x_psc_fifo __iomem *fifo; + unsigned int irq; + u8 bits_per_word; + u8 busy; + u32 mclk; + u8 eofbyte; + + struct workqueue_struct *workqueue; + struct work_struct work; + + struct list_head queue; + spinlock_t lock;/* Message queue lock */ + + struct completion done; +}; + +/* controller state */ +struct mpc512x_psc_spi_cs { + int bits_per_word; + int speed_hz; +}; + +/* set clock freq, clock ramp, bits per work + * if t is NULL then reset the values to the default values + */ +static int mpc512x_psc_spi_transfer_setup(struct spi_device *spi, + struct spi_transfer *t) +{ + struct mpc512x_psc_spi_cs *cs = spi->controller_state; + + cs->speed_hz = (t && t->speed_hz) + ? t->speed_hz : spi->max_speed_hz; + cs->bits_per_word = (t && t->bits_per_word) + ? t->bits_per_word : spi->bits_per_word; + cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8; + return 0; +} + +static void mpc512x_psc_spi_activate_cs(struct spi_device *spi) +{ + struct mpc512x_psc_spi_cs *cs = spi->controller_state; + struct mpc512x_psc_spi *mps = spi_master_get_devdata(spi->master); + struct mpc52xx_psc __iomem *psc = mps->psc; + u32 sicr; + u32 ccr; + u16 bclkdiv; + + sicr = in_be32(&psc->sicr); + + /* Set clock phase and polarity */ + if (spi->mode & SPI_CPHA) + sicr |= 0x1000; + else + sicr &= ~0x1000; + + if (spi->mode & SPI_CPOL) +
[spi-devel-general] [PATCH 1/2] powerpc/mpc5121: move PSC FIFO memory init to platform code
Since PSC could also be used in other modes than UART mode we move PSC FIFO memory initialization from serial driver to common platform code. The initialized FIFO memory slices may not overlap, so the most easy way would be to configure them all at once at init time for all PSC devices. This is now done by this patch. Signed-off-by: Anatolij Gustschin --- arch/powerpc/platforms/512x/mpc512x_shared.c | 78 ++ drivers/serial/mpc52xx_uart.c| 69 --- 2 files changed, 78 insertions(+), 69 deletions(-) diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index 796080c..a717466 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "mpc512x.h" @@ -369,9 +370,86 @@ void __init mpc512x_declare_of_platform_devices(void) } } +#define DEFAULT_FIFO_SIZE 16 + +static unsigned int __init get_fifo_size(struct device_node *np, +char *prop_name) +{ + const unsigned int *fp; + + fp = of_get_property(np, prop_name, NULL); + if (fp) + return *fp; + + pr_warning("no %s property in %s node, defaulting to %d\n", + prop_name, np->full_name, DEFAULT_FIFO_SIZE); + + return DEFAULT_FIFO_SIZE; +} + +#define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \ + ((u32)(_base) + sizeof(struct mpc52xx_psc))) + +/* Init PSC FIFO space for TX and RX slices */ +void __init mpc512x_psc_fifo_init(void) +{ + struct device_node *np; + void __iomem *psc; + unsigned int tx_fifo_size; + unsigned int rx_fifo_size; + int fifobase = 0; /* current fifo address in 32 bit words */ + + for_each_compatible_node(np, NULL, "fsl,mpc5121-psc") { + tx_fifo_size = get_fifo_size(np, "fsl,tx-fifo-size"); + rx_fifo_size = get_fifo_size(np, "fsl,rx-fifo-size"); + + /* size in register is in 4 byte units */ + tx_fifo_size /= 4; + rx_fifo_size /= 4; + if (!tx_fifo_size) + tx_fifo_size = 1; + if (!rx_fifo_size) + rx_fifo_size = 1; + + psc = of_iomap(np, 0); + if (!psc) { + pr_err("%s: Can't map %s device\n", + __func__, np->full_name); + continue; + } + + /* FIFO space is 4KiB, check if requested size is available */ + if ((fifobase + tx_fifo_size + rx_fifo_size) > 0x1000) { + pr_err("%s: no fifo space available for %s\n", + __func__, np->full_name); + iounmap(psc); + /* +* chances are that another device requests less +* fifo space, so we continue. +*/ + continue; + } + + /* set tx and rx fifo size registers */ + out_be32(&FIFOC(psc)->txsz, (fifobase << 16) | tx_fifo_size); + fifobase += tx_fifo_size; + out_be32(&FIFOC(psc)->rxsz, (fifobase << 16) | rx_fifo_size); + fifobase += rx_fifo_size; + + /* reset and enable the slices */ + out_be32(&FIFOC(psc)->txcmd, 0x80); + out_be32(&FIFOC(psc)->txcmd, 0x01); + out_be32(&FIFOC(psc)->rxcmd, 0x80); + out_be32(&FIFOC(psc)->rxcmd, 0x01); + + iounmap(psc); + } +} + void __init mpc512x_init(void) { mpc512x_declare_of_platform_devices(); mpc5121_clk_init(); mpc512x_restart_init(); + mpc512x_psc_fifo_init(); } diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 3119fdd..843e7fb 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -430,34 +430,10 @@ static unsigned long mpc512x_getuartclk(void *p) return mpc5xxx_get_bus_frequency(p); } -#define DEFAULT_FIFO_SIZE 16 - -static unsigned int __init get_fifo_size(struct device_node *np, -char *fifo_name) -{ - const unsigned int *fp; - - fp = of_get_property(np, fifo_name, NULL); - if (fp) - return *fp; - - pr_warning("no %s property in %s node, defaulting to %d\n", - fifo_name, np->full_name, DEFAULT_FIFO_SIZE); - - return DEFAULT_FIFO_SIZE; -} - -#define FIFOC(_base) ((struct mpc512x_psc_fifo __iomem *) \ - ((u32)(_base) + sizeof(struct mpc52xx_psc))) - /* Init
[spi-devel-general] [PATCH 0/2] Add SPI driver for MPC5121 PSC SPI
Anatolij Gustschin (2): powerpc/mpc5121: move PSC FIFO memory init to platform code spi: Add SPI master driver for MPC5121 PSC arch/powerpc/include/asm/mpc52xx_psc.h |1 + arch/powerpc/platforms/512x/mpc512x_shared.c | 78 drivers/serial/mpc52xx_uart.c| 69 --- drivers/spi/Kconfig |7 + drivers/spi/Makefile |1 + drivers/spi/mpc512x_psc_spi.c| 576 ++ 6 files changed, 663 insertions(+), 69 deletions(-) create mode 100644 drivers/spi/mpc512x_psc_spi.c -- ___ spi-devel-general mailing list spi-devel-general@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/spi-devel-general