]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/caif/caif_spi.c
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
[karo-tx-linux.git] / drivers / net / caif / caif_spi.c
index 05e791f46aef7db07b5df2393db24d7a56108ab5..b71ce9bf0afb7297df000208492e420ff9bd58ad 100644 (file)
@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("CAIF SPI driver");
 /* Returns the number of padding bytes for alignment. */
 #define PAD_POW2(x, pow) ((((x)&((pow)-1))==0) ? 0 : (((pow)-((x)&((pow)-1)))))
 
-static int spi_loop;
+static bool spi_loop;
 module_param(spi_loop, bool, S_IRUGO);
 MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode.");
 
@@ -127,12 +127,6 @@ static inline void dev_debugfs_rem(struct cfspi *cfspi)
        debugfs_remove(cfspi->dbgfs_dir);
 }
 
-static int dbgfs_open(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
 static ssize_t dbgfs_state(struct file *file, char __user *user_buf,
                           size_t count, loff_t *ppos)
 {
@@ -226,7 +220,7 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf,
                        "Tx data (Len: %d):\n", cfspi->tx_cpck_len);
 
        len += print_frame((buf + len), (DEBUGFS_BUF_SIZE - len),
-                          cfspi->xfer.va_tx,
+                          cfspi->xfer.va_tx[0],
                           (cfspi->tx_cpck_len + SPI_CMD_SZ), 100);
 
        len += snprintf((buf + len), (DEBUGFS_BUF_SIZE - len),
@@ -243,13 +237,13 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf,
 }
 
 static const struct file_operations dbgfs_state_fops = {
-       .open = dbgfs_open,
+       .open = simple_open,
        .read = dbgfs_state,
        .owner = THIS_MODULE
 };
 
 static const struct file_operations dbgfs_frame_fops = {
-       .open = dbgfs_open,
+       .open = simple_open,
        .read = dbgfs_frame,
        .owner = THIS_MODULE
 };
@@ -599,48 +593,11 @@ static int cfspi_close(struct net_device *dev)
        netif_stop_queue(dev);
        return 0;
 }
-static const struct net_device_ops cfspi_ops = {
-       .ndo_open = cfspi_open,
-       .ndo_stop = cfspi_close,
-       .ndo_start_xmit = cfspi_xmit
-};
 
-static void cfspi_setup(struct net_device *dev)
+static int cfspi_init(struct net_device *dev)
 {
+       int res = 0;
        struct cfspi *cfspi = netdev_priv(dev);
-       dev->features = 0;
-       dev->netdev_ops = &cfspi_ops;
-       dev->type = ARPHRD_CAIF;
-       dev->flags = IFF_NOARP | IFF_POINTOPOINT;
-       dev->tx_queue_len = 0;
-       dev->mtu = SPI_MAX_PAYLOAD_SIZE;
-       dev->destructor = free_netdev;
-       skb_queue_head_init(&cfspi->qhead);
-       skb_queue_head_init(&cfspi->chead);
-       cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
-       cfspi->cfdev.use_frag = false;
-       cfspi->cfdev.use_stx = false;
-       cfspi->cfdev.use_fcs = false;
-       cfspi->ndev = dev;
-}
-
-int cfspi_spi_probe(struct platform_device *pdev)
-{
-       struct cfspi *cfspi = NULL;
-       struct net_device *ndev;
-       struct cfspi_dev *dev;
-       int res;
-       dev = (struct cfspi_dev *)pdev->dev.platform_data;
-
-       ndev = alloc_netdev(sizeof(struct cfspi),
-                       "cfspi%d", cfspi_setup);
-       if (!ndev)
-               return -ENOMEM;
-
-       cfspi = netdev_priv(ndev);
-       netif_stop_queue(ndev);
-       cfspi->ndev = ndev;
-       cfspi->pdev = pdev;
 
        /* Set flow info. */
        cfspi->flow_off_sent = 0;
@@ -656,16 +613,11 @@ int cfspi_spi_probe(struct platform_device *pdev)
                cfspi->slave_talked = false;
        }
 
-       /* Assign the SPI device. */
-       cfspi->dev = dev;
-       /* Assign the device ifc to this SPI interface. */
-       dev->ifc = &cfspi->ifc;
-
        /* Allocate DMA buffers. */
-       cfspi->xfer.va_tx = dma_alloc(&cfspi->xfer.pa_tx);
-       if (!cfspi->xfer.va_tx) {
+       cfspi->xfer.va_tx[0] = dma_alloc(&cfspi->xfer.pa_tx[0]);
+       if (!cfspi->xfer.va_tx[0]) {
                res = -ENODEV;
-               goto err_dma_alloc_tx;
+               goto err_dma_alloc_tx_0;
        }
 
        cfspi->xfer.va_rx = dma_alloc(&cfspi->xfer.pa_rx);
@@ -714,6 +666,87 @@ int cfspi_spi_probe(struct platform_device *pdev)
        /* Schedule the work queue. */
        queue_work(cfspi->wq, &cfspi->work);
 
+       return 0;
+
+ err_create_wq:
+       dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
+ err_dma_alloc_rx:
+       dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]);
+ err_dma_alloc_tx_0:
+       return res;
+}
+
+static void cfspi_uninit(struct net_device *dev)
+{
+       struct cfspi *cfspi = netdev_priv(dev);
+
+       /* Remove from list. */
+       spin_lock(&cfspi_list_lock);
+       list_del(&cfspi->list);
+       spin_unlock(&cfspi_list_lock);
+
+       cfspi->ndev = NULL;
+       /* Free DMA buffers. */
+       dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
+       dma_free(cfspi->xfer.va_tx[0], cfspi->xfer.pa_tx[0]);
+       set_bit(SPI_TERMINATE, &cfspi->state);
+       wake_up_interruptible(&cfspi->wait);
+       destroy_workqueue(cfspi->wq);
+       /* Destroy debugfs directory and files. */
+       dev_debugfs_rem(cfspi);
+       return;
+}
+
+static const struct net_device_ops cfspi_ops = {
+       .ndo_open = cfspi_open,
+       .ndo_stop = cfspi_close,
+       .ndo_init = cfspi_init,
+       .ndo_uninit = cfspi_uninit,
+       .ndo_start_xmit = cfspi_xmit
+};
+
+static void cfspi_setup(struct net_device *dev)
+{
+       struct cfspi *cfspi = netdev_priv(dev);
+       dev->features = 0;
+       dev->netdev_ops = &cfspi_ops;
+       dev->type = ARPHRD_CAIF;
+       dev->flags = IFF_NOARP | IFF_POINTOPOINT;
+       dev->tx_queue_len = 0;
+       dev->mtu = SPI_MAX_PAYLOAD_SIZE;
+       dev->destructor = free_netdev;
+       skb_queue_head_init(&cfspi->qhead);
+       skb_queue_head_init(&cfspi->chead);
+       cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
+       cfspi->cfdev.use_frag = false;
+       cfspi->cfdev.use_stx = false;
+       cfspi->cfdev.use_fcs = false;
+       cfspi->ndev = dev;
+}
+
+int cfspi_spi_probe(struct platform_device *pdev)
+{
+       struct cfspi *cfspi = NULL;
+       struct net_device *ndev;
+       struct cfspi_dev *dev;
+       int res;
+       dev = (struct cfspi_dev *)pdev->dev.platform_data;
+
+       ndev = alloc_netdev(sizeof(struct cfspi),
+                       "cfspi%d", cfspi_setup);
+       if (!dev)
+               return -ENODEV;
+
+       cfspi = netdev_priv(ndev);
+       netif_stop_queue(ndev);
+       cfspi->ndev = ndev;
+       cfspi->pdev = pdev;
+
+       /* Assign the SPI device. */
+       cfspi->dev = dev;
+       /* Assign the device ifc to this SPI interface. */
+       dev->ifc = &cfspi->ifc;
+
        /* Register network device. */
        res = register_netdev(ndev);
        if (res) {
@@ -723,15 +756,6 @@ int cfspi_spi_probe(struct platform_device *pdev)
        return res;
 
  err_net_reg:
-       dev_debugfs_rem(cfspi);
-       set_bit(SPI_TERMINATE, &cfspi->state);
-       wake_up_interruptible(&cfspi->wait);
-       destroy_workqueue(cfspi->wq);
- err_create_wq:
-       dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
- err_dma_alloc_rx:
-       dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx);
- err_dma_alloc_tx:
        free_netdev(ndev);
 
        return res;
@@ -739,34 +763,8 @@ int cfspi_spi_probe(struct platform_device *pdev)
 
 int cfspi_spi_remove(struct platform_device *pdev)
 {
-       struct list_head *list_node;
-       struct list_head *n;
-       struct cfspi *cfspi = NULL;
-       struct cfspi_dev *dev;
-
-       dev = (struct cfspi_dev *)pdev->dev.platform_data;
-       spin_lock(&cfspi_list_lock);
-       list_for_each_safe(list_node, n, &cfspi_list) {
-               cfspi = list_entry(list_node, struct cfspi, list);
-               /* Find the corresponding device. */
-               if (cfspi->dev == dev) {
-                       /* Remove from list. */
-                       list_del(list_node);
-                       /* Free DMA buffers. */
-                       dma_free(cfspi->xfer.va_rx, cfspi->xfer.pa_rx);
-                       dma_free(cfspi->xfer.va_tx, cfspi->xfer.pa_tx);
-                       set_bit(SPI_TERMINATE, &cfspi->state);
-                       wake_up_interruptible(&cfspi->wait);
-                       destroy_workqueue(cfspi->wq);
-                       /* Destroy debugfs directory and files. */
-                       dev_debugfs_rem(cfspi);
-                       unregister_netdev(cfspi->ndev);
-                       spin_unlock(&cfspi_list_lock);
-                       return 0;
-               }
-       }
-       spin_unlock(&cfspi_list_lock);
-       return -ENODEV;
+       /* Everything is done in cfspi_uninit(). */
+       return 0;
 }
 
 static void __exit cfspi_exit_module(void)
@@ -777,7 +775,7 @@ static void __exit cfspi_exit_module(void)
 
        list_for_each_safe(list_node, n, &cfspi_list) {
                cfspi = list_entry(list_node, struct cfspi, list);
-               platform_device_unregister(cfspi->pdev);
+               unregister_netdev(cfspi->ndev);
        }
 
        /* Destroy sysfs files. */