^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for the Diolan DLN-2 USB adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2014 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Derived from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * i2c-diolan-u2c.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 2010-2011 Ericsson AB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/mfd/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mfd/dln2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct dln2_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) __le16 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) __le16 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) __le16 echo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) __le16 handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct dln2_response {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct dln2_header hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) __le16 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define DLN2_GENERIC_MODULE_ID 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define DLN2_GENERIC_CMD(cmd) DLN2_CMD(cmd, DLN2_GENERIC_MODULE_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CMD_GET_DEVICE_VER DLN2_GENERIC_CMD(0x30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define CMD_GET_DEVICE_SN DLN2_GENERIC_CMD(0x31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define DLN2_HW_ID 0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define DLN2_USB_TIMEOUT 200 /* in ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DLN2_MAX_RX_SLOTS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define DLN2_MAX_URBS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define DLN2_RX_BUF_SIZE 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) enum dln2_handle {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) DLN2_HANDLE_EVENT = 0, /* don't change, hardware defined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) DLN2_HANDLE_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) DLN2_HANDLE_GPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) DLN2_HANDLE_I2C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) DLN2_HANDLE_SPI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) DLN2_HANDLE_ADC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) DLN2_HANDLES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Receive context used between the receive demultiplexer and the transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * routine. While sending a request the transfer routine will look for a free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * receive context and use it to wait for a response and to receive the URB and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * thus the response data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct dln2_rx_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* completion used to wait for a response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct completion done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* if non-NULL the URB contains the response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* if true then this context is used to wait for a response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) bool in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Receive contexts for a particular DLN2 module (i2c, gpio, etc.). We use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * handle header field to identify the module in dln2_dev.mod_rx_slots and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * the echo header field to index the slots field and find the receive context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * for a particular request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct dln2_mod_rx_slots {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* RX slots bitmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) DECLARE_BITMAP(bmap, DLN2_MAX_RX_SLOTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* used to wait for a free RX slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) wait_queue_head_t wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* used to wait for an RX operation to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct dln2_rx_context slots[DLN2_MAX_RX_SLOTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* avoid races between alloc/free_rx_slot and dln2_rx_transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) enum dln2_endpoint {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) DLN2_EP_OUT = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) DLN2_EP_IN = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct dln2_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct usb_device *usb_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct usb_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u8 ep_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u8 ep_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct urb *rx_urb[DLN2_MAX_URBS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) void *rx_buf[DLN2_MAX_URBS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct dln2_mod_rx_slots mod_rx_slots[DLN2_HANDLES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct list_head event_cb_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) spinlock_t event_cb_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) bool disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int active_transfers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) wait_queue_head_t disconnect_wq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) spinlock_t disconnect_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct dln2_event_cb_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u16 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dln2_event_cb_t callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int dln2_register_event_cb(struct platform_device *pdev, u16 id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) dln2_event_cb_t event_cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct dln2_dev *dln2 = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct dln2_event_cb_entry *i, *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) entry = kzalloc(sizeof(*entry), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) entry->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) entry->callback = event_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) entry->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) spin_lock_irqsave(&dln2->event_cb_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) list_for_each_entry(i, &dln2->event_cb_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (i->id == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) list_add_rcu(&entry->list, &dln2->event_cb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) spin_unlock_irqrestore(&dln2->event_cb_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) EXPORT_SYMBOL(dln2_register_event_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) void dln2_unregister_event_cb(struct platform_device *pdev, u16 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct dln2_dev *dln2 = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct dln2_event_cb_entry *i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) spin_lock_irqsave(&dln2->event_cb_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) list_for_each_entry(i, &dln2->event_cb_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (i->id == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) list_del_rcu(&i->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) spin_unlock_irqrestore(&dln2->event_cb_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) kfree(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) EXPORT_SYMBOL(dln2_unregister_event_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Returns true if a valid transfer slot is found. In this case the URB must not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * be resubmitted immediately in dln2_rx as we need the data when dln2_transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * is woke up. It will be resubmitted there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static bool dln2_transfer_complete(struct dln2_dev *dln2, struct urb *urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u16 handle, u16 rx_slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct device *dev = &dln2->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct dln2_rx_context *rxc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) bool valid_slot = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (rx_slot >= DLN2_MAX_RX_SLOTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) rxc = &rxs->slots[rx_slot];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) spin_lock_irqsave(&rxs->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (rxc->in_use && !rxc->urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) rxc->urb = urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) complete(&rxc->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) valid_slot = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) spin_unlock_irqrestore(&rxs->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (!valid_slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dev_warn(dev, "bad/late response %d/%d\n", handle, rx_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return valid_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static void dln2_run_event_callbacks(struct dln2_dev *dln2, u16 id, u16 echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) void *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct dln2_event_cb_entry *i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) list_for_each_entry_rcu(i, &dln2->event_cb_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (i->id == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) i->callback(i->pdev, echo, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void dln2_rx(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct dln2_dev *dln2 = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct dln2_header *hdr = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct device *dev = &dln2->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u16 id, echo, handle, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) u8 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case -EPIPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* this urb is terminated, clean up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dev_dbg(dev, "urb shutting down with status %d\n", urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dev_dbg(dev, "nonzero urb status received %d\n", urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (urb->actual_length < sizeof(struct dln2_header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) dev_err(dev, "short response: %d\n", urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) handle = le16_to_cpu(hdr->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) id = le16_to_cpu(hdr->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) echo = le16_to_cpu(hdr->echo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) size = le16_to_cpu(hdr->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (size != urb->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) dev_err(dev, "size mismatch: handle %x cmd %x echo %x size %d actual %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) handle, id, echo, size, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (handle >= DLN2_HANDLES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) dev_warn(dev, "invalid handle %d\n", handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) data = urb->transfer_buffer + sizeof(struct dln2_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) len = urb->actual_length - sizeof(struct dln2_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (handle == DLN2_HANDLE_EVENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) spin_lock_irqsave(&dln2->event_cb_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) dln2_run_event_callbacks(dln2, id, echo, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) spin_unlock_irqrestore(&dln2->event_cb_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* URB will be re-submitted in _dln2_transfer (free_rx_slot) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (dln2_transfer_complete(dln2, urb, handle, echo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) err = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) dev_err(dev, "failed to resubmit RX URB: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static void *dln2_prep_buf(u16 handle, u16 cmd, u16 echo, const void *obuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) int *obuf_len, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct dln2_header *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) len = *obuf_len + sizeof(*hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) buf = kmalloc(len, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) hdr = (struct dln2_header *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) hdr->id = cpu_to_le16(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) hdr->size = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) hdr->echo = cpu_to_le16(echo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) hdr->handle = cpu_to_le16(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) memcpy(buf + sizeof(*hdr), obuf, *obuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) *obuf_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int dln2_send_wait(struct dln2_dev *dln2, u16 handle, u16 cmd, u16 echo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) const void *obuf, int obuf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int len = obuf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) int actual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) buf = dln2_prep_buf(handle, cmd, echo, obuf, &len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ret = usb_bulk_msg(dln2->usb_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) usb_sndbulkpipe(dln2->usb_dev, dln2->ep_out),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) buf, len, &actual, DLN2_USB_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static bool find_free_slot(struct dln2_dev *dln2, u16 handle, int *slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct dln2_mod_rx_slots *rxs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (dln2->disconnect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *slot = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) rxs = &dln2->mod_rx_slots[handle];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) spin_lock_irqsave(&rxs->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) *slot = find_first_zero_bit(rxs->bmap, DLN2_MAX_RX_SLOTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (*slot < DLN2_MAX_RX_SLOTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct dln2_rx_context *rxc = &rxs->slots[*slot];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) set_bit(*slot, rxs->bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) rxc->in_use = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) spin_unlock_irqrestore(&rxs->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return *slot < DLN2_MAX_RX_SLOTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static int alloc_rx_slot(struct dln2_dev *dln2, u16 handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * No need to timeout here, the wait is bounded by the timeout in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * _dln2_transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ret = wait_event_interruptible(dln2->mod_rx_slots[handle].wq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) find_free_slot(dln2, handle, &slot));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static void free_rx_slot(struct dln2_dev *dln2, u16 handle, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct dln2_mod_rx_slots *rxs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct urb *urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct dln2_rx_context *rxc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) rxs = &dln2->mod_rx_slots[handle];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) spin_lock_irqsave(&rxs->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) clear_bit(slot, rxs->bmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) rxc = &rxs->slots[slot];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) rxc->in_use = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) urb = rxc->urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) rxc->urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) reinit_completion(&rxc->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) spin_unlock_irqrestore(&rxs->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct device *dev = &dln2->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) err = usb_submit_urb(urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dev_err(dev, "failed to resubmit RX URB: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) wake_up_interruptible(&rxs->wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int _dln2_transfer(struct dln2_dev *dln2, u16 handle, u16 cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) const void *obuf, unsigned obuf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) void *ibuf, unsigned *ibuf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int rx_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct dln2_response *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct dln2_rx_context *rxc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct device *dev = &dln2->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) const unsigned long timeout = msecs_to_jiffies(DLN2_USB_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) spin_lock(&dln2->disconnect_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!dln2->disconnect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) dln2->active_transfers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) spin_unlock(&dln2->disconnect_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) rx_slot = alloc_rx_slot(dln2, handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (rx_slot < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ret = rx_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) goto out_decr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ret = dln2_send_wait(dln2, handle, cmd, rx_slot, obuf, obuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dev_err(dev, "USB write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) goto out_free_rx_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) rxc = &rxs->slots[rx_slot];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ret = wait_for_completion_interruptible_timeout(&rxc->done, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (ret <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) goto out_free_rx_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (dln2->disconnect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) goto out_free_rx_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* if we got here we know that the response header has been checked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) rsp = rxc->urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) size = le16_to_cpu(rsp->hdr.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (size < sizeof(*rsp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ret = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) goto out_free_rx_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (le16_to_cpu(rsp->result) > 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) dev_dbg(dev, "%d received response with error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) handle, le16_to_cpu(rsp->result));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto out_free_rx_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!ibuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) goto out_free_rx_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (*ibuf_len > size - sizeof(*rsp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) *ibuf_len = size - sizeof(*rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) memcpy(ibuf, rsp + 1, *ibuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) out_free_rx_slot:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) free_rx_slot(dln2, handle, rx_slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) out_decr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) spin_lock(&dln2->disconnect_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) dln2->active_transfers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) spin_unlock(&dln2->disconnect_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (dln2->disconnect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) wake_up(&dln2->disconnect_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) int dln2_transfer(struct platform_device *pdev, u16 cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) const void *obuf, unsigned obuf_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) void *ibuf, unsigned *ibuf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct dln2_platform_data *dln2_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct dln2_dev *dln2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) u16 handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) dln2 = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) dln2_pdata = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) handle = dln2_pdata->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return _dln2_transfer(dln2, handle, cmd, obuf, obuf_len, ibuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ibuf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) EXPORT_SYMBOL(dln2_transfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int dln2_check_hw(struct dln2_dev *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) __le32 hw_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) int len = sizeof(hw_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) ret = _dln2_transfer(dln2, DLN2_HANDLE_CTRL, CMD_GET_DEVICE_VER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) NULL, 0, &hw_type, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (len < sizeof(hw_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (le32_to_cpu(hw_type) != DLN2_HW_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) dev_err(&dln2->interface->dev, "Device ID 0x%x not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) le32_to_cpu(hw_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int dln2_print_serialno(struct dln2_dev *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) __le32 serial_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) int len = sizeof(serial_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct device *dev = &dln2->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ret = _dln2_transfer(dln2, DLN2_HANDLE_CTRL, CMD_GET_DEVICE_SN, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) &serial_no, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (len < sizeof(serial_no))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dev_info(dev, "Diolan DLN2 serial %u\n", le32_to_cpu(serial_no));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static int dln2_hw_init(struct dln2_dev *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ret = dln2_check_hw(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return dln2_print_serialno(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static void dln2_free_rx_urbs(struct dln2_dev *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) for (i = 0; i < DLN2_MAX_URBS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) usb_free_urb(dln2->rx_urb[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) kfree(dln2->rx_buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static void dln2_stop_rx_urbs(struct dln2_dev *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) for (i = 0; i < DLN2_MAX_URBS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) usb_kill_urb(dln2->rx_urb[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static void dln2_free(struct dln2_dev *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) dln2_free_rx_urbs(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) usb_put_dev(dln2->usb_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) kfree(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static int dln2_setup_rx_urbs(struct dln2_dev *dln2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct usb_host_interface *hostif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) const int rx_max_size = DLN2_RX_BUF_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) for (i = 0; i < DLN2_MAX_URBS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) dln2->rx_buf[i] = kmalloc(rx_max_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (!dln2->rx_buf[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dln2->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (!dln2->rx_urb[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) usb_fill_bulk_urb(dln2->rx_urb[i], dln2->usb_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) usb_rcvbulkpipe(dln2->usb_dev, dln2->ep_in),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dln2->rx_buf[i], rx_max_size, dln2_rx, dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static int dln2_start_rx_urbs(struct dln2_dev *dln2, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) struct device *dev = &dln2->interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) for (i = 0; i < DLN2_MAX_URBS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) ret = usb_submit_urb(dln2->rx_urb[i], gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) dev_err(dev, "failed to submit RX URB: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) DLN2_ACPI_MATCH_GPIO = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) DLN2_ACPI_MATCH_I2C = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) DLN2_ACPI_MATCH_SPI = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) DLN2_ACPI_MATCH_ADC = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static struct dln2_platform_data dln2_pdata_gpio = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) .handle = DLN2_HANDLE_GPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static struct mfd_cell_acpi_match dln2_acpi_match_gpio = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .adr = DLN2_ACPI_MATCH_GPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* Only one I2C port seems to be supported on current hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static struct dln2_platform_data dln2_pdata_i2c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .handle = DLN2_HANDLE_I2C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .port = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static struct mfd_cell_acpi_match dln2_acpi_match_i2c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) .adr = DLN2_ACPI_MATCH_I2C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /* Only one SPI port supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static struct dln2_platform_data dln2_pdata_spi = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) .handle = DLN2_HANDLE_SPI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .port = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static struct mfd_cell_acpi_match dln2_acpi_match_spi = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) .adr = DLN2_ACPI_MATCH_SPI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /* Only one ADC port supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static struct dln2_platform_data dln2_pdata_adc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) .handle = DLN2_HANDLE_ADC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) .port = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) static struct mfd_cell_acpi_match dln2_acpi_match_adc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) .adr = DLN2_ACPI_MATCH_ADC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static const struct mfd_cell dln2_devs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) .name = "dln2-gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) .acpi_match = &dln2_acpi_match_gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) .platform_data = &dln2_pdata_gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) .pdata_size = sizeof(struct dln2_platform_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) .name = "dln2-i2c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) .acpi_match = &dln2_acpi_match_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) .platform_data = &dln2_pdata_i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) .pdata_size = sizeof(struct dln2_platform_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) .name = "dln2-spi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) .acpi_match = &dln2_acpi_match_spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) .platform_data = &dln2_pdata_spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) .pdata_size = sizeof(struct dln2_platform_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) .name = "dln2-adc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) .acpi_match = &dln2_acpi_match_adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) .platform_data = &dln2_pdata_adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) .pdata_size = sizeof(struct dln2_platform_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static void dln2_stop(struct dln2_dev *dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* don't allow starting new transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) spin_lock(&dln2->disconnect_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) dln2->disconnect = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) spin_unlock(&dln2->disconnect_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* cancel in progress transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) for (i = 0; i < DLN2_HANDLES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) spin_lock_irqsave(&rxs->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) /* cancel all response waiters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) for (j = 0; j < DLN2_MAX_RX_SLOTS; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) struct dln2_rx_context *rxc = &rxs->slots[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (rxc->in_use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) complete(&rxc->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) spin_unlock_irqrestore(&rxs->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /* wait for transfers to end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) wait_event(dln2->disconnect_wq, !dln2->active_transfers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) dln2_stop_rx_urbs(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static void dln2_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct dln2_dev *dln2 = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) dln2_stop(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) mfd_remove_devices(&interface->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) dln2_free(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static int dln2_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) const struct usb_device_id *usb_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct usb_host_interface *hostif = interface->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct usb_endpoint_descriptor *epin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct usb_endpoint_descriptor *epout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct device *dev = &interface->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct dln2_dev *dln2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (hostif->desc.bInterfaceNumber != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) hostif->desc.bNumEndpoints < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) epout = &hostif->endpoint[DLN2_EP_OUT].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (!usb_endpoint_is_bulk_out(epout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) epin = &hostif->endpoint[DLN2_EP_IN].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!usb_endpoint_is_bulk_in(epin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) dln2 = kzalloc(sizeof(*dln2), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (!dln2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dln2->ep_out = epout->bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) dln2->ep_in = epin->bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dln2->usb_dev = usb_get_dev(interface_to_usbdev(interface));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) dln2->interface = interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) usb_set_intfdata(interface, dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) init_waitqueue_head(&dln2->disconnect_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) for (i = 0; i < DLN2_HANDLES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) init_waitqueue_head(&dln2->mod_rx_slots[i].wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) spin_lock_init(&dln2->mod_rx_slots[i].lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) for (j = 0; j < DLN2_MAX_RX_SLOTS; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) init_completion(&dln2->mod_rx_slots[i].slots[j].done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) spin_lock_init(&dln2->event_cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) spin_lock_init(&dln2->disconnect_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) INIT_LIST_HEAD(&dln2->event_cb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ret = dln2_setup_rx_urbs(dln2, hostif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) ret = dln2_start_rx_urbs(dln2, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) goto out_stop_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) ret = dln2_hw_init(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dev_err(dev, "failed to initialize hardware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) goto out_stop_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) ret = mfd_add_hotplug_devices(dev, dln2_devs, ARRAY_SIZE(dln2_devs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) dev_err(dev, "failed to add mfd devices to core\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) goto out_stop_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) out_stop_rx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) dln2_stop_rx_urbs(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) dln2_free(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static int dln2_suspend(struct usb_interface *iface, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct dln2_dev *dln2 = usb_get_intfdata(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) dln2_stop(dln2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) static int dln2_resume(struct usb_interface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) struct dln2_dev *dln2 = usb_get_intfdata(iface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) dln2->disconnect = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return dln2_start_rx_urbs(dln2, GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static const struct usb_device_id dln2_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) { USB_DEVICE(0xa257, 0x2013) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) MODULE_DEVICE_TABLE(usb, dln2_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static struct usb_driver dln2_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) .name = "dln2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) .probe = dln2_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) .disconnect = dln2_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) .id_table = dln2_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) .suspend = dln2_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) .resume = dln2_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) module_usb_driver(dln2_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) MODULE_AUTHOR("Octavian Purdila <octavian.purdila@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) MODULE_DESCRIPTION("Core driver for the Diolan DLN2 interface adapter");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) MODULE_LICENSE("GPL v2");