diff options
-rw-r--r-- | drivers/mfd/lpc_sch.c | 147 |
1 files changed, 71 insertions, 76 deletions
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index 5624fcbba69b..8cc6aac27cb2 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c | |||
@@ -45,34 +45,32 @@ static struct resource smbus_sch_resource = { | |||
45 | .flags = IORESOURCE_IO, | 45 | .flags = IORESOURCE_IO, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | |||
49 | static struct resource gpio_sch_resource = { | 48 | static struct resource gpio_sch_resource = { |
50 | .flags = IORESOURCE_IO, | 49 | .flags = IORESOURCE_IO, |
51 | }; | 50 | }; |
52 | 51 | ||
53 | static struct mfd_cell lpc_sch_cells[] = { | ||
54 | { | ||
55 | .name = "isch_smbus", | ||
56 | .num_resources = 1, | ||
57 | .resources = &smbus_sch_resource, | ||
58 | }, | ||
59 | { | ||
60 | .name = "sch_gpio", | ||
61 | .num_resources = 1, | ||
62 | .resources = &gpio_sch_resource, | ||
63 | }, | ||
64 | }; | ||
65 | |||
66 | static struct resource wdt_sch_resource = { | 52 | static struct resource wdt_sch_resource = { |
67 | .flags = IORESOURCE_IO, | 53 | .flags = IORESOURCE_IO, |
68 | }; | 54 | }; |
69 | 55 | ||
70 | static struct mfd_cell tunnelcreek_cells[] = { | 56 | static struct mfd_cell lpc_sch_cells[3]; |
71 | { | 57 | |
72 | .name = "ie6xx_wdt", | 58 | static struct mfd_cell isch_smbus_cell = { |
73 | .num_resources = 1, | 59 | .name = "isch_smbus", |
74 | .resources = &wdt_sch_resource, | 60 | .num_resources = 1, |
75 | }, | 61 | .resources = &smbus_sch_resource, |
62 | }; | ||
63 | |||
64 | static struct mfd_cell sch_gpio_cell = { | ||
65 | .name = "sch_gpio", | ||
66 | .num_resources = 1, | ||
67 | .resources = &gpio_sch_resource, | ||
68 | }; | ||
69 | |||
70 | static struct mfd_cell wdt_sch_cell = { | ||
71 | .name = "ie6xx_wdt", | ||
72 | .num_resources = 1, | ||
73 | .resources = &wdt_sch_resource, | ||
76 | }; | 74 | }; |
77 | 75 | ||
78 | static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = { | 76 | static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = { |
@@ -88,79 +86,76 @@ static int lpc_sch_probe(struct pci_dev *dev, | |||
88 | { | 86 | { |
89 | unsigned int base_addr_cfg; | 87 | unsigned int base_addr_cfg; |
90 | unsigned short base_addr; | 88 | unsigned short base_addr; |
91 | int i; | 89 | int i, cells = 0; |
92 | int ret; | 90 | int ret; |
93 | 91 | ||
94 | pci_read_config_dword(dev, SMBASE, &base_addr_cfg); | 92 | pci_read_config_dword(dev, SMBASE, &base_addr_cfg); |
95 | if (!(base_addr_cfg & (1 << 31))) { | 93 | base_addr = 0; |
96 | dev_err(&dev->dev, "Decode of the SMBus I/O range disabled\n"); | 94 | if (!(base_addr_cfg & (1 << 31))) |
97 | return -ENODEV; | 95 | dev_warn(&dev->dev, "Decode of the SMBus I/O range disabled\n"); |
98 | } | 96 | else |
99 | base_addr = (unsigned short)base_addr_cfg; | 97 | base_addr = (unsigned short)base_addr_cfg; |
100 | if (base_addr == 0) { | ||
101 | dev_err(&dev->dev, "I/O space for SMBus uninitialized\n"); | ||
102 | return -ENODEV; | ||
103 | } | ||
104 | |||
105 | smbus_sch_resource.start = base_addr; | ||
106 | smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1; | ||
107 | 98 | ||
108 | pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); | ||
109 | if (!(base_addr_cfg & (1 << 31))) { | ||
110 | dev_err(&dev->dev, "Decode of the GPIO I/O range disabled\n"); | ||
111 | return -ENODEV; | ||
112 | } | ||
113 | base_addr = (unsigned short)base_addr_cfg; | ||
114 | if (base_addr == 0) { | 99 | if (base_addr == 0) { |
115 | dev_err(&dev->dev, "I/O space for GPIO uninitialized\n"); | 100 | dev_warn(&dev->dev, "I/O space for SMBus uninitialized\n"); |
116 | return -ENODEV; | 101 | } else { |
102 | lpc_sch_cells[cells++] = isch_smbus_cell; | ||
103 | smbus_sch_resource.start = base_addr; | ||
104 | smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1; | ||
117 | } | 105 | } |
118 | 106 | ||
119 | gpio_sch_resource.start = base_addr; | 107 | pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); |
120 | 108 | base_addr = 0; | |
121 | if (id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) | 109 | if (!(base_addr_cfg & (1 << 31))) |
122 | gpio_sch_resource.end = base_addr + GPIO_IO_SIZE_CENTERTON - 1; | 110 | dev_warn(&dev->dev, "Decode of the GPIO I/O range disabled\n"); |
123 | else | 111 | else |
124 | gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; | 112 | base_addr = (unsigned short)base_addr_cfg; |
125 | |||
126 | for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++) | ||
127 | lpc_sch_cells[i].id = id->device; | ||
128 | 113 | ||
129 | ret = mfd_add_devices(&dev->dev, 0, | 114 | if (base_addr == 0) { |
130 | lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, | 115 | dev_warn(&dev->dev, "I/O space for GPIO uninitialized\n"); |
131 | 0, NULL); | 116 | } else { |
132 | if (ret) | 117 | lpc_sch_cells[cells++] = sch_gpio_cell; |
133 | goto out_dev; | 118 | gpio_sch_resource.start = base_addr; |
119 | if (id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) | ||
120 | gpio_sch_resource.end = base_addr + GPIO_IO_SIZE_CENTERTON - 1; | ||
121 | else | ||
122 | gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; | ||
123 | } | ||
134 | 124 | ||
135 | if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC | 125 | if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC |
136 | || id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) { | 126 | || id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) { |
137 | pci_read_config_dword(dev, WDTBASE, &base_addr_cfg); | 127 | pci_read_config_dword(dev, WDTBASE, &base_addr_cfg); |
138 | if (!(base_addr_cfg & (1 << 31))) { | 128 | base_addr = 0; |
139 | dev_err(&dev->dev, "Decode of the WDT I/O range disabled\n"); | 129 | if (!(base_addr_cfg & (1 << 31))) |
140 | ret = -ENODEV; | 130 | dev_warn(&dev->dev, "Decode of the WDT I/O range disabled\n"); |
141 | goto out_dev; | 131 | else |
132 | base_addr = (unsigned short)base_addr_cfg; | ||
133 | if (base_addr == 0) | ||
134 | dev_warn(&dev->dev, "I/O space for WDT uninitialized\n"); | ||
135 | else { | ||
136 | lpc_sch_cells[cells++] = wdt_sch_cell; | ||
137 | wdt_sch_resource.start = base_addr; | ||
138 | wdt_sch_resource.end = base_addr + WDT_IO_SIZE - 1; | ||
142 | } | 139 | } |
143 | base_addr = (unsigned short)base_addr_cfg; | 140 | } |
144 | if (base_addr == 0) { | ||
145 | dev_err(&dev->dev, "I/O space for WDT uninitialized\n"); | ||
146 | ret = -ENODEV; | ||
147 | goto out_dev; | ||
148 | } | ||
149 | |||
150 | wdt_sch_resource.start = base_addr; | ||
151 | wdt_sch_resource.end = base_addr + WDT_IO_SIZE - 1; | ||
152 | 141 | ||
153 | for (i = 0; i < ARRAY_SIZE(tunnelcreek_cells); i++) | 142 | if (WARN_ON(cells > ARRAY_SIZE(lpc_sch_cells))) { |
154 | tunnelcreek_cells[i].id = id->device; | 143 | dev_err(&dev->dev, "Cell count exceeds array size"); |
144 | return -ENODEV; | ||
145 | } | ||
155 | 146 | ||
156 | ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, | 147 | if (cells == 0) { |
157 | ARRAY_SIZE(tunnelcreek_cells), NULL, | 148 | dev_err(&dev->dev, "All decode registers disabled.\n"); |
158 | 0, NULL); | 149 | return -ENODEV; |
159 | } | 150 | } |
160 | 151 | ||
161 | return ret; | 152 | for (i = 0; i < cells; i++) |
162 | out_dev: | 153 | lpc_sch_cells[i].id = id->device; |
163 | mfd_remove_devices(&dev->dev); | 154 | |
155 | ret = mfd_add_devices(&dev->dev, 0, lpc_sch_cells, cells, NULL, 0, NULL); | ||
156 | if (ret) | ||
157 | mfd_remove_devices(&dev->dev); | ||
158 | |||
164 | return ret; | 159 | return ret; |
165 | } | 160 | } |
166 | 161 | ||