]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/arcnet/com20020-pci.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide
[karo-tx-linux.git] / drivers / net / arcnet / com20020-pci.c
index a12bf83be7502dd6e4262907a45dc05efb090b80..239de38fbd6a588bbb0e90e3452ea60ca1e5a161 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/pci.h>
 #include <linux/list.h>
 #include <linux/io.h>
+#include <linux/leds.h>
 
 #include "arcdevice.h"
 #include "com20020.h"
@@ -62,12 +63,43 @@ module_param(clockp, int, 0);
 module_param(clockm, int, 0);
 MODULE_LICENSE("GPL");
 
+static void led_tx_set(struct led_classdev *led_cdev,
+                            enum led_brightness value)
+{
+       struct com20020_dev *card;
+       struct com20020_priv *priv;
+       struct com20020_pci_card_info *ci;
+
+       card = container_of(led_cdev, struct com20020_dev, tx_led);
+
+       priv = card->pci_priv;
+       ci = priv->ci;
+
+       outb(!!value, priv->misc + ci->leds[card->index].green);
+}
+
+static void led_recon_set(struct led_classdev *led_cdev,
+                            enum led_brightness value)
+{
+       struct com20020_dev *card;
+       struct com20020_priv *priv;
+       struct com20020_pci_card_info *ci;
+
+       card = container_of(led_cdev, struct com20020_dev, recon_led);
+
+       priv = card->pci_priv;
+       ci = priv->ci;
+
+       outb(!!value, priv->misc + ci->leds[card->index].red);
+}
+
 static void com20020pci_remove(struct pci_dev *pdev);
 
 static int com20020pci_probe(struct pci_dev *pdev,
                             const struct pci_device_id *id)
 {
        struct com20020_pci_card_info *ci;
+       struct com20020_pci_channel_map *mm;
        struct net_device *dev;
        struct arcnet_local *lp;
        struct com20020_priv *priv;
@@ -84,9 +116,22 @@ static int com20020pci_probe(struct pci_dev *pdev,
 
        ci = (struct com20020_pci_card_info *)id->driver_data;
        priv->ci = ci;
+       mm = &ci->misc_map;
 
        INIT_LIST_HEAD(&priv->list_dev);
 
+       if (mm->size) {
+               ioaddr = pci_resource_start(pdev, mm->bar) + mm->offset;
+               r = devm_request_region(&pdev->dev, ioaddr, mm->size,
+                                       "com20020-pci");
+               if (!r) {
+                       pr_err("IO region %xh-%xh already allocated.\n",
+                              ioaddr, ioaddr + mm->size - 1);
+                       return -EBUSY;
+               }
+               priv->misc = ioaddr;
+       }
+
        for (i = 0; i < ci->devcount; i++) {
                struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i];
                struct com20020_dev *card;
@@ -96,6 +141,7 @@ static int com20020pci_probe(struct pci_dev *pdev,
                        ret = -ENOMEM;
                        goto out_port;
                }
+               dev->dev_port = i;
 
                dev->netdev_ops = &com20020_netdev_ops;
 
@@ -131,6 +177,13 @@ static int com20020pci_probe(struct pci_dev *pdev,
                lp->timeout = timeout;
                lp->hw.owner = THIS_MODULE;
 
+               /* Get the dev_id from the PLX rotary coder */
+               if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15))
+                       dev->dev_id = 0xc;
+               dev->dev_id ^= inb(priv->misc + ci->rotary) >> 4;
+
+               snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i);
+
                if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) {
                        pr_err("IO address %Xh is empty!\n", ioaddr);
                        ret = -EIO;
@@ -148,14 +201,41 @@ static int com20020pci_probe(struct pci_dev *pdev,
 
                card->index = i;
                card->pci_priv = priv;
+               card->tx_led.brightness_set = led_tx_set;
+               card->tx_led.default_trigger = devm_kasprintf(&pdev->dev,
+                                               GFP_KERNEL, "arc%d-%d-tx",
+                                               dev->dev_id, i);
+               card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                               "pci:green:tx:%d-%d",
+                                               dev->dev_id, i);
+
+               card->tx_led.dev = &dev->dev;
+               card->recon_led.brightness_set = led_recon_set;
+               card->recon_led.default_trigger = devm_kasprintf(&pdev->dev,
+                                               GFP_KERNEL, "arc%d-%d-recon",
+                                               dev->dev_id, i);
+               card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                               "pci:red:recon:%d-%d",
+                                               dev->dev_id, i);
+               card->recon_led.dev = &dev->dev;
                card->dev = dev;
 
+               ret = devm_led_classdev_register(&pdev->dev, &card->tx_led);
+               if (ret)
+                       goto out_port;
+
+               ret = devm_led_classdev_register(&pdev->dev, &card->recon_led);
+               if (ret)
+                       goto out_port;
+
                dev_set_drvdata(&dev->dev, card);
 
                ret = com20020_found(dev, IRQF_SHARED);
                if (ret)
                        goto out_port;
 
+               devm_arcnet_led_init(dev, dev->dev_id, i);
+
                list_add(&card->list, &priv->list_dev);
        }
 
@@ -234,6 +314,18 @@ static struct com20020_pci_card_info card_info_eae_arc1 = {
                        .size = 0x08,
                },
        },
+       .misc_map = {
+               .bar = 2,
+               .offset = 0x10,
+               .size = 0x04,
+       },
+       .leds = {
+               {
+                       .green = 0x0,
+                       .red = 0x1,
+               },
+       },
+       .rotary = 0x0,
        .flags = ARC_CAN_10MBIT,
 };
 
@@ -251,6 +343,21 @@ static struct com20020_pci_card_info card_info_eae_ma1 = {
                        .size = 0x08,
                }
        },
+       .misc_map = {
+               .bar = 2,
+               .offset = 0x10,
+               .size = 0x04,
+       },
+       .leds = {
+               {
+                       .green = 0x0,
+                       .red = 0x1,
+               }, {
+                       .green = 0x2,
+                       .red = 0x3,
+               },
+       },
+       .rotary = 0x0,
        .flags = ARC_CAN_10MBIT,
 };