Version:  2.0.40 2.2.26 2.4.37 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17

Linux/arch/x86/platform/scx200/scx200_32.c

  1 /*
  2  *  Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
  3  *
  4  *  National Semiconductor SCx200 support.
  5  */
  6 
  7 #include <linux/module.h>
  8 #include <linux/errno.h>
  9 #include <linux/kernel.h>
 10 #include <linux/init.h>
 11 #include <linux/mutex.h>
 12 #include <linux/pci.h>
 13 
 14 #include <linux/scx200.h>
 15 #include <linux/scx200_gpio.h>
 16 
 17 /* Verify that the configuration block really is there */
 18 #define scx200_cb_probe(base) (inw((base) + SCx200_CBA) == (base))
 19 
 20 MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
 21 MODULE_DESCRIPTION("NatSemi SCx200 Driver");
 22 MODULE_LICENSE("GPL");
 23 
 24 unsigned scx200_gpio_base = 0;
 25 unsigned long scx200_gpio_shadow[2];
 26 
 27 unsigned scx200_cb_base = 0;
 28 
 29 static struct pci_device_id scx200_tbl[] = {
 30         { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
 31         { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
 32         { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SCx200_XBUS)   },
 33         { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_SC1100_XBUS)   },
 34         { },
 35 };
 36 MODULE_DEVICE_TABLE(pci,scx200_tbl);
 37 
 38 static int scx200_probe(struct pci_dev *, const struct pci_device_id *);
 39 
 40 static struct pci_driver scx200_pci_driver = {
 41         .name = "scx200",
 42         .id_table = scx200_tbl,
 43         .probe = scx200_probe,
 44 };
 45 
 46 static DEFINE_MUTEX(scx200_gpio_config_lock);
 47 
 48 static void scx200_init_shadow(void)
 49 {
 50         int bank;
 51 
 52         /* read the current values driven on the GPIO signals */
 53         for (bank = 0; bank < 2; ++bank)
 54                 scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank);
 55 }
 56 
 57 static int scx200_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 58 {
 59         unsigned base;
 60 
 61         if (pdev->device == PCI_DEVICE_ID_NS_SCx200_BRIDGE ||
 62             pdev->device == PCI_DEVICE_ID_NS_SC1100_BRIDGE) {
 63                 base = pci_resource_start(pdev, 0);
 64                 pr_info("GPIO base 0x%x\n", base);
 65 
 66                 if (!request_region(base, SCx200_GPIO_SIZE,
 67                                     "NatSemi SCx200 GPIO")) {
 68                         pr_err("can't allocate I/O for GPIOs\n");
 69                         return -EBUSY;
 70                 }
 71 
 72                 scx200_gpio_base = base;
 73                 scx200_init_shadow();
 74 
 75         } else {
 76                 /* find the base of the Configuration Block */
 77                 if (scx200_cb_probe(SCx200_CB_BASE_FIXED)) {
 78                         scx200_cb_base = SCx200_CB_BASE_FIXED;
 79                 } else {
 80                         pci_read_config_dword(pdev, SCx200_CBA_SCRATCH, &base);
 81                         if (scx200_cb_probe(base)) {
 82                                 scx200_cb_base = base;
 83                         } else {
 84                                 pr_warn("Configuration Block not found\n");
 85                                 return -ENODEV;
 86                         }
 87                 }
 88                 pr_info("Configuration Block base 0x%x\n", scx200_cb_base);
 89         }
 90 
 91         return 0;
 92 }
 93 
 94 u32 scx200_gpio_configure(unsigned index, u32 mask, u32 bits)
 95 {
 96         u32 config, new_config;
 97 
 98         mutex_lock(&scx200_gpio_config_lock);
 99 
100         outl(index, scx200_gpio_base + 0x20);
101         config = inl(scx200_gpio_base + 0x24);
102 
103         new_config = (config & mask) | bits;
104         outl(new_config, scx200_gpio_base + 0x24);
105 
106         mutex_unlock(&scx200_gpio_config_lock);
107 
108         return config;
109 }
110 
111 static int __init scx200_init(void)
112 {
113         pr_info("NatSemi SCx200 Driver\n");
114         return pci_register_driver(&scx200_pci_driver);
115 }
116 
117 static void __exit scx200_cleanup(void)
118 {
119         pci_unregister_driver(&scx200_pci_driver);
120         release_region(scx200_gpio_base, SCx200_GPIO_SIZE);
121 }
122 
123 module_init(scx200_init);
124 module_exit(scx200_cleanup);
125 
126 EXPORT_SYMBOL(scx200_gpio_base);
127 EXPORT_SYMBOL(scx200_gpio_shadow);
128 EXPORT_SYMBOL(scx200_gpio_configure);
129 EXPORT_SYMBOL(scx200_cb_base);
130 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us