lpc_sch.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  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. },
  71. };
  72. static const struct pci_device_id lpc_sch_ids[] = {
  73. { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC), LPC_SCH },
  74. { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC), LPC_ITC },
  75. { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CENTERTON_ILB), LPC_CENTERTON },
  76. { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_QUARK_X1000_ILB), LPC_QUARK_X1000 },
  77. { 0, }
  78. };
  79. MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
  80. #define LPC_NO_RESOURCE 1
  81. #define LPC_SKIP_RESOURCE 2
  82. static int lpc_sch_get_io(struct pci_dev *pdev, int where, const char *name,
  83. struct resource *res, int size)
  84. {
  85. unsigned int base_addr_cfg;
  86. unsigned short base_addr;
  87. if (size == 0)
  88. return LPC_NO_RESOURCE;
  89. pci_read_config_dword(pdev, where, &base_addr_cfg);
  90. base_addr = 0;
  91. if (!(base_addr_cfg & (1 << 31)))
  92. dev_warn(&pdev->dev, "Decode of the %s I/O range disabled\n",
  93. name);
  94. else
  95. base_addr = (unsigned short)base_addr_cfg;
  96. if (base_addr == 0) {
  97. dev_warn(&pdev->dev, "I/O space for %s uninitialized\n", name);
  98. return LPC_SKIP_RESOURCE;
  99. }
  100. res->start = base_addr;
  101. res->end = base_addr + size - 1;
  102. res->flags = IORESOURCE_IO;
  103. return 0;
  104. }
  105. static int lpc_sch_populate_cell(struct pci_dev *pdev, int where,
  106. const char *name, int size, int irq,
  107. int id, struct mfd_cell *cell)
  108. {
  109. struct resource *res;
  110. int ret;
  111. res = devm_kcalloc(&pdev->dev, 2, sizeof(*res), GFP_KERNEL);
  112. if (!res)
  113. return -ENOMEM;
  114. ret = lpc_sch_get_io(pdev, where, name, res, size);
  115. if (ret)
  116. return ret;
  117. memset(cell, 0, sizeof(*cell));
  118. cell->name = name;
  119. cell->resources = res;
  120. cell->num_resources = 1;
  121. cell->ignore_resource_conflicts = true;
  122. cell->id = id;
  123. /* Check if we need to add an IRQ resource */
  124. if (irq < 0)
  125. return 0;
  126. res++;
  127. res->start = irq;
  128. res->end = irq;
  129. res->flags = IORESOURCE_IRQ;
  130. cell->num_resources++;
  131. return 0;
  132. }
  133. static int lpc_sch_probe(struct pci_dev *dev, const struct pci_device_id *id)
  134. {
  135. struct mfd_cell lpc_sch_cells[3];
  136. struct lpc_sch_info *info = &sch_chipset_info[id->driver_data];
  137. unsigned int cells = 0;
  138. int ret;
  139. ret = lpc_sch_populate_cell(dev, SMBASE, "isch_smbus",
  140. info->io_size_smbus, -1,
  141. id->device, &lpc_sch_cells[cells]);
  142. if (ret < 0)
  143. return ret;
  144. if (ret == 0)
  145. cells++;
  146. ret = lpc_sch_populate_cell(dev, GPIOBASE, "sch_gpio",
  147. info->io_size_gpio, info->irq_gpio,
  148. id->device, &lpc_sch_cells[cells]);
  149. if (ret < 0)
  150. return ret;
  151. if (ret == 0)
  152. cells++;
  153. ret = lpc_sch_populate_cell(dev, WDTBASE, "ie6xx_wdt",
  154. info->io_size_wdt, -1,
  155. id->device, &lpc_sch_cells[cells]);
  156. if (ret < 0)
  157. return ret;
  158. if (ret == 0)
  159. cells++;
  160. if (cells == 0) {
  161. dev_err(&dev->dev, "All decode registers disabled.\n");
  162. return -ENODEV;
  163. }
  164. return mfd_add_devices(&dev->dev, 0, lpc_sch_cells, cells, NULL, 0, NULL);
  165. }
  166. static void lpc_sch_remove(struct pci_dev *dev)
  167. {
  168. mfd_remove_devices(&dev->dev);
  169. }
  170. static struct pci_driver lpc_sch_driver = {
  171. .name = "lpc_sch",
  172. .id_table = lpc_sch_ids,
  173. .probe = lpc_sch_probe,
  174. .remove = lpc_sch_remove,
  175. };
  176. module_pci_driver(lpc_sch_driver);
  177. MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
  178. MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH");
  179. MODULE_LICENSE("GPL");