lpc_sch.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * lpc_sch.c - LPC interface for Intel Poulsbo SCH
  3. *
  4. * LPC bridge function of the Intel SCH contains many other
  5. * functional units, such as Interrupt controllers, Timers,
  6. * Power Management, System Management, GPIO, RTC, and LPC
  7. * Configuration Registers.
  8. *
  9. * Copyright (c) 2010 CompuLab Ltd
  10. * Copyright (c) 2014 Intel Corp.
  11. * Author: Denis Turischev <denis@compulab.co.il>
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License 2 as published
  15. * by the Free Software Foundation.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. */
  22. #include <linux/kernel.h>
  23. #include <linux/module.h>
  24. #include <linux/errno.h>
  25. #include <linux/acpi.h>
  26. #include <linux/pci.h>
  27. #include <linux/mfd/core.h>
  28. #define SMBASE 0x40
  29. #define SMBUS_IO_SIZE 64
  30. #define GPIOBASE 0x44
  31. #define GPIO_IO_SIZE 64
  32. #define GPIO_IO_SIZE_CENTERTON 128
  33. /* Intel Quark X1000 GPIO IRQ Number */
  34. #define GPIO_IRQ_QUARK_X1000 9
  35. #define WDTBASE 0x84
  36. #define WDT_IO_SIZE 64
  37. enum sch_chipsets {
  38. LPC_SCH = 0, /* Intel Poulsbo SCH */
  39. LPC_ITC, /* Intel Tunnel Creek */
  40. LPC_CENTERTON, /* Intel Centerton */
  41. LPC_QUARK_X1000, /* Intel Quark X1000 */
  42. };
  43. struct lpc_sch_info {
  44. unsigned int io_size_smbus;
  45. unsigned int io_size_gpio;
  46. unsigned int io_size_wdt;
  47. int irq_gpio;
  48. };
  49. static struct lpc_sch_info sch_chipset_info[] = {
  50. [LPC_SCH] = {
  51. .io_size_smbus = SMBUS_IO_SIZE,
  52. .io_size_gpio = GPIO_IO_SIZE,
  53. .irq_gpio = -1,
  54. },
  55. [LPC_ITC] = {
  56. .io_size_smbus = SMBUS_IO_SIZE,
  57. .io_size_gpio = GPIO_IO_SIZE,
  58. .io_size_wdt = WDT_IO_SIZE,
  59. .irq_gpio = -1,
  60. },
  61. [LPC_CENTERTON] = {
  62. .io_size_smbus = SMBUS_IO_SIZE,
  63. .io_size_gpio = GPIO_IO_SIZE_CENTERTON,
  64. .io_size_wdt = WDT_IO_SIZE,
  65. .irq_gpio = -1,
  66. },
  67. [LPC_QUARK_X1000] = {
  68. .io_size_gpio = GPIO_IO_SIZE,
  69. .irq_gpio = GPIO_IRQ_QUARK_X1000,
  70. .io_size_wdt = WDT_IO_SIZE,
  71. },
  72. };
  73. static const struct pci_device_id lpc_sch_ids[] = {
  74. { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC), LPC_SCH },
  75. { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC), LPC_ITC },
  76. { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CENTERTON_ILB), LPC_CENTERTON },
  77. { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_QUARK_X1000_ILB), LPC_QUARK_X1000 },
  78. { 0, }
  79. };
  80. MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
  81. #define LPC_NO_RESOURCE 1
  82. #define LPC_SKIP_RESOURCE 2
  83. static int lpc_sch_get_io(struct pci_dev *pdev, int where, const char *name,
  84. struct resource *res, int size)
  85. {
  86. unsigned int base_addr_cfg;
  87. unsigned short base_addr;
  88. if (size == 0)
  89. return LPC_NO_RESOURCE;
  90. pci_read_config_dword(pdev, where, &base_addr_cfg);
  91. base_addr = 0;
  92. if (!(base_addr_cfg & (1 << 31)))
  93. dev_warn(&pdev->dev, "Decode of the %s I/O range disabled\n",
  94. name);
  95. else
  96. base_addr = (unsigned short)base_addr_cfg;
  97. if (base_addr == 0) {
  98. dev_warn(&pdev->dev, "I/O space for %s uninitialized\n", name);
  99. return LPC_SKIP_RESOURCE;
  100. }
  101. res->start = base_addr;
  102. res->end = base_addr + size - 1;
  103. res->flags = IORESOURCE_IO;
  104. return 0;
  105. }
  106. static int lpc_sch_populate_cell(struct pci_dev *pdev, int where,
  107. const char *name, int size, int irq,
  108. int id, struct mfd_cell *cell)
  109. {
  110. struct resource *res;
  111. int ret;
  112. res = devm_kcalloc(&pdev->dev, 2, sizeof(*res), GFP_KERNEL);
  113. if (!res)
  114. return -ENOMEM;
  115. ret = lpc_sch_get_io(pdev, where, name, res, size);
  116. if (ret)
  117. return ret;
  118. memset(cell, 0, sizeof(*cell));
  119. cell->name = name;
  120. cell->resources = res;
  121. cell->num_resources = 1;
  122. cell->ignore_resource_conflicts = true;
  123. cell->id = id;
  124. /* Check if we need to add an IRQ resource */
  125. if (irq < 0)
  126. return 0;
  127. res++;
  128. res->start = irq;
  129. res->end = irq;
  130. res->flags = IORESOURCE_IRQ;
  131. cell->num_resources++;
  132. return 0;
  133. }
  134. static int lpc_sch_probe(struct pci_dev *dev, const struct pci_device_id *id)
  135. {
  136. struct mfd_cell lpc_sch_cells[3];
  137. struct lpc_sch_info *info = &sch_chipset_info[id->driver_data];
  138. unsigned int cells = 0;
  139. int ret;
  140. ret = lpc_sch_populate_cell(dev, SMBASE, "isch_smbus",
  141. info->io_size_smbus, -1,
  142. id->device, &lpc_sch_cells[cells]);
  143. if (ret < 0)
  144. return ret;
  145. if (ret == 0)
  146. cells++;
  147. ret = lpc_sch_populate_cell(dev, GPIOBASE, "sch_gpio",
  148. info->io_size_gpio, info->irq_gpio,
  149. id->device, &lpc_sch_cells[cells]);
  150. if (ret < 0)
  151. return ret;
  152. if (ret == 0)
  153. cells++;
  154. ret = lpc_sch_populate_cell(dev, WDTBASE, "ie6xx_wdt",
  155. info->io_size_wdt, -1,
  156. id->device, &lpc_sch_cells[cells]);
  157. if (ret < 0)
  158. return ret;
  159. if (ret == 0)
  160. cells++;
  161. if (cells == 0) {
  162. dev_err(&dev->dev, "All decode registers disabled.\n");
  163. return -ENODEV;
  164. }
  165. return mfd_add_devices(&dev->dev, 0, lpc_sch_cells, cells, NULL, 0, NULL);
  166. }
  167. static void lpc_sch_remove(struct pci_dev *dev)
  168. {
  169. mfd_remove_devices(&dev->dev);
  170. }
  171. static struct pci_driver lpc_sch_driver = {
  172. .name = "lpc_sch",
  173. .id_table = lpc_sch_ids,
  174. .probe = lpc_sch_probe,
  175. .remove = lpc_sch_remove,
  176. };
  177. module_pci_driver(lpc_sch_driver);
  178. MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
  179. MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH");
  180. MODULE_LICENSE("GPL");