Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / net / wireless / libertas / if_spi.c
index cb8be8d..3ea03f2 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/kthread.h>
 #include <linux/list.h>
 #include <linux/netdevice.h>
+#include <linux/semaphore.h>
 #include <linux/spi/libertas_spi.h>
 #include <linux/spi/spi.h>
 
 #include "dev.h"
 #include "if_spi.h"
 
-struct if_spi_packet {
-       struct list_head                list;
-       u16                             blen;
-       u8                              buffer[0] __attribute__((aligned(4)));
-};
-
 struct if_spi_card {
        struct spi_device               *spi;
        struct lbs_private              *priv;
@@ -66,33 +61,10 @@ struct if_spi_card {
        struct semaphore                spi_thread_terminated;
 
        u8                              cmd_buffer[IF_SPI_CMD_BUF_SIZE];
-
-       /* A buffer of incoming packets from libertas core.
-        * Since we can't sleep in hw_host_to_card, we have to buffer
-        * them. */
-       struct list_head                cmd_packet_list;
-       struct list_head                data_packet_list;
-
-       /* Protects cmd_packet_list and data_packet_list */
-       spinlock_t                      buffer_lock;
 };
 
 static void free_if_spi_card(struct if_spi_card *card)
 {
-       struct list_head *cursor, *next;
-       struct if_spi_packet *packet;
-
-       BUG_ON(card->run_thread);
-       list_for_each_safe(cursor, next, &card->cmd_packet_list) {
-               packet = container_of(cursor, struct if_spi_packet, list);
-               list_del(&packet->list);
-               kfree(packet);
-       }
-       list_for_each_safe(cursor, next, &card->data_packet_list) {
-               packet = container_of(cursor, struct if_spi_packet, list);
-               list_del(&packet->list);
-               kfree(packet);
-       }
        spi_set_drvdata(card->spi, NULL);
        kfree(card);
 }
@@ -134,7 +106,7 @@ static void spu_transaction_finish(struct if_spi_card *card)
 static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
 {
        int err = 0;
-       u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
+       __le16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
        struct spi_message m;
        struct spi_transfer reg_trans;
        struct spi_transfer data_trans;
@@ -166,7 +138,7 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
 
 static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
 {
-       u16 buff;
+       __le16 buff;
 
        buff = cpu_to_le16(val);
        return spu_write(card, reg, (u8 *)&buff, sizeof(u16));
@@ -188,7 +160,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
 {
        unsigned int delay;
        int err = 0;
-       u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
+       __le16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
        struct spi_message m;
        struct spi_transfer reg_trans;
        struct spi_transfer dummy_trans;
@@ -235,7 +207,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
 /* Read 16 bits from an SPI register */
 static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
 {
-       u16 buf;
+       __le16 buf;
        int ret;
 
        ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
@@ -248,7 +220,7 @@ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
  * The low 16 bits are read first. */
 static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
 {
-       u32 buf;
+       __le32 buf;
        int err;
 
        err = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
@@ -774,40 +746,6 @@ out:
        return err;
 }
 
-/* Move data or a command from the host to the card. */
-static void if_spi_h2c(struct if_spi_card *card,
-                       struct if_spi_packet *packet, int type)
-{
-       int err = 0;
-       u16 int_type, port_reg;
-
-       switch (type) {
-       case MVMS_DAT:
-               int_type = IF_SPI_CIC_TX_DOWNLOAD_OVER;
-               port_reg = IF_SPI_DATA_RDWRPORT_REG;
-               break;
-       case MVMS_CMD:
-               int_type = IF_SPI_CIC_CMD_DOWNLOAD_OVER;
-               port_reg = IF_SPI_CMD_RDWRPORT_REG;
-               break;
-       default:
-               lbs_pr_err("can't transfer buffer of type %d\n", type);
-               err = -EINVAL;
-               goto out;
-       }
-
-       /* Write the data to the card */
-       err = spu_write(card, port_reg, packet->buffer, packet->blen);
-       if (err)
-               goto out;
-
-out:
-       kfree(packet);
-
-       if (err)
-               lbs_pr_err("%s: error %d\n", __func__, err);
-}
-
 /* Inform the host about a card event */
 static void if_spi_e2h(struct if_spi_card *card)
 {
@@ -837,8 +775,6 @@ static int lbs_spi_thread(void *data)
        int err;
        struct if_spi_card *card = data;
        u16 hiStatus;
-       unsigned long flags;
-       struct if_spi_packet *packet;
 
        while (1) {
                /* Wait to be woken up by one of two things.  First, our ISR
@@ -877,43 +813,9 @@ static int lbs_spi_thread(void *data)
                if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY ||
                   (card->priv->psstate != PS_STATE_FULL_POWER &&
                    (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) {
-                       /* This means two things. First of all,
-                        * if there was a previous command sent, the card has
-                        * successfully received it.
-                        * Secondly, it is now ready to download another
-                        * command.
-                        */
                        lbs_host_to_card_done(card->priv);
-
-                       /* Do we have any command packets from the host to
-                        * send? */
-                       packet = NULL;
-                       spin_lock_irqsave(&card->buffer_lock, flags);
-                       if (!list_empty(&card->cmd_packet_list)) {
-                               packet = (struct if_spi_packet *)(card->
-                                               cmd_packet_list.next);
-                               list_del(&packet->list);
-                       }
-                       spin_unlock_irqrestore(&card->buffer_lock, flags);
-
-                       if (packet)
-                               if_spi_h2c(card, packet, MVMS_CMD);
                }
-               if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) {
-                       /* Do we have any data packets from the host to
-                        * send? */
-                       packet = NULL;
-                       spin_lock_irqsave(&card->buffer_lock, flags);
-                       if (!list_empty(&card->data_packet_list)) {
-                               packet = (struct if_spi_packet *)(card->
-                                               data_packet_list.next);
-                               list_del(&packet->list);
-                       }
-                       spin_unlock_irqrestore(&card->buffer_lock, flags);
 
-                       if (packet)
-                               if_spi_h2c(card, packet, MVMS_DAT);
-               }
                if (hiStatus & IF_SPI_HIST_CARD_EVENT)
                        if_spi_e2h(card);
 
@@ -942,40 +844,18 @@ static int if_spi_host_to_card(struct lbs_private *priv,
                                u8 type, u8 *buf, u16 nb)
 {
        int err = 0;
-       unsigned long flags;
        struct if_spi_card *card = priv->card;
-       struct if_spi_packet *packet;
-       u16 blen;
 
        lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb);
 
-       if (nb == 0) {
-               lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb);
-               err = -EINVAL;
-               goto out;
-       }
-       blen = ALIGN(nb, 4);
-       packet = kzalloc(sizeof(struct if_spi_packet) + blen, GFP_ATOMIC);
-       if (!packet) {
-               err = -ENOMEM;
-               goto out;
-       }
-       packet->blen = blen;
-       memcpy(packet->buffer, buf, nb);
-       memset(packet->buffer + nb, 0, blen - nb);
+       nb = ALIGN(nb, 4);
 
        switch (type) {
        case MVMS_CMD:
-               priv->dnld_sent = DNLD_CMD_SENT;
-               spin_lock_irqsave(&card->buffer_lock, flags);
-               list_add_tail(&packet->list, &card->cmd_packet_list);
-               spin_unlock_irqrestore(&card->buffer_lock, flags);
+               err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, buf, nb);
                break;
        case MVMS_DAT:
-               priv->dnld_sent = DNLD_DATA_SENT;
-               spin_lock_irqsave(&card->buffer_lock, flags);
-               list_add_tail(&packet->list, &card->data_packet_list);
-               spin_unlock_irqrestore(&card->buffer_lock, flags);
+               err = spu_write(card, IF_SPI_DATA_RDWRPORT_REG, buf, nb);
                break;
        default:
                lbs_pr_err("can't transfer buffer of type %d", type);
@@ -983,9 +863,6 @@ static int if_spi_host_to_card(struct lbs_private *priv,
                break;
        }
 
-       /* Wake up the spi thread */
-       up(&card->spi_ready);
-out:
        lbs_deb_leave_args(LBS_DEB_SPI, "err=%d", err);
        return err;
 }
@@ -1026,6 +903,10 @@ static int if_spi_calculate_fw_names(u16 card_id,
                 chip_id_to_device_name[i].name);
        return 0;
 }
+MODULE_FIRMWARE("libertas/gspi8385_hlp.bin");
+MODULE_FIRMWARE("libertas/gspi8385.bin");
+MODULE_FIRMWARE("libertas/gspi8686_hlp.bin");
+MODULE_FIRMWARE("libertas/gspi8686.bin");
 
 static int __devinit if_spi_probe(struct spi_device *spi)
 {
@@ -1062,9 +943,6 @@ static int __devinit if_spi_probe(struct spi_device *spi)
 
        sema_init(&card->spi_ready, 0);
        sema_init(&card->spi_thread_terminated, 0);
-       INIT_LIST_HEAD(&card->cmd_packet_list);
-       INIT_LIST_HEAD(&card->data_packet_list);
-       spin_lock_init(&card->buffer_lock);
 
        /* Initialize the SPI Interface Unit */
        err = spu_init(card, pdata->use_dummy_writes);
@@ -1117,6 +995,9 @@ static int __devinit if_spi_probe(struct spi_device *spi)
        card->priv = priv;
        priv->card = card;
        priv->hw_host_to_card = if_spi_host_to_card;
+       priv->enter_deep_sleep = NULL;
+       priv->exit_deep_sleep = NULL;
+       priv->reset_deep_sleep_wakeup = NULL;
        priv->fw_ready = 1;
 
        /* Initialize interrupt handling stuff. */
@@ -1138,6 +1019,9 @@ static int __devinit if_spi_probe(struct spi_device *spi)
                goto terminate_thread;
        }
 
+       /* poke the IRQ handler so that we don't miss the first interrupt */
+       up(&card->spi_ready);
+
        /* Start the card.
         * This will call register_netdev, and we'll start
         * getting interrupts... */