Module: xenomai-head
Branch: master
Commit: bbd18368d30da7c76fd96a502e8f9628fe2f09b7
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=bbd18368d30da7c76fd96a502e8f9628fe2f09b7

Author: Stefan Kisdaroczi <ki...@hispeed.ch>
Date:   Fri Jan  7 20:21:48 2011 +0100

16550A: pci support

---

 ksrc/drivers/serial/16550A.c     |    3 +
 ksrc/drivers/serial/16550A_pci.h |  110 ++++++++++++++++++++++++++++++++++++++
 ksrc/drivers/serial/Kconfig      |    8 +++
 3 files changed, 121 insertions(+), 0 deletions(-)

diff --git a/ksrc/drivers/serial/16550A.c b/ksrc/drivers/serial/16550A.c
index f290e43..8c8c864 100644
--- a/ksrc/drivers/serial/16550A.c
+++ b/ksrc/drivers/serial/16550A.c
@@ -143,6 +143,7 @@ MODULE_AUTHOR("jan.kis...@web.de");
 
 #include "16550A_io.h"
 #include "16550A_pnp.h"
+#include "16550A_pci.h"
 
 static inline int rt_16550_rx_interrupt(struct rt_16550_context *ctx,
                                        uint64_t * timestamp)
@@ -1121,6 +1122,7 @@ int __init rt_16550_init(void)
        int i;
 
        rt_16550_pnp_init();
+       rt_16550_pci_init();
 
        for (i = 0; i < MAX_DEVICES; i++) {
                if (!rt_16550_addr_param(i))
@@ -1194,6 +1196,7 @@ void rt_16550_exit(void)
                        kfree(device[i]);
                }
 
+       rt_16550_pci_cleanup();
        rt_16550_pnp_cleanup();
 }
 
diff --git a/ksrc/drivers/serial/16550A_pci.h b/ksrc/drivers/serial/16550A_pci.h
new file mode 100644
index 0000000..442846d
--- /dev/null
+++ b/ksrc/drivers/serial/16550A_pci.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2006-2007 Jan Kiszka <jan.kis...@web.de>.
+ * Copyright (C) 2011 Stefan Kisdaroczi <ki...@hispeed.ch>.
+ *
+ * Xenomai is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Xenomai is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Xenomai; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && defined(CONFIG_PCI) && \
+       defined(CONFIG_XENO_DRIVERS_16550A_PCI)
+
+#include <linux/pci.h>
+
+struct rt_16550_pci_board {
+       char *name;
+       resource_size_t resource_base_addr;
+       unsigned int nports;
+       unsigned int port_ofs;
+       unsigned long irqtype;
+       unsigned int baud_base;
+       int tx_fifo;
+};
+
+DEFINE_PCI_DEVICE_TABLE( rt_16550_pci_table ) = {
+       { }
+};
+
+static int __devinit rt_16550_pci_probe( struct pci_dev *pdev,
+                                        const struct pci_device_id *ent )
+{
+       struct rt_16550_pci_board *board;
+       int err;
+       int i;
+       int port = 0;
+       int base_addr;
+       int max_devices = 0;
+
+       if (!ent->driver_data)
+               return -ENODEV;
+
+       board = (struct rt_16550_pci_board *)ent->driver_data;
+
+       for (i = 0; i < MAX_DEVICES; i++)
+               if (!rt_16550_addr_param(i))
+                       max_devices++;
+
+       if (board->nports > max_devices)
+               return -ENODEV;
+
+       if ((err = pci_enable_device(pdev)))
+               return err;
+
+       base_addr = pci_resource_start(pdev, board->resource_base_addr);
+
+       for (i = 0; i < MAX_DEVICES; i++) {
+               if ((port < board->nports) && (!rt_16550_addr_param(i))) {
+                       io[i] = base_addr + port * board->port_ofs;
+                       irq[i] = pdev->irq;
+                       irqtype[i] = board->irqtype;
+                       baud_base[i] = board->baud_base;
+                       tx_fifo[i] = board->tx_fifo;
+                       port++;
+               }
+       }
+
+       return 0;
+}
+
+static void __devexit rt_16550_pci_remove( struct pci_dev *pdev ) {
+       pci_disable_device( pdev );
+};
+
+static struct pci_driver rt_16550_pci_driver = {
+       .name     = RT_16550_DRIVER_NAME,
+       .id_table = rt_16550_pci_table,
+       .probe    = rt_16550_pci_probe,
+       .remove   = __devexit_p(rt_16550_pci_remove)
+};
+
+static int pci_registered;
+
+static inline void rt_16550_pci_init(void)
+{
+       if (pci_register_driver(&rt_16550_pci_driver) == 0)
+               pci_registered = 1;
+}
+
+static inline void rt_16550_pci_cleanup(void)
+{
+       if (pci_registered)
+               pci_unregister_driver(&rt_16550_pci_driver);
+}
+
+#else /* Linux < 2.6.0 || !CONFIG_PCI || !(..._16550A_PCI */
+
+#define rt_16550_pci_init()    do { } while (0)
+#define rt_16550_pci_cleanup() do { } while (0)
+
+#endif /* Linux < 2.6.0 || !CONFIG_PCI || !(..._16550A_PCI */
diff --git a/ksrc/drivers/serial/Kconfig b/ksrc/drivers/serial/Kconfig
index afbaabf..b468fbc 100644
--- a/ksrc/drivers/serial/Kconfig
+++ b/ksrc/drivers/serial/Kconfig
@@ -39,4 +39,12 @@ config XENO_DRIVERS_16550A_ANY
 
 endchoice
 
+config XENO_DRIVERS_16550A_PCI
+       depends on XENO_DRIVERS_16550A_PIO || XENO_DRIVERS_16550A_ANY
+       bool "PCI board support"
+       default n
+       help
+
+       This option activates support for PCI serial boards.
+
 endmenu


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to