0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/errno.h>
0018 #include <linux/acpi.h>
0019 #include <linux/pci.h>
0020 #include <linux/mfd/core.h>
0021
0022 #define SMBASE 0x40
0023 #define SMBUS_IO_SIZE 64
0024
0025 #define GPIO_BASE 0x44
0026 #define GPIO_IO_SIZE 64
0027 #define GPIO_IO_SIZE_CENTERTON 128
0028
0029 #define WDTBASE 0x84
0030 #define WDT_IO_SIZE 64
0031
0032 enum sch_chipsets {
0033 LPC_SCH = 0,
0034 LPC_ITC,
0035 LPC_CENTERTON,
0036 LPC_QUARK_X1000,
0037 };
0038
0039 struct lpc_sch_info {
0040 unsigned int io_size_smbus;
0041 unsigned int io_size_gpio;
0042 unsigned int io_size_wdt;
0043 };
0044
0045 static struct lpc_sch_info sch_chipset_info[] = {
0046 [LPC_SCH] = {
0047 .io_size_smbus = SMBUS_IO_SIZE,
0048 .io_size_gpio = GPIO_IO_SIZE,
0049 },
0050 [LPC_ITC] = {
0051 .io_size_smbus = SMBUS_IO_SIZE,
0052 .io_size_gpio = GPIO_IO_SIZE,
0053 .io_size_wdt = WDT_IO_SIZE,
0054 },
0055 [LPC_CENTERTON] = {
0056 .io_size_smbus = SMBUS_IO_SIZE,
0057 .io_size_gpio = GPIO_IO_SIZE_CENTERTON,
0058 .io_size_wdt = WDT_IO_SIZE,
0059 },
0060 [LPC_QUARK_X1000] = {
0061 .io_size_gpio = GPIO_IO_SIZE,
0062 .io_size_wdt = WDT_IO_SIZE,
0063 },
0064 };
0065
0066 static const struct pci_device_id lpc_sch_ids[] = {
0067 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC), LPC_SCH },
0068 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC), LPC_ITC },
0069 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CENTERTON_ILB), LPC_CENTERTON },
0070 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_QUARK_X1000_ILB), LPC_QUARK_X1000 },
0071 { 0, }
0072 };
0073 MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
0074
0075 #define LPC_NO_RESOURCE 1
0076 #define LPC_SKIP_RESOURCE 2
0077
0078 static int lpc_sch_get_io(struct pci_dev *pdev, int where, const char *name,
0079 struct resource *res, int size)
0080 {
0081 unsigned int base_addr_cfg;
0082 unsigned short base_addr;
0083
0084 if (size == 0)
0085 return LPC_NO_RESOURCE;
0086
0087 pci_read_config_dword(pdev, where, &base_addr_cfg);
0088 base_addr = 0;
0089 if (!(base_addr_cfg & (1 << 31)))
0090 dev_warn(&pdev->dev, "Decode of the %s I/O range disabled\n",
0091 name);
0092 else
0093 base_addr = (unsigned short)base_addr_cfg;
0094
0095 if (base_addr == 0) {
0096 dev_warn(&pdev->dev, "I/O space for %s uninitialized\n", name);
0097 return LPC_SKIP_RESOURCE;
0098 }
0099
0100 res->start = base_addr;
0101 res->end = base_addr + size - 1;
0102 res->flags = IORESOURCE_IO;
0103
0104 return 0;
0105 }
0106
0107 static int lpc_sch_populate_cell(struct pci_dev *pdev, int where,
0108 const char *name, int size, int id,
0109 struct mfd_cell *cell)
0110 {
0111 struct resource *res;
0112 int ret;
0113
0114 res = devm_kzalloc(&pdev->dev, sizeof(*res), GFP_KERNEL);
0115 if (!res)
0116 return -ENOMEM;
0117
0118 ret = lpc_sch_get_io(pdev, where, name, res, size);
0119 if (ret)
0120 return ret;
0121
0122 memset(cell, 0, sizeof(*cell));
0123
0124 cell->name = name;
0125 cell->resources = res;
0126 cell->num_resources = 1;
0127 cell->ignore_resource_conflicts = true;
0128 cell->id = id;
0129
0130 return 0;
0131 }
0132
0133 static int lpc_sch_probe(struct pci_dev *dev, const struct pci_device_id *id)
0134 {
0135 struct mfd_cell lpc_sch_cells[3];
0136 struct lpc_sch_info *info = &sch_chipset_info[id->driver_data];
0137 unsigned int cells = 0;
0138 int ret;
0139
0140 ret = lpc_sch_populate_cell(dev, SMBASE, "isch_smbus",
0141 info->io_size_smbus,
0142 id->device, &lpc_sch_cells[cells]);
0143 if (ret < 0)
0144 return ret;
0145 if (ret == 0)
0146 cells++;
0147
0148 ret = lpc_sch_populate_cell(dev, GPIO_BASE, "sch_gpio",
0149 info->io_size_gpio,
0150 id->device, &lpc_sch_cells[cells]);
0151 if (ret < 0)
0152 return ret;
0153 if (ret == 0)
0154 cells++;
0155
0156 ret = lpc_sch_populate_cell(dev, WDTBASE, "ie6xx_wdt",
0157 info->io_size_wdt,
0158 id->device, &lpc_sch_cells[cells]);
0159 if (ret < 0)
0160 return ret;
0161 if (ret == 0)
0162 cells++;
0163
0164 if (cells == 0) {
0165 dev_err(&dev->dev, "All decode registers disabled.\n");
0166 return -ENODEV;
0167 }
0168
0169 return mfd_add_devices(&dev->dev, 0, lpc_sch_cells, cells, NULL, 0, NULL);
0170 }
0171
0172 static void lpc_sch_remove(struct pci_dev *dev)
0173 {
0174 mfd_remove_devices(&dev->dev);
0175 }
0176
0177 static struct pci_driver lpc_sch_driver = {
0178 .name = "lpc_sch",
0179 .id_table = lpc_sch_ids,
0180 .probe = lpc_sch_probe,
0181 .remove = lpc_sch_remove,
0182 };
0183
0184 module_pci_driver(lpc_sch_driver);
0185
0186 MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
0187 MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH");
0188 MODULE_LICENSE("GPL");