All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai] [PATCH] rtcan/peek_pci: add support for 3 and 4 port cards.
@ 2013-11-07 11:33 Konrad Banachowicz
  2013-11-07 11:40 ` Jan Kiszka
  0 siblings, 1 reply; 2+ messages in thread
From: Konrad Banachowicz @ 2013-11-07 11:33 UTC (permalink / raw)
  To: xenomai

---
 ksrc/drivers/can/sja1000/rtcan_peak_pci.c |  451 ++++++++++++++---------------
 1 file changed, 224 insertions(+), 227 deletions(-)

diff --git a/ksrc/drivers/can/sja1000/rtcan_peak_pci.c b/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
index d13a7ff..132d4e8 100644
--- a/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
+++ b/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
@@ -46,13 +46,12 @@ MODULE_DESCRIPTION("RTCAN board driver for PEAK-PCI cards");
 MODULE_SUPPORTED_DEVICE("PEAK-PCI card CAN controller");
 MODULE_LICENSE("GPL");
 
-struct rtcan_peak_pci
-{
-    struct pci_dev *pci_dev;
-    struct rtcan_device *slave_dev;
-    int channel;
-    volatile void __iomem *base_addr;
-    volatile void __iomem *conf_addr;
+struct rtcan_peak_pci {
+        struct pci_dev *pci_dev;
+        struct rtcan_device *slave_dev;
+        int channel;
+        volatile void __iomem *base_addr;
+        volatile void __iomem *conf_addr;
 };
 
 #define PEAK_PCI_CAN_SYS_CLOCK (16000000 / 2)
@@ -62,8 +61,11 @@ struct rtcan_peak_pci
 #define PELICAN_DEFAULT (SJA_CDR_CAN_MODE                                 )
 
 #define CHANNEL_SINGLE 0 /* this is a single channel device */
-#define CHANNEL_MASTER 1 /* multi channel device, this device is master */
-#define CHANNEL_SLAVE  2 /* multi channel device, this is slave */
+#define CHANNEL_MASTER 0 /* multi channel device, this device is master */
+#define CHANNEL_SLAVE  1 /* multi channel device, this is slave */
+#define CHANNEL_SLAVE_1 1 /* multi channel device, this is slave 1*/
+#define CHANNEL_SLAVE_2 2 /* multi channel device, this is slave 2*/
+#define CHANNEL_SLAVE_3 3 /* multi channel device, this is slave 3*/
 
 // important PITA registers
 #define PITA_ICR         0x00        // interrupt control register
@@ -82,282 +84,277 @@ struct rtcan_peak_pci
 #define PCI_CONFIG_PORT_SIZE 0x1000  // size of the config io-memory
 #define PCI_PORT_SIZE        0x0400  // size of a channel io-memory
 
+static const u16 peak_pci_icr_masks[] = {0x02, 0x01, 0x40, 0x80};
+
 static struct pci_device_id peak_pci_tbl[] = {
-	{PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-	{PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-	{PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-	{PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-	{PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-	{PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-	{PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
-	{ }
+        {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+        {PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+        {PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+        {PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+        {PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+        {PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+        {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+        { }
 };
 MODULE_DEVICE_TABLE (pci, peak_pci_tbl);
 
 
 static u8 rtcan_peak_pci_read_reg(struct rtcan_device *dev, int port)
 {
-    struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
-    return readb(board->base_addr + ((unsigned long)port << 2));
+        struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
+        return readb(board->base_addr + ((unsigned long)port << 2));
 }
 
 static void rtcan_peak_pci_write_reg(struct rtcan_device *dev, int port, u8 data)
 {
-    struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
-    writeb(data, board->base_addr + ((unsigned long)port << 2));
+        struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
+        writeb(data, board->base_addr + ((unsigned long)port << 2));
 }
 
 static void rtcan_peak_pci_irq_ack(struct rtcan_device *dev)
 {
-    struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
-    u16 pita_icr_low;
-
-    /* Select and clear in Pita stored interrupt */
-    pita_icr_low = readw(board->conf_addr + PITA_ICR);
-    if (board->channel == CHANNEL_SLAVE) {
-	if (pita_icr_low & 0x0001)
-	    writew(0x0001, board->conf_addr + PITA_ICR);
-    }
-    else {
-	if (pita_icr_low & 0x0002)
-	    writew(0x0002, board->conf_addr + PITA_ICR);
-    }
+        struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
+        u16 pita_icr_low;
+
+        /* Select and clear in Pita stored interrupt */
+        pita_icr_low = readw(board->conf_addr + PITA_ICR);
+
+        if (pita_icr_low & peak_pci_icr_masks[board->channel]) {
+                writew(peak_pci_icr_masks[board->channel], board->conf_addr + PITA_ICR);
+        }
 }
 
 static void rtcan_peak_pci_del_chan(struct rtcan_device *dev,
-				    int init_step)
+                                    int init_step)
 {
-    struct rtcan_peak_pci *board;
-    u16 pita_icr_high;
-
-    if (!dev)
-	return;
-
-    board = (struct rtcan_peak_pci *)dev->board_priv;
-
-    switch (init_step) {
-    case 0:			/* Full cleanup */
-	printk("Removing %s %s device %s\n",
-	       peak_pci_board_name, dev->ctrl_name, dev->name);
-	rtcan_sja1000_unregister(dev);
-    case 5:
-	pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
-	if (board->channel == CHANNEL_SLAVE) {
-	    pita_icr_high &= ~0x0001;
-	} else {
-	    pita_icr_high &= ~0x0002;
-	}
-	writew(pita_icr_high, board->conf_addr + PITA_ICR + 2);
-    case 4:
-	iounmap((void *)board->base_addr);
-    case 3:
-	if (board->channel != CHANNEL_SLAVE)
-	    iounmap((void *)board->conf_addr);
-    case 2:
-	rtcan_dev_free(dev);
-    case 1:
-	break;
-    }
+        struct rtcan_peak_pci *board;
+        u16 pita_icr_high;
+
+        if (!dev)
+                return;
+
+        board = (struct rtcan_peak_pci *)dev->board_priv;
+
+        switch (init_step) {
+        case 0:			/* Full cleanup */
+                printk("Removing %s %s device %s\n",
+                       peak_pci_board_name, dev->ctrl_name, dev->name);
+                rtcan_sja1000_unregister(dev);
+        case 5:
+                pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
+                pita_icr_high &= ~peak_pci_icr_masks[board->channel];
+                writew(pita_icr_high, board->conf_addr + PITA_ICR + 2);
+        case 4:
+                iounmap((void *)board->base_addr);
+        case 3:
+                if (board->channel != CHANNEL_SLAVE)
+                        iounmap((void *)board->conf_addr);
+        case 2:
+                rtcan_dev_free(dev);
+        case 1:
+                break;
+        }
 
 }
 
 static int rtcan_peak_pci_add_chan(struct pci_dev *pdev, int channel,
-				   struct rtcan_device **master_dev)
+                                   struct rtcan_device **master_dev)
 {
-    struct rtcan_device *dev;
-    struct rtcan_sja1000 *chip;
-    struct rtcan_peak_pci *board;
-    u16 pita_icr_high;
-    unsigned long addr;
-    int ret, init_step = 1;
-
-    dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000),
-			  sizeof(struct rtcan_peak_pci));
-    if (dev == NULL)
-	return -ENOMEM;
-    init_step = 2;
-
-    chip = (struct rtcan_sja1000 *)dev->priv;
-    board = (struct rtcan_peak_pci *)dev->board_priv;
-
-    board->pci_dev = pdev;
-    board->channel = channel;
-
-    if (channel != CHANNEL_SLAVE) {
-
-	addr = pci_resource_start(pdev, 0);
-	board->conf_addr = ioremap(addr, PCI_CONFIG_PORT_SIZE);
-	if (board->conf_addr == 0) {
-	    ret = -ENODEV;
-	    goto failure;
-	}
-	init_step = 3;
-
-	/* Set GPIO control register */
-	writew(0x0005, board->conf_addr + PITA_GPIOICR + 2);
-
-	if (channel == CHANNEL_MASTER)
-	    writeb(0x00, board->conf_addr + PITA_GPIOICR); /* enable both */
-	else
-	    writeb(0x04, board->conf_addr + PITA_GPIOICR); /* enable single */
-
-	writeb(0x05, board->conf_addr + PITA_MISC + 3);  /* toggle reset */
-	mdelay(5);
-	writeb(0x04, board->conf_addr + PITA_MISC + 3);  /* leave parport mux mode */
-    } else {
-	struct rtcan_peak_pci *master_board =
-	    (struct rtcan_peak_pci *)(*master_dev)->board_priv;
-	master_board->slave_dev = dev;
-	board->conf_addr = master_board->conf_addr;
-    }
-
-    addr = pci_resource_start(pdev, 1);
-    if (channel == CHANNEL_SLAVE)
-	addr += 0x400;
-
-    board->base_addr = ioremap(addr, PCI_PORT_SIZE);
-    if (board->base_addr == 0) {
-	ret = -ENODEV;
-	goto failure;
-    }
-    init_step = 4;
-
-    dev->board_name = peak_pci_board_name;
-
-    chip->read_reg = rtcan_peak_pci_read_reg;
-    chip->write_reg = rtcan_peak_pci_write_reg;
-    chip->irq_ack = rtcan_peak_pci_irq_ack;
-
-    /* Clock frequency in Hz */
-    dev->can_sys_clock = PEAK_PCI_CAN_SYS_CLOCK;
-
-    /* Output control register */
-    chip->ocr = SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL;
-
-    /* Clock divider register */
-    if (channel == CHANNEL_MASTER)
-	chip->cdr = PELICAN_MASTER;
-    else
-	chip->cdr = PELICAN_SINGLE;
-
-    strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ);
-
-    /* Register and setup interrupt handling */
-    chip->irq_flags = RTDM_IRQTYPE_SHARED;
-    chip->irq_num = pdev->irq;
-    pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
-    if (channel == CHANNEL_SLAVE) {
-	pita_icr_high |= 0x0001;
-    } else {
-	pita_icr_high |= 0x0002;
-    }
-    writew(pita_icr_high, board->conf_addr + PITA_ICR + 2);
-    init_step = 5;
-
-    printk("%s: base_addr=%p conf_addr=%p irq=%d\n", RTCAN_DRV_NAME,
-	   board->base_addr, board->conf_addr, chip->irq_num);
-
-    /* Register SJA1000 device */
-    ret = rtcan_sja1000_register(dev);
-    if (ret) {
-	printk(KERN_ERR
-	       "ERROR %d while trying to register SJA1000 device!\n", ret);
-	goto failure;
-    }
-
-    if (channel != CHANNEL_SLAVE)
-	*master_dev = dev;
-
-    return 0;
-
- failure:
-    rtcan_peak_pci_del_chan(dev, init_step);
-    return ret;
+        struct rtcan_device *dev;
+        struct rtcan_sja1000 *chip;
+        struct rtcan_peak_pci *board;
+        u16 pita_icr_high;
+        unsigned long addr;
+        int ret, init_step = 1;
+
+        dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000),
+                              sizeof(struct rtcan_peak_pci));
+        if (dev == NULL)
+                return -ENOMEM;
+        init_step = 2;
+
+        chip = (struct rtcan_sja1000 *)dev->priv;
+        board = (struct rtcan_peak_pci *)dev->board_priv;
+
+        board->pci_dev = pdev;
+        board->channel = channel;
+
+        if (channel == CHANNEL_MASTER) {
+
+                addr = pci_resource_start(pdev, 0);
+                board->conf_addr = ioremap(addr, PCI_CONFIG_PORT_SIZE);
+                if (board->conf_addr == 0) {
+                        ret = -ENODEV;
+                        goto failure;
+                }
+                init_step = 3;
+
+                /* Set GPIO control register */
+                writew(0x0005, board->conf_addr + PITA_GPIOICR + 2);
+
+                if (channel == CHANNEL_MASTER)
+                        writeb(0x00, board->conf_addr + PITA_GPIOICR); /* enable both */
+                else
+                        writeb(0x04, board->conf_addr + PITA_GPIOICR); /* enable single */
+
+                writeb(0x05, board->conf_addr + PITA_MISC + 3);  /* toggle reset */
+                mdelay(5);
+                writeb(0x04, board->conf_addr + PITA_MISC + 3);  /* leave parport mux mode */
+        } else {
+                struct rtcan_peak_pci *master_board =
+                        (struct rtcan_peak_pci *)(*master_dev)->board_priv;
+                master_board->slave_dev = dev;
+                board->conf_addr = master_board->conf_addr;
+        }
+
+        addr = pci_resource_start(pdev, 1) + channel * PCI_PORT_SIZE;
+
+        board->base_addr = ioremap(addr, PCI_PORT_SIZE);
+        if (board->base_addr == 0) {
+                ret = -ENODEV;
+                goto failure;
+        }
+
+        init_step = 4;
+
+        dev->board_name = peak_pci_board_name;
+
+        chip->read_reg = rtcan_peak_pci_read_reg;
+        chip->write_reg = rtcan_peak_pci_write_reg;
+        chip->irq_ack = rtcan_peak_pci_irq_ack;
+
+        /* Clock frequency in Hz */
+        dev->can_sys_clock = PEAK_PCI_CAN_SYS_CLOCK;
+
+        /* Output control register */
+        chip->ocr = SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL;
+
+        /* Clock divider register */
+        if (channel == CHANNEL_MASTER)
+                chip->cdr = PELICAN_MASTER;
+        else
+                chip->cdr = PELICAN_SINGLE;
+
+        strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ);
+
+        /* Register and setup interrupt handling */
+        chip->irq_flags = RTDM_IRQTYPE_SHARED;
+        chip->irq_num = pdev->irq;
+        pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
+
+        pita_icr_high |= peak_pci_icr_masks[channel];
+
+        writew(pita_icr_high, board->conf_addr + PITA_ICR + 2);
+        init_step = 5;
+
+        printk("%s: base_addr=%p conf_addr=%p irq=%d\n", RTCAN_DRV_NAME,
+               board->base_addr, board->conf_addr, chip->irq_num);
+
+        /* Register SJA1000 device */
+        ret = rtcan_sja1000_register(dev);
+        if (ret) {
+                printk(KERN_ERR
+                       "ERROR %d while trying to register SJA1000 device!\n", ret);
+                goto failure;
+        }
+
+        if (channel != CHANNEL_SLAVE)
+                *master_dev = dev;
+
+        return 0;
+
+failure:
+        rtcan_peak_pci_del_chan(dev, init_step);
+        return ret;
 }
 
 static int peak_pci_init_one(struct pci_dev *pdev,
-			     const struct pci_device_id *ent)
+                             const struct pci_device_id *ent)
 {
-    int ret;
-    u16 sub_sys_id;
-    struct rtcan_device *master_dev = NULL;
+        int ret;
+        int num_channels;
+        int i;
+        u16 sub_sys_id;
+        struct rtcan_device *master_dev = NULL;
+
+        printk("%s: initializing device %04x:%04x\n",
+               RTCAN_DRV_NAME,  pdev->vendor, pdev->device);
 
-    printk("%s: initializing device %04x:%04x\n",
-	   RTCAN_DRV_NAME,  pdev->vendor, pdev->device);
+        if ((ret = pci_enable_device (pdev)))
+                goto failure;
 
-    if ((ret = pci_enable_device (pdev)))
-	goto failure;
+        if ((ret = pci_request_regions(pdev, RTCAN_DRV_NAME)))
+                goto failure;
 
-    if ((ret = pci_request_regions(pdev, RTCAN_DRV_NAME)))
-	goto failure;
+        if ((ret = pci_read_config_word(pdev, 0x2e, &sub_sys_id)))
+                goto failure_cleanup;
 
-    if ((ret = pci_read_config_word(pdev, 0x2e, &sub_sys_id)))
-	goto failure_cleanup;
+        /* Enable memory space */
+        if ((ret = pci_write_config_word(pdev, 0x04, 2)))
+                goto failure_cleanup;
 
-    /* Enable memory space */
-    if ((ret = pci_write_config_word(pdev, 0x04, 2)))
-	goto failure_cleanup;
+        if ((ret = pci_write_config_word(pdev, 0x44, 0)))
+                goto failure_cleanup;
 
-    if ((ret = pci_write_config_word(pdev, 0x44, 0)))
-	goto failure_cleanup;
+        if (sub_sys_id >= 12) {
+                num_channels = 4;
+        } else if (sub_sys_id >= 12) {
+                num_channels = 3;
+        } else if (sub_sys_id >= 4) {
+                num_channels = 2;
+        } else {
+                num_channels = 1;
+        }
 
-    if (sub_sys_id > 3) {
-	if ((ret = rtcan_peak_pci_add_chan(pdev, CHANNEL_MASTER,
-					   &master_dev)))
-	    goto failure_cleanup;
-	if ((ret = rtcan_peak_pci_add_chan(pdev, CHANNEL_SLAVE,
-					   &master_dev)))
-	    goto failure_cleanup;
-    } else {
-	if ((ret = rtcan_peak_pci_add_chan(pdev, CHANNEL_SINGLE,
-					   &master_dev)))
-	    goto failure_cleanup;
-    }
+        for(i = 0; i < num_channels; i++) {
+                if ((ret = rtcan_peak_pci_add_chan(pdev, i, &master_dev)))
+                        goto failure_cleanup;
+        }
 
-    pci_set_drvdata(pdev, master_dev);
-    return 0;
+        pci_set_drvdata(pdev, master_dev);
+        return 0;
 
- failure_cleanup:
-    if (master_dev)
-	rtcan_peak_pci_del_chan(master_dev, 0);
+failure_cleanup:
+        if (master_dev)
+                rtcan_peak_pci_del_chan(master_dev, 0);
 
-    pci_release_regions(pdev);
+        pci_release_regions(pdev);
 
- failure:
-    return ret;
+failure:
+        return ret;
 
 }
 
 static void peak_pci_remove_one(struct pci_dev *pdev)
 {
-    struct rtcan_device *dev = pci_get_drvdata(pdev);
-    struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
+        struct rtcan_device *dev = pci_get_drvdata(pdev);
+        struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
 
-    if (board->slave_dev)
-	rtcan_peak_pci_del_chan(board->slave_dev, 0);
-    rtcan_peak_pci_del_chan(dev, 0);
+        if (board->slave_dev)
+                rtcan_peak_pci_del_chan(board->slave_dev, 0);
+        rtcan_peak_pci_del_chan(dev, 0);
 
-    pci_release_regions(pdev);
-    pci_disable_device(pdev);
-    pci_set_drvdata(pdev, NULL);
+        pci_release_regions(pdev);
+        pci_disable_device(pdev);
+        pci_set_drvdata(pdev, NULL);
 }
 
 static struct pci_driver rtcan_peak_pci_driver = {
-	.name		= RTCAN_DRV_NAME,
-	.id_table	= peak_pci_tbl,
-	.probe		= peak_pci_init_one,
-	.remove		= peak_pci_remove_one,
+        .name		= RTCAN_DRV_NAME,
+        .id_table	= peak_pci_tbl,
+        .probe		= peak_pci_init_one,
+        .remove		= peak_pci_remove_one,
 };
 
 static int __init rtcan_peak_pci_init(void)
 {
-    return pci_register_driver(&rtcan_peak_pci_driver);
+        return pci_register_driver(&rtcan_peak_pci_driver);
 }
 
 
 static void __exit rtcan_peak_pci_exit(void)
 {
-    pci_unregister_driver(&rtcan_peak_pci_driver);
+        pci_unregister_driver(&rtcan_peak_pci_driver);
 }
 
 module_init(rtcan_peak_pci_init);
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Xenomai] [PATCH] rtcan/peek_pci: add support for 3 and 4 port cards.
  2013-11-07 11:33 [Xenomai] [PATCH] rtcan/peek_pci: add support for 3 and 4 port cards Konrad Banachowicz
@ 2013-11-07 11:40 ` Jan Kiszka
  0 siblings, 0 replies; 2+ messages in thread
From: Jan Kiszka @ 2013-11-07 11:40 UTC (permalink / raw)
  To: Konrad Banachowicz, xenomai

On 2013-11-07 12:33, Konrad Banachowicz wrote:
> ---
>  ksrc/drivers/can/sja1000/rtcan_peak_pci.c |  451 ++++++++++++++---------------
>  1 file changed, 224 insertions(+), 227 deletions(-)
> 
> diff --git a/ksrc/drivers/can/sja1000/rtcan_peak_pci.c b/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
> index d13a7ff..132d4e8 100644
> --- a/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
> +++ b/ksrc/drivers/can/sja1000/rtcan_peak_pci.c
> @@ -46,13 +46,12 @@ MODULE_DESCRIPTION("RTCAN board driver for PEAK-PCI cards");
>  MODULE_SUPPORTED_DEVICE("PEAK-PCI card CAN controller");
>  MODULE_LICENSE("GPL");
>  
> -struct rtcan_peak_pci
> -{
> -    struct pci_dev *pci_dev;
> -    struct rtcan_device *slave_dev;
> -    int channel;
> -    volatile void __iomem *base_addr;
> -    volatile void __iomem *conf_addr;
> +struct rtcan_peak_pci {
> +        struct pci_dev *pci_dev;
> +        struct rtcan_device *slave_dev;
> +        int channel;
> +        volatile void __iomem *base_addr;
> +        volatile void __iomem *conf_addr;
>  };
>  
>  #define PEAK_PCI_CAN_SYS_CLOCK (16000000 / 2)
> @@ -62,8 +61,11 @@ struct rtcan_peak_pci
>  #define PELICAN_DEFAULT (SJA_CDR_CAN_MODE                                 )
>  
>  #define CHANNEL_SINGLE 0 /* this is a single channel device */
> -#define CHANNEL_MASTER 1 /* multi channel device, this device is master */
> -#define CHANNEL_SLAVE  2 /* multi channel device, this is slave */
> +#define CHANNEL_MASTER 0 /* multi channel device, this device is master */
> +#define CHANNEL_SLAVE  1 /* multi channel device, this is slave */
> +#define CHANNEL_SLAVE_1 1 /* multi channel device, this is slave 1*/
> +#define CHANNEL_SLAVE_2 2 /* multi channel device, this is slave 2*/
> +#define CHANNEL_SLAVE_3 3 /* multi channel device, this is slave 3*/
>  
>  // important PITA registers
>  #define PITA_ICR         0x00        // interrupt control register
> @@ -82,282 +84,277 @@ struct rtcan_peak_pci
>  #define PCI_CONFIG_PORT_SIZE 0x1000  // size of the config io-memory
>  #define PCI_PORT_SIZE        0x0400  // size of a channel io-memory
>  
> +static const u16 peak_pci_icr_masks[] = {0x02, 0x01, 0x40, 0x80};
> +
>  static struct pci_device_id peak_pci_tbl[] = {
> -	{PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> -	{PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> -	{PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> -	{PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> -	{PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> -	{PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> -	{PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> -	{ }
> +        {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> +        {PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> +        {PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> +        {PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> +        {PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> +        {PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> +        {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
> +        { }
>  };
>  MODULE_DEVICE_TABLE (pci, peak_pci_tbl);
>  
>  
>  static u8 rtcan_peak_pci_read_reg(struct rtcan_device *dev, int port)
>  {
> -    struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
> -    return readb(board->base_addr + ((unsigned long)port << 2));
> +        struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
> +        return readb(board->base_addr + ((unsigned long)port << 2));
>  }
>  
>  static void rtcan_peak_pci_write_reg(struct rtcan_device *dev, int port, u8 data)
>  {
> -    struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
> -    writeb(data, board->base_addr + ((unsigned long)port << 2));
> +        struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
> +        writeb(data, board->base_addr + ((unsigned long)port << 2));
>  }
>  
>  static void rtcan_peak_pci_irq_ack(struct rtcan_device *dev)
>  {
> -    struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
> -    u16 pita_icr_low;
> -
> -    /* Select and clear in Pita stored interrupt */
> -    pita_icr_low = readw(board->conf_addr + PITA_ICR);
> -    if (board->channel == CHANNEL_SLAVE) {
> -	if (pita_icr_low & 0x0001)
> -	    writew(0x0001, board->conf_addr + PITA_ICR);
> -    }
> -    else {
> -	if (pita_icr_low & 0x0002)
> -	    writew(0x0002, board->conf_addr + PITA_ICR);
> -    }
> +        struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
> +        u16 pita_icr_low;
> +
> +        /* Select and clear in Pita stored interrupt */
> +        pita_icr_low = readw(board->conf_addr + PITA_ICR);
> +
> +        if (pita_icr_low & peak_pci_icr_masks[board->channel]) {
> +                writew(peak_pci_icr_masks[board->channel], board->conf_addr + PITA_ICR);
> +        }
>  }
>  
>  static void rtcan_peak_pci_del_chan(struct rtcan_device *dev,
> -				    int init_step)
> +                                    int init_step)
>  {
> -    struct rtcan_peak_pci *board;
> -    u16 pita_icr_high;
> -
> -    if (!dev)
> -	return;
> -
> -    board = (struct rtcan_peak_pci *)dev->board_priv;
> -
> -    switch (init_step) {
> -    case 0:			/* Full cleanup */
> -	printk("Removing %s %s device %s\n",
> -	       peak_pci_board_name, dev->ctrl_name, dev->name);
> -	rtcan_sja1000_unregister(dev);
> -    case 5:
> -	pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
> -	if (board->channel == CHANNEL_SLAVE) {
> -	    pita_icr_high &= ~0x0001;
> -	} else {
> -	    pita_icr_high &= ~0x0002;
> -	}
> -	writew(pita_icr_high, board->conf_addr + PITA_ICR + 2);
> -    case 4:
> -	iounmap((void *)board->base_addr);
> -    case 3:
> -	if (board->channel != CHANNEL_SLAVE)
> -	    iounmap((void *)board->conf_addr);
> -    case 2:
> -	rtcan_dev_free(dev);
> -    case 1:
> -	break;
> -    }
> +        struct rtcan_peak_pci *board;
> +        u16 pita_icr_high;
> +
> +        if (!dev)
> +                return;
> +
> +        board = (struct rtcan_peak_pci *)dev->board_priv;
> +
> +        switch (init_step) {
> +        case 0:			/* Full cleanup */
> +                printk("Removing %s %s device %s\n",
> +                       peak_pci_board_name, dev->ctrl_name, dev->name);
> +                rtcan_sja1000_unregister(dev);
> +        case 5:
> +                pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
> +                pita_icr_high &= ~peak_pci_icr_masks[board->channel];
> +                writew(pita_icr_high, board->conf_addr + PITA_ICR + 2);
> +        case 4:
> +                iounmap((void *)board->base_addr);
> +        case 3:
> +                if (board->channel != CHANNEL_SLAVE)
> +                        iounmap((void *)board->conf_addr);
> +        case 2:
> +                rtcan_dev_free(dev);
> +        case 1:
> +                break;
> +        }
>  
>  }
>  
>  static int rtcan_peak_pci_add_chan(struct pci_dev *pdev, int channel,
> -				   struct rtcan_device **master_dev)
> +                                   struct rtcan_device **master_dev)
>  {
> -    struct rtcan_device *dev;
> -    struct rtcan_sja1000 *chip;
> -    struct rtcan_peak_pci *board;
> -    u16 pita_icr_high;
> -    unsigned long addr;
> -    int ret, init_step = 1;
> -
> -    dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000),
> -			  sizeof(struct rtcan_peak_pci));
> -    if (dev == NULL)
> -	return -ENOMEM;
> -    init_step = 2;
> -
> -    chip = (struct rtcan_sja1000 *)dev->priv;
> -    board = (struct rtcan_peak_pci *)dev->board_priv;
> -
> -    board->pci_dev = pdev;
> -    board->channel = channel;
> -
> -    if (channel != CHANNEL_SLAVE) {
> -
> -	addr = pci_resource_start(pdev, 0);
> -	board->conf_addr = ioremap(addr, PCI_CONFIG_PORT_SIZE);
> -	if (board->conf_addr == 0) {
> -	    ret = -ENODEV;
> -	    goto failure;
> -	}
> -	init_step = 3;
> -
> -	/* Set GPIO control register */
> -	writew(0x0005, board->conf_addr + PITA_GPIOICR + 2);
> -
> -	if (channel == CHANNEL_MASTER)
> -	    writeb(0x00, board->conf_addr + PITA_GPIOICR); /* enable both */
> -	else
> -	    writeb(0x04, board->conf_addr + PITA_GPIOICR); /* enable single */
> -
> -	writeb(0x05, board->conf_addr + PITA_MISC + 3);  /* toggle reset */
> -	mdelay(5);
> -	writeb(0x04, board->conf_addr + PITA_MISC + 3);  /* leave parport mux mode */
> -    } else {
> -	struct rtcan_peak_pci *master_board =
> -	    (struct rtcan_peak_pci *)(*master_dev)->board_priv;
> -	master_board->slave_dev = dev;
> -	board->conf_addr = master_board->conf_addr;
> -    }
> -
> -    addr = pci_resource_start(pdev, 1);
> -    if (channel == CHANNEL_SLAVE)
> -	addr += 0x400;
> -
> -    board->base_addr = ioremap(addr, PCI_PORT_SIZE);
> -    if (board->base_addr == 0) {
> -	ret = -ENODEV;
> -	goto failure;
> -    }
> -    init_step = 4;
> -
> -    dev->board_name = peak_pci_board_name;
> -
> -    chip->read_reg = rtcan_peak_pci_read_reg;
> -    chip->write_reg = rtcan_peak_pci_write_reg;
> -    chip->irq_ack = rtcan_peak_pci_irq_ack;
> -
> -    /* Clock frequency in Hz */
> -    dev->can_sys_clock = PEAK_PCI_CAN_SYS_CLOCK;
> -
> -    /* Output control register */
> -    chip->ocr = SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL;
> -
> -    /* Clock divider register */
> -    if (channel == CHANNEL_MASTER)
> -	chip->cdr = PELICAN_MASTER;
> -    else
> -	chip->cdr = PELICAN_SINGLE;
> -
> -    strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ);
> -
> -    /* Register and setup interrupt handling */
> -    chip->irq_flags = RTDM_IRQTYPE_SHARED;
> -    chip->irq_num = pdev->irq;
> -    pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
> -    if (channel == CHANNEL_SLAVE) {
> -	pita_icr_high |= 0x0001;
> -    } else {
> -	pita_icr_high |= 0x0002;
> -    }
> -    writew(pita_icr_high, board->conf_addr + PITA_ICR + 2);
> -    init_step = 5;
> -
> -    printk("%s: base_addr=%p conf_addr=%p irq=%d\n", RTCAN_DRV_NAME,
> -	   board->base_addr, board->conf_addr, chip->irq_num);
> -
> -    /* Register SJA1000 device */
> -    ret = rtcan_sja1000_register(dev);
> -    if (ret) {
> -	printk(KERN_ERR
> -	       "ERROR %d while trying to register SJA1000 device!\n", ret);
> -	goto failure;
> -    }
> -
> -    if (channel != CHANNEL_SLAVE)
> -	*master_dev = dev;
> -
> -    return 0;
> -
> - failure:
> -    rtcan_peak_pci_del_chan(dev, init_step);
> -    return ret;
> +        struct rtcan_device *dev;
> +        struct rtcan_sja1000 *chip;
> +        struct rtcan_peak_pci *board;
> +        u16 pita_icr_high;
> +        unsigned long addr;
> +        int ret, init_step = 1;
> +
> +        dev = rtcan_dev_alloc(sizeof(struct rtcan_sja1000),
> +                              sizeof(struct rtcan_peak_pci));
> +        if (dev == NULL)
> +                return -ENOMEM;
> +        init_step = 2;
> +
> +        chip = (struct rtcan_sja1000 *)dev->priv;
> +        board = (struct rtcan_peak_pci *)dev->board_priv;
> +
> +        board->pci_dev = pdev;
> +        board->channel = channel;
> +
> +        if (channel == CHANNEL_MASTER) {
> +
> +                addr = pci_resource_start(pdev, 0);
> +                board->conf_addr = ioremap(addr, PCI_CONFIG_PORT_SIZE);
> +                if (board->conf_addr == 0) {
> +                        ret = -ENODEV;
> +                        goto failure;
> +                }
> +                init_step = 3;
> +
> +                /* Set GPIO control register */
> +                writew(0x0005, board->conf_addr + PITA_GPIOICR + 2);
> +
> +                if (channel == CHANNEL_MASTER)
> +                        writeb(0x00, board->conf_addr + PITA_GPIOICR); /* enable both */
> +                else
> +                        writeb(0x04, board->conf_addr + PITA_GPIOICR); /* enable single */
> +
> +                writeb(0x05, board->conf_addr + PITA_MISC + 3);  /* toggle reset */
> +                mdelay(5);
> +                writeb(0x04, board->conf_addr + PITA_MISC + 3);  /* leave parport mux mode */
> +        } else {
> +                struct rtcan_peak_pci *master_board =
> +                        (struct rtcan_peak_pci *)(*master_dev)->board_priv;
> +                master_board->slave_dev = dev;
> +                board->conf_addr = master_board->conf_addr;
> +        }
> +
> +        addr = pci_resource_start(pdev, 1) + channel * PCI_PORT_SIZE;
> +
> +        board->base_addr = ioremap(addr, PCI_PORT_SIZE);
> +        if (board->base_addr == 0) {
> +                ret = -ENODEV;
> +                goto failure;
> +        }
> +
> +        init_step = 4;
> +
> +        dev->board_name = peak_pci_board_name;
> +
> +        chip->read_reg = rtcan_peak_pci_read_reg;
> +        chip->write_reg = rtcan_peak_pci_write_reg;
> +        chip->irq_ack = rtcan_peak_pci_irq_ack;
> +
> +        /* Clock frequency in Hz */
> +        dev->can_sys_clock = PEAK_PCI_CAN_SYS_CLOCK;
> +
> +        /* Output control register */
> +        chip->ocr = SJA_OCR_MODE_NORMAL | SJA_OCR_TX0_PUSHPULL;
> +
> +        /* Clock divider register */
> +        if (channel == CHANNEL_MASTER)
> +                chip->cdr = PELICAN_MASTER;
> +        else
> +                chip->cdr = PELICAN_SINGLE;
> +
> +        strncpy(dev->name, RTCAN_DEV_NAME, IFNAMSIZ);
> +
> +        /* Register and setup interrupt handling */
> +        chip->irq_flags = RTDM_IRQTYPE_SHARED;
> +        chip->irq_num = pdev->irq;
> +        pita_icr_high = readw(board->conf_addr + PITA_ICR + 2);
> +
> +        pita_icr_high |= peak_pci_icr_masks[channel];
> +
> +        writew(pita_icr_high, board->conf_addr + PITA_ICR + 2);
> +        init_step = 5;
> +
> +        printk("%s: base_addr=%p conf_addr=%p irq=%d\n", RTCAN_DRV_NAME,
> +               board->base_addr, board->conf_addr, chip->irq_num);
> +
> +        /* Register SJA1000 device */
> +        ret = rtcan_sja1000_register(dev);
> +        if (ret) {
> +                printk(KERN_ERR
> +                       "ERROR %d while trying to register SJA1000 device!\n", ret);
> +                goto failure;
> +        }
> +
> +        if (channel != CHANNEL_SLAVE)
> +                *master_dev = dev;
> +
> +        return 0;
> +
> +failure:
> +        rtcan_peak_pci_del_chan(dev, init_step);
> +        return ret;
>  }
>  
>  static int peak_pci_init_one(struct pci_dev *pdev,
> -			     const struct pci_device_id *ent)
> +                             const struct pci_device_id *ent)
>  {
> -    int ret;
> -    u16 sub_sys_id;
> -    struct rtcan_device *master_dev = NULL;
> +        int ret;
> +        int num_channels;
> +        int i;
> +        u16 sub_sys_id;
> +        struct rtcan_device *master_dev = NULL;
> +
> +        printk("%s: initializing device %04x:%04x\n",
> +               RTCAN_DRV_NAME,  pdev->vendor, pdev->device);
>  
> -    printk("%s: initializing device %04x:%04x\n",
> -	   RTCAN_DRV_NAME,  pdev->vendor, pdev->device);
> +        if ((ret = pci_enable_device (pdev)))
> +                goto failure;
>  
> -    if ((ret = pci_enable_device (pdev)))
> -	goto failure;
> +        if ((ret = pci_request_regions(pdev, RTCAN_DRV_NAME)))
> +                goto failure;
>  
> -    if ((ret = pci_request_regions(pdev, RTCAN_DRV_NAME)))
> -	goto failure;
> +        if ((ret = pci_read_config_word(pdev, 0x2e, &sub_sys_id)))
> +                goto failure_cleanup;
>  
> -    if ((ret = pci_read_config_word(pdev, 0x2e, &sub_sys_id)))
> -	goto failure_cleanup;
> +        /* Enable memory space */
> +        if ((ret = pci_write_config_word(pdev, 0x04, 2)))
> +                goto failure_cleanup;
>  
> -    /* Enable memory space */
> -    if ((ret = pci_write_config_word(pdev, 0x04, 2)))
> -	goto failure_cleanup;
> +        if ((ret = pci_write_config_word(pdev, 0x44, 0)))
> +                goto failure_cleanup;
>  
> -    if ((ret = pci_write_config_word(pdev, 0x44, 0)))
> -	goto failure_cleanup;
> +        if (sub_sys_id >= 12) {
> +                num_channels = 4;
> +        } else if (sub_sys_id >= 12) {
> +                num_channels = 3;
> +        } else if (sub_sys_id >= 4) {
> +                num_channels = 2;
> +        } else {
> +                num_channels = 1;
> +        }
>  
> -    if (sub_sys_id > 3) {
> -	if ((ret = rtcan_peak_pci_add_chan(pdev, CHANNEL_MASTER,
> -					   &master_dev)))
> -	    goto failure_cleanup;
> -	if ((ret = rtcan_peak_pci_add_chan(pdev, CHANNEL_SLAVE,
> -					   &master_dev)))
> -	    goto failure_cleanup;
> -    } else {
> -	if ((ret = rtcan_peak_pci_add_chan(pdev, CHANNEL_SINGLE,
> -					   &master_dev)))
> -	    goto failure_cleanup;
> -    }
> +        for(i = 0; i < num_channels; i++) {
> +                if ((ret = rtcan_peak_pci_add_chan(pdev, i, &master_dev)))
> +                        goto failure_cleanup;
> +        }
>  
> -    pci_set_drvdata(pdev, master_dev);
> -    return 0;
> +        pci_set_drvdata(pdev, master_dev);
> +        return 0;
>  
> - failure_cleanup:
> -    if (master_dev)
> -	rtcan_peak_pci_del_chan(master_dev, 0);
> +failure_cleanup:
> +        if (master_dev)
> +                rtcan_peak_pci_del_chan(master_dev, 0);
>  
> -    pci_release_regions(pdev);
> +        pci_release_regions(pdev);
>  
> - failure:
> -    return ret;
> +failure:
> +        return ret;
>  
>  }
>  
>  static void peak_pci_remove_one(struct pci_dev *pdev)
>  {
> -    struct rtcan_device *dev = pci_get_drvdata(pdev);
> -    struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
> +        struct rtcan_device *dev = pci_get_drvdata(pdev);
> +        struct rtcan_peak_pci *board = (struct rtcan_peak_pci *)dev->board_priv;
>  
> -    if (board->slave_dev)
> -	rtcan_peak_pci_del_chan(board->slave_dev, 0);
> -    rtcan_peak_pci_del_chan(dev, 0);
> +        if (board->slave_dev)
> +                rtcan_peak_pci_del_chan(board->slave_dev, 0);
> +        rtcan_peak_pci_del_chan(dev, 0);
>  
> -    pci_release_regions(pdev);
> -    pci_disable_device(pdev);
> -    pci_set_drvdata(pdev, NULL);
> +        pci_release_regions(pdev);
> +        pci_disable_device(pdev);
> +        pci_set_drvdata(pdev, NULL);
>  }
>  
>  static struct pci_driver rtcan_peak_pci_driver = {
> -	.name		= RTCAN_DRV_NAME,
> -	.id_table	= peak_pci_tbl,
> -	.probe		= peak_pci_init_one,
> -	.remove		= peak_pci_remove_one,
> +        .name		= RTCAN_DRV_NAME,
> +        .id_table	= peak_pci_tbl,
> +        .probe		= peak_pci_init_one,
> +        .remove		= peak_pci_remove_one,
>  };
>  
>  static int __init rtcan_peak_pci_init(void)
>  {
> -    return pci_register_driver(&rtcan_peak_pci_driver);
> +        return pci_register_driver(&rtcan_peak_pci_driver);
>  }
>  
>  
>  static void __exit rtcan_peak_pci_exit(void)
>  {
> -    pci_unregister_driver(&rtcan_peak_pci_driver);
> +        pci_unregister_driver(&rtcan_peak_pci_driver);
>  }
>  
>  module_init(rtcan_peak_pci_init);
> 

Please split functional changes from style fixes. Specifically, a patch
addressing the latter should have no impact on the binary output.

Thanks,
Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-11-07 11:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-07 11:33 [Xenomai] [PATCH] rtcan/peek_pci: add support for 3 and 4 port cards Konrad Banachowicz
2013-11-07 11:40 ` Jan Kiszka

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.