staging: most: hdm-usb: Use setup_timer
[deliverable/linux.git] / drivers / staging / most / hdm-usb / hdm_usb.c
index 305303f2f17cd188073069589aadb4f91228c3d6..41690f801fb8c6af9ebf636da98b4128241c9970 100644 (file)
@@ -59,6 +59,8 @@
 #define DRCI_REG_HW_ADDR_HI    0x0145
 #define DRCI_REG_HW_ADDR_MI    0x0146
 #define DRCI_REG_HW_ADDR_LO    0x0147
+#define DRCI_REG_BASE          0x1100
+#define DRCI_COMMAND           0x02
 #define DRCI_READ_REQ          0xA0
 #define DRCI_WRITE_REQ         0xA1
 
@@ -75,6 +77,7 @@ struct buf_anchor {
        struct list_head list;
        struct completion urb_compl;
 };
+
 #define to_buf_anchor(w) container_of(w, struct buf_anchor, clear_work_obj)
 
 /**
@@ -86,6 +89,7 @@ struct most_dci_obj {
        struct kobject kobj;
        struct usb_device *usb_device;
 };
+
 #define to_dci_obj(p) container_of(p, struct most_dci_obj, kobj)
 
 /**
@@ -129,6 +133,7 @@ struct most_dev {
        struct timer_list link_stat_timer;
        struct work_struct poll_work_obj;
 };
+
 #define to_mdev(d) container_of(d, struct most_dev, iface)
 #define to_mdev_from_work(w) container_of(w, struct most_dev, poll_work_obj)
 
@@ -136,36 +141,6 @@ static struct workqueue_struct *schedule_usb_work;
 static void wq_clear_halt(struct work_struct *wq_obj);
 static void wq_netinfo(struct work_struct *wq_obj);
 
-/**
- * trigger_resync_vr - Vendor request to trigger HW re-sync mechanism
- * @dev: usb device
- *
- */
-static void trigger_resync_vr(struct usb_device *dev)
-{
-       int retval;
-       u8 request_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
-       int *data = kzalloc(sizeof(*data), GFP_KERNEL);
-
-       if (!data)
-               goto error;
-       *data = HW_RESYNC;
-       retval = usb_control_msg(dev,
-                                usb_sndctrlpipe(dev, 0),
-                                0,
-                                request_type,
-                                0,
-                                0,
-                                data,
-                                0,
-                                5 * HZ);
-       kfree(data);
-       if (retval >= 0)
-               return;
-error:
-       dev_err(&dev->dev, "Vendor request \"stall\" failed\n");
-}
-
 /**
  * drci_rd_reg - read a DCI register
  * @dev: usb device
@@ -174,17 +149,23 @@ error:
  *
  * This is reads data from INIC's direct register communication interface
  */
-static inline int drci_rd_reg(struct usb_device *dev, u16 reg, void *buf)
+static inline int drci_rd_reg(struct usb_device *dev, u16 reg, u16 *buf)
 {
-       return usb_control_msg(dev,
-                              usb_rcvctrlpipe(dev, 0),
-                              DRCI_READ_REQ,
-                              USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-                              0x0000,
-                              reg,
-                              buf,
-                              2,
-                              5 * HZ);
+       int retval;
+       u16 *dma_buf = kzalloc(sizeof(u16), GFP_KERNEL);
+       u8 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+
+       if (!dma_buf)
+               return -ENOMEM;
+
+       retval = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+                                DRCI_READ_REQ, req_type,
+                                0x0000,
+                                reg, dma_buf, sizeof(u16), 5 * HZ);
+       *buf = le16_to_cpu(*dma_buf);
+       kfree(dma_buf);
+
+       return retval;
 }
 
 /**
@@ -220,7 +201,8 @@ static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel)
        unsigned long flags;
 
        spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags);
-       list_for_each_entry_safe(anchor, tmp, &mdev->anchor_list[channel], list) {
+       list_for_each_entry_safe(anchor, tmp, &mdev->anchor_list[channel],
+                                list) {
                struct urb *urb = anchor->urb;
 
                spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
@@ -267,10 +249,11 @@ static unsigned int get_stream_frame_size(struct most_channel_config *cfg)
                if (cfg->packets_per_xact == 0) {
                        pr_warn("Misconfig: Packets per XACT zero\n");
                        frame_size = 0;
-               } else if (cfg->packets_per_xact == 0xFF)
+               } else if (cfg->packets_per_xact == 0xFF) {
                        frame_size = (USB_MTU / sub_size) * sub_size;
-               else
+               } else {
                        frame_size = cfg->packets_per_xact * sub_size;
+               }
                break;
        default:
                pr_warn("Query frame size of non-streaming channel\n");
@@ -308,7 +291,7 @@ static int hdm_poison_channel(struct most_interface *iface, int channel)
 
        mutex_lock(&mdev->io_mutex);
        free_anchored_buffers(mdev, channel);
-       if (mdev->padding_active[channel] == true)
+       if (mdev->padding_active[channel])
                mdev->padding_active[channel] = false;
 
        if (mdev->conf[channel].data_type == MOST_CH_ASYNC) {
@@ -365,7 +348,8 @@ static int hdm_add_padding(struct most_dev *mdev, int channel, struct mbo *mbo)
  * This takes the INIC hardware specific padding bytes off a streaming
  * channel's buffer.
  */
-static int hdm_remove_padding(struct most_dev *mdev, int channel, struct mbo *mbo)
+static int hdm_remove_padding(struct most_dev *mdev, int channel,
+                             struct mbo *mbo)
 {
        unsigned int j, num_frames, frame_size;
        struct most_channel_config *const conf = &mdev->conf[channel];
@@ -411,7 +395,7 @@ static void hdm_write_completion(struct urb *urb)
        dev = &mdev->usb_device->dev;
 
        if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) ||
-           (mdev->is_channel_healthy[channel] == false)) {
+           (!mdev->is_channel_healthy[channel])) {
                complete(&anchor->urb_compl);
                return;
        }
@@ -453,7 +437,7 @@ static void hdm_write_completion(struct urb *urb)
 }
 
 /**
- * hdm_read_completion - completion funciton for submitted Rx URBs
+ * hdm_read_completion - completion function for submitted Rx URBs
  * @urb: the URB that has been completed
  *
  * This checks the status of the completed URB. In case the URB has been
@@ -568,7 +552,6 @@ static void hdm_read_completion(struct urb *urb)
        struct device *dev;
        unsigned long flags;
        unsigned int channel;
-       struct most_channel_config *conf;
 
        mbo = urb->context;
        anchor = mbo->priv;
@@ -577,13 +560,11 @@ static void hdm_read_completion(struct urb *urb)
        dev = &mdev->usb_device->dev;
 
        if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) ||
-           (mdev->is_channel_healthy[channel] == false)) {
+           (!mdev->is_channel_healthy[channel])) {
                complete(&anchor->urb_compl);
                return;
        }
 
-       conf = &mdev->conf[channel];
-
        if (unlikely(urb->status && !(urb->status == -ENOENT ||
                                      urb->status == -ECONNRESET ||
                                      urb->status == -ESHUTDOWN))) {
@@ -608,7 +589,7 @@ static void hdm_read_completion(struct urb *urb)
                }
        } else {
                mbo->processed_length = urb->actual_length;
-               if (mdev->padding_active[channel] == false) {
+               if (!mdev->padding_active[channel]) {
                        mbo->status = MBO_SUCCESS;
                } else {
                        if (hdm_remove_padding(mdev, channel, mbo)) {
@@ -644,7 +625,8 @@ static void hdm_read_completion(struct urb *urb)
  *
  * Context: Could in _some_ cases be interrupt!
  */
-static int hdm_enqueue(struct most_interface *iface, int channel, struct mbo *mbo)
+static int hdm_enqueue(struct most_interface *iface, int channel,
+                      struct mbo *mbo)
 {
        struct most_dev *mdev;
        struct buf_anchor *anchor;
@@ -688,7 +670,7 @@ static int hdm_enqueue(struct most_interface *iface, int channel, struct mbo *mb
        list_add_tail(&anchor->list, &mdev->anchor_list[channel]);
        spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags);
 
-       if ((mdev->padding_active[channel] == true) &&
+       if ((mdev->padding_active[channel]) &&
            (conf->direction & MOST_CH_TX))
                if (hdm_add_padding(mdev, channel, mbo)) {
                        retval = -EIO;
@@ -714,7 +696,7 @@ static int hdm_enqueue(struct most_interface *iface, int channel, struct mbo *mb
                                  usb_rcvbulkpipe(mdev->usb_device,
                                                  mdev->ep_address[channel]),
                                  virt_address,
-                                 length,
+                                 length + conf->extra_len,
                                  hdm_read_completion,
                                  mbo);
        }
@@ -780,12 +762,6 @@ static int hdm_configure_channel(struct most_interface *iface, int channel,
        mdev->padding_active[channel] = true;
        temp_size = conf->buffer_size;
 
-       if ((conf->data_type != MOST_CH_SYNC) &&
-           (conf->data_type != MOST_CH_ISOC_AVP)) {
-               dev_warn(dev, "Unsupported data type\n");
-               return -EINVAL;
-       }
-
        frame_size = get_stream_frame_size(conf);
        if ((frame_size == 0) || (frame_size > USB_MTU)) {
                dev_warn(dev, "Misconfig: frame size wrong\n");
@@ -798,8 +774,7 @@ static int hdm_configure_channel(struct most_interface *iface, int channel,
                tmp_val = conf->buffer_size / frame_size;
                conf->buffer_size = tmp_val * frame_size;
                dev_notice(dev,
-                          "Channel %d - rouding buffer size to %d bytes, "
-                          "channel config says %d bytes\n",
+                          "Channel %d - rounding buffer size to %d bytes, channel config says %d bytes\n",
                           channel,
                           conf->buffer_size,
                           temp_size);
@@ -826,38 +801,41 @@ exit:
  */
 static int hdm_update_netinfo(struct most_dev *mdev)
 {
-       struct device *dev = &mdev->usb_device->dev;
-       int i;
-       u16 link;
-       u8 addr[6];
+       struct usb_device *usb_device = mdev->usb_device;
+       struct device *dev = &usb_device->dev;
+       u16 hi, mi, lo, link;
 
        if (!is_valid_ether_addr(mdev->hw_addr)) {
-               if (0 > drci_rd_reg(mdev->usb_device,
-                                   DRCI_REG_HW_ADDR_HI, addr)) {
+               if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_HI, &hi) < 0) {
                        dev_err(dev, "Vendor request \"hw_addr_hi\" failed\n");
                        return -1;
                }
-               if (0 > drci_rd_reg(mdev->usb_device,
-                                   DRCI_REG_HW_ADDR_MI, addr + 2)) {
+
+               if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_MI, &mi) < 0) {
                        dev_err(dev, "Vendor request \"hw_addr_mid\" failed\n");
                        return -1;
                }
-               if (0 > drci_rd_reg(mdev->usb_device,
-                                   DRCI_REG_HW_ADDR_LO, addr + 4)) {
+
+               if (drci_rd_reg(usb_device, DRCI_REG_HW_ADDR_LO, &lo) < 0) {
                        dev_err(dev, "Vendor request \"hw_addr_low\" failed\n");
                        return -1;
                }
+
                mutex_lock(&mdev->io_mutex);
-               for (i = 0; i < 6; i++)
-                       mdev->hw_addr[i] = addr[i];
+               mdev->hw_addr[0] = hi >> 8;
+               mdev->hw_addr[1] = hi;
+               mdev->hw_addr[2] = mi >> 8;
+               mdev->hw_addr[3] = mi;
+               mdev->hw_addr[4] = lo >> 8;
+               mdev->hw_addr[5] = lo;
                mutex_unlock(&mdev->io_mutex);
-
        }
-       if (0 > drci_rd_reg(mdev->usb_device, DRCI_REG_NI_STATE, &link)) {
+
+       if (drci_rd_reg(usb_device, DRCI_REG_NI_STATE, &link) < 0) {
                dev_err(dev, "Vendor request \"link status\" failed\n");
                return -1;
        }
-       le16_to_cpus(&link);
+
        mutex_lock(&mdev->io_mutex);
        mdev->link_stat = link;
        mutex_unlock(&mdev->io_mutex);
@@ -919,7 +897,7 @@ static void wq_netinfo(struct work_struct *wq_obj)
        for (i = 0; i < 6; i++)
                prev_hw_addr[i] = mdev->hw_addr[i];
 
-       if (0 > hdm_update_netinfo(mdev))
+       if (hdm_update_netinfo(mdev) < 0)
                return;
        if ((prev_link_stat != mdev->link_stat) ||
            (prev_hw_addr[0] != mdev->hw_addr[0]) ||
@@ -1009,8 +987,8 @@ struct most_dci_attribute {
                         const char *buf,
                         size_t count);
 };
-#define to_dci_attr(a) container_of(a, struct most_dci_attribute, attr)
 
+#define to_dci_attr(a) container_of(a, struct most_dci_attribute, attr)
 
 /**
  * dci_attr_show - show function for dci object
@@ -1107,14 +1085,14 @@ static ssize_t show_value(struct most_dci_obj *dci_obj,
        if (err < 0)
                return err;
 
-       return snprintf(buf, PAGE_SIZE, "%04x\n", le16_to_cpu(tmp_val));
+       return snprintf(buf, PAGE_SIZE, "%04x\n", tmp_val);
 }
 
 static ssize_t store_value(struct most_dci_obj *dci_obj,
                           struct most_dci_attribute *attr,
                           const char *buf, size_t count)
 {
-       u16 v16;
+       u16 val;
        u16 reg_addr;
        int err;
 
@@ -1137,11 +1115,11 @@ static ssize_t store_value(struct most_dci_obj *dci_obj,
        else
                return -EIO;
 
-       err = kstrtou16(buf, 16, &v16);
+       err = kstrtou16(buf, 16, &val);
        if (err)
                return err;
 
-       err = drci_wr_reg(dci_obj->usb_device, reg_addr, cpu_to_le16(v16));
+       err = drci_wr_reg(dci_obj->usb_device, reg_addr, val);
        if (err < 0)
                return err;
 
@@ -1248,6 +1226,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
        struct usb_host_interface *usb_iface_desc;
        struct usb_endpoint_descriptor *ep_desc;
        int ret = 0;
+       int err;
 
        usb_iface_desc = interface->cur_altsetting;
        usb_dev = interface_to_usbdev(interface);
@@ -1260,11 +1239,10 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
        num_endpoints = usb_iface_desc->desc.bNumEndpoints;
        mutex_init(&mdev->io_mutex);
        INIT_WORK(&mdev->poll_work_obj, wq_netinfo);
-       init_timer(&mdev->link_stat_timer);
+       setup_timer(&mdev->link_stat_timer, link_stat_timer_handler,
+                   (unsigned long)mdev);
 
        mdev->usb_device = usb_dev;
-       mdev->link_stat_timer.function = link_stat_timer_handler;
-       mdev->link_stat_timer.data = (unsigned long)mdev;
        mdev->link_stat_timer.expires = jiffies + (2 * HZ);
 
        mdev->iface.mod = hdm_usb_fops.owner;
@@ -1328,6 +1306,13 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
                tmp_cap++;
                INIT_LIST_HEAD(&mdev->anchor_list[i]);
                spin_lock_init(&mdev->anchor_list_lock[i]);
+               err = drci_wr_reg(usb_dev,
+                                 DRCI_REG_BASE + DRCI_COMMAND +
+                                 ep_desc->bEndpointAddress * 16,
+                                 1);
+               if (err < 0)
+                       pr_warn("DCI Sync for EP %02x failed",
+                               ep_desc->bEndpointAddress);
        }
        dev_notice(dev, "claimed gadget: Vendor=%4.4x ProdID=%4.4x Bus=%02x Device=%02x\n",
                   le16_to_cpu(usb_dev->descriptor.idVendor),
@@ -1362,7 +1347,6 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
 
                kobject_uevent(&mdev->dci->kobj, KOBJ_ADD);
                mdev->dci->usb_device = mdev->usb_device;
-               trigger_resync_vr(usb_dev);
        }
        mutex_unlock(&mdev->io_mutex);
        return 0;
@@ -1432,7 +1416,7 @@ static int __init hdm_usb_init(void)
                return -EIO;
        }
        schedule_usb_work = create_workqueue("hdmu_work");
-       if (schedule_usb_work == NULL) {
+       if (!schedule_usb_work) {
                pr_err("could not create workqueue\n");
                usb_deregister(&hdm_usb);
                return -ENOMEM;
This page took 0.100187 seconds and 5 git commands to generate.