[PATCH 00/09] Blackfin SPI driver updates for 2.6.24 - Kernel

This is a discussion on [PATCH 00/09] Blackfin SPI driver updates for 2.6.24 - Kernel ; - add BF54x support - add multi SPI ports support - fixup some bugs - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read ...

+ Reply to Thread
Results 1 to 11 of 11

Thread: [PATCH 00/09] Blackfin SPI driver updates for 2.6.24

  1. [PATCH 00/09] Blackfin SPI driver updates for 2.6.24


    - add BF54x support
    - add multi SPI ports support
    - fixup some bugs
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. [PATCH 7/9] Blackfin SPI driver: Move GPIO config to setup and cleanup

    From: Sonic Zhang

    Signed-off-by: Sonic Zhang
    Signed-off-by: Bryan Wu
    ---
    drivers/spi/spi_bfin5xx.c | 52 +++++++++++++++++++++++---------------------
    1 files changed, 27 insertions(+), 25 deletions(-)

    diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
    index ecfb7c5..c1516cb 100644
    --- a/drivers/spi/spi_bfin5xx.c
    +++ b/drivers/spi/spi_bfin5xx.c
    @@ -136,7 +136,6 @@ struct chip_data {
    u16 flag;

    u8 chip_select_num;
    - u8 chip_select_requested;
    u8 n_bytes;
    u8 width; /* 0 or 1 */
    u8 enable_dma;
    @@ -216,19 +215,7 @@ static int restore_state(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;
    int ret = 0;
    - u16 ssel[3][MAX_SPI_SSEL] = {
    - {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
    - P_SPI0_SSEL4, P_SPI0_SSEL5,
    - P_SPI0_SSEL6, P_SPI0_SSEL7},
    -
    - {P_SPI1_SSEL1, P_SPI1_SSEL2, P_SPI1_SSEL3,
    - P_SPI1_SSEL4, P_SPI1_SSEL5,
    - P_SPI1_SSEL6, P_SPI1_SSEL7},
    -
    - {P_SPI2_SSEL1, P_SPI2_SSEL2, P_SPI2_SSEL3,
    - P_SPI2_SSEL4, P_SPI2_SSEL5,
    - P_SPI2_SSEL6, P_SPI2_SSEL7},
    - };
    +
    /* Clear status and disable clock */
    write_STAT(BIT_STAT_CLR);
    bfin_spi_disable(drv_data);
    @@ -239,17 +226,6 @@ static int restore_state(struct driver_data *drv_data)
    write_BAUD(chip->baud);
    cs_active(chip);

    - if (!chip->chip_select_requested) {
    - int i = chip->chip_select_num;
    -
    - dev_dbg(&drv_data->pdev->dev, "chip select number is %d\n", i);
    - if ((i > 0) && (i <= MAX_SPI_SSEL))
    - ret = peripheral_request(
    - ssel[drv_data->master->bus_num][i-1], DRV_NAME);
    -
    - chip->chip_select_requested = 1;
    - }
    -
    if (ret)
    dev_dbg(&drv_data->pdev->dev,
    ": request chip select number %d failed\n",
    @@ -981,6 +957,22 @@ static int transfer(struct spi_device *spi, struct spi_message *msg)
    return 0;
    }

    +#define MAX_SPI_SSEL 7
    +
    +static u16 ssel[3][MAX_SPI_SSEL] = {
    + {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
    + P_SPI0_SSEL4, P_SPI0_SSEL5,
    + P_SPI0_SSEL6, P_SPI0_SSEL7},
    +
    + {P_SPI1_SSEL1, P_SPI1_SSEL2, P_SPI1_SSEL3,
    + P_SPI1_SSEL4, P_SPI1_SSEL5,
    + P_SPI1_SSEL6, P_SPI1_SSEL7},
    +
    + {P_SPI2_SSEL1, P_SPI2_SSEL2, P_SPI2_SSEL3,
    + P_SPI2_SSEL4, P_SPI2_SSEL5,
    + P_SPI2_SSEL6, P_SPI2_SSEL7},
    +};
    +
    /* first setup for new devices */
    static int setup(struct spi_device *spi)
    {
    @@ -1109,6 +1101,12 @@ static int setup(struct spi_device *spi)

    spi_set_ctldata(spi, chip);

    + dev_dbg(&spi->dev, "chip select number is %d\n", chip->chip_select_num);
    + if ((chip->chip_select_num > 0)
    + && (chip->chip_select_num <= spi->master->num_chipselect))
    + peripheral_request(ssel[spi->master->bus_num]
    + [chip->chip_select_num-1], DRV_NAME);
    +
    return 0;
    }

    @@ -1120,6 +1118,10 @@ static void cleanup(struct spi_device *spi)
    {
    struct chip_data *chip = spi_get_ctldata(spi);

    + if ((chip->chip_select_num > 0)
    + && (chip->chip_select_num <= spi->master->num_chipselect))
    + peripheral_free(ssel[spi->master->bus_num][chip->chip_select_num-1]);
    +
    kfree(chip);
    }

    --
    1.5.3.4
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. [PATCH 4/9] Blackfin SPI driver: prevent people from setting bits in ctl_reg

    From: Mike Frysinger

    Prevent people from setting bits in ctl_reg that the SPI
    framework already handles, hopefully we can one day drop
    ctl_reg completely

    Signed-off-by: Mike Frysinger
    Signed-off-by: Bryan Wu
    ---
    drivers/spi/spi_bfin5xx.c | 10 ++++++++++
    1 files changed, 10 insertions(+), 0 deletions(-)

    diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
    index 7093065..1a83656 100644
    --- a/drivers/spi/spi_bfin5xx.c
    +++ b/drivers/spi/spi_bfin5xx.c
    @@ -996,6 +996,16 @@ static int setup(struct spi_device *spi)

    /* chip_info isn't always needed */
    if (chip_info) {
    + /* Make sure people stop trying to set fields via ctl_reg when they
    + * should actually be using common SPI framework. Currently we let
    + * through: WOM EMISO PSSE GM SZ TIMOD. Not sure if a user actually
    + * needs/uses any of these, but let's assume (for now) they do.
    + */
    + if (chip_info->ctl_reg & (SPE | MSTR | CPOL | CPHA | LSBF | SIZE)) {
    + dev_err(&spi->dev, "do not set bits in ctl_reg that the SPI framework provides\n");
    + return -EINVAL;
    + }
    +
    chip->enable_dma = chip_info->enable_dma != 0
    && drv_data->master_info->enable_dma;
    chip->ctl_reg = chip_info->ctl_reg;
    --
    1.5.3.4
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. [PATCH 1/9] Blackfin SPI driver: use new GPIO API and add error handling

    From: Michael Hennerich

    Signed-off-by: Michael Hennerich
    Signed-off-by: Bryan Wu
    ---
    drivers/spi/spi_bfin5xx.c | 29 +++++++++++++++++++++++------
    include/asm-blackfin/mach-bf533/portmux.h | 2 +-
    2 files changed, 24 insertions(+), 7 deletions(-)

    diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
    index 2992ada..8041b89 100644
    --- a/drivers/spi/spi_bfin5xx.c
    +++ b/drivers/spi/spi_bfin5xx.c
    @@ -1165,6 +1165,22 @@ static inline int destroy_queue(struct driver_data *drv_data)
    return 0;
    }

    +static int setup_pin_mux(int action)
    +{
    +
    + u16 pin_req[] = {P_SPI0_SCK, P_SPI0_MISO, P_SPI0_MOSI, 0};
    +
    + if (action) {
    + if (peripheral_request_list(pin_req, DRV_NAME)) {
    + return -EFAULT;
    + }
    + } else {
    + peripheral_free_list(pin_req);
    + }
    +
    + return 0;
    +}
    +
    static int __init bfin5xx_spi_probe(struct platform_device *pdev)
    {
    struct device *dev = &pdev->dev;
    @@ -1182,12 +1198,9 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
    return -ENOMEM;
    }

    - if (peripheral_request(P_SPI0_SCK, DRV_NAME) ||
    - peripheral_request(P_SPI0_MISO, DRV_NAME) ||
    - peripheral_request(P_SPI0_MOSI, DRV_NAME) ) {
    -
    + if (setup_pin_mux(1)) {
    dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
    - goto out_error_queue_alloc;
    + goto out_error;
    }

    drv_data = spi_master_get_devdata(master);
    @@ -1223,9 +1236,11 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
    dev_dbg(&pdev->dev, "controller probe successfully\n");
    return status;

    - out_error_queue_alloc:
    +out_error_queue_alloc:
    destroy_queue(drv_data);
    +out_error:
    spi_master_put(master);
    +
    return status;
    }

    @@ -1255,6 +1270,8 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)
    /* Disconnect from the SPI framework */
    spi_unregister_master(drv_data->master);

    + setup_pin_mux(0);
    +
    /* Prevent double remove */
    platform_set_drvdata(pdev, NULL);

    diff --git a/include/asm-blackfin/mach-bf533/portmux.h b/include/asm-blackfin/mach-bf533/portmux.h
    index b88d7a0..137f488 100644
    --- a/include/asm-blackfin/mach-bf533/portmux.h
    +++ b/include/asm-blackfin/mach-bf533/portmux.h
    @@ -42,7 +42,7 @@
    #define P_SPORT0_DRPRI (P_DONTCARE)

    #define P_SPI0_MOSI (P_DONTCARE)
    -#define P_SPI0_MIS0 (P_DONTCARE)
    +#define P_SPI0_MISO (P_DONTCARE)
    #define P_SPI0_SCK (P_DONTCARE)
    #define P_SPI0_SSEL7 (P_DEFINED | P_IDENT(GPIO_PF7))
    #define P_SPI0_SSEL6 (P_DEFINED | P_IDENT(GPIO_PF6))
    --
    1.5.3.4
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. [PATCH 3/9] Blackfin SPI driver: Blackfin SPI driver does not respect the per-transfer cs_change field

    Add cs_active/cs_deactive functions and try to catch the cs_change flag.

    Signed-off-by: Bryan Wu
    ---
    drivers/spi/spi_bfin5xx.c | 76 ++++++++++++++++++++++++++++++++-------------
    1 files changed, 54 insertions(+), 22 deletions(-)

    diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
    index 2f46283..7093065 100644
    --- a/drivers/spi/spi_bfin5xx.c
    +++ b/drivers/spi/spi_bfin5xx.c
    @@ -115,6 +115,7 @@ struct driver_data {
    size_t rx_map_len;
    size_t tx_map_len;
    u8 n_bytes;
    + int cs_change;
    void (*write) (struct driver_data *);
    void (*read) (struct driver_data *);
    void (*duplex) (struct driver_data *);
    @@ -179,6 +180,26 @@ static int flush(struct driver_data *drv_data)
    return limit;
    }

    +/* Chip select operation functions for cs_change flag */
    +static void cs_active(struct chip_data *chip)
    +{
    + u16 flag = read_FLAG();
    +
    + flag |= chip->flag;
    + flag &= ~(chip->flag << 8);
    +
    + write_FLAG(flag);
    +}
    +
    +static void cs_deactive(struct chip_data *chip)
    +{
    + u16 flag = read_FLAG();
    +
    + flag |= (chip->flag << 8);
    +
    + write_FLAG(flag);
    +}
    +
    #define MAX_SPI0_SSEL 7

    /* stop controller and re-config current chip*/
    @@ -198,7 +219,7 @@ static int restore_state(struct driver_data *drv_data)
    /* Load the registers */
    write_CTRL(chip->ctl_reg);
    write_BAUD(chip->baud);
    - write_FLAG(chip->flag);
    + cs_active(chip);

    if (!chip->chip_select_requested) {
    int i = chip->chip_select_num;
    @@ -273,20 +294,20 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
    struct chip_data *chip = drv_data->cur_chip;

    while (drv_data->tx < drv_data->tx_end) {
    - write_FLAG(chip->flag);
    + cs_active(chip);

    write_TDBR(*(u8 *) (drv_data->tx));
    while (read_STAT() & BIT_STAT_TXS)
    continue;
    while (!(read_STAT() & BIT_STAT_SPIF))
    continue;
    - write_FLAG(0xFF00 | chip->flag);
    + cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    ++drv_data->tx;
    }
    - write_FLAG(0xFF00);
    + cs_deactive(chip);

    }

    @@ -318,7 +339,7 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
    struct chip_data *chip = drv_data->cur_chip;

    while (drv_data->rx < drv_data->rx_end) {
    - write_FLAG(chip->flag);
    + cs_active(chip);

    read_RDBR(); /* kick off */
    while (!(read_STAT() & BIT_STAT_RXS))
    @@ -326,13 +347,13 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
    while (!(read_STAT() & BIT_STAT_SPIF))
    continue;
    *(u8 *) (drv_data->rx) = read_SHAW();
    - write_FLAG(0xFF00 | chip->flag);
    + cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    ++drv_data->rx;
    }
    - write_FLAG(0xFF00);
    + cs_deactive(chip);

    }

    @@ -356,7 +377,7 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
    struct chip_data *chip = drv_data->cur_chip;

    while (drv_data->rx < drv_data->rx_end) {
    - write_FLAG(chip->flag);
    + cs_active(chip);


    write_TDBR(*(u8 *) (drv_data->tx));
    @@ -365,15 +386,14 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
    while (!(read_STAT() & BIT_STAT_RXS))
    continue;
    *(u8 *) (drv_data->rx) = read_RDBR();
    - write_FLAG(0xFF00 | chip->flag);
    + cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    ++drv_data->rx;
    ++drv_data->tx;
    }
    - write_FLAG(0xFF00);
    -
    + cs_deactive(chip);
    }

    static void u16_writer(struct driver_data *drv_data)
    @@ -398,20 +418,20 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
    struct chip_data *chip = drv_data->cur_chip;

    while (drv_data->tx < drv_data->tx_end) {
    - write_FLAG(chip->flag);
    + cs_active(chip);

    write_TDBR(*(u16 *) (drv_data->tx));
    while ((read_STAT() & BIT_STAT_TXS))
    continue;
    while (!(read_STAT() & BIT_STAT_SPIF))
    continue;
    - write_FLAG(0xFF00 | chip->flag);
    + cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    drv_data->tx += 2;
    }
    - write_FLAG(0xFF00);
    + cs_deactive(chip);
    }

    static void u16_reader(struct driver_data *drv_data)
    @@ -438,7 +458,7 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
    struct chip_data *chip = drv_data->cur_chip;

    while (drv_data->rx < drv_data->rx_end) {
    - write_FLAG(chip->flag);
    + cs_active(chip);

    read_RDBR(); /* kick off */
    while (!(read_STAT() & BIT_STAT_RXS))
    @@ -446,13 +466,13 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
    while (!(read_STAT() & BIT_STAT_SPIF))
    continue;
    *(u16 *) (drv_data->rx) = read_SHAW();
    - write_FLAG(0xFF00 | chip->flag);
    + cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    drv_data->rx += 2;
    }
    - write_FLAG(0xFF00);
    + cs_deactive(chip);
    }

    static void u16_duplex(struct driver_data *drv_data)
    @@ -475,7 +495,7 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
    struct chip_data *chip = drv_data->cur_chip;

    while (drv_data->tx < drv_data->tx_end) {
    - write_FLAG(chip->flag);
    + cs_active(chip);

    write_TDBR(*(u16 *) (drv_data->tx));
    while (!(read_STAT() & BIT_STAT_SPIF))
    @@ -483,14 +503,14 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
    while (!(read_STAT() & BIT_STAT_RXS))
    continue;
    *(u16 *) (drv_data->rx) = read_RDBR();
    - write_FLAG(0xFF00 | chip->flag);
    + cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    drv_data->rx += 2;
    drv_data->tx += 2;
    }
    - write_FLAG(0xFF00);
    + cs_deactive(chip);
    }

    /* test if ther is more transfer to be done */
    @@ -515,6 +535,7 @@ static void *next_transfer(struct driver_data *drv_data)
    */
    static void giveback(struct driver_data *drv_data)
    {
    + struct chip_data *chip = drv_data->cur_chip;
    struct spi_transfer *last_transfer;
    unsigned long flags;
    struct spi_message *msg;
    @@ -534,10 +555,13 @@ static void giveback(struct driver_data *drv_data)

    /* disable chip select signal. And not stop spi in autobuffer mode */
    if (drv_data->tx_dma != 0xFFFF) {
    - write_FLAG(0xFF00);
    + cs_deactive(chip);
    bfin_spi_disable(drv_data);
    }

    + if (!drv_data->cs_change)
    + cs_deactive(chip);
    +
    if (msg->complete)
    msg->complete(msg->context);
    }
    @@ -546,6 +570,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
    {
    struct driver_data *drv_data = (struct driver_data *)dev_id;
    struct spi_message *msg = drv_data->cur_msg;
    + struct chip_data *chip = drv_data->cur_chip;

    dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n");
    clear_dma_irqstat(CH_SPI);
    @@ -573,6 +598,9 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)

    msg->actual_length += drv_data->len_in_bytes;

    + if (drv_data->cs_change)
    + cs_deactive(chip);
    +
    /* Move to next transfer */
    msg->state = next_transfer(drv_data);

    @@ -659,6 +687,7 @@ static void pump_transfers(unsigned long data)
    drv_data->rx_dma = transfer->rx_dma;
    drv_data->tx_dma = transfer->tx_dma;
    drv_data->len_in_bytes = transfer->len;
    + drv_data->cs_change = transfer->cs_change;

    width = chip->width;
    if (width == CFG_SPI_WORDSIZE16) {
    @@ -683,7 +712,7 @@ static void pump_transfers(unsigned long data)
    } else {
    write_BAUD(chip->baud);
    }
    - write_FLAG(chip->flag);
    + cs_active(chip);

    dev_dbg(&drv_data->pdev->dev,
    "now pumping a transfer: width is %d, len is %d\n",
    @@ -834,6 +863,9 @@ static void pump_transfers(unsigned long data)
    /* Update total byte transfered */
    message->actual_length += drv_data->len;

    + if (drv_data->cs_change)
    + cs_deactive(chip);
    +
    /* Move to next transfer of this msg */
    message->state = next_transfer(drv_data);
    }
    --
    1.5.3.4
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  6. [PATCH 9/9] Blackfin SPI driver: Clean up useless wait in bfin SPI driver

    From: Sonic Zhang

    Signed-off-by: Sonic Zhang
    Signed-off-by: Bryan Wu
    ---
    drivers/spi/spi_bfin5xx.c | 84 ++++++++++++++++++++++++++++-----------------
    1 files changed, 52 insertions(+), 32 deletions(-)

    diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
    index 0cdfc2b..bfeaa7c 100644
    --- a/drivers/spi/spi_bfin5xx.c
    +++ b/drivers/spi/spi_bfin5xx.c
    @@ -276,22 +276,26 @@ static void u8_writer(struct driver_data *drv_data)
    dev_dbg(&drv_data->pdev->dev,
    "cr8-s is 0x%x\n", read_STAT());

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    while (drv_data->tx < drv_data->tx_end) {
    write_TDBR(*(u8 *) (drv_data->tx));
    while (read_STAT() & BIT_STAT_TXS)
    continue;
    ++drv_data->tx;
    }
    -
    - /* poll for SPI completion before returning */
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    }

    static void u8_cs_chg_writer(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    while (drv_data->tx < drv_data->tx_end) {
    cs_active(chip);

    @@ -304,10 +308,6 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
    udelay(chip->cs_chg_udelay);
    ++drv_data->tx;
    }
    -
    - /* poll for SPI completion before returning */
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    }

    static void u8_reader(struct driver_data *drv_data)
    @@ -315,6 +315,10 @@ static void u8_reader(struct driver_data *drv_data)
    dev_dbg(&drv_data->pdev->dev,
    "cr-8 is 0x%x\n", read_STAT());

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    /* clear TDBR buffer before read(else it will be shifted out) */
    write_TDBR(0xFFFF);

    @@ -337,6 +341,10 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    /* clear TDBR buffer before read(else it will be shifted out) */
    write_TDBR(0xFFFF);

    @@ -365,6 +373,10 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)

    static void u8_duplex(struct driver_data *drv_data)
    {
    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    /* in duplex mode, clk is triggered by writing of TDBR */
    while (drv_data->rx < drv_data->rx_end) {
    write_TDBR(*(u8 *) (drv_data->tx));
    @@ -376,16 +388,16 @@ static void u8_duplex(struct driver_data *drv_data)
    ++drv_data->rx;
    ++drv_data->tx;
    }
    -
    - /* poll for SPI completion before returning */
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    }

    static void u8_cs_chg_duplex(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    while (drv_data->rx < drv_data->rx_end) {
    cs_active(chip);

    @@ -402,10 +414,6 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
    ++drv_data->rx;
    ++drv_data->tx;
    }
    -
    - /* poll for SPI completion before returning */
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    }

    static void u16_writer(struct driver_data *drv_data)
    @@ -413,22 +421,26 @@ static void u16_writer(struct driver_data *drv_data)
    dev_dbg(&drv_data->pdev->dev,
    "cr16 is 0x%x\n", read_STAT());

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    while (drv_data->tx < drv_data->tx_end) {
    write_TDBR(*(u16 *) (drv_data->tx));
    while ((read_STAT() & BIT_STAT_TXS))
    continue;
    drv_data->tx += 2;
    }
    -
    - /* poll for SPI completion before returning */
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    }

    static void u16_cs_chg_writer(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    while (drv_data->tx < drv_data->tx_end) {
    cs_active(chip);

    @@ -441,10 +453,6 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
    udelay(chip->cs_chg_udelay);
    drv_data->tx += 2;
    }
    -
    - /* poll for SPI completion before returning */
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    }

    static void u16_reader(struct driver_data *drv_data)
    @@ -452,6 +460,10 @@ static void u16_reader(struct driver_data *drv_data)
    dev_dbg(&drv_data->pdev->dev,
    "cr-16 is 0x%x\n", read_STAT());

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    /* clear TDBR buffer before read(else it will be shifted out) */
    write_TDBR(0xFFFF);

    @@ -474,6 +486,10 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    /* clear TDBR buffer before read(else it will be shifted out) */
    write_TDBR(0xFFFF);

    @@ -502,6 +518,10 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)

    static void u16_duplex(struct driver_data *drv_data)
    {
    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    /* in duplex mode, clk is triggered by writing of TDBR */
    while (drv_data->tx < drv_data->tx_end) {
    write_TDBR(*(u16 *) (drv_data->tx));
    @@ -513,16 +533,16 @@ static void u16_duplex(struct driver_data *drv_data)
    drv_data->rx += 2;
    drv_data->tx += 2;
    }
    -
    - /* poll for SPI completion before returning */
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    }

    static void u16_cs_chg_duplex(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    while (drv_data->tx < drv_data->tx_end) {
    cs_active(chip);

    @@ -539,10 +559,6 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
    drv_data->rx += 2;
    drv_data->tx += 2;
    }
    -
    - /* poll for SPI completion before returning */
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    }

    /* test if ther is more transfer to be done */
    @@ -765,6 +781,10 @@ static void pump_transfers(unsigned long data)
    dma_width = WDSIZE_8;
    }

    + /* poll for SPI completion before start */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    +
    /* dirty hack for autobuffer DMA mode */
    if (drv_data->tx_dma == 0xFFFF) {
    dev_dbg(&drv_data->pdev->dev,
    --
    1.5.3.4
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  7. [PATCH 5/9] Blackfin SPI driver: update spi driver to support multi-ports

    update spi driver to support multi-ports by add platform_resource,
    tested on STAMP537+SPI_MMC, other boards need more testing

    Signed-off-by: Bryan Wu
    ---
    drivers/spi/spi_bfin5xx.c | 124 ++++++++++++++++++++++++++++++---------------
    1 files changed, 83 insertions(+), 41 deletions(-)

    diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
    index 1a83656..891d263 100644
    --- a/drivers/spi/spi_bfin5xx.c
    +++ b/drivers/spi/spi_bfin5xx.c
    @@ -13,6 +13,8 @@
    * March 10, 2006 bfin5xx_spi.c Created. (Luke Yang)
    * August 7, 2006 added full duplex mode (Axel Weiss & Luke Yang)
    * July 17, 2007 add support for BF54x SPI0 controller (Bryan Wu)
    + * July 30, 2007 add platfrom_resource interface to support multi-port
    + * SPI controller (Bryan Wu)
    *
    * Copyright 2004-2007 Analog Devices Inc.
    *
    @@ -50,18 +52,25 @@
    #include
    #include

    -MODULE_AUTHOR("Bryan Wu, Luke Yang");
    -MODULE_DESCRIPTION("Blackfin BF5xx SPI Contoller Driver");
    +#define DRV_NAME "bfin-spi"
    +#define DRV_AUTHOR "Bryan Wu, Luke Yang"
    +#define DRV_DESC "Blackfin BF5xx on-chip SPI Contoller Driver"
    +#define DRV_VERSION "1.0"
    +
    +MODULE_AUTHOR(DRV_AUTHOR);
    +MODULE_DESCRIPTION(DRV_DESC);
    MODULE_LICENSE("GPL");

    -#define DRV_NAME "bfin-spi-master"
    #define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)

    +static u32 spi_dma_ch;
    +static u32 spi_regs_base;
    +
    #define DEFINE_SPI_REG(reg, off) \
    static inline u16 read_##reg(void) \
    - { return bfin_read16(SPI0_REGBASE + off); } \
    + { return bfin_read16(spi_regs_base + off); } \
    static inline void write_##reg(u16 v) \
    - {bfin_write16(SPI0_REGBASE + off, v); }
    + {bfin_write16(spi_regs_base + off, v); }

    DEFINE_SPI_REG(CTRL, 0x00)
    DEFINE_SPI_REG(FLAG, 0x04)
    @@ -573,10 +582,10 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
    struct chip_data *chip = drv_data->cur_chip;

    dev_dbg(&drv_data->pdev->dev, "in dma_irq_handler\n");
    - clear_dma_irqstat(CH_SPI);
    + clear_dma_irqstat(spi_dma_ch);

    /* Wait for DMA to complete */
    - while (get_dma_curr_irqstat(CH_SPI) & DMA_RUN)
    + while (get_dma_curr_irqstat(spi_dma_ch) & DMA_RUN)
    continue;

    /*
    @@ -586,12 +595,12 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
    * register until it goes low for 2 successive reads
    */
    if (drv_data->tx != NULL) {
    - while ((bfin_read_SPI_STAT() & TXS) ||
    - (bfin_read_SPI_STAT() & TXS))
    + while ((read_STAT() & TXS) ||
    + (read_STAT() & TXS))
    continue;
    }

    - while (!(bfin_read_SPI_STAT() & SPIF))
    + while (!(read_STAT() & SPIF))
    continue;

    bfin_spi_disable(drv_data);
    @@ -610,8 +619,8 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
    /* free the irq handler before next transfer */
    dev_dbg(&drv_data->pdev->dev,
    "disable dma channel irq%d\n",
    - CH_SPI);
    - dma_disable_irq(CH_SPI);
    + spi_dma_ch);
    + dma_disable_irq(spi_dma_ch);

    return IRQ_HANDLED;
    }
    @@ -726,19 +735,19 @@ static void pump_transfers(unsigned long data)
    if (drv_data->cur_chip->enable_dma && drv_data->len > 6) {

    write_STAT(BIT_STAT_CLR);
    - disable_dma(CH_SPI);
    - clear_dma_irqstat(CH_SPI);
    + disable_dma(spi_dma_ch);
    + clear_dma_irqstat(spi_dma_ch);
    bfin_spi_disable(drv_data);

    /* config dma channel */
    dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n");
    if (width == CFG_SPI_WORDSIZE16) {
    - set_dma_x_count(CH_SPI, drv_data->len);
    - set_dma_x_modify(CH_SPI, 2);
    + set_dma_x_count(spi_dma_ch, drv_data->len);
    + set_dma_x_modify(spi_dma_ch, 2);
    dma_width = WDSIZE_16;
    } else {
    - set_dma_x_count(CH_SPI, drv_data->len);
    - set_dma_x_modify(CH_SPI, 1);
    + set_dma_x_count(spi_dma_ch, drv_data->len);
    + set_dma_x_modify(spi_dma_ch, 1);
    dma_width = WDSIZE_8;
    }

    @@ -753,9 +762,10 @@ static void pump_transfers(unsigned long data)
    /* no irq in autobuffer mode */
    dma_config =
    (DMAFLOW_AUTO | RESTART | dma_width | DI_EN);
    - set_dma_config(CH_SPI, dma_config);
    - set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx);
    - enable_dma(CH_SPI);
    + set_dma_config(spi_dma_ch, dma_config);
    + set_dma_start_addr(spi_dma_ch,
    + (unsigned long)drv_data->tx);
    + enable_dma(spi_dma_ch);
    write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
    (CFG_SPI_ENABLE << 14));

    @@ -776,14 +786,15 @@ static void pump_transfers(unsigned long data)
    /* clear tx reg soformer data is not shifted out */
    write_TDBR(0xFF);

    - set_dma_x_count(CH_SPI, drv_data->len);
    + set_dma_x_count(spi_dma_ch, drv_data->len);

    /* start dma */
    - dma_enable_irq(CH_SPI);
    + dma_enable_irq(spi_dma_ch);
    dma_config = (WNR | RESTART | dma_width | DI_EN);
    - set_dma_config(CH_SPI, dma_config);
    - set_dma_start_addr(CH_SPI, (unsigned long)drv_data->rx);
    - enable_dma(CH_SPI);
    + set_dma_config(spi_dma_ch, dma_config);
    + set_dma_start_addr(spi_dma_ch,
    + (unsigned long)drv_data->rx);
    + enable_dma(spi_dma_ch);

    cr |=
    CFG_SPI_DMAREAD | (width << 8) | (CFG_SPI_ENABLE <<
    @@ -794,11 +805,12 @@ static void pump_transfers(unsigned long data)
    dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");

    /* start dma */
    - dma_enable_irq(CH_SPI);
    + dma_enable_irq(spi_dma_ch);
    dma_config = (RESTART | dma_width | DI_EN);
    - set_dma_config(CH_SPI, dma_config);
    - set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx);
    - enable_dma(CH_SPI);
    + set_dma_config(spi_dma_ch, dma_config);
    + set_dma_start_addr(spi_dma_ch,
    + (unsigned long)drv_data->tx);
    + enable_dma(spi_dma_ch);

    write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
    (CFG_SPI_ENABLE << 14));
    @@ -1030,17 +1042,17 @@ static int setup(struct spi_device *spi)
    */
    if (chip->enable_dma && !dma_requested) {
    /* register dma irq handler */
    - if (request_dma(CH_SPI, "BF53x_SPI_DMA") < 0) {
    + if (request_dma(spi_dma_ch, "BF53x_SPI_DMA") < 0) {
    dev_dbg(&spi->dev,
    "Unable to request BlackFin SPI DMA channel\n");
    return -ENODEV;
    }
    - if (set_dma_callback(CH_SPI, (void *)dma_irq_handler, drv_data)
    - < 0) {
    + if (set_dma_callback(spi_dma_ch, (void *)dma_irq_handler,
    + drv_data) < 0) {
    dev_dbg(&spi->dev, "Unable to set dma callback\n");
    return -EPERM;
    }
    - dma_disable_irq(CH_SPI);
    + dma_disable_irq(spi_dma_ch);
    dma_requested = 1;
    }

    @@ -1212,6 +1224,7 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
    struct bfin5xx_spi_master *platform_info;
    struct spi_master *master;
    struct driver_data *drv_data = 0;
    + struct resource *res;
    int status = 0;

    platform_info = dev->platform_data;
    @@ -1239,15 +1252,38 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
    master->setup = setup;
    master->transfer = transfer;

    + /* Find and map our resources */
    + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    + if (res == NULL) {
    + dev_err(dev, "Cannot get IORESOURCE_MEM\n");
    + status = -ENOENT;
    + goto out_error_get_res;
    + }
    +
    + spi_regs_base = (u32) ioremap(res->start, (res->end - res->start)+1);
    + if (!spi_regs_base) {
    + dev_err(dev, "Cannot map IO\n");
    + status = -ENXIO;
    + goto out_error_ioremap;
    + }
    +
    + spi_dma_ch = platform_get_irq(pdev, 0);
    + if (spi_dma_ch < 0) {
    + dev_err(dev, "No DMA channel specified\n");
    + status = -ENOENT;
    + goto out_error_no_dma_ch;
    + }
    +
    /* Initial and start queue */
    status = init_queue(drv_data);
    if (status != 0) {
    - dev_err(&pdev->dev, "problem initializing queue\n");
    + dev_err(dev, "problem initializing queue\n");
    goto out_error_queue_alloc;
    }
    +
    status = start_queue(drv_data);
    if (status != 0) {
    - dev_err(&pdev->dev, "problem starting queue\n");
    + dev_err(dev, "problem starting queue\n");
    goto out_error_queue_alloc;
    }

    @@ -1255,14 +1291,20 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
    platform_set_drvdata(pdev, drv_data);
    status = spi_register_master(master);
    if (status != 0) {
    - dev_err(&pdev->dev, "problem registering spi master\n");
    + dev_err(dev, "problem registering spi master\n");
    goto out_error_queue_alloc;
    }
    - dev_dbg(&pdev->dev, "controller probe successfully\n");
    +
    + dev_info(dev, "%s, Version %s, regs_base @ 0x%08x\n",
    + DRV_DESC, DRV_VERSION, spi_regs_base);
    return status;

    out_error_queue_alloc:
    destroy_queue(drv_data);
    +out_error_no_dma_ch:
    + iounmap((void *) spi_regs_base);
    +out_error_ioremap:
    +out_error_get_res:
    out_error:
    spi_master_put(master);

    @@ -1288,8 +1330,8 @@ static int __devexit bfin5xx_spi_remove(struct platform_device *pdev)

    /* Release DMA */
    if (drv_data->master_info->enable_dma) {
    - if (dma_channel_active(CH_SPI))
    - free_dma(CH_SPI);
    + if (dma_channel_active(spi_dma_ch))
    + free_dma(spi_dma_ch);
    }

    /* Disconnect from the SPI framework */
    @@ -1344,7 +1386,7 @@ static int bfin5xx_spi_resume(struct platform_device *pdev)
    MODULE_ALIAS("bfin-spi-master"); /* for platform bus hotplug */
    static struct platform_driver bfin5xx_spi_driver = {
    .driver = {
    - .name = "bfin-spi-master",
    + .name = DRV_NAME,
    .owner = THIS_MODULE,
    },
    .suspend = bfin5xx_spi_suspend,
    --
    1.5.3.4
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  8. [PATCH 2/9] Blackfin SPI driver: add error handing

    - add error handling in SPI bus driver with selecting clients
    - use proper defines to access Blackfin MMRs
    - remove useless SSYNCs

    Signed-off-by: Michael Hennerich
    Signed-off-by: Bryan Wu
    ---
    drivers/spi/spi_bfin5xx.c | 107 +++++++++++++++++++--------------------------
    1 files changed, 45 insertions(+), 62 deletions(-)

    diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
    index 8041b89..2f46283 100644
    --- a/drivers/spi/spi_bfin5xx.c
    +++ b/drivers/spi/spi_bfin5xx.c
    @@ -59,10 +59,9 @@ MODULE_LICENSE("GPL");

    #define DEFINE_SPI_REG(reg, off) \
    static inline u16 read_##reg(void) \
    - { return *(volatile unsigned short*)(SPI0_REGBASE + off); } \
    + { return bfin_read16(SPI0_REGBASE + off); } \
    static inline void write_##reg(u16 v) \
    - {*(volatile unsigned short*)(SPI0_REGBASE + off) = v;\
    - SSYNC();}
    + {bfin_write16(SPI0_REGBASE + off, v); }

    DEFINE_SPI_REG(CTRL, 0x00)
    DEFINE_SPI_REG(FLAG, 0x04)
    @@ -145,7 +144,6 @@ static void bfin_spi_enable(struct driver_data *drv_data)

    cr = read_CTRL();
    write_CTRL(cr | BIT_CTL_ENABLE);
    - SSYNC();
    }

    static void bfin_spi_disable(struct driver_data *drv_data)
    @@ -154,7 +152,6 @@ static void bfin_spi_disable(struct driver_data *drv_data)

    cr = read_CTRL();
    write_CTRL(cr & (~BIT_CTL_ENABLE));
    - SSYNC();
    }

    /* Caculate the SPI_BAUD register value based on input HZ */
    @@ -182,52 +179,44 @@ static int flush(struct driver_data *drv_data)
    return limit;
    }

    +#define MAX_SPI0_SSEL 7
    +
    /* stop controller and re-config current chip*/
    -static void restore_state(struct driver_data *drv_data)
    +static int restore_state(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;
    + int ret = 0;
    + u16 ssel[MAX_SPI0_SSEL] = {P_SPI0_SSEL1, P_SPI0_SSEL2, P_SPI0_SSEL3,
    + P_SPI0_SSEL4, P_SPI0_SSEL5,
    + P_SPI0_SSEL6, P_SPI0_SSEL7,};

    /* Clear status and disable clock */
    write_STAT(BIT_STAT_CLR);
    bfin_spi_disable(drv_data);
    dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n");

    + /* Load the registers */
    + write_CTRL(chip->ctl_reg);
    + write_BAUD(chip->baud);
    + write_FLAG(chip->flag);
    +
    if (!chip->chip_select_requested) {
    + int i = chip->chip_select_num;

    - dev_dbg(&drv_data->pdev->dev,
    - "chip select number is %d\n", chip->chip_select_num);
    -
    - switch (chip->chip_select_num) {
    - case 1:
    - peripheral_request(P_SPI0_SSEL1, DRV_NAME);
    - break;
    - case 2:
    - peripheral_request(P_SPI0_SSEL2, DRV_NAME);
    - break;
    - case 3:
    - peripheral_request(P_SPI0_SSEL3, DRV_NAME);
    - break;
    - case 4:
    - peripheral_request(P_SPI0_SSEL4, DRV_NAME);
    - break;
    - case 5:
    - peripheral_request(P_SPI0_SSEL5, DRV_NAME);
    - break;
    - case 6:
    - peripheral_request(P_SPI0_SSEL6, DRV_NAME);
    - break;
    - case 7:
    - peripheral_request(P_SPI0_SSEL7, DRV_NAME);
    - break;
    - }
    + dev_dbg(&drv_data->pdev->dev, "chip select number is %d\n", i);
    +
    + if ((i > 0) && (i <= MAX_SPI0_SSEL))
    + ret = peripheral_request(ssel[i-1], DRV_NAME);

    chip->chip_select_requested = 1;
    }

    - /* Load the registers */
    - write_CTRL(chip->ctl_reg);
    - write_BAUD(chip->baud);
    - write_FLAG(chip->flag);
    + if (ret)
    + dev_dbg(&drv_data->pdev->dev,
    + ": request chip select number %d failed\n",
    + chip->chip_select_num);
    +
    + return ret;
    }

    /* used to kick off transfer in rx mode */
    @@ -285,7 +274,6 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)

    while (drv_data->tx < drv_data->tx_end) {
    write_FLAG(chip->flag);
    - SSYNC();

    write_TDBR(*(u8 *) (drv_data->tx));
    while (read_STAT() & BIT_STAT_TXS)
    @@ -293,13 +281,13 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
    while (!(read_STAT() & BIT_STAT_SPIF))
    continue;
    write_FLAG(0xFF00 | chip->flag);
    - SSYNC();
    +
    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    ++drv_data->tx;
    }
    write_FLAG(0xFF00);
    - SSYNC();
    +
    }

    static void u8_reader(struct driver_data *drv_data)
    @@ -331,7 +319,6 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)

    while (drv_data->rx < drv_data->rx_end) {
    write_FLAG(chip->flag);
    - SSYNC();

    read_RDBR(); /* kick off */
    while (!(read_STAT() & BIT_STAT_RXS))
    @@ -340,13 +327,13 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
    continue;
    *(u8 *) (drv_data->rx) = read_SHAW();
    write_FLAG(0xFF00 | chip->flag);
    - SSYNC();
    +
    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    ++drv_data->rx;
    }
    write_FLAG(0xFF00);
    - SSYNC();
    +
    }

    static void u8_duplex(struct driver_data *drv_data)
    @@ -370,7 +357,7 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)

    while (drv_data->rx < drv_data->rx_end) {
    write_FLAG(chip->flag);
    - SSYNC();
    +

    write_TDBR(*(u8 *) (drv_data->tx));
    while (!(read_STAT() & BIT_STAT_SPIF))
    @@ -379,14 +366,14 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
    continue;
    *(u8 *) (drv_data->rx) = read_RDBR();
    write_FLAG(0xFF00 | chip->flag);
    - SSYNC();
    +
    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    ++drv_data->rx;
    ++drv_data->tx;
    }
    write_FLAG(0xFF00);
    - SSYNC();
    +
    }

    static void u16_writer(struct driver_data *drv_data)
    @@ -412,7 +399,6 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)

    while (drv_data->tx < drv_data->tx_end) {
    write_FLAG(chip->flag);
    - SSYNC();

    write_TDBR(*(u16 *) (drv_data->tx));
    while ((read_STAT() & BIT_STAT_TXS))
    @@ -420,13 +406,12 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
    while (!(read_STAT() & BIT_STAT_SPIF))
    continue;
    write_FLAG(0xFF00 | chip->flag);
    - SSYNC();
    +
    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    drv_data->tx += 2;
    }
    write_FLAG(0xFF00);
    - SSYNC();
    }

    static void u16_reader(struct driver_data *drv_data)
    @@ -454,7 +439,6 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)

    while (drv_data->rx < drv_data->rx_end) {
    write_FLAG(chip->flag);
    - SSYNC();

    read_RDBR(); /* kick off */
    while (!(read_STAT() & BIT_STAT_RXS))
    @@ -463,13 +447,12 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
    continue;
    *(u16 *) (drv_data->rx) = read_SHAW();
    write_FLAG(0xFF00 | chip->flag);
    - SSYNC();
    +
    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    drv_data->rx += 2;
    }
    write_FLAG(0xFF00);
    - SSYNC();
    }

    static void u16_duplex(struct driver_data *drv_data)
    @@ -493,7 +476,6 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)

    while (drv_data->tx < drv_data->tx_end) {
    write_FLAG(chip->flag);
    - SSYNC();

    write_TDBR(*(u16 *) (drv_data->tx));
    while (!(read_STAT() & BIT_STAT_SPIF))
    @@ -502,14 +484,13 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
    continue;
    *(u16 *) (drv_data->rx) = read_RDBR();
    write_FLAG(0xFF00 | chip->flag);
    - SSYNC();
    +
    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    drv_data->rx += 2;
    drv_data->tx += 2;
    }
    write_FLAG(0xFF00);
    - SSYNC();
    }

    /* test if ther is more transfer to be done */
    @@ -811,7 +792,6 @@ static void pump_transfers(unsigned long data)
    "IO duplex: cr is 0x%x\n", cr);

    write_CTRL(cr);
    - SSYNC();

    drv_data->duplex(drv_data);

    @@ -826,7 +806,6 @@ static void pump_transfers(unsigned long data)
    "IO write: cr is 0x%x\n", cr);

    write_CTRL(cr);
    - SSYNC();

    drv_data->write(drv_data);

    @@ -841,7 +820,6 @@ static void pump_transfers(unsigned long data)
    "IO read: cr is 0x%x\n", cr);

    write_CTRL(cr);
    - SSYNC();

    drv_data->read(drv_data);
    if (drv_data->rx != drv_data->rx_end)
    @@ -890,6 +868,14 @@ static void pump_messages(struct work_struct *work)
    /* Extract head of queue */
    drv_data->cur_msg = list_entry(drv_data->queue.next,
    struct spi_message, queue);
    +
    + /* Setup the SSP using the per chip configuration */
    + drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
    + if (restore_state(drv_data)) {
    + spin_unlock_irqrestore(&drv_data->lock, flags);
    + return;
    + };
    +
    list_del_init(&drv_data->cur_msg->queue);

    /* Initial message state */
    @@ -897,13 +883,10 @@ static void pump_messages(struct work_struct *work)
    drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
    struct spi_transfer, transfer_list);

    - /* Setup the SSP using the per chip configuration */
    - drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
    - restore_state(drv_data);
    dev_dbg(&drv_data->pdev->dev,
    "got a message to pump, state is set to: baud %d, flag 0x%x, ctl 0x%x\n",
    - drv_data->cur_chip->baud, drv_data->cur_chip->flag,
    - drv_data->cur_chip->ctl_reg);
    + drv_data->cur_chip->baud, drv_data->cur_chip->flag,
    + drv_data->cur_chip->ctl_reg);

    dev_dbg(&drv_data->pdev->dev,
    "the first transfer len is %d\n",
    --
    1.5.3.4
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  9. [PATCH 8/9] Blackfin SPI driver: Fix SPI driver to work with SPI flash ST25P16 on bf548

    From: Sonic Zhang

    Current SPI driver enables SPI controller and set the SPI baud register
    for each SPI transfer. But, they should never be changed within a SPI
    message session, in which seveal SPI transfers are pumped. This patch
    move move SPI setting to the begining of a message session. And never
    disables SPI controller until an error occurs.

    Signed-off-by: Sonic Zhang
    Signed-off-by: Bryan Wu
    ---
    drivers/spi/spi_bfin5xx.c | 162 ++++++++++++++++++++++++---------------------
    1 files changed, 87 insertions(+), 75 deletions(-)

    diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
    index c1516cb..0cdfc2b 100644
    --- a/drivers/spi/spi_bfin5xx.c
    +++ b/drivers/spi/spi_bfin5xx.c
    @@ -222,9 +222,13 @@ static int restore_state(struct driver_data *drv_data)
    dev_dbg(&drv_data->pdev->dev, "restoring spi ctl state\n");

    /* Load the registers */
    - write_CTRL(chip->ctl_reg);
    + cs_deactive(chip);
    write_BAUD(chip->baud);
    - cs_active(chip);
    + chip->ctl_reg &= (~BIT_CTL_TIMOD);
    + chip->ctl_reg |= (chip->width << 8);
    + write_CTRL(chip->ctl_reg);
    +
    + bfin_spi_enable(drv_data);

    if (ret)
    dev_dbg(&drv_data->pdev->dev,
    @@ -271,6 +275,7 @@ static void u8_writer(struct driver_data *drv_data)
    {
    dev_dbg(&drv_data->pdev->dev,
    "cr8-s is 0x%x\n", read_STAT());
    +
    while (drv_data->tx < drv_data->tx_end) {
    write_TDBR(*(u8 *) (drv_data->tx));
    while (read_STAT() & BIT_STAT_TXS)
    @@ -293,16 +298,16 @@ static void u8_cs_chg_writer(struct driver_data *drv_data)
    write_TDBR(*(u8 *) (drv_data->tx));
    while (read_STAT() & BIT_STAT_TXS)
    continue;
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    ++drv_data->tx;
    }
    - cs_deactive(chip);

    + /* poll for SPI completion before returning */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    }

    static void u8_reader(struct driver_data *drv_data)
    @@ -314,6 +319,7 @@ static void u8_reader(struct driver_data *drv_data)
    write_TDBR(0xFFFF);

    dummy_read();
    +
    while (drv_data->rx < drv_data->rx_end - 1) {
    while (!(read_STAT() & BIT_STAT_RXS))
    continue;
    @@ -331,23 +337,30 @@ static void u8_cs_chg_reader(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;

    - while (drv_data->rx < drv_data->rx_end) {
    - cs_active(chip);
    + /* clear TDBR buffer before read(else it will be shifted out) */
    + write_TDBR(0xFFFF);

    - read_RDBR(); /* kick off */
    - while (!(read_STAT() & BIT_STAT_RXS))
    - continue;
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    - *(u8 *) (drv_data->rx) = read_SHAW();
    + cs_active(chip);
    + dummy_read();
    +
    + while (drv_data->rx < drv_data->rx_end - 1) {
    cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    +
    + while (!(read_STAT() & BIT_STAT_RXS))
    + continue;
    + cs_active(chip);
    + *(u8 *) (drv_data->rx) = read_RDBR();
    ++drv_data->rx;
    }
    cs_deactive(chip);

    + while (!(read_STAT() & BIT_STAT_RXS))
    + continue;
    + *(u8 *) (drv_data->rx) = read_SHAW();
    + ++drv_data->rx;
    }

    static void u8_duplex(struct driver_data *drv_data)
    @@ -355,7 +368,7 @@ static void u8_duplex(struct driver_data *drv_data)
    /* in duplex mode, clk is triggered by writing of TDBR */
    while (drv_data->rx < drv_data->rx_end) {
    write_TDBR(*(u8 *) (drv_data->tx));
    - while (!(read_STAT() & BIT_STAT_SPIF))
    + while (read_STAT() & BIT_STAT_TXS)
    continue;
    while (!(read_STAT() & BIT_STAT_RXS))
    continue;
    @@ -363,6 +376,10 @@ static void u8_duplex(struct driver_data *drv_data)
    ++drv_data->rx;
    ++drv_data->tx;
    }
    +
    + /* poll for SPI completion before returning */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    }

    static void u8_cs_chg_duplex(struct driver_data *drv_data)
    @@ -372,9 +389,8 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
    while (drv_data->rx < drv_data->rx_end) {
    cs_active(chip);

    -
    write_TDBR(*(u8 *) (drv_data->tx));
    - while (!(read_STAT() & BIT_STAT_SPIF))
    + while (read_STAT() & BIT_STAT_TXS)
    continue;
    while (!(read_STAT() & BIT_STAT_RXS))
    continue;
    @@ -386,7 +402,10 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data)
    ++drv_data->rx;
    ++drv_data->tx;
    }
    - cs_deactive(chip);
    +
    + /* poll for SPI completion before returning */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    }

    static void u16_writer(struct driver_data *drv_data)
    @@ -416,21 +435,26 @@ static void u16_cs_chg_writer(struct driver_data *drv_data)
    write_TDBR(*(u16 *) (drv_data->tx));
    while ((read_STAT() & BIT_STAT_TXS))
    continue;
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    drv_data->tx += 2;
    }
    - cs_deactive(chip);
    +
    + /* poll for SPI completion before returning */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    }

    static void u16_reader(struct driver_data *drv_data)
    {
    dev_dbg(&drv_data->pdev->dev,
    "cr-16 is 0x%x\n", read_STAT());
    +
    + /* clear TDBR buffer before read(else it will be shifted out) */
    + write_TDBR(0xFFFF);
    +
    dummy_read();

    while (drv_data->rx < (drv_data->rx_end - 2)) {
    @@ -450,22 +474,30 @@ static void u16_cs_chg_reader(struct driver_data *drv_data)
    {
    struct chip_data *chip = drv_data->cur_chip;

    - while (drv_data->rx < drv_data->rx_end) {
    - cs_active(chip);
    + /* clear TDBR buffer before read(else it will be shifted out) */
    + write_TDBR(0xFFFF);

    - read_RDBR(); /* kick off */
    - while (!(read_STAT() & BIT_STAT_RXS))
    - continue;
    - while (!(read_STAT() & BIT_STAT_SPIF))
    - continue;
    - *(u16 *) (drv_data->rx) = read_SHAW();
    + cs_active(chip);
    + dummy_read();
    +
    + while (drv_data->rx < drv_data->rx_end) {
    cs_deactive(chip);

    if (chip->cs_chg_udelay)
    udelay(chip->cs_chg_udelay);
    +
    + while (!(read_STAT() & BIT_STAT_RXS))
    + continue;
    + cs_active(chip);
    + *(u16 *) (drv_data->rx) = read_RDBR();
    drv_data->rx += 2;
    }
    cs_deactive(chip);
    +
    + while (!(read_STAT() & BIT_STAT_RXS))
    + continue;
    + *(u16 *) (drv_data->rx) = read_SHAW();
    + drv_data->rx += 2;
    }

    static void u16_duplex(struct driver_data *drv_data)
    @@ -473,7 +505,7 @@ static void u16_duplex(struct driver_data *drv_data)
    /* in duplex mode, clk is triggered by writing of TDBR */
    while (drv_data->tx < drv_data->tx_end) {
    write_TDBR(*(u16 *) (drv_data->tx));
    - while (!(read_STAT() & BIT_STAT_SPIF))
    + while (read_STAT() & BIT_STAT_TXS)
    continue;
    while (!(read_STAT() & BIT_STAT_RXS))
    continue;
    @@ -481,6 +513,10 @@ static void u16_duplex(struct driver_data *drv_data)
    drv_data->rx += 2;
    drv_data->tx += 2;
    }
    +
    + /* poll for SPI completion before returning */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    }

    static void u16_cs_chg_duplex(struct driver_data *drv_data)
    @@ -491,7 +527,7 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
    cs_active(chip);

    write_TDBR(*(u16 *) (drv_data->tx));
    - while (!(read_STAT() & BIT_STAT_SPIF))
    + while (read_STAT() & BIT_STAT_TXS)
    continue;
    while (!(read_STAT() & BIT_STAT_RXS))
    continue;
    @@ -503,7 +539,10 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data)
    drv_data->rx += 2;
    drv_data->tx += 2;
    }
    - cs_deactive(chip);
    +
    + /* poll for SPI completion before returning */
    + while (!(read_STAT() & BIT_STAT_SPIF))
    + continue;
    }

    /* test if ther is more transfer to be done */
    @@ -587,8 +626,6 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
    while (!(read_STAT() & SPIF))
    continue;

    - bfin_spi_disable(drv_data);
    -
    msg->actual_length += drv_data->len_in_bytes;

    if (drv_data->cs_change)
    @@ -698,12 +735,8 @@ static void pump_transfers(unsigned long data)
    message->state = RUNNING_STATE;
    dma_config = 0;

    - /* restore spi status for each spi transfer */
    - if (transfer->speed_hz) {
    - write_BAUD(hz_to_spi_baud(transfer->speed_hz));
    - } else {
    - write_BAUD(chip->baud);
    - }
    + write_STAT(BIT_STAT_CLR);
    + cr = (read_CTRL() & (~BIT_CTL_TIMOD));
    cs_active(chip);

    dev_dbg(&drv_data->pdev->dev,
    @@ -717,10 +750,8 @@ static void pump_transfers(unsigned long data)
    */
    if (drv_data->cur_chip->enable_dma && drv_data->len > 6) {

    - write_STAT(BIT_STAT_CLR);
    disable_dma(spi_dma_ch);
    clear_dma_irqstat(spi_dma_ch);
    - bfin_spi_disable(drv_data);

    /* config dma channel */
    dev_dbg(&drv_data->pdev->dev, "doing dma transfer\n");
    @@ -734,14 +765,14 @@ static void pump_transfers(unsigned long data)
    dma_width = WDSIZE_8;
    }

    - /* set transfer width,direction. And enable spi */
    - cr = (read_CTRL() & (~BIT_CTL_TIMOD));
    -
    /* dirty hack for autobuffer DMA mode */
    if (drv_data->tx_dma == 0xFFFF) {
    dev_dbg(&drv_data->pdev->dev,
    "doing autobuffer DMA out.\n");

    + /* set SPI transfer mode */
    + write_CTRL(cr | CFG_SPI_DMAWRITE);
    +
    /* no irq in autobuffer mode */
    dma_config =
    (DMAFLOW_AUTO | RESTART | dma_width | DI_EN);
    @@ -749,8 +780,6 @@ static void pump_transfers(unsigned long data)
    set_dma_start_addr(spi_dma_ch,
    (unsigned long)drv_data->tx);
    enable_dma(spi_dma_ch);
    - write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
    - (CFG_SPI_ENABLE << 14));

    /* just return here, there can only be one transfer in this mode */
    message->status = 0;
    @@ -763,11 +792,11 @@ static void pump_transfers(unsigned long data)
    /* set transfer mode, and enable SPI */
    dev_dbg(&drv_data->pdev->dev, "doing DMA in.\n");

    - /* disable SPI before write to TDBR */
    - write_CTRL(cr & ~BIT_CTL_ENABLE);
    + /* set SPI transfer mode */
    + write_CTRL(cr | CFG_SPI_DMAREAD);

    /* clear tx reg soformer data is not shifted out */
    - write_TDBR(0xFF);
    + write_TDBR(0xFFFF);

    set_dma_x_count(spi_dma_ch, drv_data->len);

    @@ -779,14 +808,12 @@ static void pump_transfers(unsigned long data)
    (unsigned long)drv_data->rx);
    enable_dma(spi_dma_ch);

    - cr |=
    - CFG_SPI_DMAREAD | (width << 8) | (CFG_SPI_ENABLE <<
    - 14);
    - /* set transfer mode, and enable SPI */
    - write_CTRL(cr);
    } else if (drv_data->tx != NULL) {
    dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");

    + /* set SPI transfer mode */
    + write_CTRL(cr | CFG_SPI_DMAWRITE);
    +
    /* start dma */
    dma_enable_irq(spi_dma_ch);
    dma_config = (RESTART | dma_width | DI_EN);
    @@ -794,28 +821,20 @@ static void pump_transfers(unsigned long data)
    set_dma_start_addr(spi_dma_ch,
    (unsigned long)drv_data->tx);
    enable_dma(spi_dma_ch);
    -
    - write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) |
    - (CFG_SPI_ENABLE << 14));
    -
    }
    } else {
    /* IO mode write then read */
    dev_dbg(&drv_data->pdev->dev, "doing IO transfer\n");

    - write_STAT(BIT_STAT_CLR);
    -
    if (drv_data->tx != NULL && drv_data->rx != NULL) {
    /* full duplex mode */
    BUG_ON((drv_data->tx_end - drv_data->tx) !=
    (drv_data->rx_end - drv_data->rx));
    - cr = (read_CTRL() & (~BIT_CTL_TIMOD));
    - cr |= CFG_SPI_WRITE | (width << 8) |
    - (CFG_SPI_ENABLE << 14);
    dev_dbg(&drv_data->pdev->dev,
    "IO duplex: cr is 0x%x\n", cr);

    - write_CTRL(cr);
    + /* set SPI transfer mode */
    + write_CTRL(cr | CFG_SPI_WRITE);

    drv_data->duplex(drv_data);

    @@ -823,13 +842,11 @@ static void pump_transfers(unsigned long data)
    tranf_success = 0;
    } else if (drv_data->tx != NULL) {
    /* write only half duplex */
    - cr = (read_CTRL() & (~BIT_CTL_TIMOD));
    - cr |= CFG_SPI_WRITE | (width << 8) |
    - (CFG_SPI_ENABLE << 14);
    dev_dbg(&drv_data->pdev->dev,
    "IO write: cr is 0x%x\n", cr);

    - write_CTRL(cr);
    + /* set SPI transfer mode */
    + write_CTRL(cr | CFG_SPI_WRITE);

    drv_data->write(drv_data);

    @@ -837,13 +854,11 @@ static void pump_transfers(unsigned long data)
    tranf_success = 0;
    } else if (drv_data->rx != NULL) {
    /* read only half duplex */
    - cr = (read_CTRL() & (~BIT_CTL_TIMOD));
    - cr |= CFG_SPI_READ | (width << 8) |
    - (CFG_SPI_ENABLE << 14);
    dev_dbg(&drv_data->pdev->dev,
    "IO read: cr is 0x%x\n", cr);

    - write_CTRL(cr);
    + /* set SPI transfer mode */
    + write_CTRL(cr | CFG_SPI_READ);

    drv_data->read(drv_data);
    if (drv_data->rx != drv_data->rx_end)
    @@ -858,9 +873,6 @@ static void pump_transfers(unsigned long data)
    /* Update total byte transfered */
    message->actual_length += drv_data->len;

    - if (drv_data->cs_change)
    - cs_deactive(chip);
    -
    /* Move to next transfer of this msg */
    message->state = next_transfer(drv_data);
    }
    --
    1.5.3.4
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  10. Re: [PATCH 1/9] Blackfin SPI driver: use new GPIO API and add error handling

    On Thursday 11 October 2007, Bryan Wu wrote:
    > @@ -1182,12 +1198,9 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
    > ****************return -ENOMEM;
    > ********}
    > *
    > -*******if (peripheral_request(P_SPI0_SCK, DRV_NAME) ||
    > -*************** peripheral_request(P_SPI0_MISO, DRV_NAME) ||
    > -*************** peripheral_request(P_SPI0_MOSI, DRV_NAME) ) {
    > -
    > +*******if (setup_pin_mux(1)) {
    > ****************dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
    > -***************goto out_error_queue_alloc;
    > +***************goto out_error;
    > ********}
    > *
    > ********drv_data = spi_master_get_devdata(master);



    This doesn't apply against 2.6.23 ... ?
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  11. Re: [PATCH 1/9] Blackfin SPI driver: use new GPIO API and add error handling

    On Thu, 2007-10-11 at 14:46 -0700, David Brownell wrote:
    > On Thursday 11 October 2007, Bryan Wu wrote:
    > > @@ -1182,12 +1198,9 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
    > > return -ENOMEM;
    > > }
    > >
    > > - if (peripheral_request(P_SPI0_SCK, DRV_NAME) ||
    > > - peripheral_request(P_SPI0_MISO, DRV_NAME) ||
    > > - peripheral_request(P_SPI0_MOSI, DRV_NAME) ) {
    > > -
    > > + if (setup_pin_mux(1)) {
    > > dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
    > > - goto out_error_queue_alloc;
    > > + goto out_error;
    > > }
    > >
    > > drv_data = spi_master_get_devdata(master);

    >
    >
    > This doesn't apply against 2.6.23 ... ?


    Oops, I missed the first patch in this patch series.
    It will be sent as soon as possible.

    Thanks a lot
    -Bryan
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread