[PATCH] libertas: add abilty to set DMA buffers alignmnet for SPI interface in compile time
Dan Williams
dcbw at redhat.com
Tue Feb 3 10:47:08 EST 2009
On Tue, 2009-02-03 at 09:04 +0200, Mike Rapoport wrote:
> Different SPI controllers pose different alignment requirements on DMAable
> buffers. It's possible to alter the SPI controller driver to use it's own
> properly aligned buffers for DMA and copy the data it gets from the client
> into these buffers. However, this approach also impacts overall performance.
> Adding ability to set DMA buffers alignment for SPI interface in compile
> time prevents unnecessary memcpy calls.
I'd still rather that alignment constraints were handled in the
*controller* code, where the constraint actually is. If this path is
followed, then every SPI-connected device for a platform would have to
have specific hacks for every platform, which is quite unmaintainable.
Is there a good way to fit the alignment constraints into the SPI
controller code?
Dan
> Signed-off-by: Mike Rapoport <mike at compulab.co.il>
> ---
> drivers/net/wireless/Kconfig | 10 ++++++++++
> drivers/net/wireless/libertas/if_spi.c | 27 ++++++++++++++++-----------
> 2 files changed, 26 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
> index fe819a7..3bbb7b2 100644
> --- a/drivers/net/wireless/Kconfig
> +++ b/drivers/net/wireless/Kconfig
> @@ -157,6 +157,16 @@ config LIBERTAS_SPI
> ---help---
> A driver for Marvell Libertas 8686 SPI devices.
>
> +config LIBERTAS_SPI_DMA_ALIGN
> + int "DMA buffers alignment for SPI interface"
> + depends on LIBERTAS_SPI
> + default 4 if !ARCH_PXA
> + default 8 if ARCH_PXA
> + ---help---
> + Different SPI controllers pose different alignment
> + requirements on DMAable buffers. Allow proper setting of
> + this value in compile-time.
> +
> config LIBERTAS_DEBUG
> bool "Enable full debugging output in the Libertas module."
> depends on LIBERTAS
> diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
> index 07311e7..3499948 100644
> --- a/drivers/net/wireless/libertas/if_spi.c
> +++ b/drivers/net/wireless/libertas/if_spi.c
> @@ -33,10 +33,12 @@
> #include "dev.h"
> #include "if_spi.h"
>
> +#define DMA_ALIGN CONFIG_LIBERTAS_SPI_DMA_ALIGN
> +
> struct if_spi_packet {
> - struct list_head list;
> - u16 blen;
> - u8 buffer[0] __attribute__((aligned(4)));
> + struct list_head list;
> + u16 blen;
> + u8 buffer[0] __attribute__((aligned(DMA_ALIGN)));
> };
>
> struct if_spi_card {
> @@ -73,7 +75,7 @@ struct if_spi_card {
> struct semaphore spi_ready;
> struct semaphore spi_thread_terminated;
>
> - u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE];
> + u8 cmd_buffer[IF_SPI_CMD_BUF_SIZE] __attribute__((aligned(DMA_ALIGN)));
>
> /* A buffer of incoming packets from libertas core.
> * Since we can't sleep in hw_host_to_card, we have to buffer
> @@ -665,10 +667,13 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
> BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE);
> BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE);
>
> - /* It's just annoying if the buffer size isn't a multiple of 4, because
> - * then we might have len < IF_SPI_CMD_BUF_SIZE but
> - * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */
> - BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0);
> + /*
> + * It's just annoying if the buffer size isn't a multiple of
> + * DMA_ALIGN, because then we might have
> + * len < IF_SPI_CMD_BUF_SIZE but
> + * ALIGN(len, DMA_ALIGN) > IF_SPI_CMD_BUF_SIZE
> + */
> + BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % DMA_ALIGN != 0);
>
> lbs_deb_enter(LBS_DEB_SPI);
>
> @@ -691,7 +696,7 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
>
> /* Read the data from the WLAN module into our command buffer */
> err = spu_read(card, IF_SPI_CMD_RDWRPORT_REG,
> - card->cmd_buffer, ALIGN(len, 4));
> + card->cmd_buffer, ALIGN(len, DMA_ALIGN));
> if (err)
> goto out;
>
> @@ -747,7 +752,7 @@ static int if_spi_c2h_data(struct if_spi_card *card)
> data = skb_put(skb, len);
>
> /* Read the data from the WLAN module into our skb... */
> - err = spu_read(card, IF_SPI_DATA_RDWRPORT_REG, data, ALIGN(len, 4));
> + err = spu_read(card, IF_SPI_DATA_RDWRPORT_REG, data, ALIGN(len, DMA_ALIGN));
> if (err)
> goto free_skb;
>
> @@ -940,7 +945,7 @@ static int if_spi_host_to_card(struct lbs_private *priv,
> err = -EINVAL;
> goto out;
> }
> - blen = ALIGN(nb, 4);
> + blen = ALIGN(nb, DMA_ALIGN);
> packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC);
> if (!packet) {
> err = -ENOMEM;
> --
> 1.5.6.4
>
>
> --
> Sincerely yours,
> Mike.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the libertas-dev
mailing list