From: Roland Stigge <stigge-uj/7R2tJ6VmzQB+pC5nmwQ@public.gmane.org>
To: linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
aletes.xgr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org,
grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org,
rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org,
rob-VoJi6FS/r0vR7s880joybQ@public.gmane.org,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
gabriel.fernandez-0IS4wlFg1OjSUeElwK9/Pw@public.gmane.org,
lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
sachin.verma-lpHj6iFQ3dU@public.gmane.org
Cc: Roland Stigge <stigge-uj/7R2tJ6VmzQB+pC5nmwQ@public.gmane.org>
Subject: [PATCH v6 1/3] spi/pl022: Add chip select handling via GPIO
Date: Wed, 22 Aug 2012 15:49:17 +0200 [thread overview]
Message-ID: <1345643359-16584-1-git-send-email-stigge@antcom.de> (raw)
This patch adds the ability for the driver to control the chip select directly.
This enables independence from cs_control callbacks. Configurable via
platform_data, to be extended as DT in the following patch.
Based on the initial patch by Alexandre Pereira da Silva <aletes.xgr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Roland Stigge <stigge-uj/7R2tJ6VmzQB+pC5nmwQ@public.gmane.org>
Acked-by: Alexandre Pereira da Silva <aletes.xgr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
Applies to v3.6-rc2
Patch set changes since v5:
* struct pl022: renamed "chipselect" -> "chipselects"
* Fixed dev_warn() message
* Improved pointer construction for chipselect data
* Added DT documentation for "num-cs" property (patch 3/3)
Patch set changes since v4:
* Rename DT property: "pl022,num-chipselects" -> "num-cs"
* Removed reference to Linux code in DT binding documentation
* Removed property "pl022,hierarchy" - only support SPI master for now
* Documented DT property pl022,interface
* Removed property "pl022,slave-tx-disable" - not relevant in master mode
* Added kerneldoc for cur_cs and chipselect list
* Reorganized struct pl022 (int *chipselects)
* Introduced int *chipselects to struct pl022_ssp_controller
* Let platform data override DT data
* Split patches into CS handling vs. DT support
Changes since v3:
* Proper use of IS_ENABLED
Changes since v2:
* Use IS_ENABLED instead of #ifdef
* Remove bogus const change
Changes since v1:
* return EPROBE_DEFFER if gpios are not initialized yet
Thanks Thierry Reding, Rob Herring and Linus Walleij for reviewing!
drivers/spi/spi-pl022.c | 48 +++++++++++++++++++++++++++++++--------------
include/linux/amba/pl022.h | 2 +
2 files changed, 36 insertions(+), 14 deletions(-)
--- linux-2.6.orig/drivers/spi/spi-pl022.c
+++ linux-2.6/drivers/spi/spi-pl022.c
@@ -40,6 +40,7 @@
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
/*
* This macro is used to define some register default values.
@@ -356,6 +357,8 @@ struct vendor_data {
* @sgt_rx: scattertable for the RX transfer
* @sgt_tx: scattertable for the TX transfer
* @dummypage: a dummy page used for driving data on the bus with DMA
+ * @cur_cs: current chip select (gpio)
+ * @chipselects: list of chipselects (gpios)
*/
struct pl022 {
struct amba_device *adev;
@@ -389,6 +392,8 @@ struct pl022 {
char *dummypage;
bool dma_running;
#endif
+ int cur_cs;
+ int *chipselects;
};
/**
@@ -433,6 +438,14 @@ static void null_cs_control(u32 command)
pr_debug("pl022: dummy chip select control, CS=0x%x\n", command);
}
+static void pl022_cs_control(struct pl022 *pl022, u32 command)
+{
+ if (gpio_is_valid(pl022->cur_cs))
+ gpio_set_value(pl022->cur_cs, command);
+ else
+ pl022->cur_chip->cs_control(command);
+}
+
/**
* giveback - current spi_message is over, schedule next message and call
* callback of this message. Assumes that caller already
@@ -479,7 +492,7 @@ static void giveback(struct pl022 *pl022
if (next_msg && next_msg->spi != pl022->cur_msg->spi)
next_msg = NULL;
if (!next_msg || pl022->cur_msg->state == STATE_ERROR)
- pl022->cur_chip->cs_control(SSP_CHIP_DESELECT);
+ pl022_cs_control(pl022, SSP_CHIP_DESELECT);
else
pl022->next_msg_cs_active = true;
@@ -818,8 +831,7 @@ static void dma_callback(void *data)
/* Update total bytes transferred */
msg->actual_length += pl022->cur_transfer->len;
if (pl022->cur_transfer->cs_change)
- pl022->cur_chip->
- cs_control(SSP_CHIP_DESELECT);
+ pl022_cs_control(pl022, SSP_CHIP_DESELECT);
/* Move to next transfer */
msg->state = next_transfer(pl022);
@@ -1252,8 +1264,7 @@ static irqreturn_t pl022_interrupt_handl
/* Update total bytes transferred */
msg->actual_length += pl022->cur_transfer->len;
if (pl022->cur_transfer->cs_change)
- pl022->cur_chip->
- cs_control(SSP_CHIP_DESELECT);
+ pl022_cs_control(pl022, SSP_CHIP_DESELECT);
/* Move to next transfer */
msg->state = next_transfer(pl022);
tasklet_schedule(&pl022->pump_transfers);
@@ -1338,7 +1349,7 @@ static void pump_transfers(unsigned long
/* Reselect chip select only if cs_change was requested */
if (previous->cs_change)
- pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
+ pl022_cs_control(pl022, SSP_CHIP_SELECT);
} else {
/* STATE_START */
message->state = STATE_RUNNING;
@@ -1377,7 +1388,7 @@ static void do_interrupt_dma_transfer(st
/* Enable target chip, if not already active */
if (!pl022->next_msg_cs_active)
- pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
+ pl022_cs_control(pl022, SSP_CHIP_SELECT);
if (set_up_next_transfer(pl022, pl022->cur_transfer)) {
/* Error path */
@@ -1429,12 +1440,12 @@ static void do_polling_transfer(struct p
if (previous->delay_usecs)
udelay(previous->delay_usecs);
if (previous->cs_change)
- pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
+ pl022_cs_control(pl022, SSP_CHIP_SELECT);
} else {
/* STATE_START */
message->state = STATE_RUNNING;
if (!pl022->next_msg_cs_active)
- pl022->cur_chip->cs_control(SSP_CHIP_SELECT);
+ pl022_cs_control(pl022, SSP_CHIP_SELECT);
}
/* Configuration Changing Per Transfer */
@@ -1466,7 +1477,7 @@ static void do_polling_transfer(struct p
/* Update total byte transferred */
message->actual_length += pl022->cur_transfer->len;
if (pl022->cur_transfer->cs_change)
- pl022->cur_chip->cs_control(SSP_CHIP_DESELECT);
+ pl022_cs_control(pl022, SSP_CHIP_DESELECT);
/* Move to next transfer */
message->state = next_transfer(pl022);
}
@@ -1495,6 +1506,7 @@ static int pl022_transfer_one_message(st
/* Setup the SPI using the per chip configuration */
pl022->cur_chip = spi_get_ctldata(msg->spi);
+ pl022->cur_cs = pl022->chipselects[msg->spi->chip_select];
restore_state(pl022);
flush(pl022);
@@ -1840,8 +1852,9 @@ static int pl022_setup(struct spi_device
chip->xfer_type = chip_info->com_mode;
if (!chip_info->cs_control) {
chip->cs_control = null_cs_control;
- dev_warn(&spi->dev,
- "chip select function is NULL for this chip\n");
+ if (!gpio_is_valid(pl022->chipselects[spi->chip_select]))
+ dev_warn(&spi->dev,
+ "invalid chip select\n");
} else
chip->cs_control = chip_info->cs_control;
@@ -1993,7 +2006,7 @@ pl022_probe(struct amba_device *adev, co
struct pl022_ssp_controller *platform_info = adev->dev.platform_data;
struct spi_master *master;
struct pl022 *pl022 = NULL; /*Data for this driver */
- int status = 0;
+ int status = 0, i;
dev_info(&adev->dev,
"ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
@@ -2004,7 +2017,8 @@ pl022_probe(struct amba_device *adev, co
}
/* Allocate master with space for data */
- master = spi_alloc_master(dev, sizeof(struct pl022));
+ master = spi_alloc_master(dev, sizeof(struct pl022) + sizeof(int) *
+ platform_info->num_chipselect);
if (master == NULL) {
dev_err(&adev->dev, "probe - cannot alloc SPI master\n");
status = -ENOMEM;
@@ -2016,6 +2030,8 @@ pl022_probe(struct amba_device *adev, co
pl022->master_info = platform_info;
pl022->adev = adev;
pl022->vendor = id->data;
+ /* Point chipselects to allocated memory beyond the main struct */
+ pl022->chipselects = (int *) pl022 + sizeof(struct pl022);
/*
* Bus Number Which has been Assigned to this SSP controller
@@ -2030,6 +2046,10 @@ pl022_probe(struct amba_device *adev, co
master->unprepare_transfer_hardware = pl022_unprepare_transfer_hardware;
master->rt = platform_info->rt;
+ if (platform_info->num_chipselect && platform_info->chipselects)
+ for (i = 0; i < platform_info->num_chipselect; i++)
+ pl022->chipselects[i] = platform_info->chipselects[i];
+
/*
* Supports mode 0-3, loopback, and active low CS. Transfers are
* always MS bit first on the original pl022.
--- linux-2.6.orig/include/linux/amba/pl022.h
+++ linux-2.6/include/linux/amba/pl022.h
@@ -244,6 +244,7 @@ struct dma_chan;
* indicates no delay and the device will be suspended immediately.
* @rt: indicates the controller should run the message pump with realtime
* priority to minimise the transfer latency on the bus.
+ * @chipselects: list of <num_chipselects> chip select gpios
*/
struct pl022_ssp_controller {
u16 bus_id;
@@ -254,6 +255,7 @@ struct pl022_ssp_controller {
void *dma_tx_param;
int autosuspend_delay;
bool rt;
+ int *chipselects;
};
/**
next reply other threads:[~2012-08-22 13:49 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-22 13:49 Roland Stigge [this message]
[not found] ` <1345643359-16584-1-git-send-email-stigge-uj/7R2tJ6VmzQB+pC5nmwQ@public.gmane.org>
2012-08-22 13:49 ` [PATCH v6 2/3] spi/pl022: Add devicetree support Roland Stigge
[not found] ` <1345643359-16584-2-git-send-email-stigge-uj/7R2tJ6VmzQB+pC5nmwQ@public.gmane.org>
2012-08-22 18:38 ` Linus Walleij
2012-08-22 13:49 ` [PATCH v6 3/3] DT bindings documentation: "num-cs" property for SPI controllers Roland Stigge
[not found] ` <1345643359-16584-3-git-send-email-stigge-uj/7R2tJ6VmzQB+pC5nmwQ@public.gmane.org>
2012-08-22 18:39 ` Linus Walleij
2012-08-22 19:03 ` Mark Brown
2012-09-01 11:14 ` [PATCH v6 1/3] spi/pl022: Add chip select handling via GPIO shiraz hashim
[not found] ` <CAPub14-Oot_wJsRTv2AGu3SAAf40+3_wK43=0Swxj+5XjPaDew-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-09-02 7:18 ` Linus Walleij
[not found] ` <CACRpkdY3atmx4N-Zq2imrgPoukueYiexzndD7bVyQTgV02Vpuw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-09-02 13:12 ` shiraz hashim
[not found] ` <CAPub14891Bhdt=KNz8SZLS6Ps2snhy9LgOU=yGGMrntcK9xxRA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-09-03 9:10 ` Linus Walleij
2012-09-02 20:04 ` Roland Stigge
2012-08-22 18:37 ` Linus Walleij
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1345643359-16584-1-git-send-email-stigge@antcom.de \
--to=stigge-uj/7r2tj6vmzqb+pc5nmwq@public.gmane.org \
--cc=aletes.xgr-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=broonie-yzvPICuk2AATkU/dhu1WVueM+bqZidxxQQ4Iyu8u01E@public.gmane.org \
--cc=devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org \
--cc=gabriel.fernandez-0IS4wlFg1OjSUeElwK9/Pw@public.gmane.org \
--cc=grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org \
--cc=lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
--cc=linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=rob-VoJi6FS/r0vR7s880joybQ@public.gmane.org \
--cc=rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org \
--cc=sachin.verma-lpHj6iFQ3dU@public.gmane.org \
--cc=spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=viresh.kumar-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).