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

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. scx200_init_shadow
  2. scx200_probe
  3. scx200_gpio_configure
  4. scx200_init
  5. scx200_cleanup

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

/* [<][>][^][v][top][bottom][index][help] */